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
29 -
    buffer, into a @ref value container.
29 +
    single character 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 +

33 -
    specify a @ref storage_ptr to use for the resulting @ref value. Then call
33 +
    To use the parser first construct it, then optionally
34 -
    @ref write to parse a character buffer containing a complete JSON text. If
34 +
    call @ref reset to specify a @ref storage_ptr to use
35 -
    the parse is successful, call @ref release to take ownership of the value:
35 +
    for the resulting @ref value. Then call @ref write
 
36 +
    to parse a character buffer containing a complete
 
37 +
    JSON text. If the parse is successful, call @ref release
 
38 +
    to take ownership of the value:
36  
    @code
39  
    @code
37  
    parser p;                                       // construct a parser
40  
    parser p;                                       // construct a parser
38  
    size_t n = p.write( "[1,2,3]" );                // parse a complete JSON text
41  
    size_t n = p.write( "[1,2,3]" );                // parse a complete JSON text
39  
    assert( n == 7 );                               // all characters consumed
42  
    assert( n == 7 );                               // all characters consumed
40  
    value jv = p.release();                         // take ownership of the value
43  
    value jv = p.release();                         // take ownership of the value
41  
    @endcode
44  
    @endcode
42  

45  

43  
    @par Extra Data
46  
    @par Extra Data
44 -
    When the character buffer provided as input contains additional data that
47 +

45 -
    is not part of the complete JSON text, an error is returned. The @ref
48 +
    When the character buffer provided as input contains
46 -
    write_some function is an alternative which allows the parse to finish
49 +
    additional data that is not part of the complete
47 -
    early, without consuming all the characters in the buffer. This allows
50 +
    JSON text, an error is returned. The @ref write_some
48 -
    parsing of a buffer containing multiple individual JSON texts or containing
51 +
    function is an alternative which allows the parse
 
52 +
    to finish early, without consuming all the characters
 
53 +
    in the buffer. This allows parsing of a buffer
 
54 +
    containing multiple individual JSON texts or containing
49  
    different protocol data:
55  
    different protocol data:
50  
    @code
56  
    @code
51  
    parser p;                                       // construct a parser
57  
    parser p;                                       // construct a parser
52  
    size_t n = p.write_some( "[1,2,3] null" );      // parse a complete JSON text
58  
    size_t n = p.write_some( "[1,2,3] null" );      // parse a complete JSON text
53  
    assert( n == 8 );                               // only some characters consumed
59  
    assert( n == 8 );                               // only some characters consumed
54  
    value jv = p.release();                         // take ownership of the value
60  
    value jv = p.release();                         // take ownership of the value
55  
    @endcode
61  
    @endcode
56  

62  

57 -
    The parser may dynamically allocate temporary storage as needed to
 
58 -
    accommodate the nesting level of the JSON text being parsed. Temporary
 
59 -
    storage is first obtained from an optional, caller-owned buffer specified
 
60 -
    upon construction. When that is exhausted, the next allocation uses the
 
61 -
    @ref boost::container::pmr::memory_resource passed to the constructor; if
 
62 -
    no such argument is specified, the default memory resource is used.
 
63 -
    Temporary storage is freed only when the parser is destroyed; The
 
64 -
    performance of parsing multiple JSON texts may be improved by reusing the
 
65 -
    same parser instance.
 
66  
    @par Temporary Storage
63  
    @par Temporary Storage
67  

64  

 
65 +
    The parser may dynamically allocate temporary
 
66 +
    storage as needed to accommodate the nesting level
 
67 +
    of the JSON text being parsed. Temporary storage is
 
68 +
    first obtained from an optional, caller-owned
 
69 +
    buffer specified upon construction. When that
 
70 +
    is exhausted, the next allocation uses the
 
71 +
    `boost::container::pmr::memory_resource` passed to the constructor; if
 
72 +
    no such argument is specified, the default memory
 
73 +
    resource is used. Temporary storage is freed only
 
74 +
    when the parser is destroyed; The performance of
 
75 +
    parsing multiple JSON texts may be improved by reusing
 
76 +
    the same parser instance.
 
77 +
\n
68  
    It is important to note that the `boost::container::pmr::memory_resource`
78  
    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
79 +
    supplied upon construction is used for temporary
70 -
    allocating the elements which make up the parsed value. That other memory
80 +
    storage only, and not for allocating the elements
71 -
    resource is optionally supplied in each call to @ref reset.
81 +
    which make up the parsed value. That other memory
 
82 +
    resource is optionally supplied in each call
 
83 +
    to @ref reset.
72  

84  

73  
    @par Duplicate Keys
85  
    @par Duplicate Keys
74 -
    If there are object elements with duplicate keys; that is, if multiple
86 +

75 -
    elements in an object have keys that compare equal, only the last
87 +
    If there are object elements with duplicate keys;
76 -
    equivalent element will be inserted.
88 +
    that is, if multiple elements in an object have
 
89 +
    keys that compare equal, only the last equivalent
 
90 +
    element will be inserted.
77  

91  

78  
    @par Non-Standard JSON
92  
    @par Non-Standard JSON
79 -
    The @ref parse_options structure optionally provided upon construction is
93 +

80 -
    used to customize some parameters of the parser, including which
94 +
    The @ref parse_options structure optionally
81 -
    non-standard JSON extensions should be allowed. A default-constructed parse
95 +
    provided upon construction is used to customize
82 -
    options allows only standard JSON.
96 +
    some parameters of the parser, including which
 
97 +
    non-standard JSON extensions should be allowed.
 
98 +
    A default-constructed parse options allows only
 
99 +
    standard JSON.
83  

100  

84 -
    Distinct instances may be accessed concurrently. Non-const member functions
 
