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