impl/serialize.ipp

99.0% Lines (96 / 97) 100.0% Functions (14 / 14)
serialize.ipp
f(x) Functions (14)
Function Calls Lines Blocks
boost::json::(anonymous namespace)::to_bitmask(boost::json::serialize_options const&) :30 2x 100.0% 100.0% boost::json::(anonymous namespace)::get_stream_flags(std::ostream&) :39 10x 100.0% 100.0% boost::json::detail::serialize_impl(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, boost::json::serializer&) :56 18894x 95.2% 94.0% boost::json::serialize[abi:cxx11](boost::json::value const&, boost::json::serialize_options const&) :99 18801x 100.0% 73.0% boost::json::serialize[abi:cxx11](boost::json::array const&, boost::json::serialize_options const&) :116 2x 100.0% 73.0% boost::json::serialize[abi:cxx11](boost::json::object const&, boost::json::serialize_options const&) :133 49x 100.0% 73.0% boost::json::serialize[abi:cxx11](boost::json::string const&, boost::json::serialize_options const&) :150 2x 100.0% 100.0% boost::json::serialize[abi:cxx11](boost::core::basic_string_view<char>, boost::json::serialize_options const&) :159 2x 100.0% 73.0% boost::json::operator<<(std::ostream&, boost::json::value const&) :181 6x 100.0% 76.0% boost::json::to_ostream(std::ostream&, boost::json::serializer&) :205 4x 100.0% 100.0% boost::json::operator<<(std::ostream&, boost::json::array const&) :218 1x 100.0% 73.0% boost::json::operator<<(std::ostream&, boost::json::object const&) :229 1x 100.0% 73.0% boost::json::operator<<(std::ostream&, boost::json::string const&) :240 2x 100.0% 73.0% boost::json::operator<<(std::ostream&, boost::json::serialize_options const&) :251 2x 100.0% 100.0%
Line TLA Hits Source Code
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 2x to_bitmask( serialize_options const& opts )
31 {
32 using E = serialize_stream_flags;
33 using I = std::underlying_type<E>::type;
34 2x return (opts.allow_infinity_and_nan
35 2x ? static_cast<I>(E::allow_infinity_and_nan) : 0);
36 }
37
38 serialize_options
39 10x get_stream_flags( std::ostream& os )
40 {
41 10x auto const flags = os.iword(serialize_xalloc);
42
43 10x serialize_options opts;
44 using E = serialize_stream_flags;
45 using I = std::underlying_type<E>::type;
46 10x opts.allow_infinity_and_nan =
47 10x flags & static_cast<I>(E::allow_infinity_and_nan);
48 10x return opts;
49 }
50
51 } // namespace
52
53 namespace detail {
54
55 void
56 18894x 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 18894x string_view sv;
64 18894x sv = sr.read(buf);
65 18894x if(sr.done())
66 {
67 // fast path
68 10885x s.append(
69 sv.data(), sv.size());
70 10885x return;
71 }
72 8009x std::size_t len = sv.size();
73 8009x s.reserve(len * 2);
74 8009x s.resize(s.capacity());
75 8009x BOOST_ASSERT(
76 s.size() >= len * 2);
77 16018x std::memcpy(&s[0],
78 8009x sv.data(), sv.size());
79 auto const lim =
80 8009x s.max_size() / 2;
81 for(;;)
82 {
83 8010x sv = sr.read(&s[0] + len, s.size() - len);
84 8010x len += sv.size();
85 8010x if(sr.done())
86 8009x break;
87 // growth factor 2x
88 1x if(s.size() < lim)
89 1x s.resize(s.size() * 2);
90 else
91 ✗ s.resize(2 * lim);
92 }
93 8009x s.resize(len);
94 }
95
96 } // namespace detail
97
98 std::string
99 18801x serialize(
100 value const& jv,
101 serialize_options const& opts)
102 {
103 unsigned char buf[256];
104 serializer sr(
105 37602x storage_ptr(),
106 buf,
107 sizeof(buf),
108 18801x opts);
109 18801x sr.reset(&jv);
110 18801x std::string s;
111 18801x serialize_impl(s, sr);
112 37602x return s;
113 18801x }
114
115 std::string
116 2x serialize(
117 array const& arr,
118 serialize_options const& opts)
119 {
120 unsigned char buf[256];
121 serializer sr(
122 4x storage_ptr(),
123 buf,
124 sizeof(buf),
125 2x opts);
126 2x std::string s;
127 2x sr.reset(&arr);
128 2x serialize_impl(s, sr);
129 4x return s;
130 2x }
131
132 std::string
133 49x serialize(
134 object const& obj,
135 serialize_options const& opts)
136 {
137 unsigned char buf[256];
138 serializer sr(
139 98x storage_ptr(),
140 buf,
141 sizeof(buf),
142 49x opts);
143 49x std::string s;
144 49x sr.reset(&obj);
145 49x serialize_impl(s, sr);
146 98x return s;
147 49x }
148
149 std::string
150 2x serialize(
151 string const& str,
152 serialize_options const& opts)
153 {
154 2x return serialize( str.subview(), opts );
155 }
156
157 // this is here for key_value_pair::key()
158 std::string
159 2x serialize(
160 string_view sv,
161 serialize_options const& opts)
162 {
163 unsigned char buf[256];
164 serializer sr(
165 4x storage_ptr(),
166 buf,
167 sizeof(buf),
168 2x opts);
169 2x std::string s;
170 2x sr.reset(sv);
171 2x serialize_impl(s, sr);
172 4x return s;
173 2x }
174
175 //----------------------------------------------------------
176
177 // tag::example_operator_lt_lt[]
178 // Serialize a value into an output stream
179
180 std::ostream&
181 6x operator<<( std::ostream& os, value const& jv )
182 {
183 // Create a serializer
184 6x serializer sr( get_stream_flags(os) );
185
186 // Set the serializer up for our value
187 6x sr.reset( &jv );
188
189 // Loop until all output is produced.
190 12x while( ! sr.done() )
191 {
192 // Use a local buffer to avoid allocation.
193 char buf[ BOOST_JSON_STACK_BUFFER_SIZE ];
194
195 // Fill our buffer with serialized characters and write it to the output stream.
196 6x os << sr.read( buf );
197 }
198
199 6x return os;
200 6x }
201 // end::example_operator_lt_lt[]
202
203 static
204 void
205 4x to_ostream(
206 std::ostream& os,
207 serializer& sr)
208 {
209 10x while(! sr.done())
210 {
211 char buf[BOOST_JSON_STACK_BUFFER_SIZE];
212 6x auto s = sr.read(buf);
213 6x os.write(s.data(), s.size());
214 }
215 4x }
216
217 std::ostream&
218 1x operator<<(
219 std::ostream& os,
220 array const& arr)
221 {
222 1x serializer sr( get_stream_flags(os) );
223 1x sr.reset(&arr);
224 1x to_ostream(os, sr);
225 1x return os;
226 1x }
227
228 std::ostream&
229 1x operator<<(
230 std::ostream& os,
231 object const& obj)
232 {
233 1x serializer sr( get_stream_flags(os) );
234 1x sr.reset(&obj);
235 1x to_ostream(os, sr);
236 1x return os;
237 1x }
238
239 std::ostream&
240 2x operator<<(
241 std::ostream& os,
242 string const& str)
243 {
244 2x serializer sr( get_stream_flags(os) );
245 2x sr.reset(&str);
246 2x to_ostream(os, sr);
247 2x return os;
248 2x }
249
250 std::ostream&
251 2x operator<<( std::ostream& os, serialize_options const& opts )
252 {
253 2x os.iword(serialize_xalloc) = to_bitmask(opts);
254 2x return os;
255 }
256
257 } // namespace json
258 } // namespace boost
259
260 #endif
261