GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: impl/serialize.ipp
Date: 2025-12-23 17:20:53
Exec Total Coverage
Lines: 95 99 96.0%
Functions: 14 14 100.0%
Branches: 34 40 85.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/json
8 //
9
10 #ifndef BOOST_JSON_IMPL_SERIALIZE_IPP
11 #define BOOST_JSON_IMPL_SERIALIZE_IPP
12
13 #include <boost/json/serialize.hpp>
14 #include <boost/json/serializer.hpp>
15 #include <ostream>
16
17 namespace boost {
18 namespace json {
19
20 namespace {
21
22 int serialize_xalloc = std::ios::xalloc();
23
24 enum class serialize_stream_flags : long
25 {
26 allow_infinity_and_nan = 1,
27 };
28
29 std::underlying_type<serialize_stream_flags>::type
30 2 to_bitmask( serialize_options const& opts )
31 {
32 using E = serialize_stream_flags;
33 using I = std::underlying_type<E>::type;
34 2 return (opts.allow_infinity_and_nan
35
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 ? static_cast<I>(E::allow_infinity_and_nan) : 0);
36 }
37
38 serialize_options
39 9 get_stream_flags( std::ostream& os )
40 {
41
1/1
✓ Branch 1 taken 9 times.
9 auto const flags = os.iword(serialize_xalloc);
42
43 9 serialize_options opts;
44 using E = serialize_stream_flags;
45 using I = std::underlying_type<E>::type;
46 9 opts.allow_infinity_and_nan =
47 9 flags & static_cast<I>(E::allow_infinity_and_nan);
48 9 return opts;
49 }
50
51 } // namespace
52
53 namespace detail {
54
55 void
56 18898 serialize_impl(
57 std::string& s,
58 serializer& sr)
59 {
60 // serialize to a small buffer to avoid
61 // the first few allocations in std::string
62 char buf[BOOST_JSON_STACK_BUFFER_SIZE];
63 18898 string_view sv;
64
1/1
✓ Branch 1 taken 18898 times.
18898 sv = sr.read(buf);
65
2/2
✓ Branch 1 taken 10890 times.
✓ Branch 2 taken 8008 times.
18898 if(sr.done())
66 {
67 // fast path
68
1/1
✓ Branch 3 taken 10890 times.
10890 s.append(
69 sv.data(), sv.size());
70 10890 return;
71 }
72 8008 std::size_t len = sv.size();
73
1/1
✓ Branch 1 taken 8008 times.
8008 s.reserve(len * 2);
74
1/1
✓ Branch 2 taken 8008 times.
8008 s.resize(s.capacity());
75
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8008 times.
8008 BOOST_ASSERT(
76 s.size() >= len * 2);
77
1/1
✓ Branch 2 taken 8008 times.
16016 std::memcpy(&s[0],
78 8008 sv.data(), sv.size());
79 auto const lim =
80 8008 s.max_size() / 2;
81 for(;;)
82 {
83 sv = sr.read(
84
2/2
✓ Branch 1 taken 8008 times.
✓ Branch 4 taken 8008 times.
8008 &s[0] + len,
85 8008 s.size() - len);
86 8008 len += sv.size();
87
1/2
✓ Branch 1 taken 8008 times.
✗ Branch 2 not taken.
8008 if(sr.done())
88 8008 break;
89 // growth factor 2x
90 if(s.size() < lim)
91 s.resize(s.size() * 2);
92 else
93 s.resize(2 * lim);
94 }
95
1/1
✓ Branch 1 taken 8008 times.
8008 s.resize(len);
96 }
97
98 } // namespace detail
99
100 std::string
101 18806 serialize(
102 value const& jv,
103 serialize_options const& opts)
104 {
105 unsigned char buf[256];
106 serializer sr(
107 37612 storage_ptr(),
108 buf,
109 sizeof(buf),
110 18806 opts);
111 18806 sr.reset(&jv);
112 18806 std::string s;
113
1/1
✓ Branch 1 taken 18806 times.
18806 serialize_impl(s, sr);
114 37612 return s;
115 18806 }
116
117 std::string
118 2 serialize(
119 array const& arr,
120 serialize_options const& opts)
121 {
122 unsigned char buf[256];
123 serializer sr(
124 4 storage_ptr(),
125 buf,
126 sizeof(buf),
127 2 opts);
128 2 std::string s;
129 2 sr.reset(&arr);
130
1/1
✓ Branch 1 taken 2 times.
2 serialize_impl(s, sr);
131 4 return s;
132 2 }
133
134 std::string
135 49 serialize(
136 object const& obj,
137 serialize_options const& opts)
138 {
139 unsigned char buf[256];
140 serializer sr(
141 98 storage_ptr(),
142 buf,
143 sizeof(buf),
144 49 opts);
145 49 std::string s;
146 49 sr.reset(&obj);
147
1/1
✓ Branch 1 taken 49 times.
49 serialize_impl(s, sr);
148 98 return s;
149 49 }
150
151 std::string
152 1 serialize(
153 string const& str,
154 serialize_options const& opts)
155 {
156 1 return serialize( str.subview(), opts );
157 }
158
159 // this is here for key_value_pair::key()
160 std::string
161 1 serialize(
162 string_view sv,
163 serialize_options const& opts)
164 {
165 unsigned char buf[256];
166 serializer sr(
167 2 storage_ptr(),
168 buf,
169 sizeof(buf),
170 1 opts);
171 1 std::string s;
172 1 sr.reset(sv);
173
1/1
✓ Branch 1 taken 1 times.
1 serialize_impl(s, sr);
174 2 return s;
175 1 }
176
177 //----------------------------------------------------------
178
179 //[example_operator_lt__lt_
180 // Serialize a value into an output stream
181
182 std::ostream&
183 6 operator<<( std::ostream& os, value const& jv )
184 {
185 // Create a serializer
186
1/1
✓ Branch 1 taken 6 times.
6 serializer sr( get_stream_flags(os) );
187
188 // Set the serializer up for our value
189 6 sr.reset( &jv );
190
191 // Loop until all output is produced.
192
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
12 while( ! sr.done() )
193 {
194 // Use a local buffer to avoid allocation.
195 char buf[ BOOST_JSON_STACK_BUFFER_SIZE ];
196
197 // Fill our buffer with serialized characters and write it to the output stream.
198
2/2
✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
6 os << sr.read( buf );
199 }
200
201 6 return os;
202 6 }
203 //]
204
205 static
206 void
207 3 to_ostream(
208 std::ostream& os,
209 serializer& sr)
210 {
211
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
6 while(! sr.done())
212 {
213 char buf[BOOST_JSON_STACK_BUFFER_SIZE];
214
1/1
✓ Branch 1 taken 3 times.
3 auto s = sr.read(buf);
215
1/1
✓ Branch 3 taken 3 times.
3 os.write(s.data(), s.size());
216 }
217 3 }
218
219 std::ostream&
220 1 operator<<(
221 std::ostream& os,
222 array const& arr)
223 {
224
1/1
✓ Branch 1 taken 1 times.
1 serializer sr( get_stream_flags(os) );
225 1 sr.reset(&arr);
226
1/1
✓ Branch 1 taken 1 times.
1 to_ostream(os, sr);
227 1 return os;
228 1 }
229
230 std::ostream&
231 1 operator<<(
232 std::ostream& os,
233 object const& obj)
234 {
235
1/1
✓ Branch 1 taken 1 times.
1 serializer sr( get_stream_flags(os) );
236 1 sr.reset(&obj);
237
1/1
✓ Branch 1 taken 1 times.
1 to_ostream(os, sr);
238 1 return os;
239 1 }
240
241 std::ostream&
242 1 operator<<(
243 std::ostream& os,
244 string const& str)
245 {
246
1/1
✓ Branch 1 taken 1 times.
1 serializer sr( get_stream_flags(os) );
247 1 sr.reset(&str);
248
1/1
✓ Branch 1 taken 1 times.
1 to_ostream(os, sr);
249 1 return os;
250 1 }
251
252 std::ostream&
253 2 operator<<( std::ostream& os, serialize_options const& opts )
254 {
255 2 os.iword(serialize_xalloc) = to_bitmask(opts);
256 2 return os;
257 }
258
259 } // namespace json
260 } // namespace boost
261
262 #endif
263