1  
//
1  
//
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/boostorg/json
7  
// Official repository: https://github.com/boostorg/json
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_JSON_PARSER_HPP
10  
#ifndef BOOST_JSON_PARSER_HPP
11  
#define BOOST_JSON_PARSER_HPP
11  
#define BOOST_JSON_PARSER_HPP
12  

12  

13  
#include <boost/json/detail/config.hpp>
13  
#include <boost/json/detail/config.hpp>
14  
#include <boost/json/basic_parser.hpp>
14  
#include <boost/json/basic_parser.hpp>
15  
#include <boost/json/storage_ptr.hpp>
15  
#include <boost/json/storage_ptr.hpp>
16  
#include <boost/json/value.hpp>
16  
#include <boost/json/value.hpp>
17  
#include <boost/json/detail/handler.hpp>
17  
#include <boost/json/detail/handler.hpp>
18  
#include <type_traits>
18  
#include <type_traits>
19  
#include <cstddef>
19  
#include <cstddef>
20  

20  

21  
namespace boost {
21  
namespace boost {
22  
namespace json {
22  
namespace json {
23  

23  

24  
//----------------------------------------------------------
24  
//----------------------------------------------------------
25  

25  

26  
/** A DOM parser for JSON contained in a single buffer.
26  
/** A DOM parser for JSON contained in a single buffer.
27  

27  

28  
    This class is used to parse a JSON text contained in a single character
28  
    This class is used to parse a JSON text contained in a single character
29  
    buffer, into a @ref value container.
29  
    buffer, into a @ref value container.
30  

30  

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

42  

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

56  

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

67  

68  
    It is important to note that the `boost::container::pmr::memory_resource`
68  
    It is important to note that the `boost::container::pmr::memory_resource`
69  
    supplied upon construction is used for temporary storage only, and not for
69  
    supplied upon construction is used for temporary storage only, and not for
70  
    allocating the elements which make up the parsed value. That other memory
70  
    allocating the elements which make up the parsed value. That other memory
71  
    resource is optionally supplied in each call to @ref reset.
71  
    resource is optionally supplied in each call to @ref reset.
72  

72  

73  
    @par Duplicate Keys
73  
    @par Duplicate Keys
74  
    If there are object elements with duplicate keys; that is, if multiple
74  
    If there are object elements with duplicate keys; that is, if multiple
75  
    elements in an object have keys that compare equal, only the last
75  
    elements in an object have keys that compare equal, only the last
76  
    equivalent element will be inserted.
76  
    equivalent element will be inserted.
77  

77  

78  
    @par Non-Standard JSON
78  
    @par Non-Standard JSON
79  
    The @ref parse_options structure optionally provided upon construction is
79  
    The @ref parse_options structure optionally provided upon construction is
80  
    used to customize some parameters of the parser, including which
80  
    used to customize some parameters of the parser, including which
81  
    non-standard JSON extensions should be allowed. A default-constructed parse
81  
    non-standard JSON extensions should be allowed. A default-constructed parse
82  
    options allows only standard JSON.
82  
    options allows only standard JSON.
83  

83  

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

88  

89  
    @see @ref parse, @ref stream_parser.
89  
    @see @ref parse, @ref stream_parser.
90  
*/
90  
*/
91  
class parser
91  
class parser
92  
{
92  
{
93  
    basic_parser<detail::handler> p_;
93  
    basic_parser<detail::handler> p_;
94  

94  

95  
public:
95  
public:
96  
    /** Assignment operator.
96  
    /** Assignment operator.
97  

97  

98  
        This type is neither copyable nor movable. The operator is deleted.
98  
        This type is neither copyable nor movable. The operator is deleted.
99  
    */
99  
    */
100  
    parser& operator=(
100  
    parser& operator=(
101  
        parser const&) = delete;
101  
        parser const&) = delete;
102  

102  

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

104  

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

107  

108  
        @par Complexity
108  
        @par Complexity
109  
        Linear in the size of partial results.
109  
        Linear in the size of partial results.
110  

110  

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

115  

116  
    /** Constructors.
116  
    /** Constructors.
117  

117  

118  
        Construct a new parser.
118  
        Construct a new parser.
119  

119  

120  
        The parser will only support standard JSON if overloads **(1)**
120  
        The parser will only support standard JSON if overloads **(1)**
121  
        or **(2)** are used. Otherwise the parser will support extensions
121  
        or **(2)** are used. Otherwise the parser will support extensions
122  
        specified by the parameter `opt`.
122  
        specified by the parameter `opt`.
123  

123  

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

127  

128  
        The main difference between the overloads is in what the constructed
128  
        The main difference between the overloads is in what the constructed
129  
        parser will use for temporary storage:
129  
        parser will use for temporary storage:
130  

130  

131  
        @li **(1)** the constructed parser uses the default memory resource for
131  
        @li **(1)** the constructed parser uses the default memory resource for
132  
        temporary storage.
132  
        temporary storage.
133  

133  

134  
        @li **(2)**, **(3)** the constructed parser uses the memory resource of
134  
        @li **(2)**, **(3)** the constructed parser uses the memory resource of
135  
        `sp` for temporary storage.
135  
        `sp` for temporary storage.
136  

136  

137  
        @li **(4)**, **(6)** the constructed parser first uses the caller-owned
137  
        @li **(4)**, **(6)** the constructed parser first uses the caller-owned
138  
        storage `[buffer, buffer + size)` for temporary storage, falling back
138  
        storage `[buffer, buffer + size)` for temporary storage, falling back
139  
        to the memory resource of `sp` if needed.
139  
        to the memory resource of `sp` if needed.
140  

140  

141  
        @li **(5)**, **(7)** the constructed parser first uses the caller-owned
141  
        @li **(5)**, **(7)** the constructed parser first uses the caller-owned
142  
        storage `[buffer, buffer + N)` for temporary storage, falling back to
142  
        storage `[buffer, buffer + N)` for temporary storage, falling back to
143  
        the memory resource of `sp` if needed.
143  
        the memory resource of `sp` if needed.
144  

144  

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

148  

149  
        Overload **(8)** is the copy constructor. The type is neither copyable
149  
        Overload **(8)** is the copy constructor. The type is neither copyable
150  
        nor movable, so the overload is deleted.
150  
        nor movable, so the overload is deleted.
151  

151  

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

154  

155  
        @par Exception Safety
155  
        @par Exception Safety
156  
        No-throw guarantee.
156  
        No-throw guarantee.
157  

157  

158  
        @{
158  
        @{
159  
    */
159  
    */
160  
    parser() noexcept
160  
    parser() noexcept
161  
        : parser({}, {})
161  
        : parser({}, {})
162  
    {
162  
    {
163  
    }
163  
    }
164  

164  

165  
    /** Overload
165  
    /** Overload
166  

166  

167  
        @param sp The memory resource to use for temporary storage.
167  
        @param sp The memory resource to use for temporary storage.
168  
    */
168  
    */
169  
    explicit
169  
    explicit
170  
    parser(storage_ptr sp) noexcept
170  
    parser(storage_ptr sp) noexcept
171  
        : parser(std::move(sp), {})
171  
        : parser(std::move(sp), {})
172  
    {
172  
    {
173  
    }
173  
    }
174  

174  

175  
    /** Overload
175  
    /** Overload
176  

176  

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

184  

185  
    /** Overload
185  
    /** Overload
186  

186  

187  
        @param buffer A pointer to valid storage.
187  
        @param buffer A pointer to valid storage.
188  
        @param size The number of valid bytes in `buffer`.
188  
        @param size The number of valid bytes in `buffer`.
189  
        @param sp
189  
        @param sp
190  
        @param opt
190  
        @param opt
191  
    */
191  
    */
192  
    BOOST_JSON_DECL
192  
    BOOST_JSON_DECL
193  
    parser(
193  
    parser(
194  
        storage_ptr sp,
194  
        storage_ptr sp,
195  
        parse_options const& opt,
195  
        parse_options const& opt,
196  
        unsigned char* buffer,
196  
        unsigned char* buffer,
197  
        std::size_t size) noexcept;
197  
        std::size_t size) noexcept;
198  

198  

199  
    /** Overload
199  
    /** Overload
200  

200  

201  
        @tparam N The number of valid bytes in `buffer`.
201  
        @tparam N The number of valid bytes in `buffer`.
202  
        @param sp
202  
        @param sp
203  
        @param opt
203  
        @param opt
204  
        @param buffer
204  
        @param buffer
205  
    */
205  
    */
206  
    template<std::size_t N>
206  
    template<std::size_t N>
207  
    parser(
207  
    parser(
208  
        storage_ptr sp,
208  
        storage_ptr sp,
209  
        parse_options const& opt,
209  
        parse_options const& opt,
210  
        unsigned char(&buffer)[N]) noexcept
210  
        unsigned char(&buffer)[N]) noexcept
211  
        : parser(std::move(sp),
211  
        : parser(std::move(sp),
212  
            opt, &buffer[0], N)
212  
            opt, &buffer[0], N)
213  
    {
213  
    {
214  
    }
214  
    }
215  

215  

216  
#if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
216  
#if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
217  
    /** Overload
217  
    /** Overload
218  

218  

219  
        @param buffer
219  
        @param buffer
220  
        @param size
220  
        @param size
221  
        @param sp
221  
        @param sp
222  
        @param opt
222  
        @param opt
223  
    */
223  
    */
224  
    parser(
224  
    parser(
225  
        storage_ptr sp,
225  
        storage_ptr sp,
226  
        parse_options const& opt,
226  
        parse_options const& opt,
227  
        std::byte* buffer,
227  
        std::byte* buffer,
228  
        std::size_t size) noexcept
228  
        std::size_t size) noexcept
229  
        : parser(sp, opt, reinterpret_cast<
229  
        : parser(sp, opt, reinterpret_cast<
230  
            unsigned char*>(buffer), size)
230  
            unsigned char*>(buffer), size)
231  
    {
231  
    {
232  
    }
232  
    }
233  

233  

234  
    /** Overload
234  
    /** Overload
235  

235  

236  
        @tparam N
236  
        @tparam N
237  
        @param sp
237  
        @param sp
238  
        @param opt
238  
        @param opt
239  
        @param buffer
239  
        @param buffer
240  
    */
240  
    */
241  
    template<std::size_t N>
241  
    template<std::size_t N>
242  
    parser(
242  
    parser(
243  
        storage_ptr sp,
243  
        storage_ptr sp,
244  
        parse_options const& opt,
244  
        parse_options const& opt,
245  
        std::byte(&buffer)[N]) noexcept
245  
        std::byte(&buffer)[N]) noexcept
246  
        : parser(std::move(sp),
246  
        : parser(std::move(sp),
247  
            opt, &buffer[0], N)
247  
            opt, &buffer[0], N)
248  
    {
248  
    {
249  
    }
249  
    }
250  
#endif
250  
#endif
251  

251  

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

268  

269  
#ifdef __cpp_lib_byte
269  
#ifdef __cpp_lib_byte
270  
    // Safety net for accidental buffer overflows
270  
    // Safety net for accidental buffer overflows
271  
    template<std::size_t N>
271  
    template<std::size_t N>
272  
    parser(
272  
    parser(
273  
        storage_ptr sp,
273  
        storage_ptr sp,
274  
        parse_options const& opt,
274  
        parse_options const& opt,
275  
        std::byte(&buffer)[N], std::size_t n) noexcept
275  
        std::byte(&buffer)[N], std::size_t n) noexcept
276  
        : parser(std::move(sp),
276  
        : parser(std::move(sp),
277  
            opt, &buffer[0], n)
277  
            opt, &buffer[0], n)
278  
    {
278  
    {
279  
        // If this goes off, check your parameters
279  
        // If this goes off, check your parameters
280  
        // closely, chances are you passed an array
280  
        // closely, chances are you passed an array
281  
        // thinking it was a pointer.
281  
        // thinking it was a pointer.
282  
        BOOST_ASSERT(n <= N);
282  
        BOOST_ASSERT(n <= N);
283  
    }
283  
    }
284  
#endif
284  
#endif
285  
#endif
285  
#endif
286  

286  

287  
    /// Overload
287  
    /// Overload
288  
    parser(
288  
    parser(
289  
        parser const&) = delete;
289  
        parser const&) = delete;
290  
    /// @}
290  
    /// @}
291  

291  

292  

292  

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

294  

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

298  

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

302  

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

305  

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

313  

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

315  

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

322  

323  
        @par Example
323  
        @par Example
324  
        @code
324  
        @code
325  
        parser p;                                       // construct a parser
325  
        parser p;                                       // construct a parser
326  
        size_t n = p.write_some( "[1,2,3] null" );      // parse a complete JSON text
326  
        size_t n = p.write_some( "[1,2,3] null" );      // parse a complete JSON text
327  
        assert( n == 8 );                               // only some characters consumed
327  
        assert( n == 8 );                               // only some characters consumed
328  
        value jv = p.release();                         // take ownership of the value
328  
        value jv = p.release();                         // take ownership of the value
329  
        @endcode
329  
        @endcode
330  

330  

331  
        Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
331  
        Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
332  
        setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
332  
        setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
333  
        exceptions.
333  
        exceptions.
334  

334  

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

338  

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

343  

344  
        @return The number of characters consumed from the buffer.
344  
        @return The number of characters consumed from the buffer.
345  

345  

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

349  

350  
        @{
350  
        @{
351  
    */
351  
    */
352  
    BOOST_JSON_DECL
352  
    BOOST_JSON_DECL
353  
    std::size_t
353  
    std::size_t
354  
    write_some(
354  
    write_some(
355  
        char const* data,
355  
        char const* data,
356  
        std::size_t size,
356  
        std::size_t size,
357  
        system::error_code& ec);
357  
        system::error_code& ec);
358  

358  

359  
    BOOST_JSON_DECL
359  
    BOOST_JSON_DECL
360  
    std::size_t
360  
    std::size_t
361  
    write_some(
361  
    write_some(
362  
        char const* data,
362  
        char const* data,
363  
        std::size_t size,
363  
        std::size_t size,
364  
        std::error_code& ec);
364  
        std::error_code& ec);
365  

365  

366  
    /** Overload
366  
    /** Overload
367  

367  

368  
        @param data
368  
        @param data
369  
        @param size
369  
        @param size
370  
    */
370  
    */
371  
    BOOST_JSON_DECL
371  
    BOOST_JSON_DECL
372  
    std::size_t
372  
    std::size_t
373  
    write_some(
373  
    write_some(
374  
        char const* data,
374  
        char const* data,
375  
        std::size_t size);
375  
        std::size_t size);
376  

376  

377  
    /** Overload
377  
    /** Overload
378  

378  

379  
        @param s The character string to parse.
379  
        @param s The character string to parse.
380  
        @param ec
380  
        @param ec
381  
    */
381  
    */
382  
    std::size_t
382  
    std::size_t
383  
    write_some(
383  
    write_some(
384  
        string_view s,
384  
        string_view s,
385  
        system::error_code& ec)
385  
        system::error_code& ec)
386  
    {
386  
    {
387  
        return write_some(
387  
        return write_some(
388  
            s.data(), s.size(), ec);
388  
            s.data(), s.size(), ec);
389  
    }
389  
    }
390  

390  

391  
    /** Overload
391  
    /** Overload
392  

392  

393  
        @param s
393  
        @param s
394  
        @param ec
394  
        @param ec
395  
    */
395  
    */
396  
    std::size_t
396  
    std::size_t
397  
    write_some(
397  
    write_some(
398  
        string_view s,
398  
        string_view s,
399  
        std::error_code& ec)
399  
        std::error_code& ec)
400  
    {
400  
    {
401  
        return write_some(
401  
        return write_some(
402  
            s.data(), s.size(), ec);
402  
            s.data(), s.size(), ec);
403  
    }
403  
    }
404  

404  

405  
    /** Overload
405  
    /** Overload
406  

406  

407  
        @param s
407  
        @param s
408  
    */
408  
    */
409  
    std::size_t
409  
    std::size_t
410  
    write_some(
410  
    write_some(
411  
        string_view s)
411  
        string_view s)
412  
    {
412  
    {
413  
        return write_some(
413  
        return write_some(
414  
            s.data(), s.size());
414  
            s.data(), s.size());
415  
    }
415  
    }
416  
    /// @}
416  
    /// @}
417  

417  

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

419  

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

424  

425  
        @par Example
425  
        @par Example
426  
        @code
426  
        @code
427  
        parser p;                                       // construct a parser
427  
        parser p;                                       // construct a parser
428  
        size_t n = p.write( "[1,2,3]" );                // parse a complete JSON text
428  
        size_t n = p.write( "[1,2,3]" );                // parse a complete JSON text
429  
        assert( n == 7 );                               // all characters consumed
429  
        assert( n == 7 );                               // all characters consumed
430  
        value jv = p.release();                         // take ownership of the value
430  
        value jv = p.release();                         // take ownership of the value
431  
        @endcode
431  
        @endcode
432  

432  

433  
        Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
433  
        Overloads **(1)**, **(2)**, **(4)**, and **(5)** report errors by
434  
        setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
434  
        setting `ec`. Overloads **(3)** and **(6)** report errors by throwing
435  
        exceptions.
435  
        exceptions.
436  

436  

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

440  

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

445  

446  
        @return The number of characters consumed from the buffer.
446  
        @return The number of characters consumed from the buffer.
447  

447  

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

451  

452  
        @{
452  
        @{
453  
    */
453  
    */
454  
    BOOST_JSON_DECL
454  
    BOOST_JSON_DECL
455  
    std::size_t
455  
    std::size_t
456  
    write(
456  
    write(
457  
        char const* data,
457  
        char const* data,
458  
        std::size_t size,
458  
        std::size_t size,
459  
        system::error_code& ec);
459  
        system::error_code& ec);
460  

460  

461  
    BOOST_JSON_DECL
461  
    BOOST_JSON_DECL
462  
    std::size_t
462  
    std::size_t
463  
    write(
463  
    write(
464  
        char const* data,
464  
        char const* data,
465  
        std::size_t size,
465  
        std::size_t size,
466  
        std::error_code& ec);
466  
        std::error_code& ec);
467  

467  

468  
    /** Overload
468  
    /** Overload
469  

469  

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

477  

478  
    /** Overload
478  
    /** Overload
479  

479  

480  
        @param s The character string to parse.
480  
        @param s The character string to parse.
481  
        @param ec
481  
        @param ec
482  
    */
482  
    */
483  
    std::size_t
483  
    std::size_t
484  
    write(
484  
    write(
485  
        string_view s,
485  
        string_view s,
486  
        system::error_code& ec)
486  
        system::error_code& ec)
487  
    {
487  
    {
488  
        return write(
488  
        return write(
489  
            s.data(), s.size(), ec);
489  
            s.data(), s.size(), ec);
490  
    }
490  
    }
491  

491  

492  
    /** Overload
492  
    /** Overload
493  

493  

494  
        @param s
494  
        @param s
495  
        @param ec
495  
        @param ec
496  
    */
496  
    */
497  
    std::size_t
497  
    std::size_t
498  
    write(
498  
    write(
499  
        string_view s,
499  
        string_view s,
500  
        std::error_code& ec)
500  
        std::error_code& ec)
501  
    {
501  
    {
502  
        return write(
502  
        return write(
503  
            s.data(), s.size(), ec);
503  
            s.data(), s.size(), ec);
504  
    }
504  
    }
505  

505  

506  
    /** Overload
506  
    /** Overload
507  

507  

508  
        @param s
508  
        @param s
509  
    */
509  
    */
510  
    std::size_t
510  
    std::size_t
511  
    write(
511  
    write(
512  
        string_view s)
512  
        string_view s)
513  
    {
513  
    {
514  
        return write(
514  
        return write(
515  
            s.data(), s.size());
515  
            s.data(), s.size());
516  
    }
516  
    }
517  
    /// @}
517  
    /// @}
518  

518  

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

520  

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

524  

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

527  

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

530  

531  
        @throw boost::system::system_error A complete JSON text hasn't been
531  
        @throw boost::system::system_error A complete JSON text hasn't been
532  
               parsed, or parsing failed.
532  
               parsed, or parsing failed.
533  
    */
533  
    */
534  
    BOOST_JSON_DECL
534  
    BOOST_JSON_DECL
535  
    value
535  
    value
536  
    release();
536  
    release();
537  
};
537  
};
538  

538  

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

541  

542  
#endif
542  
#endif