]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
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_STREAM_PARSER_HPP | |
11 | #define BOOST_JSON_STREAM_PARSER_HPP | |
12 | ||
13 | #include <boost/json/detail/config.hpp> | |
14 | #include <boost/json/basic_parser.hpp> | |
15 | #include <boost/json/parse_options.hpp> | |
16 | #include <boost/json/storage_ptr.hpp> | |
17 | #include <boost/json/value.hpp> | |
18 | #include <boost/json/detail/handler.hpp> | |
19 | #include <type_traits> | |
20 | #include <cstddef> | |
21 | ||
22 | BOOST_JSON_NS_BEGIN | |
23 | ||
24 | //---------------------------------------------------------- | |
25 | ||
26 | /** A DOM parser for JSON contained in multiple buffers. | |
27 | ||
28 | This class is used to parse a JSON contained in a | |
29 | series of one or more character buffers, into a | |
30 | @ref value container. It implements a | |
31 | <a href="https://en.wikipedia.org/wiki/Streaming_algorithm"> | |
32 | <em>streaming algorithm</em></a>, allowing these | |
33 | parsing strategies: | |
34 | ||
35 | @li Parse a JSON file a piece at a time. | |
36 | ||
37 | @li Parse incoming JSON as it arrives, | |
38 | one buffer at a time. | |
39 | ||
40 | @li Parse with bounded resource consumption | |
41 | per cycle. | |
42 | ||
43 | @par Usage | |
44 | ||
45 | To use the parser first construct it, then optionally | |
46 | call @ref reset to specify a @ref storage_ptr to use | |
47 | for the resulting @ref value. Then call @ref write | |
48 | one or more times to parse a single, complete JSON. | |
49 | Call @ref done to determine if the parse has completed. | |
50 | To indicate there are no more buffers, call @ref finish. | |
51 | If the parse is successful, call @ref release to take | |
52 | ownership of the value: | |
53 | ||
54 | @code | |
55 | stream_parser p; // construct a parser | |
56 | p.write( "[1,2" ); // parse some of a JSON | |
57 | p.write( ",3,4]" ); // parse the rest of the JSON | |
58 | assert( p.done() ); // we have a complete JSON | |
59 | value jv = p.release(); // take ownership of the value | |
60 | @endcode | |
61 | ||
62 | @par Extra Data | |
63 | ||
64 | When the character buffer provided as input contains | |
65 | additional data that is not part of the complete | |
66 | JSON, an error is returned. The @ref write_some | |
67 | function is an alternative which allows the parse | |
68 | to finish early, without consuming all the characters | |
69 | in the buffer. This allows parsing of a buffer | |
70 | containing multiple individual JSONs or containing | |
71 | different protocol data: | |
72 | @code | |
73 | stream_parser p; // construct a parser | |
74 | std::size_t n; // number of characters used | |
75 | n = p.write_some( "[1,2" ); // parse some of a JSON | |
76 | assert( n == 4 ); // all characters consumed | |
77 | n = p.write_some( ",3,4] null" ); // parse the remainder of the JSON | |
78 | assert( n == 6 ); // only some characters consumed | |
79 | assert( p.done() ); // we have a complete JSON | |
80 | value jv = p.release(); // take ownership of the value | |
81 | @endcode | |
82 | ||
83 | @par Temporary Storage | |
84 | ||
85 | The parser may dynamically allocate temporary | |
86 | storage as needed to accommodate the nesting level | |
87 | of the JSON being parsed. Temporary storage is | |
88 | first obtained from an optional, caller-owned | |
89 | buffer specified upon construction. When that | |
90 | is exhausted, the next allocation uses the | |
91 | @ref memory_resource passed to the constructor; if | |
92 | no such argument is specified, the default memory | |
93 | resource is used. Temporary storage is freed only | |
94 | when the parser is destroyed; The performance of | |
95 | parsing multiple JSONs may be improved by reusing | |
96 | the same parser instance. | |
97 | \n | |
98 | It is important to note that the @ref memory_resource | |
99 | supplied upon construction is used for temporary | |
100 | storage only, and not for allocating the elements | |
101 | which make up the parsed value. That other memory | |
102 | resource is optionally supplied in each call | |
103 | to @ref reset. | |
104 | ||
105 | @par Duplicate Keys | |
106 | ||
107 | If there are object elements with duplicate keys; | |
108 | that is, if multiple elements in an object have | |
109 | keys that compare equal, only the last equivalent | |
110 | element will be inserted. | |
111 | ||
112 | @par Non-Standard JSON | |
113 | ||
114 | The @ref parse_options structure optionally | |
115 | provided upon construction is used to customize | |
116 | some parameters of the parser, including which | |
117 | non-standard JSON extensions should be allowed. | |
118 | A default-constructed parse options allows only | |
119 | standard JSON. | |
120 | ||
121 | @par Thread Safety | |
122 | ||
123 | Distinct instances may be accessed concurrently. | |
124 | Non-const member functions of a shared instance | |
125 | may not be called concurrently with any other | |
126 | member functions of that instance. | |
127 | ||
128 | @see | |
129 | @ref parse, | |
130 | @ref parser, | |
131 | @ref parse_options, | |
132 | */ | |
133 | class stream_parser | |
134 | { | |
135 | basic_parser<detail::handler> p_; | |
136 | ||
137 | public: | |
138 | /// Copy constructor (deleted) | |
139 | stream_parser( | |
140 | stream_parser const&) = delete; | |
141 | ||
142 | /// Copy assignment (deleted) | |
143 | stream_parser& operator=( | |
144 | stream_parser const&) = delete; | |
145 | ||
146 | /** Destructor. | |
147 | ||
148 | All dynamically allocated memory, including | |
149 | any incomplete parsing results, is freed. | |
150 | ||
151 | @par Complexity | |
152 | Linear in the size of partial results | |
153 | ||
154 | @par Exception Safety | |
155 | No-throw guarantee. | |
156 | */ | |
157 | ~stream_parser() = default; | |
158 | ||
159 | /** Constructor. | |
160 | ||
161 | This constructs a new parser which first uses | |
162 | the caller-owned storage pointed to by `buffer` | |
163 | for temporary storage, falling back to the memory | |
164 | resource `sp` if needed. The parser will use the | |
165 | specified parsing options. | |
166 | \n | |
167 | The parsed value will use the default memory | |
168 | resource for storage. To use a different resource, | |
169 | call @ref reset after construction. | |
170 | ||
171 | @par Complexity | |
172 | Constant. | |
173 | ||
174 | @par Exception Safety | |
175 | No-throw guarantee. | |
176 | ||
177 | @param sp The memory resource to use for | |
178 | temporary storage after `buffer` is exhausted. | |
179 | ||
180 | @param opt The parsing options to use. | |
181 | ||
182 | @param buffer A pointer to valid memory of at least | |
183 | `size` bytes for the parser to use for temporary storage. | |
184 | Ownership is not transferred, the caller is responsible | |
185 | for ensuring the lifetime of the memory pointed to by | |
186 | `buffer` extends until the parser is destroyed. | |
187 | ||
188 | @param size The number of valid bytes in `buffer`. | |
189 | */ | |
190 | BOOST_JSON_DECL | |
191 | stream_parser( | |
192 | storage_ptr sp, | |
193 | parse_options const& opt, | |
194 | unsigned char* buffer, | |
195 | std::size_t size) noexcept; | |
196 | ||
197 | /** Constructor. | |
198 | ||
199 | This constructs a new parser which uses the default | |
200 | memory resource for temporary storage, and accepts | |
201 | only strict JSON. | |
202 | \n | |
203 | The parsed value will use the default memory | |
204 | resource for storage. To use a different resource, | |
205 | call @ref reset after construction. | |
206 | ||
207 | @par Complexity | |
208 | Constant. | |
209 | ||
210 | @par Exception Safety | |
211 | No-throw guarantee. | |
212 | */ | |
213 | stream_parser() noexcept | |
214 | : stream_parser({}, {}) | |
215 | { | |
216 | } | |
217 | ||
218 | /** Constructor. | |
219 | ||
220 | This constructs a new parser which uses the | |
221 | specified memory resource for temporary storage, | |
222 | and is configured to use the specified parsing | |
223 | options. | |
224 | \n | |
225 | The parsed value will use the default memory | |
226 | resource for storage. To use a different resource, | |
227 | call @ref reset after construction. | |
228 | ||
229 | @par Complexity | |
230 | Constant. | |
231 | ||
232 | @par Exception Safety | |
233 | No-throw guarantee. | |
234 | ||
235 | @param sp The memory resource to use for temporary storage. | |
236 | ||
237 | @param opt The parsing options to use. | |
238 | */ | |
239 | BOOST_JSON_DECL | |
240 | stream_parser( | |
241 | storage_ptr sp, | |
242 | parse_options const& opt) noexcept; | |
243 | ||
244 | /** Constructor. | |
245 | ||
246 | This constructs a new parser which uses the | |
247 | specified memory resource for temporary storage, | |
248 | and accepts only strict JSON. | |
249 | \n | |
250 | The parsed value will use the default memory | |
251 | resource for storage. To use a different resource, | |
252 | call @ref reset after construction. | |
253 | ||
254 | @par Complexity | |
255 | Constant. | |
256 | ||
257 | @par Exception Safety | |
258 | No-throw guarantee. | |
259 | ||
260 | @param sp The memory resource to use for temporary storage. | |
261 | */ | |
262 | explicit | |
263 | stream_parser(storage_ptr sp) noexcept | |
264 | : stream_parser(std::move(sp), {}) | |
265 | { | |
266 | } | |
267 | ||
268 | /** Constructor. | |
269 | ||
270 | This constructs a new parser which first uses the | |
271 | caller-owned storage `buffer` for temporary storage, | |
272 | falling back to the memory resource `sp` if needed. | |
273 | The parser will use the specified parsing options. | |
274 | \n | |
275 | The parsed value will use the default memory | |
276 | resource for storage. To use a different resource, | |
277 | call @ref reset after construction. | |
278 | ||
279 | @par Complexity | |
280 | Constant. | |
281 | ||
282 | @par Exception Safety | |
283 | No-throw guarantee. | |
284 | ||
285 | @param sp The memory resource to use for | |
286 | temporary storage after `buffer` is exhausted. | |
287 | ||
288 | @param opt The parsing options to use. | |
289 | ||
290 | @param buffer A buffer for the parser to use for | |
291 | temporary storage. Ownership is not transferred, | |
292 | the caller is responsible for ensuring the lifetime | |
293 | of `buffer` extends until the parser is destroyed. | |
294 | */ | |
295 | template<std::size_t N> | |
296 | stream_parser( | |
297 | storage_ptr sp, | |
298 | parse_options const& opt, | |
299 | unsigned char(&buffer)[N]) noexcept | |
300 | : stream_parser(std::move(sp), | |
301 | opt, &buffer[0], N) | |
302 | { | |
303 | } | |
304 | ||
305 | #if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS) | |
306 | /** Constructor. | |
307 | ||
308 | This constructs a new parser which first uses | |
309 | the caller-owned storage pointed to by `buffer` | |
310 | for temporary storage, falling back to the memory | |
311 | resource `sp` if needed. The parser will use the | |
312 | specified parsing options. | |
313 | \n | |
314 | The parsed value will use the default memory | |
315 | resource for storage. To use a different resource, | |
316 | call @ref reset after construction. | |
317 | ||
318 | @par Complexity | |
319 | Constant. | |
320 | ||
321 | @par Exception Safety | |
322 | No-throw guarantee. | |
323 | ||
324 | @param sp The memory resource to use for | |
325 | temporary storage after `buffer` is exhausted. | |
326 | ||
327 | @param opt The parsing options to use. | |
328 | ||
329 | @param buffer A pointer to valid memory of at least | |
330 | `size` bytes for the parser to use for temporary storage. | |
331 | Ownership is not transferred, the caller is responsible | |
332 | for ensuring the lifetime of the memory pointed to by | |
333 | `buffer` extends until the parser is destroyed. | |
334 | ||
335 | @param size The number of valid bytes in `buffer`. | |
336 | */ | |
337 | stream_parser( | |
338 | storage_ptr sp, | |
339 | parse_options const& opt, | |
340 | std::byte* buffer, | |
341 | std::size_t size) noexcept | |
342 | : stream_parser(sp, opt, reinterpret_cast< | |
343 | unsigned char*>(buffer), size) | |
344 | { | |
345 | } | |
346 | ||
347 | /** Constructor. | |
348 | ||
349 | This constructs a new parser which first uses the | |
350 | caller-owned storage `buffer` for temporary storage, | |
351 | falling back to the memory resource `sp` if needed. | |
352 | The parser will use the specified parsing options. | |
353 | \n | |
354 | The parsed value will use the default memory | |
355 | resource for storage. To use a different resource, | |
356 | call @ref reset after construction. | |
357 | ||
358 | @par Complexity | |
359 | Constant. | |
360 | ||
361 | @par Exception Safety | |
362 | No-throw guarantee. | |
363 | ||
364 | @param sp The memory resource to use for | |
365 | temporary storage after `buffer` is exhausted. | |
366 | ||
367 | @param opt The parsing options to use. | |
368 | ||
369 | @param buffer A buffer for the parser to use for | |
370 | temporary storage. Ownership is not transferred, | |
371 | the caller is responsible for ensuring the lifetime | |
372 | of `buffer` extends until the parser is destroyed. | |
373 | */ | |
374 | template<std::size_t N> | |
375 | stream_parser( | |
376 | storage_ptr sp, | |
377 | parse_options const& opt, | |
378 | std::byte(&buffer)[N]) noexcept | |
379 | : stream_parser(std::move(sp), | |
380 | opt, &buffer[0], N) | |
381 | { | |
382 | } | |
383 | #endif | |
384 | ||
385 | #ifndef BOOST_JSON_DOCS | |
386 | // Safety net for accidental buffer overflows | |
387 | template<std::size_t N> | |
388 | stream_parser( | |
389 | storage_ptr sp, | |
390 | parse_options const& opt, | |
391 | unsigned char(&buffer)[N], | |
392 | std::size_t n) noexcept | |
393 | : stream_parser(std::move(sp), | |
394 | opt, &buffer[0], n) | |
395 | { | |
396 | // If this goes off, check your parameters | |
397 | // closely, chances are you passed an array | |
398 | // thinking it was a pointer. | |
399 | BOOST_ASSERT(n <= N); | |
400 | } | |
401 | ||
402 | #ifdef __cpp_lib_byte | |
403 | // Safety net for accidental buffer overflows | |
404 | template<std::size_t N> | |
405 | stream_parser( | |
406 | storage_ptr sp, | |
407 | parse_options const& opt, | |
408 | std::byte(&buffer)[N], std::size_t n) noexcept | |
409 | : stream_parser(std::move(sp), | |
410 | opt, &buffer[0], n) | |
411 | { | |
412 | // If this goes off, check your parameters | |
413 | // closely, chances are you passed an array | |
414 | // thinking it was a pointer. | |
415 | BOOST_ASSERT(n <= N); | |
416 | } | |
417 | #endif | |
418 | #endif | |
419 | ||
420 | /** Reset the parser for a new JSON. | |
421 | ||
422 | This function is used to reset the parser to | |
423 | prepare it for parsing a new complete JSON. | |
424 | Any previous partial results are destroyed. | |
425 | ||
426 | @par Complexity | |
427 | Constant or linear in the size of any previous | |
428 | partial parsing results. | |
429 | ||
430 | @par Exception Safety | |
431 | No-throw guarantee. | |
432 | ||
433 | @param sp A pointer to the @ref memory_resource | |
434 | to use for the resulting @ref value. The parser | |
435 | will acquire shared ownership. | |
436 | */ | |
437 | BOOST_JSON_DECL | |
438 | void | |
439 | reset(storage_ptr sp = {}) noexcept; | |
440 | ||
441 | /** Return true if a complete JSON has been parsed. | |
442 | ||
443 | This function returns `true` when all of these | |
444 | conditions are met: | |
445 | ||
446 | @li A complete serialized JSON has been | |
447 | presented to the parser, and | |
448 | ||
449 | @li No error has occurred since the parser | |
450 | was constructed, or since the last call | |
451 | to @ref reset, | |
452 | ||
453 | @par Complexity | |
454 | Constant. | |
455 | ||
456 | @par Exception Safety | |
457 | No-throw guarantee. | |
458 | */ | |
459 | bool | |
460 | done() const noexcept | |
461 | { | |
462 | return p_.done(); | |
463 | } | |
464 | ||
465 | /** Parse a buffer containing all or part of a complete JSON. | |
466 | ||
467 | This function parses JSON contained in the | |
468 | specified character buffer. If parsing completes, | |
469 | any additional characters past the end of the | |
470 | complete JSON are ignored. The function returns the | |
471 | actual number of characters parsed, which may be | |
472 | less than the size of the input. This allows parsing | |
473 | of a buffer containing multiple individual JSONs or | |
474 | containing different protocol data. | |
475 | ||
476 | @par Example | |
477 | @code | |
478 | stream_parser p; // construct a parser | |
479 | std::size_t n; // number of characters used | |
480 | n = p.write_some( "[1,2" ); // parse the first part of the JSON | |
481 | assert( n == 4 ); // all characters consumed | |
482 | n = p.write_some( "3,4] null" ); // parse the rest of the JSON | |
483 | assert( n == 5 ); // only some characters consumed | |
484 | value jv = p.release(); // take ownership of the value | |
485 | @endcode | |
486 | ||
487 | @note | |
488 | ||
489 | To indicate there are no more character buffers, | |
490 | such as when @ref done returns `false` after | |
491 | writing, call @ref finish. | |
492 | ||
493 | @par Complexity | |
494 | Linear in `size`. | |
495 | ||
496 | @par Exception Safety | |
497 | Basic guarantee. | |
498 | Calls to `memory_resource::allocate` may throw. | |
499 | Upon error or exception, subsequent calls will | |
500 | fail until @ref reset is called to parse a new JSON. | |
501 | ||
502 | @return The number of characters consumed from | |
503 | the buffer. | |
504 | ||
505 | @param data A pointer to a buffer of `size` | |
506 | characters to parse. | |
507 | ||
508 | @param size The number of characters pointed to | |
509 | by `data`. | |
510 | ||
511 | @param ec Set to the error, if any occurred. | |
512 | */ | |
513 | BOOST_JSON_DECL | |
514 | std::size_t | |
515 | write_some( | |
516 | char const* data, | |
517 | std::size_t size, | |
518 | error_code& ec); | |
519 | ||
520 | /** Parse a buffer containing all or part of a complete JSON. | |
521 | ||
522 | This function parses JSON contained in the | |
523 | specified character buffer. If parsing completes, | |
524 | any additional characters past the end of the | |
525 | complete JSON are ignored. The function returns the | |
526 | actual number of characters parsed, which may be | |
527 | less than the size of the input. This allows parsing | |
528 | of a buffer containing multiple individual JSONs or | |
529 | containing different protocol data. | |
530 | ||
531 | @par Example | |
532 | @code | |
533 | stream_parser p; // construct a parser | |
534 | std::size_t n; // number of characters used | |
535 | n = p.write_some( "[1,2" ); // parse the first part of the JSON | |
536 | assert( n == 4 ); // all characters consumed | |
537 | n = p.write_some( "3,4] null" ); // parse the rest of the JSON | |
538 | assert( n == 5 ); // only some characters consumed | |
539 | value jv = p.release(); // take ownership of the value | |
540 | @endcode | |
541 | ||
542 | @note | |
543 | ||
544 | To indicate there are no more character buffers, | |
545 | such as when @ref done returns `false` after | |
546 | writing, call @ref finish. | |
547 | ||
548 | @par Complexity | |
549 | Linear in `size`. | |
550 | ||
551 | @par Exception Safety | |
552 | Basic guarantee. | |
553 | Calls to `memory_resource::allocate` may throw. | |
554 | Upon error or exception, subsequent calls will | |
555 | fail until @ref reset is called to parse a new JSON. | |
556 | ||
557 | @return The number of characters consumed from | |
558 | the buffer. | |
559 | ||
560 | @param data A pointer to a buffer of `size` | |
561 | characters to parse. | |
562 | ||
563 | @param size The number of characters pointed to | |
564 | by `data`. | |
565 | ||
566 | @throw system_error Thrown on error. | |
567 | */ | |
568 | BOOST_JSON_DECL | |
569 | std::size_t | |
570 | write_some( | |
571 | char const* data, | |
572 | std::size_t size); | |
573 | ||
574 | /** Parse a buffer containing all or part of a complete JSON. | |
575 | ||
576 | This function parses JSON contained in the | |
577 | specified character buffer. If parsing completes, | |
578 | any additional characters past the end of the | |
579 | complete JSON are ignored. The function returns the | |
580 | actual number of characters parsed, which may be | |
581 | less than the size of the input. This allows parsing | |
582 | of a buffer containing multiple individual JSONs or | |
583 | containing different protocol data. | |
584 | ||
585 | @par Example | |
586 | @code | |
587 | stream_parser p; // construct a parser | |
588 | std::size_t n; // number of characters used | |
589 | n = p.write_some( "[1,2" ); // parse the first part of the JSON | |
590 | assert( n == 4 ); // all characters consumed | |
591 | n = p.write_some( "3,4] null" ); // parse the rest of the JSON | |
592 | assert( n == 5 ); // only some characters consumed | |
593 | value jv = p.release(); // take ownership of the value | |
594 | @endcode | |
595 | ||
596 | @note | |
597 | ||
598 | To indicate there are no more character buffers, | |
599 | such as when @ref done returns `false` after | |
600 | writing, call @ref finish. | |
601 | ||
602 | @par Complexity | |
603 | Linear in `size`. | |
604 | ||
605 | @par Exception Safety | |
606 | Basic guarantee. | |
607 | Calls to `memory_resource::allocate` may throw. | |
608 | Upon error or exception, subsequent calls will | |
609 | fail until @ref reset is called to parse a new JSON. | |
610 | ||
611 | @return The number of characters consumed from | |
612 | the buffer. | |
613 | ||
614 | @param s The character string to parse. | |
615 | ||
616 | @param ec Set to the error, if any occurred. | |
617 | */ | |
618 | std::size_t | |
619 | write_some( | |
620 | string_view s, | |
621 | error_code& ec) | |
622 | { | |
623 | return write_some( | |
624 | s.data(), s.size(), ec); | |
625 | } | |
626 | ||
627 | /** Parse a buffer containing all or part of a complete JSON. | |
628 | ||
629 | This function parses JSON contained in the | |
630 | specified character buffer. If parsing completes, | |
631 | any additional characters past the end of the | |
632 | complete JSON are ignored. The function returns the | |
633 | actual number of characters parsed, which may be | |
634 | less than the size of the input. This allows parsing | |
635 | of a buffer containing multiple individual JSONs or | |
636 | containing different protocol data. | |
637 | ||
638 | @par Example | |
639 | @code | |
640 | stream_parser p; // construct a parser | |
641 | std::size_t n; // number of characters used | |
642 | n = p.write_some( "[1,2" ); // parse the first part of the JSON | |
643 | assert( n == 4 ); // all characters consumed | |
644 | n = p.write_some( "3,4] null" ); // parse the rest of the JSON | |
645 | assert( n == 5 ); // only some characters consumed | |
646 | value jv = p.release(); // take ownership of the value | |
647 | @endcode | |
648 | ||
649 | @note | |
650 | ||
651 | To indicate there are no more character buffers, | |
652 | such as when @ref done returns `false` after | |
653 | writing, call @ref finish. | |
654 | ||
655 | @par Complexity | |
656 | Linear in `size`. | |
657 | ||
658 | @par Exception Safety | |
659 | Basic guarantee. | |
660 | Calls to `memory_resource::allocate` may throw. | |
661 | Upon error or exception, subsequent calls will | |
662 | fail until @ref reset is called to parse a new JSON. | |
663 | ||
664 | @return The number of characters consumed from | |
665 | the buffer. | |
666 | ||
667 | @param s The character string to parse. | |
668 | ||
669 | @throw system_error Thrown on error. | |
670 | */ | |
671 | std::size_t | |
672 | write_some( | |
673 | string_view s) | |
674 | { | |
675 | return write_some( | |
676 | s.data(), s.size()); | |
677 | } | |
678 | ||
679 | /** Parse a buffer containing all or part of a complete JSON. | |
680 | ||
681 | This function parses a all or part of a JSON | |
682 | contained in the specified character buffer. The | |
683 | entire buffer must be consumed; if there are | |
684 | additional characters past the end of the complete | |
685 | JSON, the parse fails and an error is returned. | |
686 | ||
687 | @par Example | |
688 | @code | |
689 | stream_parser p; // construct a parser | |
690 | std::size_t n; // number of characters used | |
691 | n = p.write( "[1,2" ); // parse some of the JSON | |
692 | assert( n == 4 ); // all characters consumed | |
693 | n = p.write( "3,4]" ); // parse the rest of the JSON | |
694 | assert( n == 4 ); // all characters consumed | |
695 | value jv = p.release(); // take ownership of the value | |
696 | @endcode | |
697 | ||
698 | @note | |
699 | ||
700 | To indicate there are no more character buffers, | |
701 | such as when @ref done returns `false` after | |
702 | writing, call @ref finish. | |
703 | ||
704 | @par Complexity | |
705 | Linear in `size`. | |
706 | ||
707 | @par Exception Safety | |
708 | Basic guarantee. | |
709 | Calls to `memory_resource::allocate` may throw. | |
710 | Upon error or exception, subsequent calls will | |
711 | fail until @ref reset is called to parse a new JSON. | |
712 | ||
713 | @return The number of characters consumed from | |
714 | the buffer. | |
715 | ||
716 | @param data A pointer to a buffer of `size` | |
717 | characters to parse. | |
718 | ||
719 | @param size The number of characters pointed to | |
720 | by `data`. | |
721 | ||
722 | @param ec Set to the error, if any occurred. | |
723 | */ | |
724 | BOOST_JSON_DECL | |
725 | std::size_t | |
726 | write( | |
727 | char const* data, | |
728 | std::size_t size, | |
729 | error_code& ec); | |
730 | ||
731 | /** Parse a buffer containing all or part of a complete JSON. | |
732 | ||
733 | This function parses a all or part of a JSON | |
734 | contained in the specified character buffer. The | |
735 | entire buffer must be consumed; if there are | |
736 | additional characters past the end of the complete | |
737 | JSON, the parse fails and an error is returned. | |
738 | ||
739 | @par Example | |
740 | @code | |
741 | stream_parser p; // construct a parser | |
742 | std::size_t n; // number of characters used | |
743 | n = p.write( "[1,2" ); // parse some of the JSON | |
744 | assert( n == 4 ); // all characters consumed | |
745 | n = p.write( "3,4]" ); // parse the rest of the JSON | |
746 | assert( n == 4 ); // all characters consumed | |
747 | value jv = p.release(); // take ownership of the value | |
748 | @endcode | |
749 | ||
750 | @note | |
751 | ||
752 | To indicate there are no more character buffers, | |
753 | such as when @ref done returns `false` after | |
754 | writing, call @ref finish. | |
755 | ||
756 | @par Complexity | |
757 | Linear in `size`. | |
758 | ||
759 | @par Exception Safety | |
760 | Basic guarantee. | |
761 | Calls to `memory_resource::allocate` may throw. | |
762 | Upon error or exception, subsequent calls will | |
763 | fail until @ref reset is called to parse a new JSON. | |
764 | ||
765 | @return The number of characters consumed from | |
766 | the buffer. | |
767 | ||
768 | @param data A pointer to a buffer of `size` | |
769 | characters to parse. | |
770 | ||
771 | @param size The number of characters pointed to | |
772 | by `data`. | |
773 | ||
774 | @throw system_error Thrown on error. | |
775 | */ | |
776 | BOOST_JSON_DECL | |
777 | std::size_t | |
778 | write( | |
779 | char const* data, | |
780 | std::size_t size); | |
781 | ||
782 | /** Parse a buffer containing all or part of a complete JSON. | |
783 | ||
784 | This function parses a all or part of a JSON | |
785 | contained in the specified character buffer. The | |
786 | entire buffer must be consumed; if there are | |
787 | additional characters past the end of the complete | |
788 | JSON, the parse fails and an error is returned. | |
789 | ||
790 | @par Example | |
791 | @code | |
792 | stream_parser p; // construct a parser | |
793 | std::size_t n; // number of characters used | |
794 | n = p.write( "[1,2" ); // parse some of the JSON | |
795 | assert( n == 4 ); // all characters consumed | |
796 | n = p.write( "3,4]" ); // parse the rest of the JSON | |
797 | assert( n == 4 ); // all characters consumed | |
798 | value jv = p.release(); // take ownership of the value | |
799 | @endcode | |
800 | ||
801 | @note | |
802 | ||
803 | To indicate there are no more character buffers, | |
804 | such as when @ref done returns `false` after | |
805 | writing, call @ref finish. | |
806 | ||
807 | @par Complexity | |
808 | Linear in `size`. | |
809 | ||
810 | @par Exception Safety | |
811 | Basic guarantee. | |
812 | Calls to `memory_resource::allocate` may throw. | |
813 | Upon error or exception, subsequent calls will | |
814 | fail until @ref reset is called to parse a new JSON. | |
815 | ||
816 | @return The number of characters consumed from | |
817 | the buffer. | |
818 | ||
819 | @param s The character string to parse. | |
820 | ||
821 | @param ec Set to the error, if any occurred. | |
822 | */ | |
823 | std::size_t | |
824 | write( | |
825 | string_view s, | |
826 | error_code& ec) | |
827 | { | |
828 | return write( | |
829 | s.data(), s.size(), ec); | |
830 | } | |
831 | ||
832 | /** Parse a buffer containing all or part of a complete JSON. | |
833 | ||
834 | This function parses a all or part of a JSON | |
835 | contained in the specified character buffer. The | |
836 | entire buffer must be consumed; if there are | |
837 | additional characters past the end of the complete | |
838 | JSON, the parse fails and an error is returned. | |
839 | ||
840 | @par Example | |
841 | @code | |
842 | stream_parser p; // construct a parser | |
843 | std::size_t n; // number of characters used | |
844 | n = p.write( "[1,2" ); // parse some of the JSON | |
845 | assert( n == 4 ); // all characters consumed | |
846 | n = p.write( "3,4]" ); // parse the rest of the JSON | |
847 | assert( n == 4 ); // all characters consumed | |
848 | value jv = p.release(); // take ownership of the value | |
849 | @endcode | |
850 | ||
851 | @note | |
852 | ||
853 | To indicate there are no more character buffers, | |
854 | such as when @ref done returns `false` after | |
855 | writing, call @ref finish. | |
856 | ||
857 | @par Complexity | |
858 | Linear in `size`. | |
859 | ||
860 | @par Exception Safety | |
861 | Basic guarantee. | |
862 | Calls to `memory_resource::allocate` may throw. | |
863 | Upon error or exception, subsequent calls will | |
864 | fail until @ref reset is called to parse a new JSON. | |
865 | ||
866 | @return The number of characters consumed from | |
867 | the buffer. | |
868 | ||
869 | @param s The character string to parse. | |
870 | ||
871 | @throw system_error Thrown on error. | |
872 | */ | |
873 | std::size_t | |
874 | write( | |
875 | string_view s) | |
876 | { | |
877 | return write( | |
878 | s.data(), s.size()); | |
879 | } | |
880 | ||
881 | /** Indicate the end of JSON input. | |
882 | ||
883 | This function is used to indicate that there | |
884 | are no more character buffers in the current | |
885 | JSON being parsed. If ther resulting JSON is | |
886 | incomplete, the error is set to indicate a | |
887 | parsing failure. | |
888 | ||
889 | @par Example | |
890 | In the code below, @ref finish is called to | |
891 | indicate there are no more digits in the | |
892 | resulting number: | |
893 | @code | |
894 | stream_parser p; // construct a parser | |
895 | p.write( "3." ); // write the first part of the number | |
896 | p.write( "14" ); // write the second part of the number | |
897 | assert( ! p.done() ); // there could be more digits | |
898 | p.finish(); // indicate the end of the JSON input | |
899 | assert( p.done() ); // now we are finished | |
900 | value jv = p.release(); // take ownership of the value | |
901 | @endcode | |
902 | ||
903 | @par Complexity | |
904 | Constant. | |
905 | ||
906 | @par Exception Safety | |
907 | Basic guarantee. | |
908 | Calls to `memory_resource::allocate` may throw. | |
909 | Upon error or exception, subsequent calls will | |
910 | fail until @ref reset is called to parse a new JSON. | |
911 | ||
912 | @param ec Set to the error, if any occurred. | |
913 | */ | |
914 | BOOST_JSON_DECL | |
915 | void | |
916 | finish(error_code& ec); | |
917 | ||
918 | /** Indicate the end of JSON input. | |
919 | ||
920 | This function is used to indicate that there | |
921 | are no more character buffers in the current | |
922 | JSON being parsed. If ther resulting JSON is | |
923 | incomplete, the error is set to indicate a | |
924 | parsing failure. | |
925 | ||
926 | @par Example | |
927 | In the code below, @ref finish is called to | |
928 | indicate there are no more digits in the | |
929 | resulting number: | |
930 | @code | |
931 | stream_parser p; // construct a parser | |
932 | p.write( "3." ); // write the first part of the number | |
933 | p.write( "14" ); // write the second part of the number | |
934 | assert( ! p.done() ); // there could be more digits | |
935 | p.finish(); // indicate the end of the JSON input | |
936 | assert( p.done() ); // now we are finished | |
937 | value jv = p.release(); // take ownership of the value | |
938 | @endcode | |
939 | ||
940 | @par Complexity | |
941 | Constant. | |
942 | ||
943 | @par Exception Safety | |
944 | Basic guarantee. | |
945 | Calls to `memory_resource::allocate` may throw. | |
946 | Upon error or exception, subsequent calls will | |
947 | fail until @ref reset is called to parse a new JSON. | |
948 | ||
949 | @throw system_error Thrown on error. | |
950 | */ | |
951 | BOOST_JSON_DECL | |
952 | void | |
953 | finish(); | |
954 | ||
955 | /** Return the parsed JSON as a @ref value. | |
956 | ||
957 | This returns the parsed value, or throws | |
958 | an exception if the parsing is incomplete or | |
959 | failed. It is necessary to call @ref reset | |
960 | after calling this function in order to parse | |
961 | another JSON. | |
962 | ||
963 | @par Effects | |
964 | @code | |
965 | if( ! this->done() ) | |
966 | this->finish(); | |
967 | @endcode | |
968 | @note | |
969 | ||
970 | @par Complexity | |
971 | Constant. | |
972 | ||
973 | @return The parsed value. Ownership of this | |
974 | value is transferred to the caller. | |
975 | ||
976 | @throw system_error Thrown on failure. | |
977 | */ | |
978 | BOOST_JSON_DECL | |
979 | value | |
980 | release(); | |
981 | }; | |
982 | ||
983 | BOOST_JSON_NS_END | |
984 | ||
985 | #endif |