stream_parser.hpp 34 KB

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