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