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
30 -
    more character buffers, into a @ref value container. It implements a
30 +
    series of one or more character buffers, into a
31 -
    [_streaming algorithm_](https://en.wikipedia.org/wiki/Streaming_algorithm),
31 +
    @ref value container. It implements a
32 -
    allowing these parsing strategies:
32 +
    <a href="https://en.wikipedia.org/wiki/Streaming_algorithm">
 
33 +
        <em>streaming algorithm</em></a>, allowing these
 
34 +
    parsing strategies:
33  

35  

34 -
    @li parse a JSON file a piece at a time;
36 +
    @li Parse a JSON file a piece at a time.
35 -
    @li parse incoming JSON text as it arrives, one buffer at a time;
37 +

36 -
    @li parse with bounded resource consumption per cycle.
38 +
    @li Parse incoming JSON text as it arrives,
 
39 +
        one buffer at a time.
 
40 +

 
41 +
    @li Parse with bounded resource consumption
 
42 +
        per cycle.
37  

43  

38  
    @par Usage
44  
    @par Usage
39 -
    To use the parser first construct it, then optionally call @ref reset to
45 +

40 -
    specify a @ref storage_ptr to use for the resulting @ref value. Then call
46 +
    To use the parser first construct it, then optionally
41 -
    @ref write one or more times to parse a single, complete JSON text. Call
47 +
    call @ref reset to specify a @ref storage_ptr to use
42 -
    @ref done to determine if the parse has completed. To indicate there are no
48 +
    for the resulting @ref value. Then call @ref write
43 -
    more buffers, call @ref finish. If the parse is successful, call @ref
49 +
    one or more times to parse a single, complete JSON text.
44 -
    release to take ownership of the value:
50 +
    Call @ref done to determine if the parse has completed.
 
51 +
    To indicate there are no more buffers, call @ref finish.
 
52 +
    If the parse is successful, call @ref release to take
 
53 +
    ownership of the value:
45  

54  

46  
    @code
55  
    @code
47  
    stream_parser p;                                // construct a parser
56  
    stream_parser p;                                // construct a parser
48  
    p.write( "[1,2" );                              // parse some of a JSON text
57  
    p.write( "[1,2" );                              // parse some of a JSON text
49  
    p.write( ",3,4]" );                             // parse the rest of the JSON text
58  
    p.write( ",3,4]" );                             // parse the rest of the JSON text
50  
    assert( p.done() );                             // we have a complete JSON text
59  
    assert( p.done() );                             // we have a complete JSON text
51  
    value jv = p.release();                         // take ownership of the value
60  
    value jv = p.release();                         // take ownership of the value
52  
    @endcode
61  
    @endcode
53  

62  

54 -
    When the character buffer provided as input contains additional data that
 
55 -
    is not part of the complete JSON text, an error is returned. The @ref
 
56 -
    write_some function is an alternative which allows the parse to finish
 
57 -
    early, without consuming all the characters in the buffer. This allows
 
58 -
    parsing of a buffer containing multiple individual JSON texts or containing
 
59 -
    different protocol data:
 
60  
    @par Extra Data
63  
    @par Extra Data
61  

64  

 
65 +
    When the character buffer provided as input contains
 
66 +
    additional data that is not part of the complete
 
67 +
    JSON text, an error is returned. The @ref write_some
 
68 +
    function is an alternative which allows the parse
 
69 +
    to finish early, without consuming all the characters
 
70 +
    in the buffer. This allows parsing of a buffer
 
71 +
    containing multiple individual JSON texts or containing
 
72 +
    different protocol data:
62  
    @code
73  
    @code
63  
    stream_parser p;                                // construct a parser
74  
    stream_parser p;                                // construct a parser
64  
    std::size_t n;                                  // number of characters used
75  
    std::size_t n;                                  // number of characters used
65  
    n = p.write_some( "[1,2" );                     // parse some of a JSON text
76  
    n = p.write_some( "[1,2" );                     // parse some of a JSON text
66  
    assert( n == 4 );                               // all characters consumed
77  
    assert( n == 4 );                               // all characters consumed
67  
    n = p.write_some( ",3,4] null" );               // parse the remainder of the JSON text
78  
    n = p.write_some( ",3,4] null" );               // parse the remainder of the JSON text
68  
    assert( n == 6 );                               // only some characters consumed
79  
    assert( n == 6 );                               // only some characters consumed
69  
    assert( p.done() );                             // we have a complete JSON text
80  
    assert( p.done() );                             // we have a complete JSON text
70  
    value jv = p.release();                         // take ownership of the value
81  
    value jv = p.release();                         // take ownership of the value
71  
    @endcode
82  
    @endcode
72  

83  

73 -
    The parser may dynamically allocate temporary storage as needed to
 
74 -
    accommodate the nesting level of the JSON text being parsed. Temporary
 
75 -
    storage is first obtained from an optional, caller-owned buffer specified
 
76 -
    upon construction. When that is exhausted, the next allocation uses the
 
77 -
    @ref boost::container::pmr::memory_resource passed to the constructor; if
 
78 -
    no such argument is specified, the default memory resource is used.
 
79 -
    Temporary storage is freed only when the parser is destroyed; The
 
80 -
    performance of parsing multiple JSON texts may be improved by reusing the
 
81 -
    same parser instance.
 
82  
    @par Temporary Storage
84  
    @par Temporary Storage
83  

85  

84 -
    It is important to note that the @ref
86 +
    The parser may dynamically allocate temporary
85 -
    boost::container::pmr::memory_resource supplied upon construction is used
87 +
    storage as needed to accommodate the nesting level
86 -
    for temporary storage only, and not for allocating the elements which make
88 +
    of the JSON text being parsed. Temporary storage is
87 -
    up the parsed value. That other memory resource is optionally supplied in
89 +
    first obtained from an optional, caller-owned
88 -
    each call to @ref reset.
90 +
    buffer specified upon construction. When that
 
91 +
    is exhausted, the next allocation uses the
 
92 +
    `boost::container::pmr::memory_resource` passed to the constructor; if
 
93 +
    no such argument is specified, the default memory
 
94 +
    resource is used. Temporary storage is freed only
 
95 +
    when the parser is destroyed; The performance of
 
96 +
    parsing multiple JSON texts may be improved by reusing
 
97 +
    the same parser instance.
 
98 +
\n
 
99 +
    It is important to note that the `boost::container::pmr::memory_resource`
 
100 +
    supplied upon construction is used for temporary storage only, and not for
 
101 +
    allocating the elements which make up the parsed value. That other memory
 
102 +
    resource is optionally supplied in each call to @ref reset.
89  

103  

90  
    @par Duplicate Keys
104  
    @par Duplicate Keys
91 -
    If there are object elements with duplicate keys; that is, if multiple
105 +

92 -
    elements in an object have keys that compare equal, only the last
106 +
    If there are object elements with duplicate keys;
93 -
    equivalent element will be inserted.
107 +
    that is, if multiple elements in an object have
 
108 +
    keys that compare equal, only the last equivalent
 
109 +
    element will be inserted.
94  

110  

95  
    @par Non-Standard JSON
111  
    @par Non-Standard JSON
96 -
    The @ref parse_options structure optionally provided upon construction is
112 +

97 -
    used to customize some parameters of the parser, including which
113 +
    The @ref parse_options structure optionally
98 -
    non-standard JSON extensions should be allowed. A default-constructed parse
114 +
    provided upon construction is used to customize
99 -
    options allows only standard JSON.
115 +
    some parameters of the parser, including which
 
116 +
    non-standard JSON extensions should be allowed.
 
117 +
    A default-constructed parse options allows only
 
118 +
    standard JSON.
100  

119  

101 -
    Distinct instances may be accessed concurrently. Non-const member functions
 
102 -
    of a shared instance may not be called concurrently with any other member
 
103 -
    functions of that instance.
 
104  
    @par Thread Safety
120  
    @par Thread Safety
105  

121  

106 -
    @see @ref parse, @ref parser, @ref parse_options.
122 +
    Distinct instances may be accessed concurrently.
 
123 +
    Non-const member functions of a shared instance
 
124 +
    may not be called concurrently with any other
 
125 +
    member functions of that instance.
 
126 +

 
127 +
    @see
 
128 +
        @ref parse,
 
129 +
        @ref parser,
 
130 +
        @ref parse_options,
107  
*/
131  
*/
108  
class stream_parser
132  
class stream_parser
109  
{
133  
{
110  
    basic_parser<detail::handler> p_;
134  
    basic_parser<detail::handler> p_;
111  

135  

112  
public:
136  
public:
 
137 +
    /// Copy constructor (deleted)
 
138 +
    stream_parser(
 
139 +
        stream_parser const&) = delete;
 
140 +

 
141 +
    /// Copy assignment (deleted)
 
142 +
    stream_parser& operator=(
 
143 +
        stream_parser const&) = delete;
 
144 +

113  
    /** Destructor.
145  
    /** Destructor.
114  

146  

115  
        All dynamically allocated memory, including
147  
        All dynamically allocated memory, including
116  
        any incomplete parsing results, is freed.
148  
        any incomplete parsing results, is freed.
117  

149  

118  
        @par Complexity
150  
        @par Complexity
119  
        Linear in the size of partial results
151  
        Linear in the size of partial results
120  

152  

121  
        @par Exception Safety
153  
        @par Exception Safety
122  
        No-throw guarantee.
154  
        No-throw guarantee.
123  
    */
155  
    */
124  
    ~stream_parser() = default;
156  
    ~stream_parser() = default;
125  

157  

126 -
    /** Constructors.
158 +
    /** Constructor.
127 -

 
128 -
        Construct a new parser.
 
129  

159  

130 -
        The parser will only support standard JSON if overloads **(1)**
160 +
        This constructs a new parser which first uses
131 -
        or **(2)** are used. Otherwise the parser will support extensions
161 +
        the caller-owned storage pointed to by `buffer`
132 -
        specified by the parameter `opt`.
162 +
        for temporary storage, falling back to the memory
 
163 +
        resource `sp` if needed. The parser will use the
 
164 +
        specified parsing options.
 
165 +
    \n
 
166 +
        The parsed value will use the default memory
 
167 +
        resource for storage. To use a different resource,
 
168 +
        call @ref reset after construction.
133  

169  

134 -
        The parsed value will use the \<\<default_memory_resource,default
170 +
        @par Complexity
135 -
        memory resource\>\> for storage. To use a different resource, call @ref
171 +
        Constant.
136 -
        reset after construction.
 
137  

172  

138 -
        The main difference between the overloads is in what the constructed
173 +
        @par Exception Safety
139 -
        parser will use for temporary storage:
174 +
        No-throw guarantee.
140  

175  

141 -
        @li **(1)** the constructed parser uses the default memory resource for
176 +
        @param sp The memory resource to use for
142 -
        temporary storage.
177 +
        temporary storage after `buffer` is exhausted.
143  

178  

144 -
        @li **(2)**, **(3)** the constructed parser uses the memory resource of
179 +
        @param opt The parsing options to use.
145 -
        `sp` for temporary storage.
 
146  

180  

147 -
        @li **(4)**, **(6)** the constructed parser first uses the caller-owned
181 +
        @param buffer A pointer to valid memory of at least
148 -
        storage `[buffer, buffer + size)` for temporary storage, falling back
182 +
        `size` bytes for the parser to use for temporary storage.
149 -
        to the memory resource of `sp` if needed.
183 +
        Ownership is not transferred, the caller is responsible
 
184 +
        for ensuring the lifetime of the memory pointed to by
 
185 +
        `buffer` extends until the parser is destroyed.
150  

186  

151 -
        @li **(5)**, **(7)** the constructed parser first uses the caller-owned
187 +
        @param size The number of valid bytes in `buffer`.
152 -
        storage `[buffer, buffer + N)` for temporary storage, falling back to
188 +
    */
153 -
        the memory resource of `sp` if needed.
189 +
    BOOST_JSON_DECL
 
190 +
    stream_parser(
 
191 +
        storage_ptr sp,
 
192 +
        parse_options const& opt,
 
193 +
        unsigned char* buffer,
 
194 +
        std::size_t size) noexcept;
154  

195  

155 -
        @note Ownership of `buffer` is not transferred. The caller is
196 +
    /** Constructor.
156 -
        responsible for ensuring the lifetime of the storage pointed to by
 
157 -
        `buffer` extends until the parser is destroyed.
 
158  

197  

159 -
        Overload **(8)** is the copy constructor. The type is neither copyable
198 +
        This constructs a new parser which uses the default
160 -
        nor movable, so the overload is deleted.
199 +
        memory resource for temporary storage, and accepts
 
200 +
        only strict JSON.
 
201 +
    \n
 
202 +
        The parsed value will use the default memory
 
203 +
        resource for storage. To use a different resource,
 
204 +
        call @ref reset after construction.
161  

205  

162  
        @par Complexity
206  
        @par Complexity
163  
        Constant.
207  
        Constant.
164  

208  

165  
        @par Exception Safety
209  
        @par Exception Safety
166 -

 
167 -
        @{
 
168  
        No-throw guarantee.
210  
        No-throw guarantee.
169  
    */
211  
    */
170  
    stream_parser() noexcept
212  
    stream_parser() noexcept
171  
        : stream_parser({}, {})
213  
        : stream_parser({}, {})
172  
    {
214  
    {
173  
    }
215  
    }
174  

216  

 
217 +
    /** Constructor.
175  

218  

176 -
    /** Overload
219 +
        This constructs a new parser which uses the
 
220 +
        specified memory resource for temporary storage,
 
221 +
        and is configured to use the specified parsing
 
222 +
        options.
 
223 +
    \n
 
224 +
        The parsed value will use the default memory
 
225 +
        resource for storage. To use a different resource,
 
226 +
        call @ref reset after construction.
177  

227  

178 -
        @param sp The memory resource to use for temporary storage.
228 +
        @par Complexity
179 -
    */
229 +
        Constant.
180 -
    explicit
 
181 -
    stream_parser(storage_ptr sp) noexcept
 
182 -
        : stream_parser(std::move(sp), {})
 
183 -
    {
 
184 -
    }
 
185  

230  

186 -
    /** Overload
231 +
        @par Exception Safety
 
232 +
        No-throw guarantee.
 
233 +

 
234 +
        @param sp The memory resource to use for temporary storage.
187  

235  

188 -
        @param sp
 
189  
        @param opt The parsing options to use.
236  
        @param opt The parsing options to use.
190  
    */
237  
    */
191  
    BOOST_JSON_DECL
238  
    BOOST_JSON_DECL
192  
    stream_parser(
239  
    stream_parser(
193  
        storage_ptr sp,
240  
        storage_ptr sp,
194  
        parse_options const& opt) noexcept;
241  
        parse_options const& opt) noexcept;
195  

242  

196 -
    /** Overload
243 +
    /** Constructor.
197 -
        @param buffer A pointer to valid storage.
244 +

198 -
        @param size The number of valid bytes in `buffer`.
245 +
        This constructs a new parser which uses the
199 -
        @param sp
246 +
        specified memory resource for temporary storage,
200 -
        @param opt
247 +
        and accepts only strict JSON.
 
248 +
    \n
 
249 +
        The parsed value will use the default memory
 
250 +
        resource for storage. To use a different resource,
 
251 +
        call @ref reset after construction.
 
252 +

 
253 +
        @par Complexity
 
254 +
        Constant.
 
255 +

 
256 +
        @par Exception Safety
 
257 +
        No-throw guarantee.
 
258 +

 
259 +
        @param sp The memory resource to use for temporary storage.
201  
    */
260  
    */
202 -
    BOOST_JSON_DECL
261 +
    explicit
203 -
    stream_parser(
262 +
    stream_parser(storage_ptr sp) noexcept
204 -
        storage_ptr sp,
263 +
        : stream_parser(std::move(sp), {})
205 -
        parse_options const& opt,
264 +
    {
206 -
        unsigned char* buffer,
265 +
    }
207 -
        std::size_t size) noexcept;
 
208  

266  

209 -
    /** Overload
267 +
    /** Constructor.
210  

268  

211 -
        @tparam N The number of valid bytes in `buffer`.
269 +
        This constructs a new parser which first uses the
212 -
        @param sp
270 +
        caller-owned storage `buffer` for temporary storage,
213 -
        @param opt
271 +
        falling back to the memory resource `sp` if needed.
214 -
        @param buffer
272 +
        The parser will use the specified parsing options.
 
273 +
    \n
 
274 +
        The parsed value will use the default memory
 
275 +
        resource for storage. To use a different resource,
 
276 +
        call @ref reset after construction.
 
277 +

 
278 +
        @par Complexity
 
279 +
        Constant.
 
280 +

 
281 +
        @par Exception Safety
 
282 +
        No-throw guarantee.
 
283 +

 
284 +
        @param sp The memory resource to use for
 
285 +
        temporary storage after `buffer` is exhausted.
 
286 +

 
287 +
        @param opt The parsing options to use.
 
288 +

 
289 +
        @param buffer A buffer for the parser to use for
 
290 +
        temporary storage. Ownership is not transferred,
 
291 +
        the caller is responsible for ensuring the lifetime
 
292 +
        of `buffer` extends until the parser is destroyed.
215  
    */
293  
    */
216  
    template<std::size_t N>
294  
    template<std::size_t N>
217  
    stream_parser(
295  
    stream_parser(
218  
        storage_ptr sp,
296  
        storage_ptr sp,
219  
        parse_options const& opt,
297  
        parse_options const& opt,
220  
        unsigned char(&buffer)[N]) noexcept
298  
        unsigned char(&buffer)[N]) noexcept
221  
        : stream_parser(std::move(sp),
299  
        : stream_parser(std::move(sp),
222  
            opt, &buffer[0], N)
300  
            opt, &buffer[0], N)
223  
    {
301  
    {
224  
    }
302  
    }
225  

303  

226  
#if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
304  
#if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
227 -
    /** Overload
305 +
    /** Constructor.
228  

306  

229 -
        @param sp
307 +
        This constructs a new parser which first uses
230 -
        @param opt
308 +
        the caller-owned storage pointed to by `buffer`
231 -
        @param buffer
309 +
        for temporary storage, falling back to the memory
232 -
        @param size
310 +
        resource `sp` if needed. The parser will use the
 
311 +
        specified parsing options.
 
312 +
    \n
 
313 +
        The parsed value will use the default memory
 
314 +
        resource for storage. To use a different resource,
 
315 +
        call @ref reset after construction.
 
316 +

 
317 +
        @par Complexity
 
318 +
        Constant.
 
319 +

 
320 +
        @par Exception Safety
 
321 +
        No-throw guarantee.
 
322 +

 
323 +
        @param sp The memory resource to use for
 
324 +
        temporary storage after `buffer` is exhausted.
 
325 +

 
326 +
        @param opt The parsing options to use.
 
327 +

 
328 +
        @param buffer A pointer to valid memory of at least
 
329 +
        `size` bytes for the parser to use for temporary storage.
 
330 +
        Ownership is not transferred, the caller is responsible
 
331 +
        for ensuring the lifetime of the memory pointed to by
 
332 +
        `buffer` extends until the parser is destroyed.
 
333 +

 
334 +
        @param size The number of valid bytes in `buffer`.
233  
    */
335  
    */
234  
    stream_parser(
336  
    stream_parser(
235  
        storage_ptr sp,
337  
        storage_ptr sp,
236  
        parse_options const& opt,
338  
        parse_options const& opt,
237  
        std::byte* buffer,
339  
        std::byte* buffer,
238  
        std::size_t size) noexcept
340  
        std::size_t size) noexcept
239  
        : stream_parser(sp, opt, reinterpret_cast<
341  
        : stream_parser(sp, opt, reinterpret_cast<
240  
            unsigned char*>(buffer), size)
342  
            unsigned char*>(buffer), size)
241  
    {
343  
    {
242  
    }
344  
    }
243  

345  

244 -
    /** Overload
346 +
    /** Constructor.
245  

347  

246 -
        @tparam N
348 +
        This constructs a new parser which first uses the
247 -
        @param sp
349 +
        caller-owned storage `buffer` for temporary storage,
248 -
        @param opt
350 +
        falling back to the memory resource `sp` if needed.
249 -
        @param buffer
351 +
        The parser will use the specified parsing options.
 
352 +
    \n
 
353 +
        The parsed value will use the default memory
 
354 +
        resource for storage. To use a different resource,
 
355 +
        call @ref reset after construction.
 
356 +

 
357 +
        @par Complexity
 
358 +
        Constant.
 
359 +

 
360 +
        @par Exception Safety
 
361 +
        No-throw guarantee.
 
362 +

 
363 +
        @param sp The memory resource to use for
 
364 +
        temporary storage after `buffer` is exhausted.
 
365 +

 
366 +
        @param opt The parsing options to use.
 
367 +

 
368 +
        @param buffer A buffer for the parser to use for
 
369 +
        temporary storage. Ownership is not transferred,
 
370 +
        the caller is responsible for ensuring the lifetime
 
371 +
        of `buffer` extends until the parser is destroyed.
250  
    */
372  
    */
251  
    template<std::size_t N>
373  
    template<std::size_t N>
252  
    stream_parser(
374  
    stream_parser(
253  
        storage_ptr sp,
375  
        storage_ptr sp,
254  
        parse_options const& opt,
376  
        parse_options const& opt,
255  
        std::byte(&buffer)[N]) noexcept
377  
        std::byte(&buffer)[N]) noexcept
256  
        : stream_parser(std::move(sp),
378  
        : stream_parser(std::move(sp),
257  
            opt, &buffer[0], N)
379  
            opt, &buffer[0], N)
258  
    {
380  
    {
259  
    }
381  
    }
260  
#endif
382  
#endif
261  

383  

262  
#ifndef BOOST_JSON_DOCS
384  
#ifndef BOOST_JSON_DOCS
263  
    // Safety net for accidental buffer overflows
385  
    // Safety net for accidental buffer overflows
264  
    template<std::size_t N>
386  
    template<std::size_t N>
265  
    stream_parser(
387  
    stream_parser(
266  
        storage_ptr sp,
388  
        storage_ptr sp,
267  
        parse_options const& opt,
389  
        parse_options const& opt,
268  
        unsigned char(&buffer)[N],
390  
        unsigned char(&buffer)[N],
269  
        std::size_t n) noexcept
391  
        std::size_t n) noexcept
270  
        : stream_parser(std::move(sp),
392  
        : stream_parser(std::move(sp),
271  
            opt, &buffer[0], n)
393  
            opt, &buffer[0], n)
272  
    {
394  
    {
273  
        // If this goes off, check your parameters
395  
        // If this goes off, check your parameters
274  
        // closely, chances are you passed an array
396  
        // closely, chances are you passed an array
275  
        // thinking it was a pointer.
397  
        // thinking it was a pointer.
276  
        BOOST_ASSERT(n <= N);
398  
        BOOST_ASSERT(n <= N);
277  
    }
399  
    }
278  

400  

279  
#ifdef __cpp_lib_byte
401  
#ifdef __cpp_lib_byte
280  
    // Safety net for accidental buffer overflows
402  
    // Safety net for accidental buffer overflows
281  
    template<std::size_t N>
403  
    template<std::size_t N>
282  
    stream_parser(
404  
    stream_parser(
283  
        storage_ptr sp,
405  
        storage_ptr sp,
284  
        parse_options const& opt,
406  
        parse_options const& opt,
285  
        std::byte(&buffer)[N], std::size_t n) noexcept
407  
        std::byte(&buffer)[N], std::size_t n) noexcept
286  
        : stream_parser(std::move(sp),
408  
        : stream_parser(std::move(sp),
287  
            opt, &buffer[0], n)
409  
            opt, &buffer[0], n)
288  
    {
410  
    {
289  
        // If this goes off, check your parameters
411  
        // If this goes off, check your parameters
290  
        // closely, chances are you passed an array
412  
        // closely, chances are you passed an array
291  
        // thinking it was a pointer.
413  
        // thinking it was a pointer.
292  
        BOOST_ASSERT(n <= N);
414  
        BOOST_ASSERT(n <= N);
293  
    }
415  
    }
294  
#endif
416  
#endif
295  
#endif
417  
#endif
296 -
    /// Overload
 
297 -
    stream_parser(
 
298 -
        stream_parser const&) = delete;
 
299 -
    /// @}
 
300 -

 
301 -
    /** Assignment operator.
 
302 -

 
303 -
       This type is neither copyable nor movable, so copy assignment operator
 
304 -
       is deleted.
 
305 -
   */
 
306 -
    stream_parser& operator=(
 
307 -
        stream_parser const&) = delete;
 
308 -

 
309  

418  

310  
    /** Reset the parser for a new JSON text.
419  
    /** Reset the parser for a new JSON text.
311  

420  

312 -
        This function is used to reset the parser to prepare it for parsing
421 +
        This function is used to reset the parser to
313 -
        a new complete JSON text. Any previous partial results are destroyed.
422 +
        prepare it for parsing a new complete JSON text.
314 -
        The new value will use the memory resource of `sp`.
423 +
        Any previous partial results are destroyed.
315  

424  

316  
        @par Complexity
425  
        @par Complexity
317 -
        Constant or linear in the size of any previous partial parsing results.
426 +
        Constant or linear in the size of any previous
 
427 +
        partial parsing results.
318  

428  

319  
        @par Exception Safety
429  
        @par Exception Safety
320  
        No-throw guarantee.
430  
        No-throw guarantee.
321  

431  

322 -
        @param sp A pointer to the @ref boost::container::pmr::memory_resource.
432 +
        @param sp A pointer to the `boost::container::pmr::memory_resource` to
 
433 +
        use for the resulting @ref value. The parser will acquire shared
 
434 +
        ownership.
323  
    */
435  
    */
324  
    BOOST_JSON_DECL
436  
    BOOST_JSON_DECL
325  
    void
437  
    void
326  
    reset(storage_ptr sp = {}) noexcept;
438  
    reset(storage_ptr sp = {}) noexcept;
327  

439  

328 -
    /** Check if a complete JSON text has been parsed.
440 +
    /** Return true if a complete JSON text has been parsed.
329  

441  

330 -
        This function returns `true` when all of these conditions are met:
442 +
        This function returns `true` when all of these
 
443 +
        conditions are met:
331  

444  

332 -
        @li A complete serialized JSON text has been presented to the parser,
445 +
        @li A complete serialized JSON text has been
333 -
        and
446 +
            presented to the parser, and
334  

447  

335 -
        @li No error has occurred since the parser was constructed, or since
448 +
        @li No error has occurred since the parser
336 -
        the last call to @ref reset,
449 +
            was constructed, or since the last call
 
450 +
            to @ref reset,
337  

451  

338  
        @par Complexity
452  
        @par Complexity
339  
        Constant.
453  
        Constant.
340  

454  

341  
        @par Exception Safety
455  
        @par Exception Safety
342  
        No-throw guarantee.
456  
        No-throw guarantee.
343  
    */
457  
    */
344  
    bool
458  
    bool
345  
    done() const noexcept
459  
    done() const noexcept
346  
    {
460  
    {
347  
        return p_.done();
461  
        return p_.done();
348  
    }
462  
    }
349  

463  

350  
    /** Parse a buffer containing all or part of a complete JSON text.
464  
    /** Parse a buffer containing all or part of a complete JSON text.
351  

465  

352 -
        This function parses JSON text contained in the specified character
466 +
        This function parses JSON text contained in the
353 -
        buffer. If parsing completes, any additional characters past the end of
467 +
        specified character buffer. If parsing completes,
354 -
        the complete JSON text are ignored. The function returns the actual
468 +
        any additional characters past the end of the
355 -
        number of characters parsed, which may be less than the size of the
469 +
        complete JSON text are ignored. The function returns the
356 -
        input. This allows parsing of a buffer containing multiple individual
470 +
        actual number of characters parsed, which may be
357 -
        JSON texts or containing different protocol data.
471 +
        less than the size of the input. This allows parsing
358 -

472 +
        of a buffer containing multiple individual JSON texts or
359 -
        Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
473 +
        containing different protocol data.
360 -
        setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
 
361 -
        exceptions. Upon error or exception, subsequent calls will fail until
 
362 -
        @ref reset is called to parse a new JSON text.
 
363 -

 
364 -
        @note To indicate there are no more character buffers, such as when
 
365 -
        @ref done returns `false` after writing, call @ref finish.
 
366  

474  

367  
        @par Example
475  
        @par Example
368  
        @code
476  
        @code
369  
        stream_parser p;                                // construct a parser
477  
        stream_parser p;                                // construct a parser
370  
        std::size_t n;                                  // number of characters used
478  
        std::size_t n;                                  // number of characters used
371  
        n = p.write_some( "[1,2" );                     // parse the first part of the JSON text
479  
        n = p.write_some( "[1,2" );                     // parse the first part of the JSON text
372  
        assert( n == 4 );                               // all characters consumed
480  
        assert( n == 4 );                               // all characters consumed
373  
        n = p.write_some( "3,4] null" );                // parse the rest of the JSON text
481  
        n = p.write_some( "3,4] null" );                // parse the rest of the JSON text
374  
        assert( n == 5 );                               // only some characters consumed
482  
        assert( n == 5 );                               // only some characters consumed
375  
        value jv = p.release();                         // take ownership of the value
483  
        value jv = p.release();                         // take ownership of the value
376  
        @endcode
484  
        @endcode
377  

485  

 
486 +
        @note
 
487 +

 
488 +
        To indicate there are no more character buffers,
 
489 +
        such as when @ref done returns `false` after
 
490 +
        writing, call @ref finish.
 
491 +

378  
        @par Complexity
492  
        @par Complexity
379 -
        @li **(1)**--**(3)** linear in `size`.
493 +
        Linear in `size`.
380 -
        @li **(4)**--**(6)** linear in `s.size()`.
 
381  

494  

382  
        @par Exception Safety
495  
        @par Exception Safety
383 -
        Basic guarantee. Calls to `memory_resource::allocate` may throw.
496 +
        Basic guarantee.
 
497 +
        Calls to `memory_resource::allocate` may throw.
 
498 +
        Upon error or exception, subsequent calls will
 
499 +
        fail until @ref reset is called to parse a new JSON text.
384  

500  

385 -
        @return The number of characters consumed from the buffer.
501 +
        @return The number of characters consumed from
 
502 +
        the buffer.
386  

503  

387 -
        @param data A pointer to a buffer of `size` characters to parse.
504 +
        @param data A pointer to a buffer of `size`
388 -
        @param size The number of characters pointed to by `data`.
505 +
        characters to parse.
389 -
        @param ec Set to the error, if any occurred.
 
390  

506  

391 -
        @{
507 +
        @param size The number of characters pointed to
 
508 +
        by `data`.
 
509 +

 
510 +
        @param ec Set to the error, if any occurred.
392  
    */
511  
    */
 
512 +
    /** @{ */
393  
    BOOST_JSON_DECL
513  
    BOOST_JSON_DECL
394  
    std::size_t
514  
    std::size_t
395  
    write_some(
515  
    write_some(
396  
        char const* data,
516  
        char const* data,
397  
        std::size_t size,
517  
        std::size_t size,
398  
        system::error_code& ec);
518  
        system::error_code& ec);
399  

519  

400  
    BOOST_JSON_DECL
520  
    BOOST_JSON_DECL
401  
    std::size_t
521  
    std::size_t
402  
    write_some(
522  
    write_some(
403  
        char const* data,
523  
        char const* data,
404  
        std::size_t size,
524  
        std::size_t size,
405  
        std::error_code& ec);
525  
        std::error_code& ec);
 
526 +
    /** @} */
406  

527  

407 -
    /** Overload
528 +
    /** Parse a buffer containing all or part of a complete JSON text.
408  

529  

409 -
        @param data
530 +
        This function parses JSON text contained in the
410 -
        @param size
531 +
        specified character buffer. If parsing completes,
 
532 +
        any additional characters past the end of the
 
533 +
        complete JSON text are ignored. The function returns the
 
534 +
        actual number of characters parsed, which may be
 
535 +
        less than the size of the input. This allows parsing
 
536 +
        of a buffer containing multiple individual JSON texts or
 
537 +
        containing different protocol data.
411  

538  

412 -
        @throw boost::system::system_error Thrown on error.
539 +
        @par Example
 
540 +
        @code
 
541 +
        stream_parser p;                                // construct a parser
 
542 +
        std::size_t n;                                  // number of characters used
 
543 +
        n = p.write_some( "[1,2" );                     // parse the first part of the JSON text
 
544 +
        assert( n == 4 );                               // all characters consumed
 
545 +
        n = p.write_some( "3,4] null" );                // parse the rest of the JSON text
 
546 +
        assert( n == 5 );                               // only some characters consumed
 
547 +
        value jv = p.release();                         // take ownership of the value
 
548 +
        @endcode
 
549 +

 
550 +
        @note
 
551 +

 
552 +
        To indicate there are no more character buffers,
 
553 +
        such as when @ref done returns `false` after
 
554 +
        writing, call @ref finish.
 
555 +

 
556 +
        @par Complexity
 
557 +
        Linear in `size`.
 
558 +

 
559 +
        @par Exception Safety
 
560 +
        Basic guarantee.
 
561 +
        Calls to `memory_resource::allocate` may throw.
 
562 +
        Upon error or exception, subsequent calls will
 
563 +
        fail until @ref reset is called to parse a new JSON text.
 
564 +

 
565 +
        @return The number of characters consumed from
 
566 +
        the buffer.
 
567 +

 
568 +
        @param data A pointer to a buffer of `size`
 
569 +
        characters to parse.
 
570 +

 
571 +
        @param size The number of characters pointed to
 
572 +
        by `data`.
 
573 +

 
574 +
        @throw `boost::system::system_error` Thrown on error.
413  
    */
575  
    */
414  
    BOOST_JSON_DECL
576  
    BOOST_JSON_DECL
415  
    std::size_t
577  
    std::size_t
416  
    write_some(
578  
    write_some(
417  
        char const* data,
579  
        char const* data,
418  
        std::size_t size);
580  
        std::size_t size);
419  

581  

420 -
    /** Overload
582 +
    /** Parse a buffer containing all or part of a complete JSON text.
 
583 +

 
584 +
        This function parses JSON text contained in the
 
585 +
        specified character buffer. If parsing completes,
 
586 +
        any additional characters past the end of the
 
587 +
        complete JSON text are ignored. The function returns the
 
588 +
        actual number of characters parsed, which may be
 
589 +
        less than the size of the input. This allows parsing
 
590 +
        of a buffer containing multiple individual JSON texts or
 
591 +
        containing different protocol data.
 
592 +

 
593 +
        @par Example
 
594 +
        @code
 
595 +
        stream_parser p;                                // construct a parser
 
596 +
        std::size_t n;                                  // number of characters used
 
597 +
        n = p.write_some( "[1,2" );                     // parse the first part of the JSON text
 
598 +
        assert( n == 4 );                               // all characters consumed
 
599 +
        n = p.write_some( "3,4] null" );                // parse the rest of the JSON text
 
600 +
        assert( n == 5 );                               // only some characters consumed
 
601 +
        value jv = p.release();                         // take ownership of the value
 
602 +
        @endcode
 
603 +

 
604 +
        @note
 
605 +

 
606 +
        To indicate there are no more character buffers,
 
607 +
        such as when @ref done returns `false` after
 
608 +
        writing, call @ref finish.
 
609 +

 
610 +
        @par Complexity
 
611 +
        Linear in `size`.
 
612 +

 
613 +
        @par Exception Safety
 
614 +
        Basic guarantee.
 
615 +
        Calls to `memory_resource::allocate` may throw.
 
616 +
        Upon error or exception, subsequent calls will
 
617 +
        fail until @ref reset is called to parse a new JSON text.
 
618 +

 
619 +
        @return The number of characters consumed from
 
620 +
        the buffer.
 
621 +

421  
        @param s The character string to parse.
622  
        @param s The character string to parse.
422 -
        @param ec
623 +

 
624 +
        @param ec Set to the error, if any occurred.
423  
    */
625  
    */
 
626 +
    /** @{ */
424  
    std::size_t
627  
    std::size_t
425  
    write_some(
628  
    write_some(
426  
        string_view s,
629  
        string_view s,
427  
        system::error_code& ec)
630  
        system::error_code& ec)
428  
    {
631  
    {
429  
        return write_some(
632  
        return write_some(
430  
            s.data(), s.size(), ec);
633  
            s.data(), s.size(), ec);
431  
    }
634  
    }
432 -
    /** Overload
 
433 -
        @param s
 
434 -
        @param ec
 
435 -
    */
 
436  

635  

437  
    std::size_t
636  
    std::size_t
438  
    write_some(
637  
    write_some(
439  
        string_view s,
638  
        string_view s,
440  
        std::error_code& ec)
639  
        std::error_code& ec)
441  
    {
640  
    {
442  
        return write_some(
641  
        return write_some(
443  
            s.data(), s.size(), ec);
642  
            s.data(), s.size(), ec);
444  
    }
643  
    }
 
644 +
    /** @} */
445  

645  

446 -
    /** Overload
646 +
    /** Parse a buffer containing all or part of a complete JSON text.
447 -
        @param s
647 +

 
648 +
        This function parses JSON text contained in the
 
649 +
        specified character buffer. If parsing completes,
 
650 +
        any additional characters past the end of the
 
651 +
        complete JSON text are ignored. The function returns the
 
652 +
        actual number of characters parsed, which may be
 
653 +
        less than the size of the input. This allows parsing
 
654 +
        of a buffer containing multiple individual JSON texts or
 
655 +
        containing different protocol data.
 
656 +

 
657 +
        @par Example
 
658 +
        @code
 
659 +
        stream_parser p;                                // construct a parser
 
660 +
        std::size_t n;                                  // number of characters used
 
661 +
        n = p.write_some( "[1,2" );                     // parse the first part of the JSON text
 
662 +
        assert( n == 4 );                               // all characters consumed
 
663 +
        n = p.write_some( "3,4] null" );                // parse the rest of the JSON text
 
664 +
        assert( n == 5 );                               // only some characters consumed
 
665 +
        value jv = p.release();                         // take ownership of the value
 
666 +
        @endcode
 
667 +

 
668 +
        @note
 
669 +

 
670 +
        To indicate there are no more character buffers,
 
671 +
        such as when @ref done returns `false` after
 
672 +
        writing, call @ref finish.
 
673 +

 
674 +
        @par Complexity
 
675 +
        Linear in `size`.
 
676 +

 
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 +

 
683 +
        @return The number of characters consumed from
 
684 +
        the buffer.
 
685 +

 
686 +
        @param s The character string to parse.
 
687 +

 
688 +
        @throw `boost::system::system_error` Thrown on error.
448  
    */
689  
    */
449  
    std::size_t
690  
    std::size_t
450  
    write_some(
691  
    write_some(
451  
        string_view s)
692  
        string_view s)
452  
    {
693  
    {
453  
        return write_some(
694  
        return write_some(
454  
            s.data(), s.size());
695  
            s.data(), s.size());
455 -
    /// @}
 
456  
    }
696  
    }
457  

697  

458  
    /** Parse a buffer containing all or part of a complete JSON text.
698  
    /** Parse a buffer containing all or part of a complete JSON text.
459  

699  

460 -
        This function parses all or part of a JSON text contained in the
700 +
        This function parses a all or part of a JSON text
461 -
        specified character buffer. The entire buffer must be consumed; if
701 +
        contained in the specified character buffer. The
462 -
        there are additional characters past the end of the complete JSON text,
702 +
        entire buffer must be consumed; if there are
463 -
        the parse fails and an error is returned.
703 +
        additional characters past the end of the complete
464 -

704 +
        JSON text, the parse fails and an error is returned.
465 -
        Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
 
466 -
        setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
 
467 -
        exceptions. Upon error or exception, subsequent calls will fail until
 
468 -
        @ref reset is called to parse a new JSON text.
 
469 -

 
470 -
        @note To indicate there are no more character buffers, such as when
 
471 -
        @ref done returns `false` after writing, call @ref finish.
 
472  

705  

473  
        @par Example
706  
        @par Example
474  
        @code
707  
        @code
475  
        stream_parser p;                                // construct a parser
708  
        stream_parser p;                                // construct a parser
476  
        std::size_t n;                                  // number of characters used
709  
        std::size_t n;                                  // number of characters used
477  
        n = p.write( "[1,2" );                          // parse some of the JSON text
710  
        n = p.write( "[1,2" );                          // parse some of the JSON text
478  
        assert( n == 4 );                               // all characters consumed
711  
        assert( n == 4 );                               // all characters consumed
479  
        n = p.write( "3,4]" );                          // parse the rest of the JSON text
712  
        n = p.write( "3,4]" );                          // parse the rest of the JSON text
480  
        assert( n == 4 );                               // all characters consumed
713  
        assert( n == 4 );                               // all characters consumed
481  
        value jv = p.release();                         // take ownership of the value
714  
        value jv = p.release();                         // take ownership of the value
482  
        @endcode
715  
        @endcode
483  

716  

 
717 +
        @note
 
718 +

 
719 +
        To indicate there are no more character buffers,
 
720 +
        such as when @ref done returns `false` after
 
721 +
        writing, call @ref finish.
 
722 +

484  
        @par Complexity
723  
        @par Complexity
485 -
        @li **(1)**--**(3)** linear in `size`.
724 +
        Linear in `size`.
486 -
        @li **(4)**--**(6)** linear in `s.size()`.
 
487  

725  

488  
        @par Exception Safety
726  
        @par Exception Safety
489 -
        Basic guarantee. Calls to `memory_resource::allocate` may throw.
727 +
        Basic guarantee.
490 -
        @return The number of characters consumed from the buffer.
728 +
        Calls to `memory_resource::allocate` may throw.
 
729 +
        Upon error or exception, subsequent calls will
 
730 +
        fail until @ref reset is called to parse a new JSON text.
491  

731  

492 -
        @param data A pointer to a buffer of `size` characters to parse.
732 +
        @return The number of characters consumed from
 
733 +
        the buffer.
493  

734  

494 -
        @param size The number of characters pointed to by `data`.
735 +
        @param data A pointer to a buffer of `size`
 
736 +
        characters to parse.
495  

737  

496 -
        @param ec Set to the error, if any occurred.
738 +
        @param size The number of characters pointed to
 
739 +
        by `data`.
497  

740  

498 -
        @{
741 +
        @param ec Set to the error, if any occurred.
499  
    */
742  
    */
 
743 +
    /** @{ */
500  
    BOOST_JSON_DECL
744  
    BOOST_JSON_DECL
501  
    std::size_t
745  
    std::size_t
502  
    write(
746  
    write(
503  
        char const* data,
747  
        char const* data,
504  
        std::size_t size,
748  
        std::size_t size,
505  
        system::error_code& ec);
749  
        system::error_code& ec);
506  

750  

507  
    BOOST_JSON_DECL
751  
    BOOST_JSON_DECL
508  
    std::size_t
752  
    std::size_t
509  
    write(
753  
    write(
510  
        char const* data,
754  
        char const* data,
511  
        std::size_t size,
755  
        std::size_t size,
512  
        std::error_code& ec);
756  
        std::error_code& ec);
 
757 +
    /** @} */
513  

758  

514 -
    /** Overload
759 +
    /** Parse a buffer containing all or part of a complete JSON text.
515  

760  

516 -
        @param data
761 +
        This function parses a all or part of a JSON text
517 -
        @param size
762 +
        contained in the specified character buffer. The
 
763 +
        entire buffer must be consumed; if there are
 
764 +
        additional characters past the end of the complete
 
765 +
        JSON text, the parse fails and an error is returned.
518  

766  

519 -
        @throw boost::system::system_error Thrown on error.
767 +
        @par Example
 
768 +
        @code
 
769 +
        stream_parser p;                                // construct a parser
 
770 +
        std::size_t n;                                  // number of characters used
 
771 +
        n = p.write( "[1,2" );                          // parse some of the JSON text
 
772 +
        assert( n == 4 );                               // all characters consumed
 
773 +
        n = p.write( "3,4]" );                          // parse the rest of the JSON text
 
774 +
        assert( n == 4 );                               // all characters consumed
 
775 +
        value jv = p.release();                         // take ownership of the value
 
776 +
        @endcode
 
777 +

 
778 +
        @note
 
779 +

 
780 +
        To indicate there are no more character buffers,
 
781 +
        such as when @ref done returns `false` after
 
782 +
        writing, call @ref finish.
 
783 +

 
784 +
        @par Complexity
 
785 +
        Linear in `size`.
 
786 +

 
787 +
        @par Exception Safety
 
788 +
        Basic guarantee.
 
789 +
        Calls to `memory_resource::allocate` may throw.
 
790 +
        Upon error or exception, subsequent calls will
 
791 +
        fail until @ref reset is called to parse a new JSON text.
 
792 +

 
793 +
        @return The number of characters consumed from
 
794 +
        the buffer.
 
795 +

 
796 +
        @param data A pointer to a buffer of `size`
 
797 +
        characters to parse.
 
798 +

 
799 +
        @param size The number of characters pointed to
 
800 +
        by `data`.
 
801 +

 
802 +
        @throw `boost::system::system_error` Thrown on error.
520  
    */
803  
    */
521  
    BOOST_JSON_DECL
804  
    BOOST_JSON_DECL
522  
    std::size_t
805  
    std::size_t
523  
    write(
806  
    write(
524  
        char const* data,
807  
        char const* data,
525  
        std::size_t size);
808  
        std::size_t size);
526  

809  

527 -
    /** Overload
810 +
    /** Parse a buffer containing all or part of a complete JSON text.
 
811 +

 
812 +
        This function parses a all or part of a JSON text
 
813 +
        contained in the specified character buffer. The
 
814 +
        entire buffer must be consumed; if there are
 
815 +
        additional characters past the end of the complete
 
816 +
        JSON text, the parse fails and an error is returned.
 
817 +

 
818 +
        @par Example
 
819 +
        @code
 
820 +
        stream_parser p;                                // construct a parser
 
821 +
        std::size_t n;                                  // number of characters used
 
822 +
        n = p.write( "[1,2" );                          // parse some of the JSON text
 
823 +
        assert( n == 4 );                               // all characters consumed
 
824 +
        n = p.write( "3,4]" );                          // parse the rest of the JSON text
 
825 +
        assert( n == 4 );                               // all characters consumed
 
826 +
        value jv = p.release();                         // take ownership of the value
 
827 +
        @endcode
 
828 +

 
829 +
        @note
 
830 +

 
831 +
        To indicate there are no more character buffers,
 
832 +
        such as when @ref done returns `false` after
 
833 +
        writing, call @ref finish.
 
834 +

 
835 +
        @par Complexity
 
836 +
        Linear in `size`.
 
837 +

 
838 +
        @par Exception Safety
 
839 +
        Basic guarantee.
 
840 +
        Calls to `memory_resource::allocate` may throw.
 
841 +
        Upon error or exception, subsequent calls will
 
842 +
        fail until @ref reset is called to parse a new JSON text.
 
843 +

 
844 +
        @return The number of characters consumed from
 
845 +
        the buffer.
528  

846  

529  
        @param s The character string to parse.
847  
        @param s The character string to parse.
530 -
        @param ec
848 +

 
849 +
        @param ec Set to the error, if any occurred.
531  
    */
850  
    */
 
851 +
    /** @{ */
532  
    std::size_t
852  
    std::size_t
533  
    write(
853  
    write(
534  
        string_view s,
854  
        string_view s,
535  
        system::error_code& ec)
855  
        system::error_code& ec)
536  
    {
856  
    {
537  
        return write(
857  
        return write(
538  
            s.data(), s.size(), ec);
858  
            s.data(), s.size(), ec);
539  
    }
859  
    }
540 -
    /** Overload
 
541 -

 
542 -
        @param s
 
543 -
        @param ec
 
544 -
    */
 
545  

860  

546  
    std::size_t
861  
    std::size_t
547  
    write(
862  
    write(
548  
        string_view s,
863  
        string_view s,
549  
        std::error_code& ec)
864  
        std::error_code& ec)
550  
    {
865  
    {
551  
        return write(
866  
        return write(
552  
            s.data(), s.size(), ec);
867  
            s.data(), s.size(), ec);
553  
    }
868  
    }
 
869 +
    /** @} */
554  

870  

555 -
    /** Overload
871 +
    /** Parse a buffer containing all or part of a complete JSON text.
556 -
        @param s
872 +

 
873 +
        This function parses a all or part of a JSON text
 
874 +
        contained in the specified character buffer. The
 
875 +
        entire buffer must be consumed; if there are
 
876 +
        additional characters past the end of the complete
 
877 +
        JSON text, the parse fails and an error is returned.
 
878 +

 
879 +
        @par Example
 
880 +
        @code
 
881 +
        stream_parser p;                                // construct a parser
 
882 +
        std::size_t n;                                  // number of characters used
 
883 +
        n = p.write( "[1,2" );                          // parse some of the JSON text
 
884 +
        assert( n == 4 );                               // all characters consumed
 
885 +
        n = p.write( "3,4]" );                          // parse the rest of the JSON text
 
886 +
        assert( n == 4 );                               // all characters consumed
 
887 +
        value jv = p.release();                         // take ownership of the value
 
888 +
        @endcode
 
889 +

 
890 +
        @note
 
891 +

 
892 +
        To indicate there are no more character buffers,
 
893 +
        such as when @ref done returns `false` after
 
894 +
        writing, call @ref finish.
 
895 +

 
896 +
        @par Complexity
 
897 +
        Linear in `size`.
 
898 +

 
899 +
        @par Exception Safety
 
900 +
        Basic guarantee.
 
901 +
        Calls to `memory_resource::allocate` may throw.
 
902 +
        Upon error or exception, subsequent calls will
 
903 +
        fail until @ref reset is called to parse a new JSON text.
 
904 +

 
905 +
        @return The number of characters consumed from
 
906 +
        the buffer.
 
907 +

 
908 +
        @param s The character string to parse.
 
909 +

 
910 +
        @throw `boost::system::system_error` Thrown on error.
557  
    */
911  
    */
558  
    std::size_t
912  
    std::size_t
559  
    write(
913  
    write(
560  
        string_view s)
914  
        string_view s)
561  
    {
915  
    {
562  
        return write(
916  
        return write(
563  
            s.data(), s.size());
917  
            s.data(), s.size());
564 -
    /// @}
 
565  
    }
918  
    }
566  

919  

567  
    /** Indicate the end of JSON input.
920  
    /** Indicate the end of JSON input.
568  

921  

569 -
        This function is used to indicate that there are no more character
922 +
        This function is used to indicate that there
570 -
        buffers in the current JSON text being parsed. If the resulting JSON
923 +
        are no more character buffers in the current
571 -
        text is incomplete, **(1)** and **(2)** assign the relevant
924 +
        JSON text being parsed. If the resulting JSON text is
572 -
        `error_code` to `ec`, while **(3)** throws an exception.
925 +
        incomplete, the error is set to indicate a
573 -

926 +
        parsing failure.
574 -
        Upon error or exception, subsequent calls will fail until @ref reset is
 
575 -
        called to parse a new JSON text.
 
576  

927  

577  
        @par Example
928  
        @par Example
578  
        In the code below, @ref finish is called to
929  
        In the code below, @ref finish is called to
579  
        indicate there are no more digits in the
930  
        indicate there are no more digits in the
580  
        resulting number:
931  
        resulting number:
581  
        @code
932  
        @code
582  
        stream_parser p;                                // construct a parser
933  
        stream_parser p;                                // construct a parser
583  
        p.write( "3." );                                // write the first part of the number
934  
        p.write( "3." );                                // write the first part of the number
584  
        p.write( "14" );                                // write the second part of the number
935  
        p.write( "14" );                                // write the second part of the number
585  
        assert( ! p.done() );                           // there could be more digits
936  
        assert( ! p.done() );                           // there could be more digits
586  
        p.finish();                                     // indicate the end of the JSON input
937  
        p.finish();                                     // indicate the end of the JSON input
587  
        assert( p.done() );                             // now we are finished
938  
        assert( p.done() );                             // now we are finished
588  
        value jv = p.release();                         // take ownership of the value
939  
        value jv = p.release();                         // take ownership of the value
589  
        @endcode
940  
        @endcode
590  

941  

591  
        @par Complexity
942  
        @par Complexity
592  
        Constant.
943  
        Constant.
593  

944  

594  
        @par Exception Safety
945  
        @par Exception Safety
595 -
        Basic guarantee. Calls to `memory_resource::allocate` may throw.
946 +
        Basic guarantee.
 
947 +
        Calls to `memory_resource::allocate` may throw.
 
948 +
        Upon error or exception, subsequent calls will
 
949 +
        fail until @ref reset is called to parse a new JSON text.
596  

950  

597 -

 
598 -
        @{
 
599  
        @param ec Set to the error, if any occurred.
951  
        @param ec Set to the error, if any occurred.
600  
    */
952  
    */
 
953 +
    /** @{ */
601  
    BOOST_JSON_DECL
954  
    BOOST_JSON_DECL
602  
    void
955  
    void
603  
    finish(system::error_code& ec);
956  
    finish(system::error_code& ec);
604  

957  

605  
    BOOST_JSON_DECL
958  
    BOOST_JSON_DECL
606  
    void
959  
    void
607  
    finish(std::error_code& ec);
960  
    finish(std::error_code& ec);
 
961 +
    /** @} */
608  

962  

609 -
    /** Overload
963 +
    /** Indicate the end of JSON input.
610  

964  

611 -
        @throw boost::system::system_error Parsing error.
965 +
        This function is used to indicate that there
 
966 +
        are no more character buffers in the current
 
967 +
        JSON text being parsed. If the resulting JSON text is
 
968 +
        incomplete, the error is set to indicate a
 
969 +
        parsing failure.
 
970 +

 
971 +
        @par Example
 
972 +
        In the code below, @ref finish is called to
 
973 +
        indicate there are no more digits in the
 
974 +
        resulting number:
 
975 +
        @code
 
976 +
        stream_parser p;                                // construct a parser
 
977 +
        p.write( "3." );                                // write the first part of the number
 
978 +
        p.write( "14" );                                // write the second part of the number
 
979 +
        assert( ! p.done() );                           // there could be more digits
 
980 +
        p.finish();                                     // indicate the end of the JSON input
 
981 +
        assert( p.done() );                             // now we are finished
 
982 +
        value jv = p.release();                         // take ownership of the value
 
983 +
        @endcode
 
984 +

 
985 +
        @par Complexity
 
986 +
        Constant.
 
987 +

 
988 +
        @par Exception Safety
 
989 +
        Basic guarantee.
 
990 +
        Calls to `memory_resource::allocate` may throw.
 
991 +
        Upon error or exception, subsequent calls will
 
992 +
        fail until @ref reset is called to parse a new JSON text.
 
993 +

 
994 +
        @throw `boost::system::system_error` Thrown on error.
612  
    */
995  
    */
613  
    BOOST_JSON_DECL
996  
    BOOST_JSON_DECL
614  
    void
997  
    void
615 -
    /// @}
 
616  
    finish();
998  
    finish();
617  

999  

618  
    /** Return the parsed JSON as a @ref value.
1000  
    /** Return the parsed JSON as a @ref value.
619  

1001  

620 -
        This returns the parsed value, or throws an exception if the parsing is
1002 +
        This returns the parsed value, or throws
621 -
        incomplete or failed. If `! this->done()`, calls @ref finish() first.
1003 +
        an exception if the parsing is incomplete or
622 -
        It is necessary to call @ref reset after calling this function in order
1004 +
        failed. It is necessary to call @ref reset
623 -
        to parse another JSON text.
1005 +
        after calling this function in order to parse
 
1006 +
        another JSON text.
 
1007 +

 
1008 +
        @par Effects
 
1009 +
        @code
 
1010 +
        if( ! this->done() )
 
1011 +
            this->finish();
 
1012 +
        @endcode
 
1013 +
        @note
624  

1014  

625  
        @par Complexity
1015  
        @par Complexity
626  
        Constant.
1016  
        Constant.
627  

1017  

628 -
        @return The parsed value. Ownership of this value is transferred to the
1018 +
        @return The parsed value. Ownership of this
629 -
        caller.
1019 +
        value is transferred to the caller.
630  

1020  

631 -
        @throw boost::system::system_error A complete JSON text hasn't been
1021 +
        @throw `boost::system::system_error` Thrown on failure.
632 -
               parsed, or parsing failed.
 
633  
    */
1022  
    */
634  
    BOOST_JSON_DECL
1023  
    BOOST_JSON_DECL
635  
    value
1024  
    value
636  
    release();
1025  
    release();
637  
};
1026  
};
638  

1027  

639  
} // namespace json
1028  
} // namespace json
640  
} // namespace boost
1029  
} // namespace boost
641  

1030  

642  
#endif
1031  
#endif