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

10  

11  
#ifndef BOOST_JSON_BASIC_PARSER_HPP
11  
#ifndef BOOST_JSON_BASIC_PARSER_HPP
12  
#define BOOST_JSON_BASIC_PARSER_HPP
12  
#define BOOST_JSON_BASIC_PARSER_HPP
13  

13  

14  
#include <boost/json/detail/config.hpp>
14  
#include <boost/json/detail/config.hpp>
15  
#include <boost/json/detail/except.hpp>
15  
#include <boost/json/detail/except.hpp>
16  
#include <boost/json/error.hpp>
16  
#include <boost/json/error.hpp>
17  
#include <boost/json/kind.hpp>
17  
#include <boost/json/kind.hpp>
18  
#include <boost/json/parse_options.hpp>
18  
#include <boost/json/parse_options.hpp>
19  
#include <boost/json/detail/stack.hpp>
19  
#include <boost/json/detail/stack.hpp>
20  
#include <boost/json/detail/stream.hpp>
20  
#include <boost/json/detail/stream.hpp>
21  
#include <boost/json/detail/utf8.hpp>
21  
#include <boost/json/detail/utf8.hpp>
22  
#include <boost/json/detail/sbo_buffer.hpp>
22  
#include <boost/json/detail/sbo_buffer.hpp>
23  

23  

