stream_parser.hpp 34 KB

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