85 -
    of a shared instance may not be called concurrently with any other member
 
86 -
    functions of that instance.
 
87  
    @par Thread Safety
101  
    @par Thread Safety
88  

102  

89 -
    @see @ref parse, @ref stream_parser.
103 +
    Distinct instances may be accessed concurrently.
 
104 +
    Non-const member functions of a shared instance
 
105 +
    may not be called concurrently with any other
 
106 +
    member functions of that instance.
 
107 +

 
108 +
    @see
 
109 +
        @ref parse,
 
110 +
        @ref parse_options,
 
111 +
        @ref stream_parser.
90  
*/
112  
*/
91  
class parser
113  
class parser
92  
{
114  
{
93  
    basic_parser<detail::handler> p_;
115  
    basic_parser<detail::handler> p_;
94  

116  

95  
public:
117  
public:
96 -
    /** Assignment operator.
118 +
    /// Copy constructor (deleted)
 
119 +
    parser(
 
120 +
        parser const&) = delete;
97  

121  

98 -
        This type is neither copyable nor movable. The operator is deleted.
122 +
    /// Copy assignment (deleted)
99 -
    */
 
100  
    parser& operator=(
123  
    parser& operator=(
101  
        parser const&) = delete;
124  
        parser const&) = delete;
102  

125  

103  
    /** Destructor.
126  
    /** Destructor.
104  

127  

105  
        All dynamically allocated memory, including
128  
        All dynamically allocated memory, including
106  
        any incomplete parsing results, is freed.
129  
        any incomplete parsing results, is freed.
107  

130  

108  
        @par Complexity
131  
        @par Complexity
109 -
        Linear in the size of partial results.
132 +
        Linear in the size of partial results
110  

133  

111  
        @par Exception Safety
134  
        @par Exception Safety
112  
        No-throw guarantee.
135  
        No-throw guarantee.
113  
    */
136  
    */
114  
    ~parser() = default;
137  
    ~parser() = default;
115  

138  

116 -
    /** Constructors.
139 +
    /** Constructor.
117 -

 
118 -
        Construct a new parser.
 
119  

140  

120 -
        The parser will only support standard JSON if overloads **(1)**
141 +
        This constructs a new parser which first uses
121 -
        or **(2)** are used. Otherwise the parser will support extensions
142 +
        the caller-owned storage pointed to by `buffer`
122 -
        specified by the parameter `opt`.
143 +
        for temporary storage, falling back to the memory
 
144 +
        resource `sp` if needed. The parser will use the
 
145 +
        specified parsing options.
 
146 +
    \n
 
147 +
        The parsed value will use the default memory
 
148 +
        resource for storage. To use a different resource,
 
149 +
        call @ref reset after construction.
123  

150  

124 -
        The parsed value will use the \<\<default_memory_resource,default
151 +
        @par Complexity
125 -
        memory resource\>\> for storage. To use a different resource, call @ref
152 +
        Constant.
126 -
        reset after construction.
 
127  

153  

128 -
        The main difference between the overloads is in what the constructed
154 +
        @par Exception Safety
129 -
        parser will use for temporary storage:
155 +
        No-throw guarantee.
130  

156  

131 -
        @li **(1)** the constructed parser uses the default memory resource for
157 +
        @param sp The memory resource to use for
132 -
        temporary storage.
158 +
        temporary storage after `buffer` is exhausted.
133  

159  

134 -
        @li **(2)**, **(3)** the constructed parser uses the memory resource of
160 +
        @param opt The parsing options to use.
135 -
        `sp` for temporary storage.
 
136  

161  

137 -
        @li **(4)**, **(6)** the constructed parser first uses the caller-owned
162 +
        @param buffer A pointer to valid memory of at least
138 -
        storage `[buffer, buffer + size)` for temporary storage, falling back
163 +
        `size` bytes for the parser to use for temporary storage.
139 -
        to the memory resource of `sp` if needed.
164 +
        Ownership is not transferred, the caller is responsible
 
165 +
        for ensuring the lifetime of the memory pointed to by
 
166 +
        `buffer` extends until the parser is destroyed.
140  

167  

141 -
        @li **(5)**, **(7)** the constructed parser first uses the caller-owned
168 +
        @param size The number of valid bytes in `buffer`.
142 -
        storage `[buffer, buffer + N)` for temporary storage, falling back to
169 +
    */
143 -
        the memory resource of `sp` if needed.
170 +
    BOOST_JSON_DECL
 
171 +
    parser(
 
172 +
        storage_ptr sp,
 
173 +
        parse_options const& opt,
 
174 +
        unsigned char* buffer,
 
175 +
        std::size_t size) noexcept;
144  

176  

145 -
        @note Ownership of `buffer` is not transferred. The caller is
177 +
    /** Constructor.
146 -
        responsible for ensuring the lifetime of the storage pointed to by
 
147 -
        `buffer` extends until the parser is destroyed.
 
148  

178  

149 -
        Overload **(8)** is the copy constructor. The type is neither copyable
179 +
        This constructs a new parser which uses the default
150 -
        nor movable, so the overload is deleted.
180 +
        memory resource for temporary storage, and accepts
 
181 +
        only strict JSON.
 
182 +
    \n
 
183 +
        The parsed value will use the default memory
 
184 +
        resource for storage. To use a different resource,
 
185 +
        call @ref reset after construction.
151  

186  

152  
        @par Complexity
187  
        @par Complexity
153  
        Constant.
188  
        Constant.
154  

189  

155  
        @par Exception Safety
190  
        @par Exception Safety
156 -

 
157 -
        @{
 
158  
        No-throw guarantee.
191  
        No-throw guarantee.
159  
    */
192  
    */
160  
    parser() noexcept
193  
    parser() noexcept
161  
        : parser({}, {})
194  
        : parser({}, {})
162  
    {
195  
    {
163  
    }
196  
    }
164  

197  

165 -
    /** Overload
198 +
    /** Constructor.
166  

199  

167 -
        @param sp The memory resource to use for temporary storage.
200 +
        This constructs a new parser which uses the
168 -
    */
201 +
        specified memory resource for temporary storage,
169 -
    explicit
202 +
        and is configured to use the specified parsing
170 -
    parser(storage_ptr sp) noexcept
203 +
        options.
171 -
        : parser(std::move(sp), {})
204 +
    \n
172 -
    {
205 +
        The parsed value will use the default memory
173 -
    }
206 +
        resource for storage. To use a different resource,
 
207 +
        call @ref reset after construction.
174  

208  

175 -
    /** Overload
209 +
        @par Complexity
 
210 +
        Constant.
 
211 +

 
212 +
        @par Exception Safety
 
213 +
        No-throw guarantee.
 
214 +

 
215 +
        @param sp The memory resource to use for temporary storage.
176  

216  

177 -
        @param sp
 
178  
        @param opt The parsing options to use.
217  
        @param opt The parsing options to use.
179  
    */
218  
    */
180  
    BOOST_JSON_DECL
219  
    BOOST_JSON_DECL
181  
    parser(
220  
    parser(
182  
        storage_ptr sp,
221  
        storage_ptr sp,
183  
        parse_options const& opt) noexcept;
222  
        parse_options const& opt) noexcept;
184  

223  

185 -
    /** Overload
224 +
    /** Constructor.
186  

225  

187 -
        @param buffer A pointer to valid storage.
226 +
        This constructs a new parser which uses the
188 -
        @param size The number of valid bytes in `buffer`.
227 +
        specified memory resource for temporary storage,
189 -
        @param sp
228 +
        and accepts only strict JSON.
190 -
        @param opt
229 +
    \n
 
230 +
        The parsed value will use the default memory
 
231 +
        resource for storage. To use a different resource,
 
232 +
        call @ref reset after construction.
 
233 +

 
234 +
        @par Complexity
 
235 +
        Constant.
 
236 +

 
237 +
        @par Exception Safety
 
238 +
        No-throw guarantee.
 
239 +

 
240 +
        @param sp The memory resource to use for temporary storage.
191  
    */
241  
    */
192 -
    BOOST_JSON_DECL
242 +
    explicit
193 -
    parser(
243 +
    parser(storage_ptr sp) noexcept
194 -
        storage_ptr sp,
244 +
        : parser(std::move(sp), {})
195 -
        parse_options const& opt,
245 +
    {
196 -
        unsigned char* buffer,
246 +
    }
197 -
        std::size_t size) noexcept;
 
198  

247  

199 -
    /** Overload
248 +
    /** Constructor.
200  

249  

201 -
        @tparam N The number of valid bytes in `buffer`.
250 +
        This constructs a new parser which first uses the
202 -
        @param sp
251 +
        caller-owned storage `buffer` for temporary storage,
203 -
        @param opt
252 +
        falling back to the memory resource `sp` if needed.
204 -
        @param buffer
253 +
        The parser will use the specified parsing options.
 
254 +
    \n
 
255 +
        The parsed value will use the default memory
 
256 +
        resource for storage. To use a different resource,
 
257 +
        call @ref reset after construction.
 
258 +

 
259 +
        @par Complexity
 
260 +
        Constant.
 
261 +

 
262 +
        @par Exception Safety
 
263 +
        No-throw guarantee.
 
264 +

 
265 +
        @param sp The memory resource to use for
 
266 +
        temporary storage after `buffer` is exhausted.
 
267 +

 
268 +
        @param opt The parsing options to use.
 
269 +

 
270 +
        @param buffer A buffer for the parser to use for
 
271 +
        temporary storage. Ownership is not transferred,
 
272 +
        the caller is responsible for ensuring the lifetime
 
273 +
        of `buffer` extends until the parser is destroyed.
205  
    */
274  
    */
206  
    template<std::size_t N>
275  
    template<std::size_t N>
207  
    parser(
276  
    parser(
208  
        storage_ptr sp,
277  
        storage_ptr sp,
209  
        parse_options const& opt,
278  
        parse_options const& opt,
210  
        unsigned char(&buffer)[N]) noexcept
279  
        unsigned char(&buffer)[N]) noexcept
211  
        : parser(std::move(sp),
280  
        : parser(std::move(sp),
212  
            opt, &buffer[0], N)
281  
            opt, &buffer[0], N)
213  
    {
282  
    {
214  
    }
283  
    }
215  

284  

216  
#if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
285  
#if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
217 -
    /** Overload
286 +
    /** Constructor.
218  

287  

219 -
        @param buffer
288 +
        This constructs a new parser which first uses
220 -
        @param size
289 +
        the caller-owned storage pointed to by `buffer`
221 -
        @param sp
290 +
        for temporary storage, falling back to the memory
222 -
        @param opt
291 +
        resource `sp` if needed. The parser will use the
 
292 +
        specified parsing options.
 
293 +
    \n
 
294 +
        The parsed value will use the default memory
 
295 +
        resource for storage. To use a different resource,
 
296 +
        call @ref reset after construction.
 
297 +

 
298 +
        @par Complexity
 
299 +
        Constant.
 
300 +

 
301 +
        @par Exception Safety
 
302 +
        No-throw guarantee.
 
303 +

 
304 +
        @param sp The memory resource to use for
 
305 +
        temporary storage after `buffer` is exhausted.
 
306 +

 
307 +
        @param opt The parsing options to use.
 
308 +

 
309 +
        @param buffer A pointer to valid memory of at least
 
310 +
        `size` bytes for the parser to use for temporary storage.
 
311 +
        Ownership is not transferred, the caller is responsible
 
312 +
        for ensuring the lifetime of the memory pointed to by
 
313 +
        `buffer` extends until the parser is destroyed.
 
314 +

 
315 +
        @param size The number of valid bytes in `buffer`.
223  
    */
316  
    */
224  
    parser(
317  
    parser(
225  
        storage_ptr sp,
318  
        storage_ptr sp,
226  
        parse_options const& opt,
319  
        parse_options const& opt,
227  
        std::byte* buffer,
320  
        std::byte* buffer,
228  
        std::size_t size) noexcept
321  
        std::size_t size) noexcept
229  
        : parser(sp, opt, reinterpret_cast<
322  
        : parser(sp, opt, reinterpret_cast<
230  
            unsigned char*>(buffer), size)
323  
            unsigned char*>(buffer), size)
231  
    {
324  
    {
232  
    }
325  
    }
233  

326  

234 -
    /** Overload
327 +
    /** Constructor.
235  

328  

236 -
        @tparam N
329 +
        This constructs a new parser which first uses the
237 -
        @param sp
330 +
        caller-owned storage `buffer` for temporary storage,
238 -
        @param opt
331 +
        falling back to the memory resource `sp` if needed.
239 -
        @param buffer
332 +
        The parser will use the specified parsing options.
 
333 +
    \n
 
334 +
        The parsed value will use the default memory
 
335 +
        resource for storage. To use a different resource,
 
336 +
        call @ref reset after construction.
 
337 +

 
338 +
        @par Complexity
 
339 +
        Constant.
 
340 +

 
341 +
        @par Exception Safety
 
342 +
        No-throw guarantee.
 
343 +

 
344 +
        @param sp The memory resource to use for
 
345 +
        temporary storage after `buffer` is exhausted.
 
346 +

 
347 +
        @param opt The parsing options to use.
 
348 +

 
349 +
        @param buffer A buffer for the parser to use for
 
350 +
        temporary storage. Ownership is not transferred,
 
351 +
        the caller is responsible for ensuring the lifetime
 
352 +
        of `buffer` extends until the parser is destroyed.
240  
    */
353  
    */
241  
    template<std::size_t N>
354  
    template<std::size_t N>
242  
    parser(
355  
    parser(
243  
        storage_ptr sp,
356  
        storage_ptr sp,
244  
        parse_options const& opt,
357  
        parse_options const& opt,
245  
        std::byte(&buffer)[N]) noexcept
358  
        std::byte(&buffer)[N]) noexcept
246  
        : parser(std::move(sp),
359  
        : parser(std::move(sp),
247  
            opt, &buffer[0], N)
360  
            opt, &buffer[0], N)
248  
    {
361  
    {
249  
    }
362  
    }
250  
#endif
363  
#endif
251  

364  

252  
#ifndef BOOST_JSON_DOCS
365  
#ifndef BOOST_JSON_DOCS
253  
    // Safety net for accidental buffer overflows
366  
    // Safety net for accidental buffer overflows
254  
    template<std::size_t N>
367  
    template<std::size_t N>
255  
    parser(
368  
    parser(
256  
        storage_ptr sp,
369  
        storage_ptr sp,
257  
        parse_options const& opt,
370  
        parse_options const& opt,
258  
        unsigned char(&buffer)[N],
371  
        unsigned char(&buffer)[N],
259  
        std::size_t n) noexcept
372  
        std::size_t n) noexcept
260  
        : parser(std::move(sp),
373  
        : parser(std::move(sp),
261  
            opt, &buffer[0], n)
374  
            opt, &buffer[0], n)
262  
    {
375  
    {
263  
        // If this goes off, check your parameters
376  
        // If this goes off, check your parameters
264  
        // closely, chances are you passed an array
377  
        // closely, chances are you passed an array
265  
        // thinking it was a pointer.
378  
        // thinking it was a pointer.
266  
        BOOST_ASSERT(n <= N);
379  
        BOOST_ASSERT(n <= N);
267  
    }
380  
    }
268  

381  

269  
#ifdef __cpp_lib_byte
382  
#ifdef __cpp_lib_byte
270  
    // Safety net for accidental buffer overflows
383  
    // Safety net for accidental buffer overflows
271  
    template<std::size_t N>
384  
    template<std::size_t N>
272  
    parser(
385  
    parser(
273  
        storage_ptr sp,
386  
        storage_ptr sp,
274  
        parse_options const& opt,
387  
        parse_options const& opt,
275  
        std::byte(&buffer)[N], std::size_t n) noexcept
388  
        std::byte(&buffer)[N], std::size_t n) noexcept
276  
        : parser(std::move(sp),
389  
        : parser(std::move(sp),
277  
            opt, &buffer[0], n)
390  
            opt, &buffer[0], n)
278  
    {
391  
    {
279  
        // If this goes off, check your parameters
392  
        // If this goes off, check your parameters
280  
        // closely, chances are you passed an array
393  
        // closely, chances are you passed an array
281  
        // thinking it was a pointer.
394  
        // thinking it was a pointer.
282  
        BOOST_ASSERT(n <= N);
395  
        BOOST_ASSERT(n <= N);
283  
    }
396  
    }
284  
#endif
397  
#endif
285  
#endif
398  
#endif
286 -
    /// Overload
 
287 -
    parser(
 
288 -
        parser const&) = delete;
 
289 -
    /// @}
 
290 -

 
291 -

 
292  

399  

293  
    /** Reset the parser for a new JSON text.
400  
    /** Reset the parser for a new JSON text.
294  

401  

295  
        This function is used to reset the parser to
402  
        This function is used to reset the parser to
296  
        prepare it for parsing a new complete JSON text.
403  
        prepare it for parsing a new complete JSON text.
297  
        Any previous partial results are destroyed.
404  
        Any previous partial results are destroyed.
298  

405  

299  
        @par Complexity
406  
        @par Complexity
300  
        Constant or linear in the size of any previous
407  
        Constant or linear in the size of any previous
301  
        partial parsing results.
408  
        partial parsing results.
302  

409  

303  
        @par Exception Safety
410  
        @par Exception Safety
304  
        No-throw guarantee.
411  
        No-throw guarantee.
305  

412  

306 -
        @param sp A pointer to the @ref boost::container::pmr::memory_resource
413 +
        @param sp A pointer to the `boost::container::pmr::memory_resource` to
307 -
        to use for the resulting @ref value. The parser will acquire shared
414 +
        use for the resulting @ref value. The parser will acquire shared
308  
        ownership.
415  
        ownership.
309  
    */
416  
    */
310  
    BOOST_JSON_DECL
417  
    BOOST_JSON_DECL
311  
    void
418  
    void
312  
    reset(storage_ptr sp = {}) noexcept;
419  
    reset(storage_ptr sp = {}) noexcept;
313  

420  

314  
    /** Parse a buffer containing a complete JSON text.
421  
    /** Parse a buffer containing a complete JSON text.
315  

422  

316 -
        This function parses a complete JSON text contained in the specified
423 +
        This function parses a complete JSON text contained
317 -
        character buffer. Additional characters past the end of the complete
424 +
        in the specified character buffer. Additional
318 -
        JSON text are ignored. The function returns the actual number of
425 +
        characters past the end of the complete JSON text
319 -
        characters parsed, which may be less than the size of the input. This
426 +
        are ignored. The function returns the actual
320 -
        allows parsing of a buffer containing multiple individual JSON texts or
427 +
        number of characters parsed, which may be less
321 -
        containing different protocol data:
428 +
        than the size of the input. This allows parsing
 
429 +
        of a buffer containing multiple individual JSON texts
 
430 +
        or containing different protocol data:
322  

431  

323  
        @par Example
432  
        @par Example
324  
        @code
433  
        @code
325  
        parser p;                                       // construct a parser
434  
        parser p;                                       // construct a parser
326  
        size_t n = p.write_some( "[1,2,3] null" );      // parse a complete JSON text
435  
        size_t n = p.write_some( "[1,2,3] null" );      // parse a complete JSON text
327  
        assert( n == 8 );                               // only some characters consumed
436  
        assert( n == 8 );                               // only some characters consumed
328  
        value jv = p.release();                         // take ownership of the value
437  
        value jv = p.release();                         // take ownership of the value
329  
        @endcode
438  
        @endcode
330 -
        Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
 
331 -
        setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
 
332 -
        exceptions.
 
333 -

 
334  

439  

335  
        @par Complexity
440  
        @par Complexity
336 -
        @li **(1)**--**(3)** linear in `size`.
441 +
        Linear in `size`.
337 -
        @li **(4)**--**(6)** linear in `s.size()`.
 
338  

442  

339  
        @par Exception Safety
443  
        @par Exception Safety
340 -
        Basic guarantee. Calls to `memory_resource::allocate` may throw. Upon
444 +
        Basic guarantee.
341 -
        error or exception, subsequent calls will fail until @ref reset is
445 +
        Calls to `memory_resource::allocate` may throw.
342 -
        called to parse a new JSON text.
446 +
        Upon error or exception, subsequent calls will
 
447 +
        fail until @ref reset is called to parse a new JSON text.
343  

448  

344 -
        @return The number of characters consumed from the buffer.
449 +
        @return The number of characters consumed from
 
450 +
        the buffer.
345  

451  

346 -
        @param data A pointer to a buffer of `size` characters to parse.
452 +
        @param data A pointer to a buffer of `size`
347 -
        @param size The number of characters pointed to by `data`.
453 +
        characters to parse.
348 -
        @param ec Set to the error, if any occurred.
 
349  

454  

350 -
        @{
455 +
        @param size The number of characters pointed to
 
456 +
        by `data`.
 
457 +

 
458 +
        @param ec Set to the error, if any occurred.
351  
    */
459  
    */
 
460 +
/** @{ */
352  
    BOOST_JSON_DECL
461  
    BOOST_JSON_DECL
353  
    std::size_t
462  
    std::size_t
354  
    write_some(
463  
    write_some(
355  
        char const* data,
464  
        char const* data,
356  
        std::size_t size,
465  
        std::size_t size,
357  
        system::error_code& ec);
466  
        system::error_code& ec);
358  

467  

359  
    BOOST_JSON_DECL
468  
    BOOST_JSON_DECL
360  
    std::size_t
469  
    std::size_t
361  
    write_some(
470  
    write_some(
362  
        char const* data,
471  
        char const* data,
363  
        std::size_t size,
472  
        std::size_t size,
364  
        std::error_code& ec);
473  
        std::error_code& ec);
 
474 +
/** @} */
365  

475  

366 -
    /** Overload
476 +
    /** Parse a buffer containing a complete JSON text.
367  

477  

368 -
        @param data
478 +
        This function parses a complete JSON text contained
369 -
        @param size
479 +
        in the specified character buffer. Additional
 
480 +
        characters past the end of the complete JSON text
 
481 +
        are ignored. The function returns the actual
 
482 +
        number of characters parsed, which may be less
 
483 +
        than the size of the input. This allows parsing
 
484 +
        of a buffer containing multiple individual JSON texts
 
485 +
        or containing different protocol data:
 
486 +

 
487 +
        @par Example
 
488 +
        @code
 
489 +
        parser p;                                       // construct a parser
 
490 +
        size_t n = p.write_some( "[1,2,3] null" );      // parse a complete JSON text
 
491 +
        assert( n == 8 );                               // only some characters consumed
 
492 +
        value jv = p.release();                         // take ownership of the value
 
493 +
        @endcode
 
494 +

 
495 +
        @par Complexity
 
496 +
        Linear in `size`.
 
497 +

 
498 +
        @par Exception Safety
 
499 +
        Basic guarantee.
 
500 +
        Calls to `memory_resource::allocate` may throw.
 
501 +
        Upon error or exception, subsequent calls will
 
502 +
        fail until @ref reset is called to parse a new JSON text.
 
503 +

 
504 +
        @return The number of characters consumed from
 
505 +
        the buffer.
 
506 +

 
507 +
        @param data A pointer to a buffer of `size`
 
508 +
        characters to parse.
 
509 +

 
510 +
        @param size The number of characters pointed to
 
511 +
        by `data`.
 
512 +

 
513 +
        @throw `boost::system::system_error` Thrown on error.
370  
    */
514  
    */
371  
    BOOST_JSON_DECL
515  
    BOOST_JSON_DECL
372  
    std::size_t
516  
    std::size_t
373  
    write_some(
517  
    write_some(
374  
        char const* data,
518  
        char const* data,
375  
        std::size_t size);
519  
        std::size_t size);
376  

520  

377 -
    /** Overload
521 +
    /** Parse a buffer containing a complete JSON text.
 
522 +

 
523 +
        This function parses a complete JSON text contained
 
524 +
        in the specified character buffer. Additional
 
525 +
        characters past the end of the complete JSON text
 
526 +
        are ignored. The function returns the actual
 
527 +
        number of characters parsed, which may be less
 
528 +
        than the size of the input. This allows parsing
 
529 +
        of a buffer containing multiple individual JSON texts
 
530 +
        or containing different protocol data:
 
531 +

 
532 +
        @par Example
 
533 +
        @code
 
534 +
        parser p;                                       // construct a parser
 
535 +
        size_t n = p.write_some( "[1,2,3] null" );      // parse a complete JSON text
 
536 +
        assert( n == 8 );                               // only some characters consumed
 
537 +
        value jv = p.release();                         // take ownership of the value
 
538 +
        @endcode
 
539 +

 
540 +
        @par Complexity
 
541 +
        Linear in `size`.
 
542 +

 
543 +
        @par Exception Safety
 
544 +
        Basic guarantee.
 
545 +
        Calls to `memory_resource::allocate` may throw.
 
546 +
        Upon error or exception, subsequent calls will
 
547 +
        fail until @ref reset is called to parse a new JSON text.
 
548 +

 
549 +
        @return The number of characters consumed from
 
550 +
        the buffer.
378  

551  

379  
        @param s The character string to parse.
552  
        @param s The character string to parse.
380 -
        @param ec
553 +

 
554 +
        @param ec Set to the error, if any occurred.
381  
    */
555  
    */
 
556 +
/** @{ */
382  
    std::size_t
557  
    std::size_t
383  
    write_some(
558  
    write_some(
384  
        string_view s,
559  
        string_view s,
385  
        system::error_code& ec)
560  
        system::error_code& ec)
386  
    {
561  
    {
387  
        return write_some(
562  
        return write_some(
388  
            s.data(), s.size(), ec);
563  
            s.data(), s.size(), ec);
389  
    }
564  
    }
390 -
    /** Overload
 
391 -

 
392 -
        @param s
 
393 -
        @param ec
 
394 -
    */
 
395  

565  

396  
    std::size_t
566  
    std::size_t
397  
    write_some(
567  
    write_some(
398  
        string_view s,
568  
        string_view s,
399  
        std::error_code& ec)
569  
        std::error_code& ec)
400  
    {
570  
    {
401  
        return write_some(
571  
        return write_some(
402  
            s.data(), s.size(), ec);
572  
            s.data(), s.size(), ec);
403  
    }
573  
    }
 
574 +
/** @} */
404  

575  

405 -
    /** Overload
576 +
    /** Parse a buffer containing a complete JSON text.
406  

577  

407 -
        @param s
578 +
        This function parses a complete JSON text contained
 
579 +
        in the specified character buffer. Additional
 
580 +
        characters past the end of the complete JSON text
 
581 +
        are ignored. The function returns the actual
 
582 +
        number of characters parsed, which may be less
 
583 +
        than the size of the input. This allows parsing
 
584 +
        of a buffer containing multiple individual JSON texts
 
585 +
        or containing different protocol data:
 
586 +

 
587 +
        @par Example
 
588 +
        @code
 
589 +
        parser p;                                       // construct a parser
 
590 +
        size_t n = p.write_some( "[1,2,3] null" );      // parse a complete JSON text
 
591 +
        assert( n == 8 );                               // only some characters consumed
 
592 +
        value jv = p.release();                         // take ownership of the value
 
593 +
        @endcode
 
594 +

 
595 +
        @par Complexity
 
596 +
        Linear in `size`.
 
597 +

 
598 +
        @par Exception Safety
 
599 +
        Basic guarantee.
 
600 +
        Calls to `memory_resource::allocate` may throw.
 
601 +
        Upon error or exception, subsequent calls will
 
602 +
        fail until @ref reset is called to parse a new JSON text.
 
603 +

 
604 +
        @return The number of characters consumed from
 
605 +
        the buffer.
 
606 +

 
607 +
        @param s The character string to parse.
 
608 +

 
609 +
        @throw `boost::system::system_error` Thrown on error.
408  
    */
610  
    */
409  
    std::size_t
611  
    std::size_t
410  
    write_some(
612  
    write_some(
411  
        string_view s)
613  
        string_view s)
412  
    {
614  
    {
413  
        return write_some(
615  
        return write_some(
414  
            s.data(), s.size());
616  
            s.data(), s.size());
415 -
    /// @}
 
416  
    }
617  
    }
417  

618  

418  
    /** Parse a buffer containing a complete JSON text.
619  
    /** Parse a buffer containing a complete JSON text.
419  

620  

420 -
        This function parses a complete JSON text contained in the specified
621 +
        This function parses a complete JSON text contained
421 -
        character buffer. The entire buffer must be consumed; if there are
622 +
        in the specified character buffer. The entire
422 -
        additional characters past the end of the complete JSON text, the parse
623 +
        buffer must be consumed; if there are additional
423 -
        fails and an error is returned.
624 +
        characters past the end of the complete JSON text,
 
625 +
        the parse fails and an error is returned.
424  

626  

425  
        @par Example
627  
        @par Example
426  
        @code
628  
        @code
427  
        parser p;                                       // construct a parser
629  
        parser p;                                       // construct a parser
428  
        size_t n = p.write( "[1,2,3]" );                // parse a complete JSON text
630  
        size_t n = p.write( "[1,2,3]" );                // parse a complete JSON text
429  
        assert( n == 7 );                               // all characters consumed
631  
        assert( n == 7 );                               // all characters consumed
430  
        value jv = p.release();                         // take ownership of the value
632  
        value jv = p.release();                         // take ownership of the value
431  
        @endcode
633  
        @endcode
432 -
        Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
 
433 -
        setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
 
434 -
        exceptions.
 
435 -

 
436  

634  

437  
        @par Complexity
635  
        @par Complexity
438 -
        @li **(1)**--**(3)** linear in `size`.
636 +
        Linear in `size`.
439 -
        @li **(4)**--**(6)** linear in `s.size()`.
 
440  

637  

441  
        @par Exception Safety
638  
        @par Exception Safety
442 -
        Basic guarantee. Calls to `memory_resource::allocate` may throw. Upon
639 +
        Basic guarantee.
443 -
        error or exception, subsequent calls will fail until @ref reset is
640 +
        Calls to `memory_resource::allocate` may throw.
444 -
        called to parse a new JSON text.
641 +
        Upon error or exception, subsequent calls will
 
642 +
        fail until @ref reset is called to parse a new JSON text.
445  

643  

446 -
        @return The number of characters consumed from the buffer.
644 +
        @return The number of characters consumed from
 
645 +
        the buffer.
447  

646  

448 -
        @param data A pointer to a buffer of `size` characters to parse.
647 +
        @param data A pointer to a buffer of `size`
449 -
        @param size The number of characters pointed to by `data`.
648 +
        characters to parse.
450 -
        @param ec Set to the error, if any occurred.
 
451  

649  

452 -
        @{
650 +
        @param size The number of characters pointed to
 
651 +
        by `data`.
 
652 +

 
653 +
        @param ec Set to the error, if any occurred.
453  
    */
654  
    */
 
655 +
/** @{ */
454  
    BOOST_JSON_DECL
656  
    BOOST_JSON_DECL
455  
    std::size_t
657  
    std::size_t
456  
    write(
658  
    write(
457  
        char const* data,
659  
        char const* data,
458  
        std::size_t size,
660  
        std::size_t size,
459  
        system::error_code& ec);
661  
        system::error_code& ec);
460  

662  

461  
    BOOST_JSON_DECL
663  
    BOOST_JSON_DECL
462  
    std::size_t
664  
    std::size_t
463  
    write(
665  
    write(
464  
        char const* data,
666  
        char const* data,
465  
        std::size_t size,
667  
        std::size_t size,
466  
        std::error_code& ec);
668  
        std::error_code& ec);
 
669 +
/** @} */
467  

670  

468 -
    /** Overload
671 +
    /** Parse a buffer containing a complete JSON text.
 
672 +

 
673 +
        This function parses a complete JSON text contained
 
674 +
        in the specified character buffer. The entire
 
675 +
        buffer must be consumed; if there are additional
 
676 +
        characters past the end of the complete JSON text,
 
677 +
        the parse fails and an error is returned.
 
678 +

 
679 +
        @par Example
 
680 +
        @code
 
681 +
        parser p;                                       // construct a parser
 
682 +
        size_t n = p.write( "[1,2,3]" );                // parse a complete JSON text
 
683 +
        assert( n == 7 );                               // all characters consumed
 
684 +
        value jv = p.release();                         // take ownership of the value
 
685 +
        @endcode
 
686 +

 
687 +
        @par Complexity
 
688 +
        Linear in `size`.
 
689 +

 
690 +
        @par Exception Safety
 
691 +
        Basic guarantee.
 
692 +
        Calls to `memory_resource::allocate` may throw.
 
693 +
        Upon error or exception, subsequent calls will
 
694 +
        fail until @ref reset is called to parse a new JSON text.
 
695 +

 
696 +
        @return The number of characters consumed from
 
697 +
        the buffer.
 
698 +

 
699 +
        @param data A pointer to a buffer of `size`
 
700 +
        characters to parse.
 
701 +

 
702 +
        @param size The number of characters pointed to
 
703 +
        by `data`.
469  

704  

470  
        @throw `boost::system::system_error` Thrown on error.
705  
        @throw `boost::system::system_error` Thrown on error.
471  
    */
706  
    */
472  
    BOOST_JSON_DECL
707  
    BOOST_JSON_DECL
473  
    std::size_t
708  
    std::size_t
474  
    write(
709  
    write(
475  
        char const* data,
710  
        char const* data,
476  
        std::size_t size);
711  
        std::size_t size);
477  

712  

478 -
    /** Overload
713 +
    /** Parse a buffer containing a complete JSON text.
 
714 +

 
715 +
        This function parses a complete JSON text contained
 
716 +
        in the specified character buffer. The entire
 
717 +
        buffer must be consumed; if there are additional
 
718 +
        characters past the end of the complete JSON text,
 
719 +
        the parse fails and an error is returned.
 
720 +

 
721 +
        @par Example
 
722 +
        @code
 
723 +
        parser p;                                       // construct a parser
 
724 +
        size_t n = p.write( "[1,2,3]" );                // parse a complete JSON text
 
725 +
        assert( n == 7 );                               // all characters consumed
 
726 +
        value jv = p.release();                         // take ownership of the value
 
727 +
        @endcode
 
728 +

 
729 +
        @par Complexity
 
730 +
        Linear in `size`.
 
731 +

 
732 +
        @par Exception Safety
 
733 +
        Basic guarantee.
 
734 +
        Calls to `memory_resource::allocate` may throw.
 
735 +
        Upon error or exception, subsequent calls will
 
736 +
        fail until @ref reset is called to parse a new JSON text.
 
737 +

 
738 +
        @return The number of characters consumed from
 
739 +
        the buffer.
479  

740  

480  
        @param s The character string to parse.
741  
        @param s The character string to parse.
481 -
        @param ec
742 +

 
743 +
        @param ec Set to the error, if any occurred.
482  
    */
744  
    */
 
745 +
/** @{ */
483  
    std::size_t
746  
    std::size_t
484  
    write(
747  
    write(
485  
        string_view s,
748  
        string_view s,
486  
        system::error_code& ec)
749  
        system::error_code& ec)
487  
    {
750  
    {
488  
        return write(
751  
        return write(
489  
            s.data(), s.size(), ec);
752  
            s.data(), s.size(), ec);
490  
    }
753  
    }
491 -
    /** Overload
 
492 -

 
493 -
        @param s
 
494 -
        @param ec
 
495 -
    */
 
496  

754  

497  
    std::size_t
755  
    std::size_t
498  
    write(
756  
    write(
499  
        string_view s,
757  
        string_view s,
500  
        std::error_code& ec)
758  
        std::error_code& ec)
501  
    {
759  
    {
502  
        return write(
760  
        return write(
503  
            s.data(), s.size(), ec);
761  
            s.data(), s.size(), ec);
504  
    }
762  
    }
 
763 +
/** @} */
505  

764  

506 -
    /** Overload
765 +
    /** Parse a buffer containing a complete JSON text.
507  

766  

508 -
        @param s
767 +
        This function parses a complete JSON text contained
 
768 +
        in the specified character buffer. The entire
 
769 +
        buffer must be consumed; if there are additional
 
770 +
        characters past the end of the complete JSON text,
 
771 +
        the parse fails and an error is returned.
 
772 +

 
773 +
        @par Example
 
774 +
        @code
 
775 +
        parser p;                                       // construct a parser
 
776 +
        size_t n = p.write( "[1,2,3]" );                // parse a complete JSON text
 
777 +
        assert( n == 7 );                               // all characters consumed
 
778 +
        value jv = p.release();                         // take ownership of the value
 
779 +
        @endcode
 
780 +

 
781 +
        @par Complexity
 
782 +
        Linear in `size`.
 
783 +

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

 
790 +
        @return The number of characters consumed from
 
791 +
        the buffer.
 
792 +

 
793 +
        @param s The character string to parse.
 
794 +

 
795 +
        @throw `boost::system::system_error` Thrown on error.
509  
    */
796  
    */
510  
    std::size_t
797  
    std::size_t
511  
    write(
798  
    write(
512  
        string_view s)
799  
        string_view s)
513  
    {
800  
    {
514  
        return write(
801  
        return write(
515  
            s.data(), s.size());
802  
            s.data(), s.size());
516 -
    /// @}
 
517  
    }
803  
    }
518  

804  

519  
    /** Return the parsed JSON text as a @ref value.
805  
    /** Return the parsed JSON text as a @ref value.
520  

806  

521 -
        This returns the parsed value, or throws an exception if the parsing is
807 +
        This returns the parsed value, or throws
522 -
        incomplete or failed. It is necessary to call @ref reset after calling
808 +
        an exception if the parsing is incomplete or
523 -
        this function in order to parse another JSON text.
809 +
        failed. It is necessary to call @ref reset
 
810 +
        after calling this function in order to parse
 
811 +
        another JSON text.
524  

812  

525  
        @par Complexity
813  
        @par Complexity
526  
        Constant.
814  
        Constant.
527  

815  

528 -
        @return The parsed value. Ownership of this value is transferred to the
816 +
        @return The parsed value. Ownership of this
529 -
        caller.
817 +
        value is transferred to the caller.
530  

818  

531 -
        @throw boost::system::system_error A complete JSON text hasn't been
819 +
        @throw `boost::system::system_error` Thrown on failure.
532 -
               parsed, or parsing failed.
 
533  
    */
820  
    */
534  
    BOOST_JSON_DECL
821  
    BOOST_JSON_DECL
535  
    value
822  
    value
536  
    release();
823  
    release();
537  
};
824  
};
538  

825  

539  
} // namespace json
826  
} // namespace json
540  
} // namespace boost
827  
} // namespace boost
541  

828  

542  
#endif
829  
#endif