GCC Code Coverage Report


Directory: libs/json/include/boost/json/
File: impl/serialize.ipp
Date: 2025-12-23 17:22:01
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 static
54 void
55 18851 serialize_impl(
56 std::string& s,
57 serializer& sr)
58 {
59 // serialize to a small buffer to avoid
60 // the first few allocations in std::string
61 char buf[BOOST_JSON_STACK_BUFFER_SIZE];
62 18851 string_view sv;
63
1/1
✓ Branch 1 taken 18851 times.
18851 sv = sr.read(buf);
64
2/2
✓ Branch 1 taken 10843 times.
✓ Branch 2 taken 8008 times.
18851 if(sr.done())
65 {
66 // fast path
67
1/1
✓ Branch 3 taken 10843 times.
10843 s.append(
68 sv.data(), sv.size());
69 10843 return;
70 }
71 8008 std::size_t len = sv.size();
72
1/1
✓ Branch 1 taken 8008 times.
8008 s.reserve(len * 2);
73
1/1
✓ Branch 2 taken 8008 times.
8008 s.resize(s.capacity());
74
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8008 times.
8008 BOOST_ASSERT(
75 s.size() >= len * 2);
76
1/1
✓ Branch 2 taken 8008 times.
16016 std::memcpy(&s[0],
77 8008 sv.data(), sv.size());
78 auto const lim =
79 8008 s.max_size() / 2;
80 for(;;)
81 {
82 sv = sr.read(
83
2/2
✓ Branch 1 taken 8008 times.
✓ Branch 4 taken 8008 times.
8008 &s[0] + len,
84 8008 s.size() - len);
85 8008 len += sv.size();
86
1/2
✓ Branch 1 taken 8008 times.
✗ Branch 2 not taken.
8008 if(sr.done())
87 8008 break;
88 // growth factor 2x
89 if(s.size() < lim)
90 s.resize(s.size() * 2);
91 else
92 s.resize(2 * lim);
93 }
94
1/1
✓ Branch 1 taken 8008 times.
8008 s.resize(len);
95 }
96
97 std::string
98 18799 serialize(
99 value const& jv,
100 serialize_options const& opts)
101 {
102 unsigned char buf[256];
103 serializer sr(
104 37598 storage_ptr(),
105 buf,
106 sizeof(buf),
107 18799 opts);
108 18799 sr.reset(&jv);
109 18799 std::string s;
110
1/1
✓ Branch 1 taken 18799 times.
18799 serialize_impl(s, sr);
111 37598 return s;
112 18799 }
113
114 std::string
115 2 serialize(
116 array const& arr,
117 serialize_options const& opts)
118 {
119 unsigned char buf[256];
120 serializer sr(
121 4 storage_ptr(),
122 buf,
123 sizeof(buf),
124 2 opts);
125 2 std::string s;
126 2 sr.reset(&arr);
127
1/1
✓ Branch 1 taken 2 times.
2 serialize_impl(s, sr);
128 4 return s;
129 2 }
130
131 std::string
132 49 serialize(
133 object const& obj,
134 serialize_options const& opts)
135 {
136 unsigned char buf[256];
137 serializer sr(
138 98 storage_ptr(),
139 buf,
140 sizeof(buf),
141 49 opts);
142 49 std::string s;
143 49 sr.reset(&obj);
144
1/1
✓ Branch 1 taken 49 times.
49 serialize_impl(s, sr);
145 98 return s;
146 49 }
147
148 std::string
149 1 serialize(
150 string const& str,
151 serialize_options const& opts)
152 {
153 1 return serialize( str.subview(), opts );
154 }
155
156 // this is here for key_value_pair::key()
157 std::string
158 1 serialize(
159 string_view sv,
160 serialize_options const& opts)
161 {
162 unsigned char buf[256];
163 serializer sr(
164 2 storage_ptr(),
165 buf,
166 sizeof(buf),
167 1 opts);
168 1 std::string s;
169 1 sr.reset(sv);
170
1/1
✓ Branch 1 taken 1 times.
1 serialize_impl(s, sr);
171 2 return s;
172 1 }
173
174 //----------------------------------------------------------
175
176 //[example_operator_lt__lt_
177 // Serialize a value into an output stream
178
179 std::ostream&
180 6 operator<<( std::ostream& os, value const& jv )
181 {
182 // Create a serializer
183
1/1
✓ Branch 1 taken 6 times.
6 serializer sr( get_stream_flags(os) );
184
185 // Set the serializer up for our value
186 6 sr.reset( &jv );
187
188 // Loop until all output is produced.
189
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
12 while( ! sr.done() )
190 {
191 // Use a local buffer to avoid allocation.
192 char buf[ BOOST_JSON_STACK_BUFFER_SIZE ];
193
194 // Fill our buffer with serialized characters and write it to the output stream.
195
2/2
✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
6 os << sr.read( buf );
196 }
197
198 6 return os;
199 6 }
200 //]
201
202 static
203 void
204 3 to_ostream(
205 std::ostream& os,
206 serializer& sr)
207 {
208
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
6 while(! sr.done())
209 {
210 char buf[BOOST_JSON_STACK_BUFFER_SIZE];
211
1/1
✓ Branch 1 taken 3 times.
3 auto s = sr.read(buf);
212
1/1
✓ Branch 3 taken 3 times.
3 os.write(s.data(), s.size());
213 }
214 3 }
215
216 std::ostream&
217 1 operator<<(
218 std::ostream& os,
219 array const& arr)
220 {
221
1/1
✓ Branch 1 taken 1 times.
1 serializer sr( get_stream_flags(os) );
222 1 sr.reset(&arr);
223
1/1
✓ Branch 1 taken 1 times.
1 to_ostream(os, sr);
224 1 return os;
225 1 }
226
227 std::ostream&
228 1 operator<<(
229 std::ostream& os,
230 object const& obj)
231 {
232
1/1
✓ Branch 1 taken 1 times.
1 serializer sr( get_stream_flags(os) );
233 1 sr.reset(&obj);
234
1/1
✓ Branch 1 taken 1 times.
1 to_ostream(os, sr);
235 1 return os;
236 1 }
237
238 std::ostream&
239 1 operator<<(
240 std::ostream& os,
241 string const& str)
242 {
243
1/1
✓ Branch 1 taken 1 times.
1 serializer sr( get_stream_flags(os) );
244 1 sr.reset(&str);
245
1/1
✓ Branch 1 taken 1 times.
1 to_ostream(os, sr);
246 1 return os;
247 1 }
248
249 std::ostream&
250 2 operator<<( std::ostream& os, serialize_options const& opts )
251 {
252 2 os.iword(serialize_xalloc) = to_bitmask(opts);
253 2 return os;
254 }
255
256 } // namespace json
257 } // namespace boost
258
259 #endif
260