Line data 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_SERIALIZER_HPP
11 : #define BOOST_JSON_SERIALIZER_HPP
12 :
13 : #include <boost/json/detail/config.hpp>
14 : #include <boost/json/detail/format.hpp>
15 : #include <boost/json/detail/stream.hpp>
16 : #include <boost/json/detail/writer.hpp>
17 : #include <boost/json/serialize_options.hpp>
18 : #include <boost/json/value.hpp>
19 :
20 : namespace boost {
21 : namespace json {
22 :
23 : /** A serializer for JSON.
24 :
25 : This class traverses an instance of a library
26 : type and emits serialized JSON text by filling
27 : in one or more caller-provided buffers. To use,
28 : declare a variable and call @ref reset with
29 : a pointer to the variable you want to serialize.
30 : Then call @ref read over and over until
31 : @ref done returns `true`.
32 :
33 : @par Example
34 :
35 : This demonstrates how the serializer may
36 : be used to print a JSON value to an output
37 : stream.
38 :
39 : @code
40 :
41 : void print( std::ostream& os, value const& jv)
42 : {
43 : serializer sr;
44 : sr.reset( &jv );
45 : while( ! sr.done() )
46 : {
47 : char buf[ 4000 ];
48 : os << sr.read( buf );
49 : }
50 : }
51 :
52 : @endcode
53 :
54 : @par Thread Safety
55 :
56 : The same instance may not be accessed concurrently.
57 : */
58 : class serializer
59 : : detail::writer
60 : {
61 : using fn_t = bool (*)(writer&, detail::stream&);
62 :
63 : fn_t fn0_ = nullptr;
64 : fn_t fn1_ = nullptr;
65 : bool done_ = false;
66 :
67 : public:
68 : /// Move constructor (deleted)
69 : serializer(serializer&&) = delete;
70 :
71 : /** Destructor
72 :
73 : All temporary storage is deallocated.
74 :
75 : @par Complexity
76 : Constant
77 :
78 : @par Exception Safety
79 : No-throw guarantee.
80 : */
81 : #ifdef BOOST_JSON_DOCS
82 : BOOST_JSON_DECL
83 : ~serializer() noexcept;
84 : #endif // BOOST_JSON_DOCS
85 :
86 : /** Constructor
87 :
88 : This constructs a serializer with no value.
89 : The value may be set later by calling @ref reset.
90 : If serialization is attempted with no value,
91 : the output is as if a null value is serialized.
92 :
93 : @par Complexity
94 : Constant.
95 :
96 : @par Exception Safety
97 : No-throw guarantee.
98 :
99 : @param opts The options for the serializer. If this parameter
100 : is omitted, the serializer will output only standard JSON.
101 : */
102 : BOOST_JSON_DECL
103 : serializer( serialize_options const& opts = {} ) noexcept;
104 :
105 : /** Constructor
106 :
107 : This constructs a serializer with no value.
108 : The value may be set later by calling @ref reset.
109 : If serialization is attempted with no value,
110 : the output is as if a null value is serialized.
111 :
112 : @par Complexity
113 : Constant.
114 :
115 : @par Exception Safety
116 : No-throw guarantee.
117 :
118 : @param sp A pointer to the `boost::container::pmr::memory_resource` to
119 : use when producing partial output. Shared ownership of the memory
120 : resource is retained until the serializer is destroyed.
121 :
122 : @param buf An optional static buffer to
123 : use for temporary storage when producing
124 : partial output.
125 :
126 : @param buf_size The number of bytes of
127 : valid memory pointed to by `buf`.
128 :
129 : @param opts The options for the serializer. If this parameter
130 : is omitted, the serializer will output only standard JSON.
131 : */
132 : BOOST_JSON_DECL
133 : serializer(
134 : storage_ptr sp,
135 : unsigned char* buf = nullptr,
136 : std::size_t buf_size = 0,
137 : serialize_options const& opts = {}) noexcept;
138 :
139 : /** Returns `true` if the serialization is complete
140 :
141 : This function returns `true` when all of the
142 : characters in the serialized representation of
143 : the value have been read.
144 :
145 : @par Complexity
146 : Constant.
147 :
148 : @par Exception Safety
149 : No-throw guarantee.
150 : */
151 : bool
152 26927 : done() const noexcept
153 : {
154 26927 : return done_;
155 : }
156 :
157 : /** Reset the serializer for a new element
158 :
159 : This function prepares the serializer to emit
160 : a new serialized JSON representing `*p`.
161 : Any internally allocated memory is
162 : preserved and re-used for the new output.
163 :
164 : @param p A pointer to the element to serialize.
165 : Ownership is not transferred; The caller is
166 : responsible for ensuring that the lifetime of
167 : `*p` extends until it is no longer needed.
168 : */
169 : /** @{ */
170 : BOOST_JSON_DECL
171 : void
172 : reset(value const* p) noexcept;
173 :
174 : BOOST_JSON_DECL
175 : void
176 : reset(array const* p) noexcept;
177 :
178 : BOOST_JSON_DECL
179 : void
180 : reset(object const* p) noexcept;
181 :
182 : BOOST_JSON_DECL
183 : void
184 : reset(string const* p) noexcept;
185 :
186 : template<class T>
187 : void
188 : reset(T const* p) noexcept;
189 : /** @} */
190 :
191 : /** Reset the serializer for a new string
192 :
193 : This function prepares the serializer to emit
194 : a new serialized JSON representing the string.
195 : Any internally allocated memory is
196 : preserved and re-used for the new output.
197 :
198 : @param sv The characters representing the string.
199 : Ownership is not transferred; The caller is
200 : responsible for ensuring that the lifetime of
201 : the characters reference by `sv` extends
202 : until it is no longer needed.
203 : */
204 : BOOST_JSON_DECL
205 : void
206 : reset(string_view sv) noexcept;
207 :
208 : /** Reset the serializer for std::nullptr_t
209 :
210 : This function prepares the serializer to emit
211 : a new serialized JSON representing null.
212 : Any internally allocated memory is
213 : preserved and re-used for the new output.
214 : */
215 : BOOST_JSON_DECL
216 : void
217 : reset(std::nullptr_t) noexcept;
218 :
219 : /** Read the next buffer of serialized JSON
220 :
221 : This function attempts to fill the caller
222 : provided buffer starting at `dest` with
223 : up to `size` characters of the serialized
224 : JSON that represents the value. If the
225 : buffer is not large enough, multiple calls
226 : may be required.
227 : \n
228 : If serialization completes during this call;
229 : that is, that all of the characters belonging
230 : to the serialized value have been written to
231 : caller-provided buffers, the function
232 : @ref done will return `true`.
233 :
234 : @par Preconditions
235 : @code
236 : this->done() == false
237 : @endcode
238 :
239 : @par Complexity
240 : Linear in `size`.
241 :
242 : @par Exception Safety
243 : Basic guarantee.
244 : Calls to `memory_resource::allocate` may throw.
245 :
246 : @return A @ref string_view containing the
247 : characters written, which may be less than
248 : `size`.
249 :
250 : @param dest A pointer to valid memory of at
251 : least `size` bytes.
252 :
253 : @param size The maximum number of characters
254 : to write to the memory pointed to by `dest`.
255 : */
256 : BOOST_JSON_DECL
257 : string_view
258 : read(char* dest, std::size_t size);
259 :
260 : /** Read the next buffer of serialized JSON
261 :
262 : This function allows reading into a
263 : character array, with a deduced maximum size.
264 :
265 : @par Preconditions
266 : @code
267 : this->done() == false
268 : @endcode
269 :
270 : @par Effects
271 : @code
272 : return this->read( dest, N );
273 : @endcode
274 :
275 : @par Complexity
276 : Linear in `N`.
277 :
278 : @par Exception Safety
279 : Basic guarantee.
280 : Calls to `memory_resource::allocate` may throw.
281 :
282 : @return A @ref string_view containing the
283 : characters written, which may be less than
284 : `size`.
285 :
286 : @param dest The character array to write to.
287 : */
288 : template<std::size_t N>
289 : string_view
290 18916 : read(char(&dest)[N])
291 : {
292 18916 : return read(dest, N);
293 : }
294 :
295 : #ifndef BOOST_JSON_DOCS
296 : // Safety net for accidental buffer overflows
297 : template<std::size_t N>
298 : string_view
299 : read(char(&dest)[N], std::size_t n)
300 : {
301 : // If this goes off, check your parameters
302 : // closely, chances are you passed an array
303 : // thinking it was a pointer.
304 : BOOST_ASSERT(n <= N);
305 : return read(dest, n);
306 : }
307 : #endif
308 : };
309 :
310 : } // namespace json
311 : } // namespace boost
312 :
313 : #include <boost/json/impl/serializer.hpp>
314 :
315 : #endif
|