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