24  
namespace boost {
24  
namespace boost {
25  
namespace json {
25  
namespace json {
26  

26  

27  
/** An incremental SAX parser for serialized JSON.
27  
/** An incremental SAX parser for serialized JSON.
28  

28  

29 -
    This implements a SAX-style parser, invoking a caller-supplied handler with
29 +
    This implements a SAX-style parser, invoking a
30 -
    each parsing event. To use, first declare a variable of type
30 +
    caller-supplied handler with each parsing event.
31 -
    `basic_parser<T>` where `T` meets the handler requirements specified below.
31 +
    To use, first declare a variable of type
32 -
    Then call @ref write_some one or more times with the input, setting
32 +
    `basic_parser<T>` where `T` meets the handler
33 -
    `more = false` on the final buffer. The parsing events are realized through
33 +
    requirements specified below. Then call
34 -
    member function calls on the handler, which exists as a data member of the
34 +
    @ref write_some one or more times with the input,
35 -
    parser.
35 +
    setting `more = false` on the final buffer.
36 -

36 +
    The parsing events are realized through member
37 -
    The parser may dynamically allocate intermediate storage as needed to
37 +
    function calls on the handler, which exists
38 -
    accommodate the nesting level of the input JSON. On subsequent invocations,
38 +
    as a data member of the parser.
39 -
    the parser can cheaply re-use this memory, improving performance. This
39 +
\n
40 -
    storage is freed when the parser is destroyed
40 +
    The parser may dynamically allocate intermediate
 
41 +
    storage as needed to accommodate the nesting level
 
42 +
    of the input JSON. On subsequent invocations, the
 
43 +
    parser can cheaply re-use this memory, improving
 
44 +
    performance. This storage is freed when the
 
45 +
    parser is destroyed
41  

46  

42  
    @par Usage
47  
    @par Usage
43 -
    To get the declaration and function definitions for this class it is
48 +

44 -
    necessary to include this file instead:
49 +
    To get the declaration and function definitions
 
50 +
    for this class it is necessary to include this
 
51 +
    file instead:
45  
    @code
52  
    @code
46  
    #include <boost/json/basic_parser_impl.hpp>
53  
    #include <boost/json/basic_parser_impl.hpp>
47  
    @endcode
54  
    @endcode
48  

55  

49 -
    Users who wish to parse JSON into the DOM container @ref value will not use
56 +
    Users who wish to parse JSON into the DOM container
50 -
    this class directly; instead they will create an instance of @ref parser or
57 +
    @ref value will not use this class directly; instead
51 -
    @ref stream_parser and use that instead. Alternatively, they may call the
58 +
    they will create an instance of @ref parser or
52 -
    function @ref parse. This class is designed for users who wish to perform
59 +
    @ref stream_parser and use that instead. Alternatively,
53 -
    custom actions instead of building a @ref value. For example, to produce a
60 +
    they may call the function @ref parse. This class is
54 -
    DOM from an external library.
61 +
    designed for users who wish to perform custom actions
55 -

62 +
    instead of building a @ref value. For example, to
 
63 +
    produce a DOM from an external library.
 
64 +
\n
56  
    @note
65  
    @note
57 -
    By default, only conforming JSON using UTF-8 encoding is accepted. However,
66 +

58 -
    select non-compliant syntax can be allowed by construction using a
67 +
    By default, only conforming JSON using UTF-8
 
68 +
    encoding is accepted. However, select non-compliant
 
69 +
    syntax can be allowed by construction using a
59  
    @ref parse_options set to desired values.
70  
    @ref parse_options set to desired values.
60  

71  

61 -
    The handler provided must be implemented as an object of class type which
 
62 -
    defines each of the required event member functions below. The event
 
63 -
    functions return a `bool` where `true` indicates success, and `false`
 
64 -
    indicates failure. If the member function returns `false`, it must set the
 
65 -
    error code to a suitable value. This error code will be returned by the
 
66 -
    write function to the caller.
 
67  
    @par Handler
72  
    @par Handler
68  

73  

69 -
    Handlers are required to declare the maximum limits on various elements. If
74 +
    The handler provided must be implemented as an
70 -
    these limits are exceeded during parsing, then parsing fails with an error.
75 +
    object of class type which defines each of the
71 -

76 +
    required event member functions below. The event
72 -
    The following declaration meets the parser's handler requirements:
77 +
    functions return a `bool` where `true` indicates
 
78 +
    success, and `false` indicates failure. If the
 
79 +
    member function returns `false`, it must set
 
80 +
    the error code to a suitable value. This error
 
81 +
    code will be returned by the write function to
 
82 +
    the caller.
 
83 +
\n
 
84 +
    Handlers are required to declare the maximum
 
85 +
    limits on various elements. If these limits
 
86 +
    are exceeded during parsing, then parsing
 
87 +
    fails with an error.
 
88 +
\n
 
89 +
    The following declaration meets the parser's
 
90 +
    handler requirements:
73  

91  

74  
    @code
92  
    @code
75  
    struct handler
93  
    struct handler
76  
    {
94  
    {
77  
        /// The maximum number of elements allowed in an array
95  
        /// The maximum number of elements allowed in an array
78  
        static constexpr std::size_t max_array_size = -1;
96  
        static constexpr std::size_t max_array_size = -1;
79  

97  

80  
        /// The maximum number of elements allowed in an object
98  
        /// The maximum number of elements allowed in an object
81  
        static constexpr std::size_t max_object_size = -1;
99  
        static constexpr std::size_t max_object_size = -1;
82  

100  

83  
        /// The maximum number of characters allowed in a string
101  
        /// The maximum number of characters allowed in a string
84  
        static constexpr std::size_t max_string_size = -1;
102  
        static constexpr std::size_t max_string_size = -1;
85  

103  

86  
        /// The maximum number of characters allowed in a key
104  
        /// The maximum number of characters allowed in a key
87  
        static constexpr std::size_t max_key_size = -1;
105  
        static constexpr std::size_t max_key_size = -1;
88  

106  

89  
        /// Called once when the JSON parsing begins.
107  
        /// Called once when the JSON parsing begins.
90  
        ///
108  
        ///
91  
        /// @return `true` on success.
109  
        /// @return `true` on success.
92  
        /// @param ec Set to the error, if any occurred.
110  
        /// @param ec Set to the error, if any occurred.
93  
        ///
111  
        ///
94  
        bool on_document_begin( error_code& ec );
112  
        bool on_document_begin( error_code& ec );
95  

113  

96  
        /// Called when the JSON parsing is done.
114  
        /// Called when the JSON parsing is done.
97  
        ///
115  
        ///
98  
        /// @return `true` on success.
116  
        /// @return `true` on success.
99  
        /// @param ec Set to the error, if any occurred.
117  
        /// @param ec Set to the error, if any occurred.
100  
        ///
118  
        ///
101  
        bool on_document_end( error_code& ec );
119  
        bool on_document_end( error_code& ec );
102  

120  

103  
        /// Called when the beginning of an array is encountered.
121  
        /// Called when the beginning of an array is encountered.
104  
        ///
122  
        ///
105  
        /// @return `true` on success.
123  
        /// @return `true` on success.
106  
        /// @param ec Set to the error, if any occurred.
124  
        /// @param ec Set to the error, if any occurred.
107  
        ///
125  
        ///
108  
        bool on_array_begin( error_code& ec );
126  
        bool on_array_begin( error_code& ec );
109  

127  

110  
        /// Called when the end of the current array is encountered.
128  
        /// Called when the end of the current array is encountered.
111  
        ///
129  
        ///
112  
        /// @return `true` on success.
130  
        /// @return `true` on success.
113  
        /// @param n The number of elements in the array.
131  
        /// @param n The number of elements in the array.
114  
        /// @param ec Set to the error, if any occurred.
132  
        /// @param ec Set to the error, if any occurred.
115  
        ///
133  
        ///
116  
        bool on_array_end( std::size_t n, error_code& ec );
134  
        bool on_array_end( std::size_t n, error_code& ec );
117  

135  

118  
        /// Called when the beginning of an object is encountered.
136  
        /// Called when the beginning of an object is encountered.
119  
        ///
137  
        ///
120  
        /// @return `true` on success.
138  
        /// @return `true` on success.
121  
        /// @param ec Set to the error, if any occurred.
139  
        /// @param ec Set to the error, if any occurred.
122  
        ///
140  
        ///
123  
        bool on_object_begin( error_code& ec );
141  
        bool on_object_begin( error_code& ec );
124  

142  

125  
        /// Called when the end of the current object is encountered.
143  
        /// Called when the end of the current object is encountered.
126  
        ///
144  
        ///
127  
        /// @return `true` on success.
145  
        /// @return `true` on success.
128  
        /// @param n The number of elements in the object.
146  
        /// @param n The number of elements in the object.
129  
        /// @param ec Set to the error, if any occurred.
147  
        /// @param ec Set to the error, if any occurred.
130  
        ///
148  
        ///
131  
        bool on_object_end( std::size_t n, error_code& ec );
149  
        bool on_object_end( std::size_t n, error_code& ec );
132  

150  

133  
        /// Called with characters corresponding to part of the current string.
151  
        /// Called with characters corresponding to part of the current string.
134  
        ///
152  
        ///
135  
        /// @return `true` on success.
153  
        /// @return `true` on success.
136  
        /// @param s The partial characters
154  
        /// @param s The partial characters
137  
        /// @param n The total size of the string thus far
155  
        /// @param n The total size of the string thus far
138  
        /// @param ec Set to the error, if any occurred.
156  
        /// @param ec Set to the error, if any occurred.
139  
        ///
157  
        ///
140  
        bool on_string_part( string_view s, std::size_t n, error_code& ec );
158  
        bool on_string_part( string_view s, std::size_t n, error_code& ec );
141  

159  

142  
        /// Called with the last characters corresponding to the current string.
160  
        /// Called with the last characters corresponding to the current string.
143  
        ///
161  
        ///
144  
        /// @return `true` on success.
162  
        /// @return `true` on success.
145  
        /// @param s The remaining characters
163  
        /// @param s The remaining characters
146  
        /// @param n The total size of the string
164  
        /// @param n The total size of the string
147  
        /// @param ec Set to the error, if any occurred.
165  
        /// @param ec Set to the error, if any occurred.
148  
        ///
166  
        ///
149  
        bool on_string( string_view s, std::size_t n, error_code& ec );
167  
        bool on_string( string_view s, std::size_t n, error_code& ec );
150  

168  

151  
        /// Called with characters corresponding to part of the current key.
169  
        /// Called with characters corresponding to part of the current key.
152  
        ///
170  
        ///
153  
        /// @return `true` on success.
171  
        /// @return `true` on success.
154  
        /// @param s The partial characters
172  
        /// @param s The partial characters
155  
        /// @param n The total size of the key thus far
173  
        /// @param n The total size of the key thus far
156  
        /// @param ec Set to the error, if any occurred.
174  
        /// @param ec Set to the error, if any occurred.
157  
        ///
175  
        ///
158  
        bool on_key_part( string_view s, std::size_t n, error_code& ec );
176  
        bool on_key_part( string_view s, std::size_t n, error_code& ec );
159  

177  

160  
        /// Called with the last characters corresponding to the current key.
178  
        /// Called with the last characters corresponding to the current key.
161  
        ///
179  
        ///
162  
        /// @return `true` on success.
180  
        /// @return `true` on success.
163  
        /// @param s The remaining characters
181  
        /// @param s The remaining characters
164  
        /// @param n The total size of the key
182  
        /// @param n The total size of the key
165  
        /// @param ec Set to the error, if any occurred.
183  
        /// @param ec Set to the error, if any occurred.
166  
        ///
184  
        ///
167  
        bool on_key( string_view s, std::size_t n, error_code& ec );
185  
        bool on_key( string_view s, std::size_t n, error_code& ec );
168  

186  

169  
        /// Called with the characters corresponding to part of the current number.
187  
        /// Called with the characters corresponding to part of the current number.
170  
        ///
188  
        ///
171  
        /// @return `true` on success.
189  
        /// @return `true` on success.
172  
        /// @param s The partial characters
190  
        /// @param s The partial characters
173  
        /// @param ec Set to the error, if any occurred.
191  
        /// @param ec Set to the error, if any occurred.
174  
        ///
192  
        ///
175  
        bool on_number_part( string_view s, error_code& ec );
193  
        bool on_number_part( string_view s, error_code& ec );
176  

194  

177  
        /// Called when a signed integer is parsed.
195  
        /// Called when a signed integer is parsed.
178  
        ///
196  
        ///
179  
        /// @return `true` on success.
197  
        /// @return `true` on success.
180  
        /// @param i The value
198  
        /// @param i The value
181  
        /// @param s The remaining characters
199  
        /// @param s The remaining characters
182  
        /// @param ec Set to the error, if any occurred.
200  
        /// @param ec Set to the error, if any occurred.
183  
        ///
201  
        ///
184  
        bool on_int64( int64_t i, string_view s, error_code& ec );
202  
        bool on_int64( int64_t i, string_view s, error_code& ec );
185  

203  

186  
        /// Called when an unsigend integer is parsed.
204  
        /// Called when an unsigend integer is parsed.
187  
        ///
205  
        ///
188  
        /// @return `true` on success.
206  
        /// @return `true` on success.
189  
        /// @param u The value
207  
        /// @param u The value
190  
        /// @param s The remaining characters
208  
        /// @param s The remaining characters
191  
        /// @param ec Set to the error, if any occurred.
209  
        /// @param ec Set to the error, if any occurred.
192  
        ///
210  
        ///
193  
        bool on_uint64( uint64_t u, string_view s, error_code& ec );
211  
        bool on_uint64( uint64_t u, string_view s, error_code& ec );
194  

212  

195  
        /// Called when a double is parsed.
213  
        /// Called when a double is parsed.
196  
        ///
214  
        ///
197  
        /// @return `true` on success.
215  
        /// @return `true` on success.
198  
        /// @param d The value
216  
        /// @param d The value
199  
        /// @param s The remaining characters
217  
        /// @param s The remaining characters
200  
        /// @param ec Set to the error, if any occurred.
218  
        /// @param ec Set to the error, if any occurred.
201  
        ///
219  
        ///
202  
        bool on_double( double d, string_view s, error_code& ec );
220  
        bool on_double( double d, string_view s, error_code& ec );
203  

221  

204  
        /// Called when a boolean is parsed.
222  
        /// Called when a boolean is parsed.
205  
        ///
223  
        ///
206  
        /// @return `true` on success.
224  
        /// @return `true` on success.
207  
        /// @param b The value
225  
        /// @param b The value
208  
        /// @param s The remaining characters
226  
        /// @param s The remaining characters
209  
        /// @param ec Set to the error, if any occurred.
227  
        /// @param ec Set to the error, if any occurred.
210  
        ///
228  
        ///
211  
        bool on_bool( bool b, error_code& ec );
229  
        bool on_bool( bool b, error_code& ec );
212  

230  

213  
        /// Called when a null is parsed.
231  
        /// Called when a null is parsed.
214  
        ///
232  
        ///
215  
        /// @return `true` on success.
233  
        /// @return `true` on success.
216  
        /// @param ec Set to the error, if any occurred.
234  
        /// @param ec Set to the error, if any occurred.
217  
        ///
235  
        ///
218  
        bool on_null( error_code& ec );
236  
        bool on_null( error_code& ec );
219  

237  

220  
        /// Called with characters corresponding to part of the current comment.
238  
        /// Called with characters corresponding to part of the current comment.
221  
        ///
239  
        ///
222  
        /// @return `true` on success.
240  
        /// @return `true` on success.
223  
        /// @param s The partial characters.
241  
        /// @param s The partial characters.
224  
        /// @param ec Set to the error, if any occurred.
242  
        /// @param ec Set to the error, if any occurred.
225  
        ///
243  
        ///
226  
        bool on_comment_part( string_view s, error_code& ec );
244  
        bool on_comment_part( string_view s, error_code& ec );
227  

245  

228  
        /// Called with the last characters corresponding to the current comment.
246  
        /// Called with the last characters corresponding to the current comment.
229  
        ///
247  
        ///
230  
        /// @return `true` on success.
248  
        /// @return `true` on success.
231  
        /// @param s The remaining characters
249  
        /// @param s The remaining characters
232  
        /// @param ec Set to the error, if any occurred.
250  
        /// @param ec Set to the error, if any occurred.
233  
        ///
251  
        ///
234  
        bool on_comment( string_view s, error_code& ec );
252  
        bool on_comment( string_view s, error_code& ec );
235  
    };
253  
    };
236  
    @endcode
254  
    @endcode
237  

255  

238  
    @see
256  
    @see
239  
        @ref parse,
257  
        @ref parse,
240  
        @ref stream_parser,
258  
        @ref stream_parser,
241 -
        \<\<examples_validate, validating parser example\>\>.
259 +
        [Validating parser example](../../doc/html/json/examples.html#json.examples.validate).
 
260 +

 
261 +
    @headerfile <boost/json/basic_parser.hpp>
242  
*/
262  
*/
243  
template<class Handler>
263  
template<class Handler>
244  
class basic_parser
264  
class basic_parser
245  
{
265  
{
246  
    enum class state : char
266  
    enum class state : char
247  
    {
267  
    {
248  
        doc1,  doc3,
268  
        doc1,  doc3,
249  
        com1,  com2,  com3, com4,
269  
        com1,  com2,  com3, com4,
250  
        lit1,
270  
        lit1,
251  
        str1,  str2,  str3,  str4,
271  
        str1,  str2,  str3,  str4,
252  
        str5,  str6,  str7,  str8,
272  
        str5,  str6,  str7,  str8,
253  
        sur1,  sur2,  sur3,
273  
        sur1,  sur2,  sur3,
254  
        sur4,  sur5,  sur6,
274  
        sur4,  sur5,  sur6,
255  
        obj1,  obj2,  obj3,  obj4,
275  
        obj1,  obj2,  obj3,  obj4,
256  
        obj5,  obj6,  obj7,  obj8,
276  
        obj5,  obj6,  obj7,  obj8,
257  
        obj9,  obj10, obj11,
277  
        obj9,  obj10, obj11,
258  
        arr1,  arr2,  arr3,
278  
        arr1,  arr2,  arr3,
259  
        arr4,  arr5,  arr6,
279  
        arr4,  arr5,  arr6,
260  
        num1,  num2,  num3,  num4,
280  
        num1,  num2,  num3,  num4,
261  
        num5,  num6,  num7,  num8,
281  
        num5,  num6,  num7,  num8,
262  
        exp1,  exp2,  exp3,
282  
        exp1,  exp2,  exp3,
263  
        val1,  val2, val3
283  
        val1,  val2, val3
264  
    };
284  
    };
265  

285  

266  
    struct number
286  
    struct number
267  
    {
287  
    {
268  
        uint64_t mant;
288  
        uint64_t mant;
269  
        int bias;
289  
        int bias;
270  
        int exp;
290  
        int exp;
271  
        bool frac;
291  
        bool frac;
272  
        bool neg;
292  
        bool neg;
273  
    };
293  
    };
274  

294  

275  
    template< bool StackEmpty_, char First_ >
295  
    template< bool StackEmpty_, char First_ >
276  
    struct parse_number_helper;
296  
    struct parse_number_helper;
277  

297  

278  
    // optimization: must come first
298  
    // optimization: must come first
279  
    Handler h_;
299  
    Handler h_;
280  

300  

281  
    number num_;
301  
    number num_;
282  
    system::error_code ec_;
302  
    system::error_code ec_;
283  
    detail::stack st_;
303  
    detail::stack st_;
284  
    detail::utf8_sequence seq_;
304  
    detail::utf8_sequence seq_;
285  
    unsigned u1_;
305  
    unsigned u1_;
286  
    unsigned u2_;
306  
    unsigned u2_;
287  
    bool more_; // false for final buffer
307  
    bool more_; // false for final buffer
288  
    bool done_ = false; // true on complete parse
308  
    bool done_ = false; // true on complete parse
289  
    bool clean_ = true; // write_some exited cleanly
309  
    bool clean_ = true; // write_some exited cleanly
290  
    const char* end_;
310  
    const char* end_;
291  
    detail::sbo_buffer<16 + 16 + 1 + 1> num_buf_;
311  
    detail::sbo_buffer<16 + 16 + 1 + 1> num_buf_;
292  
    parse_options opt_;
312  
    parse_options opt_;
293  
    // how many levels deeper the parser can go
313  
    // how many levels deeper the parser can go
294  
    std::size_t depth_ = opt_.max_depth;
314  
    std::size_t depth_ = opt_.max_depth;
295  
    unsigned char cur_lit_ = 0;
315  
    unsigned char cur_lit_ = 0;
296  
    unsigned char lit_offset_ = 0;
316  
    unsigned char lit_offset_ = 0;
297  

317  

298  
    inline void reserve();
318  
    inline void reserve();
299  
    inline const char* sentinel();
319  
    inline const char* sentinel();
300  
    inline bool incomplete(
320  
    inline bool incomplete(
301  
        const detail::const_stream_wrapper& cs);
321  
        const detail::const_stream_wrapper& cs);
302  

322  

303  
#ifdef __INTEL_COMPILER
323  
#ifdef __INTEL_COMPILER
304  
#pragma warning push
324  
#pragma warning push
305  
#pragma warning disable 2196
325  
#pragma warning disable 2196
306  
#endif
326  
#endif
307  

327  

308  
    BOOST_NOINLINE
328  
    BOOST_NOINLINE
309  
    inline
329  
    inline
310  
    const char*
330  
    const char*
311  
    suspend_or_fail(state st);
331  
    suspend_or_fail(state st);
312  

332  

313  
    BOOST_NOINLINE
333  
    BOOST_NOINLINE
314  
    inline
334  
    inline
315  
    const char*
335  
    const char*
316  
    suspend_or_fail(
336  
    suspend_or_fail(
317  
        state st,
337  
        state st,
318  
        std::size_t n);
338  
        std::size_t n);
319  

339  

320  
    BOOST_NOINLINE
340  
    BOOST_NOINLINE
321  
    inline
341  
    inline
322  
    const char*
342  
    const char*
323  
    fail(const char* p) noexcept;
343  
    fail(const char* p) noexcept;
324  

344  

325  
    BOOST_NOINLINE
345  
    BOOST_NOINLINE
326  
    inline
346  
    inline
327  
    const char*
347  
    const char*
328  
    fail(
348  
    fail(
329  
        const char* p,
349  
        const char* p,
330  
        error ev,
350  
        error ev,
331  
        source_location const* loc) noexcept;
351  
        source_location const* loc) noexcept;
332  

352  

333  
    BOOST_NOINLINE
353  
    BOOST_NOINLINE
334  
    inline
354  
    inline
335  
    const char*
355  
    const char*
336  
    maybe_suspend(
356  
    maybe_suspend(
337  
        const char* p,
357  
        const char* p,
338  
        state st);
358  
        state st);
339  

359  

340  
    BOOST_NOINLINE
360  
    BOOST_NOINLINE
341  
    inline
361  
    inline
342  
    const char*
362  
    const char*
343  
    maybe_suspend(
363  
    maybe_suspend(
344  
        const char* p,
364  
        const char* p,
345  
        state st,
365  
        state st,
346  
        std::size_t n);
366  
        std::size_t n);
347  

367  

348  
    BOOST_NOINLINE
368  
    BOOST_NOINLINE
349  
    inline
369  
    inline
350  
    const char*
370  
    const char*
351  
    maybe_suspend(
371  
    maybe_suspend(
352  
        const char* p,
372  
        const char* p,
353  
        state st,
373  
        state st,
354  
        const number& num);
374  
        const number& num);
355  

375  

356  
    BOOST_NOINLINE
376  
    BOOST_NOINLINE
357  
    inline
377  
    inline
358  
    const char*
378  
    const char*
359  
    suspend(
379  
    suspend(
360  
        const char* p,
380  
        const char* p,
361  
        state st);
381  
        state st);
362  

382  

363  
    BOOST_NOINLINE
383  
    BOOST_NOINLINE
364  
    inline
384  
    inline
365  
    const char*
385  
    const char*
366  
    suspend(
386  
    suspend(
367  
        const char* p,
387  
        const char* p,
368  
        state st,
388  
        state st,
369  
        const number& num);
389  
        const number& num);
370  

390  

371  
#ifdef __INTEL_COMPILER
391  
#ifdef __INTEL_COMPILER
372  
#pragma warning pop
392  
#pragma warning pop
373  
#endif
393  
#endif
374  

394  

375  
    template<bool StackEmpty_/*, bool Terminal_*/>
395  
    template<bool StackEmpty_/*, bool Terminal_*/>
376  
    const char* parse_comment(const char* p,
396  
    const char* parse_comment(const char* p,
377  
        std::integral_constant<bool, StackEmpty_> stack_empty,
397  
        std::integral_constant<bool, StackEmpty_> stack_empty,
378  
        /*std::integral_constant<bool, Terminal_>*/ bool terminal);
398  
        /*std::integral_constant<bool, Terminal_>*/ bool terminal);
379  

399  

380  
    template<bool StackEmpty_>
400  
    template<bool StackEmpty_>
381  
    const char* parse_document(const char* p,
401  
    const char* parse_document(const char* p,
382  
        std::integral_constant<bool, StackEmpty_> stack_empty);
402  
        std::integral_constant<bool, StackEmpty_> stack_empty);
383  

403  

384  
    template<bool StackEmpty_, bool AllowComments_/*,
404  
    template<bool StackEmpty_, bool AllowComments_/*,
385  
        bool AllowTrailing_, bool AllowBadUTF8_*/>
405  
        bool AllowTrailing_, bool AllowBadUTF8_*/>
386  
    const char* parse_value(const char* p,
406  
    const char* parse_value(const char* p,
387  
        std::integral_constant<bool, StackEmpty_> stack_empty,
407  
        std::integral_constant<bool, StackEmpty_> stack_empty,
388  
        std::integral_constant<bool, AllowComments_> allow_comments,
408  
        std::integral_constant<bool, AllowComments_> allow_comments,
389  
        /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
409  
        /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
390  
        /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
410  
        /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
391  
        bool allow_bad_utf16);
411  
        bool allow_bad_utf16);
392  

412  

393  
    template<bool AllowComments_/*,
413  
    template<bool AllowComments_/*,
394  
        bool AllowTrailing_, bool AllowBadUTF8_*/>
414  
        bool AllowTrailing_, bool AllowBadUTF8_*/>
395  
    const char* resume_value(const char* p,
415  
    const char* resume_value(const char* p,
396  
        std::integral_constant<bool, AllowComments_> allow_comments,
416  
        std::integral_constant<bool, AllowComments_> allow_comments,
397  
        /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
417  
        /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
398  
        /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
418  
        /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
399  
        bool allow_bad_utf16);
419  
        bool allow_bad_utf16);
400  

420  

401  
    template<bool StackEmpty_, bool AllowComments_/*,
421  
    template<bool StackEmpty_, bool AllowComments_/*,
402  
        bool AllowTrailing_, bool AllowBadUTF8_*/>
422  
        bool AllowTrailing_, bool AllowBadUTF8_*/>
403  
    const char* parse_object(const char* p,
423  
    const char* parse_object(const char* p,
404  
        std::integral_constant<bool, StackEmpty_> stack_empty,
424  
        std::integral_constant<bool, StackEmpty_> stack_empty,
405  
        std::integral_constant<bool, AllowComments_> allow_comments,
425  
        std::integral_constant<bool, AllowComments_> allow_comments,
406  
        /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
426  
        /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
407  
        /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
427  
        /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
408  
        bool allow_bad_utf16);
428  
        bool allow_bad_utf16);
409  

429  

410  
    template<bool StackEmpty_, bool AllowComments_/*,
430  
    template<bool StackEmpty_, bool AllowComments_/*,
411  
        bool AllowTrailing_, bool AllowBadUTF8_*/>
431  
        bool AllowTrailing_, bool AllowBadUTF8_*/>
412  
    const char* parse_array(const char* p,
432  
    const char* parse_array(const char* p,
413  
        std::integral_constant<bool, StackEmpty_> stack_empty,
433  
        std::integral_constant<bool, StackEmpty_> stack_empty,
414  
        std::integral_constant<bool, AllowComments_> allow_comments,
434  
        std::integral_constant<bool, AllowComments_> allow_comments,
415  
        /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
435  
        /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
416  
        /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
436  
        /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
417  
        bool allow_bad_utf16);
437  
        bool allow_bad_utf16);
418  

438  

419  
    template<class Literal>
439  
    template<class Literal>
420  
    const char* parse_literal(const char* p, Literal literal);
440  
    const char* parse_literal(const char* p, Literal literal);
421  

441  

422  
    template<bool StackEmpty_, bool IsKey_>
442  
    template<bool StackEmpty_, bool IsKey_>
423  
    const char* parse_string(const char* p,
443  
    const char* parse_string(const char* p,
424  
        std::integral_constant<bool, StackEmpty_> stack_empty,
444  
        std::integral_constant<bool, StackEmpty_> stack_empty,
425  
        std::integral_constant<bool, IsKey_> is_key,
445  
        std::integral_constant<bool, IsKey_> is_key,
426  
        bool allow_bad_utf8,
446  
        bool allow_bad_utf8,
427  
        bool allow_bad_utf16);
447  
        bool allow_bad_utf16);
428  

448  

429  
    template<bool StackEmpty_>
449  
    template<bool StackEmpty_>
430  
    const char* parse_escaped(
450  
    const char* parse_escaped(
431  
        const char* p,
451  
        const char* p,
432  
        std::size_t& total,
452  
        std::size_t& total,
433  
        std::integral_constant<bool, StackEmpty_> stack_empty,
453  
        std::integral_constant<bool, StackEmpty_> stack_empty,
434  
        bool is_key,
454  
        bool is_key,
435  
        bool allow_bad_utf16);
455  
        bool allow_bad_utf16);
436  

456  

437  
    template<bool StackEmpty_, char First_, number_precision Numbers_>
457  
    template<bool StackEmpty_, char First_, number_precision Numbers_>
438  
    const char* parse_number(const char* p,
458  
    const char* parse_number(const char* p,
439  
        std::integral_constant<bool, StackEmpty_> stack_empty,
459  
        std::integral_constant<bool, StackEmpty_> stack_empty,
440  
        std::integral_constant<char, First_> first,
460  
        std::integral_constant<char, First_> first,
441  
        std::integral_constant<number_precision, Numbers_> numbers);
461  
        std::integral_constant<number_precision, Numbers_> numbers);
442  

462  

443  
    // intentionally private
463  
    // intentionally private
444  
    std::size_t
464  
    std::size_t
445  
    depth() const noexcept
465  
    depth() const noexcept
446  
    {
466  
    {
447  
        return opt_.max_depth - depth_;
467  
        return opt_.max_depth - depth_;
448  
    }
468  
    }
449  

469  

450  
public:
470  
public:
 
471 +
    /// Copy constructor (deleted)
 
472 +
    basic_parser(
 
473 +
        basic_parser const&) = delete;
 
474 +

 
475 +
    /// Copy assignment (deleted)
 
476 +
    basic_parser& operator=(
 
477 +
        basic_parser const&) = delete;
 
478 +

451  
    /** Destructor.
479  
    /** Destructor.
452  

480  

453  
        All dynamically allocated internal memory is freed.
481  
        All dynamically allocated internal memory is freed.
454  

482  

455  
        @par Effects
483  
        @par Effects
456  
        @code
484  
        @code
457 -
        handler().~Handler()
485 +
        this->handler().~Handler()
458  
        @endcode
486  
        @endcode
459  

487  

460  
        @par Complexity
488  
        @par Complexity
461  
        Same as `~Handler()`.
489  
        Same as `~Handler()`.
462  

490  

463  
        @par Exception Safety
491  
        @par Exception Safety
464  
        Same as `~Handler()`.
492  
        Same as `~Handler()`.
465  
    */
493  
    */
466  
    ~basic_parser() = default;
494  
    ~basic_parser() = default;
467  

495  

468 -
    /** Constructors.
496 +
    /** Constructor.
469 -

 
470 -
        Overload **(1)** constructs the parser with the specified options, with
 
471 -
        any additional arguments forwarded to the handler's constructor.
 
472  

497  

473 -
        `basic_parser` is not copyable or movable, so the copy constructor is
498 +
        This function constructs the parser with
474 -
        deleted.
499 +
        the specified options, with any additional
 
500 +
        arguments forwarded to the handler's constructor.
475  

501  

476  
        @par Complexity
502  
        @par Complexity
477  
        Same as `Handler( std::forward< Args >( args )... )`.
503  
        Same as `Handler( std::forward< Args >( args )... )`.
478  

504  

479  
        @par Exception Safety
505  
        @par Exception Safety
480  
        Same as `Handler( std::forward< Args >( args )... )`.
506  
        Same as `Handler( std::forward< Args >( args )... )`.
481  

507  

482 -
        @param opt Configuration settings for the parser. If this structure is
508 +
        @param opt Configuration settings for the parser.
483 -
               default constructed, the parser will accept only standard JSON.
509 +
        If this structure is default constructed, the
484 -
        @param args Optional additional arguments forwarded to the handler's
510 +
        parser will accept only standard JSON.
485 -
               constructor.
 
486  

511  

487 -
        @{
512 +
        @param args Optional additional arguments
 
513 +
        forwarded to the handler's constructor.
488  
    */
514  
    */
489  
    template<class... Args>
515  
    template<class... Args>
490  
    explicit
516  
    explicit
491  
    basic_parser(
517  
    basic_parser(
492  
        parse_options const& opt,
518  
        parse_options const& opt,
493  
        Args&&... args);
519  
        Args&&... args);
494 -
    /// Overload
 
495 -
    basic_parser(
 
496 -
        basic_parser const&) = delete;
 
497 -
    /// @}
 
498 -

 
499 -
    /** Assignment.
 
500 -

 
501 -
        This type cannot be copied or moved. The copy assignment is deleted.
 
502 -
    */
 
503 -
    basic_parser& operator=(
 
504 -
        basic_parser const&) = delete;
 
505 -

 
506  

520  

507  
    /** Return a reference to the handler.
521  
    /** Return a reference to the handler.
508  

522  

509  
        This function provides access to the constructed
523  
        This function provides access to the constructed
510  
        instance of the handler owned by the parser.
524  
        instance of the handler owned by the parser.
511  

525  

512  
        @par Complexity
526  
        @par Complexity
513  
        Constant.
527  
        Constant.
514  

528  

515  
        @par Exception Safety
529  
        @par Exception Safety
516 -

 
517 -
        @{
 
518  
        No-throw guarantee.
530  
        No-throw guarantee.
519  
    */
531  
    */
520  
    Handler&
532  
    Handler&
521  
    handler() noexcept
533  
    handler() noexcept
522  
    {
534  
    {
523  
        return h_;
535  
        return h_;
524  
    }
536  
    }
525  

537  

 
538 +
    /** Return a reference to the handler.
 
539 +

 
540 +
        This function provides access to the constructed
 
541 +
        instance of the handler owned by the parser.
 
542 +

 
543 +
        @par Complexity
 
544 +
        Constant.
 
545 +

 
546 +
        @par Exception Safety
 
547 +
        No-throw guarantee.
 
548 +
    */
526  
    Handler const&
549  
    Handler const&
527  
    handler() const noexcept
550  
    handler() const noexcept
528  
    {
551  
    {
529  
        return h_;
552  
        return h_;
530 -
    /// @}
 
531  
    }
553  
    }
532  

554  

533  
    /** Return the last error.
555  
    /** Return the last error.
534  

556  

535  
        This returns the last error code which
557  
        This returns the last error code which
536  
        was generated in the most recent call
558  
        was generated in the most recent call
537  
        to @ref write_some.
559  
        to @ref write_some.
538  

560  

539  
        @par Complexity
561  
        @par Complexity
540  
        Constant.
562  
        Constant.
541  

563  

542  
        @par Exception Safety
564  
        @par Exception Safety
543  
        No-throw guarantee.
565  
        No-throw guarantee.
544  
    */
566  
    */
545  
    system::error_code
567  
    system::error_code
546  
    last_error() const noexcept
568  
    last_error() const noexcept
547  
    {
569  
    {
548  
        return ec_;
570  
        return ec_;
549  
    }
571  
    }
550  

572  

551 -
    /** Check if a complete JSON text has been parsed.
573 +
    /** Return true if a complete JSON has been parsed.
552  

574  

553 -
        This function returns `true` when all of these conditions are met:
575 +
        This function returns `true` when all of these
 
576 +
        conditions are met:
554  

577  

555 -
        @li A complete serialized JSON text has been presented to the parser,
578 +
        @li A complete serialized JSON has been
556 -
            and
579 +
            presented to the parser, and
557 -
        @li No error or exception has occurred since the parser was
580 +

558 -
            constructed, or since the last call to @ref reset.
581 +
        @li No error or exception has occurred since the
 
582 +
            parser was constructed, or since the last call
 
583 +
            to @ref reset,
559  

584  

560  
        @par Complexity
585  
        @par Complexity
561  
        Constant.
586  
        Constant.
562  

587  

563  
        @par Exception Safety
588  
        @par Exception Safety
564  
        No-throw guarantee.
589  
        No-throw guarantee.
565  
    */
590  
    */
566  
    bool
591  
    bool
567  
    done() const noexcept
592  
    done() const noexcept
568  
    {
593  
    {
569  
        return done_;
594  
        return done_;
570  
    }
595  
    }
571  

596  

572  
    /** Reset the state, to parse a new document.
597  
    /** Reset the state, to parse a new document.
573  

598  

574  
        This function discards the current parsing
599  
        This function discards the current parsing
575  
        state, to prepare for parsing a new document.
600  
        state, to prepare for parsing a new document.
576  
        Dynamically allocated temporary memory used
601  
        Dynamically allocated temporary memory used
577  
        by the implementation is not deallocated.
602  
        by the implementation is not deallocated.
578  

603  

579  
        @par Complexity
604  
        @par Complexity
580  
        Constant.
605  
        Constant.
581  

606  

582  
        @par Exception Safety
607  
        @par Exception Safety
583  
        No-throw guarantee.
608  
        No-throw guarantee.
584  
    */
609  
    */
585  
    void
610  
    void
586  
    reset() noexcept;
611  
    reset() noexcept;
587  

612  

588  
    /** Indicate a parsing failure.
613  
    /** Indicate a parsing failure.
589  

614  

590 -
        This changes the state of the parser to indicate that the parse has
615 +
        This changes the state of the parser to indicate
591 -
        failed. A parser implementation can use this to fail the parser if
616 +
        that the parse has failed. A parser implementation
592 -
        needed due to external inputs.
617 +
        can use this to fail the parser if needed due to
 
618 +
        external inputs.
593  

619  

594 -
        @attention
620 +
        @note
595 -
        If `! ec.failed()`, an implementation-defined error code that indicates
621 +

596 -
        failure will be stored instead.
622 +
        If `!ec`, the stored error code is unspecified.
597  

623  

598  
        @par Complexity
624  
        @par Complexity
599  
        Constant.
625  
        Constant.
600  

626  

601  
        @par Exception Safety
627  
        @par Exception Safety
602  
        No-throw guarantee.
628  
        No-throw guarantee.
603  

629  

604 -
        @param ec The error code to set.
630 +
        @param ec The error code to set. If the code does
 
631 +
        not indicate failure, an implementation-defined
 
632 +
        error code that indicates failure will be stored
 
633 +
        instead.
605  
    */
634  
    */
606  
    void
635  
    void
607  
    fail(system::error_code ec) noexcept;
636  
    fail(system::error_code ec) noexcept;
608  

637  

609 -
    /** Parse some of input characters as JSON, incrementally.
638 +
    /** Parse some of an input string as JSON, incrementally.
610  

639  

611 -
        This function parses the JSON text in the specified buffer, calling the
640 +
        This function parses the JSON in the specified
612 -
        handler to emit each SAX parsing event. The parse proceeds from the
641 +
        buffer, calling the handler to emit each SAX
613 -
        current state, which is at the beginning of a new JSON or in the middle
642 +
        parsing event. The parse proceeds from the
614 -
        of the current JSON if any characters were already parsed.
643 +
        current state, which is at the beginning of a
 
644 +
        new JSON or in the middle of the current JSON
 
645 +
        if any characters were already parsed.
 
646 +
    \n
 
647 +
        The characters in the buffer are processed
 
648 +
        starting from the beginning, until one of the
 
649 +
        following conditions is met:
615  

650  

616 -
        The characters in the buffer are processed starting from the beginning,
651 +
        @li All of the characters in the buffer
617 -
        until one of the following conditions is met:
652 +
        have been parsed, or
 
653 +

 
654 +
        @li Some of the characters in the buffer
 
655 +
        have been parsed and the JSON is complete, or
618 -
        @li All of the characters in the buffer have been parsed, or
 
619 -
        @li Some of the characters in the buffer have been parsed and the JSON
 
620 -
            is complete, or
 
621  

656  

622  
        @li A parsing error occurs.
657  
        @li A parsing error occurs.
623  

658  

624 -
        The supplied buffer does not need to contain the entire JSON.
659 +
        The supplied buffer does not need to contain the
625 -
        Subsequent calls can provide more serialized data, allowing JSON to be
660 +
        entire JSON. Subsequent calls can provide more
626 -
        processed incrementally. The end of the serialized JSON can be
661 +
        serialized data, allowing JSON to be processed
627 -
        indicated by passing `more = false`.
662 +
        incrementally. The end of the serialized JSON
 
663 +
        can be indicated by passing `more = false`.
628  

664  

629  
        @par Complexity
665  
        @par Complexity
630  
        Linear in `size`.
666  
        Linear in `size`.
631  

667  

632  
        @par Exception Safety
668  
        @par Exception Safety
633 -
        Basic guarantee. Calls to the handler may throw.
669 +
        Basic guarantee.
634 -

670 +
        Calls to the handler may throw.
635 -
        Upon error or exception, subsequent calls will fail until @ref reset
671 +
        Upon error or exception, subsequent calls will
636 -
        is called to parse a new JSON.
672 +
        fail until @ref reset is called to parse a new JSON.
637  

673  

638  
        @return The number of characters successfully
674  
        @return The number of characters successfully
639  
        parsed, which may be smaller than `size`.
675  
        parsed, which may be smaller than `size`.
640  

676  

641 -
        @param more `true` if there are possibly more buffers in the current
677 +
        @param more `true` if there are possibly more
642 -
               JSON, otherwise `false`.
678 +
        buffers in the current JSON, otherwise `false`.
643  

679  

644 -
        @param data A pointer to a buffer of `size` characters to parse.
680 +
        @param data A pointer to a buffer of `size`
 
681 +
        characters to parse.
645  

682  

646 -
        @param size The number of characters pointed to by `data`.
683 +
        @param size The number of characters pointed to
 
684 +
        by `data`.
647  

685  

648 -

 
649 -
        @{
 
650  
        @param ec Set to the error, if any occurred.
686  
        @param ec Set to the error, if any occurred.
651  
    */
687  
    */
 
688 +
    /** @{ */
652  
    std::size_t
689  
    std::size_t
653  
    write_some(
690  
    write_some(
654  
        bool more,
691  
        bool more,
655  
        char const* data,
692  
        char const* data,
656  
        std::size_t size,
693  
        std::size_t size,
657  
        system::error_code& ec);
694  
        system::error_code& ec);
658  

695  

659  
    std::size_t
696  
    std::size_t
660  
    write_some(
697  
    write_some(
661  
        bool more,
698  
        bool more,
662  
        char const* data,
699  
        char const* data,
663  
        std::size_t size,
700  
        std::size_t size,
664  
        std::error_code& ec);
701  
        std::error_code& ec);
665 -
    /// @}
702 +
    /** @} */
666  
};
703  
};
667  

704  

668  
} // namespace json
705  
} // namespace json
669  
} // namespace boost
706  
} // namespace boost
670  

707  

671  
#endif
708  
#endif