stream_parser.hpp 32 KB

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