100.00% Lines (11/11) 100.00% Functions (6/6)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3   // 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 caller-supplied handler with
30   each parsing event. To use, first declare a variable of type 30   each parsing event. To use, first declare a variable of type
31   `basic_parser<T>` where `T` meets the handler requirements specified below. 31   `basic_parser<T>` where `T` meets the handler requirements specified below.
32   Then call @ref write_some one or more times with the input, setting 32   Then call @ref write_some one or more times with the input, setting
33   `more = false` on the final buffer. The parsing events are realized through 33   `more = false` on the final buffer. The parsing events are realized through
34   member function calls on the handler, which exists as a data member of the 34   member function calls on the handler, which exists as a data member of the
35   parser. 35   parser.
36   36  
37   The parser may dynamically allocate intermediate storage as needed to 37   The parser may dynamically allocate intermediate storage as needed to
38   accommodate the nesting level of the input JSON. On subsequent invocations, 38   accommodate the nesting level of the input JSON. On subsequent invocations,
39   the parser can cheaply re-use this memory, improving performance. This 39   the parser can cheaply re-use this memory, improving performance. This
40   storage is freed when the parser is destroyed 40   storage is freed when the parser is destroyed
41   41  
42   @par Usage 42   @par Usage
43   To get the declaration and function definitions for this class it is 43   To get the declaration and function definitions for this class it is
44   necessary to include this file instead: 44   necessary to include this file instead:
45   @code 45   @code
46   #include <boost/json/basic_parser_impl.hpp> 46   #include <boost/json/basic_parser_impl.hpp>
47   @endcode 47   @endcode
48   48  
49   Users who wish to parse JSON into the DOM container @ref value will not use 49   Users who wish to parse JSON into the DOM container @ref value will not use
50   this class directly; instead they will create an instance of @ref parser or 50   this class directly; instead they will create an instance of @ref parser or
51   @ref stream_parser and use that instead. Alternatively, they may call the 51   @ref stream_parser and use that instead. Alternatively, they may call the
52   function @ref parse. This class is designed for users who wish to perform 52   function @ref parse. This class is designed for users who wish to perform
53   custom actions instead of building a @ref value. For example, to produce a 53   custom actions instead of building a @ref value. For example, to produce a
54   DOM from an external library. 54   DOM from an external library.
55   55  
56   @note 56   @note
57   By default, only conforming JSON using UTF-8 encoding is accepted. However, 57   By default, only conforming JSON using UTF-8 encoding is accepted. However,
58   select non-compliant syntax can be allowed by construction using a 58   select non-compliant syntax can be allowed by construction using a
59   @ref parse_options set to desired values. 59   @ref parse_options set to desired values.
60   60  
61   @par Handler 61   @par Handler
62   The handler provided must be implemented as an object of class type which 62   The handler provided must be implemented as an object of class type which
63   defines each of the required event member functions below. The event 63   defines each of the required event member functions below. The event
64   functions return a `bool` where `true` indicates success, and `false` 64   functions return a `bool` where `true` indicates success, and `false`
65   indicates failure. If the member function returns `false`, it must set the 65   indicates failure. If the member function returns `false`, it must set the
66   error code to a suitable value. This error code will be returned by the 66   error code to a suitable value. This error code will be returned by the
67   write function to the caller. 67   write function to the caller.
68   68  
69   Handlers are required to declare the maximum limits on various elements. If 69   Handlers are required to declare the maximum limits on various elements. If
70   these limits are exceeded during parsing, then parsing fails with an error. 70   these limits are exceeded during parsing, then parsing fails with an error.
71   71  
72   The following declaration meets the parser's handler requirements: 72   The following declaration meets the parser's handler requirements:
73   73  
74   @code 74   @code
75   struct handler 75   struct handler
76   { 76   {
77   /// The maximum number of elements allowed in an array 77   /// The maximum number of elements allowed in an array
78   static constexpr std::size_t max_array_size = -1; 78   static constexpr std::size_t max_array_size = -1;
79   79  
80   /// The maximum number of elements allowed in an object 80   /// The maximum number of elements allowed in an object
81   static constexpr std::size_t max_object_size = -1; 81   static constexpr std::size_t max_object_size = -1;
82   82  
83   /// The maximum number of characters allowed in a string 83   /// The maximum number of characters allowed in a string
84   static constexpr std::size_t max_string_size = -1; 84   static constexpr std::size_t max_string_size = -1;
85   85  
86   /// The maximum number of characters allowed in a key 86   /// The maximum number of characters allowed in a key
87   static constexpr std::size_t max_key_size = -1; 87   static constexpr std::size_t max_key_size = -1;
88   88  
89   /// Called once when the JSON parsing begins. 89   /// Called once when the JSON parsing begins.
90   /// 90   ///
91   /// @return `true` on success. 91   /// @return `true` on success.
92   /// @param ec Set to the error, if any occurred. 92   /// @param ec Set to the error, if any occurred.
93   /// 93   ///
94   bool on_document_begin( error_code& ec ); 94   bool on_document_begin( error_code& ec );
95   95  
96   /// Called when the JSON parsing is done. 96   /// Called when the JSON parsing is done.
97   /// 97   ///
98   /// @return `true` on success. 98   /// @return `true` on success.
99   /// @param ec Set to the error, if any occurred. 99   /// @param ec Set to the error, if any occurred.
100   /// 100   ///
101   bool on_document_end( error_code& ec ); 101   bool on_document_end( error_code& ec );
102   102  
103   /// Called when the beginning of an array is encountered. 103   /// Called when the beginning of an array is encountered.
104   /// 104   ///
105   /// @return `true` on success. 105   /// @return `true` on success.
106   /// @param ec Set to the error, if any occurred. 106   /// @param ec Set to the error, if any occurred.
107   /// 107   ///
108   bool on_array_begin( error_code& ec ); 108   bool on_array_begin( error_code& ec );
109   109  
110   /// Called when the end of the current array is encountered. 110   /// Called when the end of the current array is encountered.
111   /// 111   ///
112   /// @return `true` on success. 112   /// @return `true` on success.
113   /// @param n The number of elements in the array. 113   /// @param n The number of elements in the array.
114   /// @param ec Set to the error, if any occurred. 114   /// @param ec Set to the error, if any occurred.
115   /// 115   ///
116   bool on_array_end( std::size_t n, error_code& ec ); 116   bool on_array_end( std::size_t n, error_code& ec );
117   117  
118   /// Called when the beginning of an object is encountered. 118   /// Called when the beginning of an object is encountered.
119   /// 119   ///
120   /// @return `true` on success. 120   /// @return `true` on success.
121   /// @param ec Set to the error, if any occurred. 121   /// @param ec Set to the error, if any occurred.
122   /// 122   ///
123   bool on_object_begin( error_code& ec ); 123   bool on_object_begin( error_code& ec );
124   124  
125   /// Called when the end of the current object is encountered. 125   /// Called when the end of the current object is encountered.
126   /// 126   ///
127   /// @return `true` on success. 127   /// @return `true` on success.
128   /// @param n The number of elements in the object. 128   /// @param n The number of elements in the object.
129   /// @param ec Set to the error, if any occurred. 129   /// @param ec Set to the error, if any occurred.
130   /// 130   ///
131   bool on_object_end( std::size_t n, error_code& ec ); 131   bool on_object_end( std::size_t n, error_code& ec );
132   132  
133   /// Called with characters corresponding to part of the current string. 133   /// Called with characters corresponding to part of the current string.
134   /// 134   ///
135   /// @return `true` on success. 135   /// @return `true` on success.
136   /// @param s The partial characters 136   /// @param s The partial characters
137   /// @param n The total size of the string thus far 137   /// @param n The total size of the string thus far
138   /// @param ec Set to the error, if any occurred. 138   /// @param ec Set to the error, if any occurred.
139   /// 139   ///
140   bool on_string_part( string_view s, std::size_t n, error_code& ec ); 140   bool on_string_part( string_view s, std::size_t n, error_code& ec );
141   141  
142   /// Called with the last characters corresponding to the current string. 142   /// Called with the last characters corresponding to the current string.
143   /// 143   ///
144   /// @return `true` on success. 144   /// @return `true` on success.
145   /// @param s The remaining characters 145   /// @param s The remaining characters
146   /// @param n The total size of the string 146   /// @param n The total size of the string
147   /// @param ec Set to the error, if any occurred. 147   /// @param ec Set to the error, if any occurred.
148   /// 148   ///
149   bool on_string( string_view s, std::size_t n, error_code& ec ); 149   bool on_string( string_view s, std::size_t n, error_code& ec );
150   150  
151   /// Called with characters corresponding to part of the current key. 151   /// Called with characters corresponding to part of the current key.
152   /// 152   ///
153   /// @return `true` on success. 153   /// @return `true` on success.
154   /// @param s The partial characters 154   /// @param s The partial characters
155   /// @param n The total size of the key thus far 155   /// @param n The total size of the key thus far
156   /// @param ec Set to the error, if any occurred. 156   /// @param ec Set to the error, if any occurred.
157   /// 157   ///
158   bool on_key_part( string_view s, std::size_t n, error_code& ec ); 158   bool on_key_part( string_view s, std::size_t n, error_code& ec );
159   159  
160   /// Called with the last characters corresponding to the current key. 160   /// Called with the last characters corresponding to the current key.
161   /// 161   ///
162   /// @return `true` on success. 162   /// @return `true` on success.
163   /// @param s The remaining characters 163   /// @param s The remaining characters
164   /// @param n The total size of the key 164   /// @param n The total size of the key
165   /// @param ec Set to the error, if any occurred. 165   /// @param ec Set to the error, if any occurred.
166   /// 166   ///
167   bool on_key( string_view s, std::size_t n, error_code& ec ); 167   bool on_key( string_view s, std::size_t n, error_code& ec );
168   168  
169   /// Called with the characters corresponding to part of the current number. 169   /// Called with the characters corresponding to part of the current number.
170   /// 170   ///
171   /// @return `true` on success. 171   /// @return `true` on success.
172   /// @param s The partial characters 172   /// @param s The partial characters
173   /// @param ec Set to the error, if any occurred. 173   /// @param ec Set to the error, if any occurred.
174   /// 174   ///
175   bool on_number_part( string_view s, error_code& ec ); 175   bool on_number_part( string_view s, error_code& ec );
176   176  
177   /// Called when a signed integer is parsed. 177   /// Called when a signed integer is parsed.
178   /// 178   ///
179   /// @return `true` on success. 179   /// @return `true` on success.
180   /// @param i The value 180   /// @param i The value
181   /// @param s The remaining characters 181   /// @param s The remaining characters
182   /// @param ec Set to the error, if any occurred. 182   /// @param ec Set to the error, if any occurred.
183   /// 183   ///
184   bool on_int64( int64_t i, string_view s, error_code& ec ); 184   bool on_int64( int64_t i, string_view s, error_code& ec );
185   185  
186   /// Called when an unsigend integer is parsed. 186   /// Called when an unsigend integer is parsed.
187   /// 187   ///
188   /// @return `true` on success. 188   /// @return `true` on success.
189   /// @param u The value 189   /// @param u The value
190   /// @param s The remaining characters 190   /// @param s The remaining characters
191   /// @param ec Set to the error, if any occurred. 191   /// @param ec Set to the error, if any occurred.
192   /// 192   ///
193   bool on_uint64( uint64_t u, string_view s, error_code& ec ); 193   bool on_uint64( uint64_t u, string_view s, error_code& ec );
194   194  
195   /// Called when a double is parsed. 195   /// Called when a double is parsed.
196   /// 196   ///
197   /// @return `true` on success. 197   /// @return `true` on success.
198   /// @param d The value 198   /// @param d The value
199   /// @param s The remaining characters 199   /// @param s The remaining characters
200   /// @param ec Set to the error, if any occurred. 200   /// @param ec Set to the error, if any occurred.
201   /// 201   ///
202   bool on_double( double d, string_view s, error_code& ec ); 202   bool on_double( double d, string_view s, error_code& ec );
203   203  
204   /// Called when a boolean is parsed. 204   /// Called when a boolean is parsed.
205   /// 205   ///
206   /// @return `true` on success. 206   /// @return `true` on success.
207   /// @param b The value 207   /// @param b The value
208   /// @param s The remaining characters 208   /// @param s The remaining characters
209   /// @param ec Set to the error, if any occurred. 209   /// @param ec Set to the error, if any occurred.
210   /// 210   ///
211   bool on_bool( bool b, error_code& ec ); 211   bool on_bool( bool b, error_code& ec );
212   212  
213   /// Called when a null is parsed. 213   /// Called when a null is parsed.
214   /// 214   ///
215   /// @return `true` on success. 215   /// @return `true` on success.
216   /// @param ec Set to the error, if any occurred. 216   /// @param ec Set to the error, if any occurred.
217   /// 217   ///
218   bool on_null( error_code& ec ); 218   bool on_null( error_code& ec );
219   219  
220   /// Called with characters corresponding to part of the current comment. 220   /// Called with characters corresponding to part of the current comment.
221   /// 221   ///
222   /// @return `true` on success. 222   /// @return `true` on success.
223   /// @param s The partial characters. 223   /// @param s The partial characters.
224   /// @param ec Set to the error, if any occurred. 224   /// @param ec Set to the error, if any occurred.
225   /// 225   ///
226   bool on_comment_part( string_view s, error_code& ec ); 226   bool on_comment_part( string_view s, error_code& ec );
227   227  
228   /// Called with the last characters corresponding to the current comment. 228   /// Called with the last characters corresponding to the current comment.
229   /// 229   ///
230   /// @return `true` on success. 230   /// @return `true` on success.
231   /// @param s The remaining characters 231   /// @param s The remaining characters
232   /// @param ec Set to the error, if any occurred. 232   /// @param ec Set to the error, if any occurred.
233   /// 233   ///
234   bool on_comment( string_view s, error_code& ec ); 234   bool on_comment( string_view s, error_code& ec );
235   }; 235   };
236   @endcode 236   @endcode
237   237  
238   @see 238   @see
239   @ref parse, 239   @ref parse,
240   @ref stream_parser, 240   @ref stream_parser,
241   \<\<examples_validate, validating parser example\>\>. 241   \<\<examples_validate, validating parser example\>\>.
242   */ 242   */
243   template<class Handler> 243   template<class Handler>
244   class basic_parser 244   class basic_parser
245   { 245   {
246   enum class state : char 246   enum class state : char
247   { 247   {
248   doc1, doc3, 248   doc1, doc3,
249   com1, com2, com3, com4, 249   com1, com2, com3, com4,
250   lit1, 250   lit1,
251   str1, str2, str3, str4, 251   str1, str2, str3, str4,
252   str5, str6, str7, str8, 252   str5, str6, str7, str8,
253   sur1, sur2, sur3, 253   sur1, sur2, sur3,
254   sur4, sur5, sur6, 254   sur4, sur5, sur6,
255   obj1, obj2, obj3, obj4, 255   obj1, obj2, obj3, obj4,
256   obj5, obj6, obj7, obj8, 256   obj5, obj6, obj7, obj8,
257   obj9, obj10, obj11, 257   obj9, obj10, obj11,
258   arr1, arr2, arr3, 258   arr1, arr2, arr3,
259   arr4, arr5, arr6, 259   arr4, arr5, arr6,
260   num1, num2, num3, num4, 260   num1, num2, num3, num4,
261   num5, num6, num7, num8, 261   num5, num6, num7, num8,
262   exp1, exp2, exp3, 262   exp1, exp2, exp3,
263   val1, val2, val3 263   val1, val2, val3
264   }; 264   };
265   265  
266   struct number 266   struct number
267   { 267   {
268   uint64_t mant; 268   uint64_t mant;
269   int bias; 269   int bias;
270   int exp; 270   int exp;
271   bool frac; 271   bool frac;
272   bool neg; 272   bool neg;
273   }; 273   };
274   274  
275   template< bool StackEmpty_, char First_ > 275   template< bool StackEmpty_, char First_ >
276   struct parse_number_helper; 276   struct parse_number_helper;
277   277  
278   // optimization: must come first 278   // optimization: must come first
279   Handler h_; 279   Handler h_;
280   280  
281   number num_; 281   number num_;
282   system::error_code ec_; 282   system::error_code ec_;
283   detail::stack st_; 283   detail::stack st_;
284   detail::utf8_sequence seq_; 284   detail::utf8_sequence seq_;
285   unsigned u1_; 285   unsigned u1_;
286   unsigned u2_; 286   unsigned u2_;
287   bool more_; // false for final buffer 287   bool more_; // false for final buffer
288   bool done_ = false; // true on complete parse 288   bool done_ = false; // true on complete parse
289   bool clean_ = true; // write_some exited cleanly 289   bool clean_ = true; // write_some exited cleanly
290   const char* end_; 290   const char* end_;
291   detail::sbo_buffer<16 + 16 + 1 + 1> num_buf_; 291   detail::sbo_buffer<16 + 16 + 1 + 1> num_buf_;
292   parse_options opt_; 292   parse_options opt_;
293   // how many levels deeper the parser can go 293   // how many levels deeper the parser can go
294   std::size_t depth_ = opt_.max_depth; 294   std::size_t depth_ = opt_.max_depth;
295   unsigned char cur_lit_ = 0; 295   unsigned char cur_lit_ = 0;
296   unsigned char lit_offset_ = 0; 296   unsigned char lit_offset_ = 0;
297   297  
298   inline void reserve(); 298   inline void reserve();
299   inline const char* sentinel(); 299   inline const char* sentinel();
300   inline bool incomplete( 300   inline bool incomplete(
301   const detail::const_stream_wrapper& cs); 301   const detail::const_stream_wrapper& cs);
302   302  
303   #ifdef __INTEL_COMPILER 303   #ifdef __INTEL_COMPILER
304   #pragma warning push 304   #pragma warning push
305   #pragma warning disable 2196 305   #pragma warning disable 2196
306   #endif 306   #endif
307   307  
308   BOOST_NOINLINE 308   BOOST_NOINLINE
309   inline 309   inline
310   const char* 310   const char*
311   suspend_or_fail(state st); 311   suspend_or_fail(state st);
312   312  
313   BOOST_NOINLINE 313   BOOST_NOINLINE
314   inline 314   inline
315   const char* 315   const char*
316   suspend_or_fail( 316   suspend_or_fail(
317   state st, 317   state st,
318   std::size_t n); 318   std::size_t n);
319   319  
320   BOOST_NOINLINE 320   BOOST_NOINLINE
321   inline 321   inline
322   const char* 322   const char*
323   fail(const char* p) noexcept; 323   fail(const char* p) noexcept;
324   324  
325   BOOST_NOINLINE 325   BOOST_NOINLINE
326   inline 326   inline
327   const char* 327   const char*
328   fail( 328   fail(
329   const char* p, 329   const char* p,
330   error ev, 330   error ev,
331   source_location const* loc) noexcept; 331   source_location const* loc) noexcept;
332   332  
333   BOOST_NOINLINE 333   BOOST_NOINLINE
334   inline 334   inline
335   const char* 335   const char*
336   maybe_suspend( 336   maybe_suspend(
337   const char* p, 337   const char* p,
338   state st); 338   state st);
339   339  
340   BOOST_NOINLINE 340   BOOST_NOINLINE
341   inline 341   inline
342   const char* 342   const char*
343   maybe_suspend( 343   maybe_suspend(
344   const char* p, 344   const char* p,
345   state st, 345   state st,
346   std::size_t n); 346   std::size_t n);
347   347  
348   BOOST_NOINLINE 348   BOOST_NOINLINE
349   inline 349   inline
350   const char* 350   const char*
351   maybe_suspend( 351   maybe_suspend(
352   const char* p, 352   const char* p,
353   state st, 353   state st,
354   const number& num); 354   const number& num);
355   355  
356   BOOST_NOINLINE 356   BOOST_NOINLINE
357   inline 357   inline
358   const char* 358   const char*
359   suspend( 359   suspend(
360   const char* p, 360   const char* p,
361   state st); 361   state st);
362   362  
363   BOOST_NOINLINE 363   BOOST_NOINLINE
364   inline 364   inline
365   const char* 365   const char*
366   suspend( 366   suspend(
367   const char* p, 367   const char* p,
368   state st, 368   state st,
369   const number& num); 369   const number& num);
370   370  
371   #ifdef __INTEL_COMPILER 371   #ifdef __INTEL_COMPILER
372   #pragma warning pop 372   #pragma warning pop
373   #endif 373   #endif
374   374  
375   template<bool StackEmpty_/*, bool Terminal_*/> 375   template<bool StackEmpty_/*, bool Terminal_*/>
376   const char* parse_comment(const char* p, 376   const char* parse_comment(const char* p,
377   std::integral_constant<bool, StackEmpty_> stack_empty, 377   std::integral_constant<bool, StackEmpty_> stack_empty,
378   /*std::integral_constant<bool, Terminal_>*/ bool terminal); 378   /*std::integral_constant<bool, Terminal_>*/ bool terminal);
379   379  
380   template<bool StackEmpty_> 380   template<bool StackEmpty_>
381   const char* parse_document(const char* p, 381   const char* parse_document(const char* p,
382   std::integral_constant<bool, StackEmpty_> stack_empty); 382   std::integral_constant<bool, StackEmpty_> stack_empty);
383   383  
384   template<bool StackEmpty_, bool AllowComments_/*, 384   template<bool StackEmpty_, bool AllowComments_/*,
385   bool AllowTrailing_, bool AllowBadUTF8_*/> 385   bool AllowTrailing_, bool AllowBadUTF8_*/>
386   const char* parse_value(const char* p, 386   const char* parse_value(const char* p,
387   std::integral_constant<bool, StackEmpty_> stack_empty, 387   std::integral_constant<bool, StackEmpty_> stack_empty,
388   std::integral_constant<bool, AllowComments_> allow_comments, 388   std::integral_constant<bool, AllowComments_> allow_comments,
389   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 389   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
390   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 390   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
391   bool allow_bad_utf16); 391   bool allow_bad_utf16);
392   392  
393   template<bool AllowComments_/*, 393   template<bool AllowComments_/*,
394   bool AllowTrailing_, bool AllowBadUTF8_*/> 394   bool AllowTrailing_, bool AllowBadUTF8_*/>
395   const char* resume_value(const char* p, 395   const char* resume_value(const char* p,
396   std::integral_constant<bool, AllowComments_> allow_comments, 396   std::integral_constant<bool, AllowComments_> allow_comments,
397   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 397   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
398   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 398   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
399   bool allow_bad_utf16); 399   bool allow_bad_utf16);
400   400  
401   template<bool StackEmpty_, bool AllowComments_/*, 401   template<bool StackEmpty_, bool AllowComments_/*,
402   bool AllowTrailing_, bool AllowBadUTF8_*/> 402   bool AllowTrailing_, bool AllowBadUTF8_*/>
403   const char* parse_object(const char* p, 403   const char* parse_object(const char* p,
404   std::integral_constant<bool, StackEmpty_> stack_empty, 404   std::integral_constant<bool, StackEmpty_> stack_empty,
405   std::integral_constant<bool, AllowComments_> allow_comments, 405   std::integral_constant<bool, AllowComments_> allow_comments,
406   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 406   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
407   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 407   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
408   bool allow_bad_utf16); 408   bool allow_bad_utf16);
409   409  
410   template<bool StackEmpty_, bool AllowComments_/*, 410   template<bool StackEmpty_, bool AllowComments_/*,
411   bool AllowTrailing_, bool AllowBadUTF8_*/> 411   bool AllowTrailing_, bool AllowBadUTF8_*/>
412   const char* parse_array(const char* p, 412   const char* parse_array(const char* p,
413   std::integral_constant<bool, StackEmpty_> stack_empty, 413   std::integral_constant<bool, StackEmpty_> stack_empty,
414   std::integral_constant<bool, AllowComments_> allow_comments, 414   std::integral_constant<bool, AllowComments_> allow_comments,
415   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 415   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
416   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 416   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
417   bool allow_bad_utf16); 417   bool allow_bad_utf16);
418   418  
419   template<class Literal> 419   template<class Literal>
420   const char* parse_literal(const char* p, Literal literal); 420   const char* parse_literal(const char* p, Literal literal);
421   421  
422   template<bool StackEmpty_, bool IsKey_> 422   template<bool StackEmpty_, bool IsKey_>
423   const char* parse_string(const char* p, 423   const char* parse_string(const char* p,
424   std::integral_constant<bool, StackEmpty_> stack_empty, 424   std::integral_constant<bool, StackEmpty_> stack_empty,
425   std::integral_constant<bool, IsKey_> is_key, 425   std::integral_constant<bool, IsKey_> is_key,
426   bool allow_bad_utf8, 426   bool allow_bad_utf8,
427   bool allow_bad_utf16); 427   bool allow_bad_utf16);
428   428  
429   template<bool StackEmpty_> 429   template<bool StackEmpty_>
430   const char* parse_escaped( 430   const char* parse_escaped(
431   const char* p, 431   const char* p,
432   std::size_t& total, 432   std::size_t& total,
433   std::integral_constant<bool, StackEmpty_> stack_empty, 433   std::integral_constant<bool, StackEmpty_> stack_empty,
434   bool is_key, 434   bool is_key,
435   bool allow_bad_utf16); 435   bool allow_bad_utf16);
436   436  
437   template<bool StackEmpty_, char First_, number_precision Numbers_> 437   template<bool StackEmpty_, char First_, number_precision Numbers_>
438   const char* parse_number(const char* p, 438   const char* parse_number(const char* p,
439   std::integral_constant<bool, StackEmpty_> stack_empty, 439   std::integral_constant<bool, StackEmpty_> stack_empty,
440   std::integral_constant<char, First_> first, 440   std::integral_constant<char, First_> first,
441   std::integral_constant<number_precision, Numbers_> numbers); 441   std::integral_constant<number_precision, Numbers_> numbers);
442   442  
443   // intentionally private 443   // intentionally private
444   std::size_t 444   std::size_t
HITCBC 445   173075 depth() const noexcept 445   173075 depth() const noexcept
446   { 446   {
HITCBC 447   173075 return opt_.max_depth - depth_; 447   173075 return opt_.max_depth - depth_;
448   } 448   }
449   449  
450   public: 450   public:
451   /** Destructor. 451   /** Destructor.
452   452  
453   All dynamically allocated internal memory is freed. 453   All dynamically allocated internal memory is freed.
454   454  
455   @par Effects 455   @par Effects
456   @code 456   @code
457   handler().~Handler() 457   handler().~Handler()
458   @endcode 458   @endcode
459   459  
460   @par Complexity 460   @par Complexity
461   Same as `~Handler()`. 461   Same as `~Handler()`.
462   462  
463   @par Exception Safety 463   @par Exception Safety
464   Same as `~Handler()`. 464   Same as `~Handler()`.
465   */ 465   */
HITCBC 466   2164604 ~basic_parser() = default; 466   2164604 ~basic_parser() = default;
467   467  
468   /** Constructors. 468   /** Constructors.
469   469  
470   Overload **(1)** constructs the parser with the specified options, with 470   Overload **(1)** constructs the parser with the specified options, with
471   any additional arguments forwarded to the handler's constructor. 471   any additional arguments forwarded to the handler's constructor.
472   472  
473   `basic_parser` is not copyable or movable, so the copy constructor is 473   `basic_parser` is not copyable or movable, so the copy constructor is
474   deleted. 474   deleted.
475   475  
476   @par Complexity 476   @par Complexity
477   Same as `Handler( std::forward< Args >( args )... )`. 477   Same as `Handler( std::forward< Args >( args )... )`.
478   478  
479   @par Exception Safety 479   @par Exception Safety
480   Same as `Handler( std::forward< Args >( args )... )`. 480   Same as `Handler( std::forward< Args >( args )... )`.
481   481  
482   @param opt Configuration settings for the parser. If this structure is 482   @param opt Configuration settings for the parser. If this structure is
483   default constructed, the parser will accept only standard JSON. 483   default constructed, the parser will accept only standard JSON.
484   @param args Optional additional arguments forwarded to the handler's 484   @param args Optional additional arguments forwarded to the handler's
485   constructor. 485   constructor.
486   486  
487   @{ 487   @{
488   */ 488   */
489   template<class... Args> 489   template<class... Args>
490   explicit 490   explicit
491   basic_parser( 491   basic_parser(
492   parse_options const& opt, 492   parse_options const& opt,
493   Args&&... args); 493   Args&&... args);
494   494  
495   /// Overload 495   /// Overload
496   basic_parser( 496   basic_parser(
497   basic_parser const&) = delete; 497   basic_parser const&) = delete;
498   /// @} 498   /// @}
499   499  
500   /** Assignment. 500   /** Assignment.
501   501  
502   This type cannot be copied or moved. The copy assignment is deleted. 502   This type cannot be copied or moved. The copy assignment is deleted.
503   */ 503   */
504   basic_parser& operator=( 504   basic_parser& operator=(
505   basic_parser const&) = delete; 505   basic_parser const&) = delete;
506   506  
507   /** Return a reference to the handler. 507   /** Return a reference to the handler.
508   508  
509   This function provides access to the constructed 509   This function provides access to the constructed
510   instance of the handler owned by the parser. 510   instance of the handler owned by the parser.
511   511  
512   @par Complexity 512   @par Complexity
513   Constant. 513   Constant.
514   514  
515   @par Exception Safety 515   @par Exception Safety
516   No-throw guarantee. 516   No-throw guarantee.
517   517  
518   @{ 518   @{
519   */ 519   */
520   Handler& 520   Handler&
HITCBC 521   6310634 handler() noexcept 521   6310634 handler() noexcept
522   { 522   {
HITCBC 523   6310634 return h_; 523   6310634 return h_;
524   } 524   }
525   525  
526   Handler const& 526   Handler const&
HITCBC 527   24 handler() const noexcept 527   24 handler() const noexcept
528   { 528   {
HITCBC 529   24 return h_; 529   24 return h_;
530   } 530   }
531   /// @} 531   /// @}
532   532  
533   /** Return the last error. 533   /** Return the last error.
534   534  
535   This returns the last error code which 535   This returns the last error code which
536   was generated in the most recent call 536   was generated in the most recent call
537   to @ref write_some. 537   to @ref write_some.
538   538  
539   @par Complexity 539   @par Complexity
540   Constant. 540   Constant.
541   541  
542   @par Exception Safety 542   @par Exception Safety
543   No-throw guarantee. 543   No-throw guarantee.
544   */ 544   */
545   system::error_code 545   system::error_code
HITCBC 546   8 last_error() const noexcept 546   8 last_error() const noexcept
547   { 547   {
HITCBC 548   8 return ec_; 548   8 return ec_;
549   } 549   }
550   550  
551   /** Check if a complete JSON text has been parsed. 551   /** Check if a complete JSON text has been parsed.
552   552  
553   This function returns `true` when all of these conditions are met: 553   This function returns `true` when all of these conditions are met:
554   554  
555   @li A complete serialized JSON text has been presented to the parser, 555   @li A complete serialized JSON text has been presented to the parser,
556   and 556   and
557   @li No error or exception has occurred since the parser was 557   @li No error or exception has occurred since the parser was
558   constructed, or since the last call to @ref reset. 558   constructed, or since the last call to @ref reset.
559   559  
560   @par Complexity 560   @par Complexity
561   Constant. 561   Constant.
562   562  
563   @par Exception Safety 563   @par Exception Safety
564   No-throw guarantee. 564   No-throw guarantee.
565   */ 565   */
566   bool 566   bool
HITCBC 567   4078231 done() const noexcept 567   4078231 done() const noexcept
568   { 568   {
HITCBC 569   4078231 return done_; 569   4078231 return done_;
570   } 570   }
571   571  
572   /** Reset the state, to parse a new document. 572   /** Reset the state, to parse a new document.
573   573  
574   This function discards the current parsing 574   This function discards the current parsing
575   state, to prepare for parsing a new document. 575   state, to prepare for parsing a new document.
576   Dynamically allocated temporary memory used 576   Dynamically allocated temporary memory used
577   by the implementation is not deallocated. 577   by the implementation is not deallocated.
578   578  
579   @par Complexity 579   @par Complexity
580   Constant. 580   Constant.
581   581  
582   @par Exception Safety 582   @par Exception Safety
583   No-throw guarantee. 583   No-throw guarantee.
584   */ 584   */
585   void 585   void
586   reset() noexcept; 586   reset() noexcept;
587   587  
588   /** Indicate a parsing failure. 588   /** Indicate a parsing failure.
589   589  
590   This changes the state of the parser to indicate that the parse has 590   This changes the state of the parser to indicate that the parse has
591   failed. A parser implementation can use this to fail the parser if 591   failed. A parser implementation can use this to fail the parser if
592   needed due to external inputs. 592   needed due to external inputs.
593   593  
594   @attention 594   @attention
595   If `! ec.failed()`, an implementation-defined error code that indicates 595   If `! ec.failed()`, an implementation-defined error code that indicates
596   failure will be stored instead. 596   failure will be stored instead.
597   597  
598   @par Complexity 598   @par Complexity
599   Constant. 599   Constant.
600   600  
601   @par Exception Safety 601   @par Exception Safety
602   No-throw guarantee. 602   No-throw guarantee.
603   603  
604   @param ec The error code to set. 604   @param ec The error code to set.
605   */ 605   */
606   void 606   void
607   fail(system::error_code ec) noexcept; 607   fail(system::error_code ec) noexcept;
608   608  
609   /** Parse some of input characters as JSON, incrementally. 609   /** Parse some of input characters as JSON, incrementally.
610   610  
611   This function parses the JSON text in the specified buffer, calling the 611   This function parses the JSON text in the specified buffer, calling the
612   handler to emit each SAX parsing event. The parse proceeds from the 612   handler to emit each SAX parsing event. The parse proceeds from the
613   current state, which is at the beginning of a new JSON or in the middle 613   current state, which is at the beginning of a new JSON or in the middle
614   of the current JSON if any characters were already parsed. 614   of the current JSON if any characters were already parsed.
615   615  
616   The characters in the buffer are processed starting from the beginning, 616   The characters in the buffer are processed starting from the beginning,
617   until one of the following conditions is met: 617   until one of the following conditions is met:
618   618  
619   @li All of the characters in the buffer have been parsed, or 619   @li All of the characters in the buffer have been parsed, or
620   @li Some of the characters in the buffer have been parsed and the JSON 620   @li Some of the characters in the buffer have been parsed and the JSON
621   is complete, or 621   is complete, or
622   @li A parsing error occurs. 622   @li A parsing error occurs.
623   623  
624   The supplied buffer does not need to contain the entire JSON. 624   The supplied buffer does not need to contain the entire JSON.
625   Subsequent calls can provide more serialized data, allowing JSON to be 625   Subsequent calls can provide more serialized data, allowing JSON to be
626   processed incrementally. The end of the serialized JSON can be 626   processed incrementally. The end of the serialized JSON can be
627   indicated by passing `more = false`. 627   indicated by passing `more = false`.
628   628  
629   @par Complexity 629   @par Complexity
630   Linear in `size`. 630   Linear in `size`.
631   631  
632   @par Exception Safety 632   @par Exception Safety
633   Basic guarantee. Calls to the handler may throw. 633   Basic guarantee. Calls to the handler may throw.
634   634  
635   Upon error or exception, subsequent calls will fail until @ref reset 635   Upon error or exception, subsequent calls will fail until @ref reset
636   is called to parse a new JSON. 636   is called to parse a new JSON.
637   637  
638   @return The number of characters successfully 638   @return The number of characters successfully
639   parsed, which may be smaller than `size`. 639   parsed, which may be smaller than `size`.
640   640  
641   @param more `true` if there are possibly more buffers in the current 641   @param more `true` if there are possibly more buffers in the current
642   JSON, otherwise `false`. 642   JSON, otherwise `false`.
643   643  
644   @param data A pointer to a buffer of `size` characters to parse. 644   @param data A pointer to a buffer of `size` characters to parse.
645   645  
646   @param size The number of characters pointed to by `data`. 646   @param size The number of characters pointed to by `data`.
647   647  
648   @param ec Set to the error, if any occurred. 648   @param ec Set to the error, if any occurred.
649   649  
650   @{ 650   @{
651   */ 651   */
652   std::size_t 652   std::size_t
653   write_some( 653   write_some(
654   bool more, 654   bool more,
655   char const* data, 655   char const* data,
656   std::size_t size, 656   std::size_t size,
657   system::error_code& ec); 657   system::error_code& ec);
658   658  
659   std::size_t 659   std::size_t
660   write_some( 660   write_some(
661   bool more, 661   bool more,
662   char const* data, 662   char const* data,
663   std::size_t size, 663   std::size_t size,
664   std::error_code& ec); 664   std::error_code& ec);
665   /// @} 665   /// @}
666   }; 666   };
667   667  
668   } // namespace json 668   } // namespace json
669   } // namespace boost 669   } // namespace boost
670   670  
671   #endif 671   #endif