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 ec Set to the error, if any occurred. 208   /// @param ec Set to the error, if any occurred.
209   /// 209   ///
210   bool on_bool( bool b, error_code& ec ); 210   bool on_bool( bool b, error_code& ec );
211   211  
212   /// Called when a null is parsed. 212   /// Called when a null is parsed.
213   /// 213   ///
214   /// @return `true` on success. 214   /// @return `true` on success.
215   /// @param ec Set to the error, if any occurred. 215   /// @param ec Set to the error, if any occurred.
216   /// 216   ///
217   bool on_null( error_code& ec ); 217   bool on_null( error_code& ec );
218   218  
219   /// Called with characters corresponding to part of the current comment. 219   /// Called with characters corresponding to part of the current comment.
220   /// 220   ///
221   /// @return `true` on success. 221   /// @return `true` on success.
222   /// @param s The partial characters. 222   /// @param s The partial characters.
223   /// @param ec Set to the error, if any occurred. 223   /// @param ec Set to the error, if any occurred.
224   /// 224   ///
225   bool on_comment_part( string_view s, error_code& ec ); 225   bool on_comment_part( string_view s, error_code& ec );
226   226  
227   /// Called with the last characters corresponding to the current comment. 227   /// Called with the last characters corresponding to the current comment.
228   /// 228   ///
229   /// @return `true` on success. 229   /// @return `true` on success.
230   /// @param s The remaining characters 230   /// @param s The remaining characters
231   /// @param ec Set to the error, if any occurred. 231   /// @param ec Set to the error, if any occurred.
232   /// 232   ///
233   bool on_comment( string_view s, error_code& ec ); 233   bool on_comment( string_view s, error_code& ec );
234   }; 234   };
235   @endcode 235   @endcode
236   236  
237   @see 237   @see
238   @ref parse, 238   @ref parse,
239   @ref stream_parser, 239   @ref stream_parser,
240   \<\<examples_validate, validating parser example\>\>. 240   \<\<examples_validate, validating parser example\>\>.
241   */ 241   */
242   template<class Handler> 242   template<class Handler>
243   class basic_parser 243   class basic_parser
244   { 244   {
245   enum class state : char 245   enum class state : char
246   { 246   {
247   doc1, doc3, 247   doc1, doc3,
248   com1, com2, com3, com4, 248   com1, com2, com3, com4,
249   lit1, 249   lit1,
250   str1, str2, str3, str4, 250   str1, str2, str3, str4,
251   str5, str6, str7, str8, 251   str5, str6, str7, str8,
252   sur1, sur2, sur3, 252   sur1, sur2, sur3,
253   sur4, sur5, sur6, 253   sur4, sur5, sur6,
254   obj1, obj2, obj3, obj4, 254   obj1, obj2, obj3, obj4,
255   obj5, obj6, obj7, obj8, 255   obj5, obj6, obj7, obj8,
256   obj9, obj10, obj11, 256   obj9, obj10, obj11,
257   arr1, arr2, arr3, 257   arr1, arr2, arr3,
258   arr4, arr5, arr6, 258   arr4, arr5, arr6,
259   num1, num2, num3, num4, 259   num1, num2, num3, num4,
260   num5, num6, num7, num8, 260   num5, num6, num7, num8,
261   exp1, exp2, exp3, 261   exp1, exp2, exp3,
262   val1, val2, val3 262   val1, val2, val3
263   }; 263   };
264   264  
265   struct number 265   struct number
266   { 266   {
267   uint64_t mant; 267   uint64_t mant;
268   int bias; 268   int bias;
269   int exp; 269   int exp;
270   bool frac; 270   bool frac;
271   bool neg; 271   bool neg;
272   }; 272   };
273   273  
274   template< bool StackEmpty_, char First_ > 274   template< bool StackEmpty_, char First_ >
275   struct parse_number_helper; 275   struct parse_number_helper;
276   276  
277   // optimization: must come first 277   // optimization: must come first
278   Handler h_; 278   Handler h_;
279   279  
280   number num_; 280   number num_;
281   system::error_code ec_; 281   system::error_code ec_;
282   detail::stack st_; 282   detail::stack st_;
283   detail::utf8_sequence seq_; 283   detail::utf8_sequence seq_;
284   unsigned u1_; 284   unsigned u1_;
285   unsigned u2_; 285   unsigned u2_;
286   bool more_; // false for final buffer 286   bool more_; // false for final buffer
287   bool done_ = false; // true on complete parse 287   bool done_ = false; // true on complete parse
288   bool clean_ = true; // write_some exited cleanly 288   bool clean_ = true; // write_some exited cleanly
289   const char* end_; 289   const char* end_;
290   detail::sbo_buffer<16 + 16 + 1 + 1> num_buf_; 290   detail::sbo_buffer<16 + 16 + 1 + 1> num_buf_;
291   parse_options opt_; 291   parse_options opt_;
292   // how many levels deeper the parser can go 292   // how many levels deeper the parser can go
293   std::size_t depth_ = opt_.max_depth; 293   std::size_t depth_ = opt_.max_depth;
294   unsigned char cur_lit_ = 0; 294   unsigned char cur_lit_ = 0;
295   unsigned char lit_offset_ = 0; 295   unsigned char lit_offset_ = 0;
296   296  
297   inline void reserve(); 297   inline void reserve();
298   inline const char* sentinel(); 298   inline const char* sentinel();
299   inline bool incomplete( 299   inline bool incomplete(
300   const detail::const_stream_wrapper& cs); 300   const detail::const_stream_wrapper& cs);
301   301  
302   #ifdef __INTEL_COMPILER 302   #ifdef __INTEL_COMPILER
303   #pragma warning push 303   #pragma warning push
304   #pragma warning disable 2196 304   #pragma warning disable 2196
305   #endif 305   #endif
306   306  
307   BOOST_NOINLINE 307   BOOST_NOINLINE
308   inline 308   inline
309   const char* 309   const char*
310   suspend_or_fail(state st); 310   suspend_or_fail(state st);
311   311  
312   BOOST_NOINLINE 312   BOOST_NOINLINE
313   inline 313   inline
314   const char* 314   const char*
315   suspend_or_fail( 315   suspend_or_fail(
316   state st, 316   state st,
317   std::size_t n); 317   std::size_t n);
318   318  
319   BOOST_NOINLINE 319   BOOST_NOINLINE
320   inline 320   inline
321   const char* 321   const char*
322   fail(const char* p) noexcept; 322   fail(const char* p) noexcept;
323   323  
324   BOOST_NOINLINE 324   BOOST_NOINLINE
325   inline 325   inline
326   const char* 326   const char*
327   fail( 327   fail(
328   const char* p, 328   const char* p,
329   error ev, 329   error ev,
330   source_location const* loc) noexcept; 330   source_location const* loc) noexcept;
331   331  
332   BOOST_NOINLINE 332   BOOST_NOINLINE
333   inline 333   inline
334   const char* 334   const char*
335   maybe_suspend( 335   maybe_suspend(
336   const char* p, 336   const char* p,
337   state st); 337   state st);
338   338  
339   BOOST_NOINLINE 339   BOOST_NOINLINE
340   inline 340   inline
341   const char* 341   const char*
342   maybe_suspend( 342   maybe_suspend(
343   const char* p, 343   const char* p,
344   state st, 344   state st,
345   std::size_t n); 345   std::size_t n);
346   346  
347   BOOST_NOINLINE 347   BOOST_NOINLINE
348   inline 348   inline
349   const char* 349   const char*
350   maybe_suspend( 350   maybe_suspend(
351   const char* p, 351   const char* p,
352   state st, 352   state st,
353   const number& num); 353   const number& num);
354   354  
355   BOOST_NOINLINE 355   BOOST_NOINLINE
356   inline 356   inline
357   const char* 357   const char*
358   suspend( 358   suspend(
359   const char* p, 359   const char* p,
360   state st); 360   state st);
361   361  
362   BOOST_NOINLINE 362   BOOST_NOINLINE
363   inline 363   inline
364   const char* 364   const char*
365   suspend( 365   suspend(
366   const char* p, 366   const char* p,
367   state st, 367   state st,
368   const number& num); 368   const number& num);
369   369  
370   #ifdef __INTEL_COMPILER 370   #ifdef __INTEL_COMPILER
371   #pragma warning pop 371   #pragma warning pop
372   #endif 372   #endif
373   373  
374   template<bool StackEmpty_/*, bool Terminal_*/> 374   template<bool StackEmpty_/*, bool Terminal_*/>
375   const char* parse_comment(const char* p, 375   const char* parse_comment(const char* p,
376   std::integral_constant<bool, StackEmpty_> stack_empty, 376   std::integral_constant<bool, StackEmpty_> stack_empty,
377   /*std::integral_constant<bool, Terminal_>*/ bool terminal); 377   /*std::integral_constant<bool, Terminal_>*/ bool terminal);
378   378  
379   template<bool StackEmpty_> 379   template<bool StackEmpty_>
380   const char* parse_document(const char* p, 380   const char* parse_document(const char* p,
381   std::integral_constant<bool, StackEmpty_> stack_empty); 381   std::integral_constant<bool, StackEmpty_> stack_empty);
382   382  
383   template<bool StackEmpty_, bool AllowComments_/*, 383   template<bool StackEmpty_, bool AllowComments_/*,
384   bool AllowTrailing_, bool AllowBadUTF8_*/> 384   bool AllowTrailing_, bool AllowBadUTF8_*/>
385   const char* parse_value(const char* p, 385   const char* parse_value(const char* p,
386   std::integral_constant<bool, StackEmpty_> stack_empty, 386   std::integral_constant<bool, StackEmpty_> stack_empty,
387   std::integral_constant<bool, AllowComments_> allow_comments, 387   std::integral_constant<bool, AllowComments_> allow_comments,
388   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 388   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
389   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 389   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
390   bool allow_bad_utf16); 390   bool allow_bad_utf16);
391   391  
392   template<bool AllowComments_/*, 392   template<bool AllowComments_/*,
393   bool AllowTrailing_, bool AllowBadUTF8_*/> 393   bool AllowTrailing_, bool AllowBadUTF8_*/>
394   const char* resume_value(const char* p, 394   const char* resume_value(const char* p,
395   std::integral_constant<bool, AllowComments_> allow_comments, 395   std::integral_constant<bool, AllowComments_> allow_comments,
396   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 396   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
397   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 397   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
398   bool allow_bad_utf16); 398   bool allow_bad_utf16);
399   399  
400   template<bool StackEmpty_, bool AllowComments_/*, 400   template<bool StackEmpty_, bool AllowComments_/*,
401   bool AllowTrailing_, bool AllowBadUTF8_*/> 401   bool AllowTrailing_, bool AllowBadUTF8_*/>
402   const char* parse_object(const char* p, 402   const char* parse_object(const char* p,
403   std::integral_constant<bool, StackEmpty_> stack_empty, 403   std::integral_constant<bool, StackEmpty_> stack_empty,
404   std::integral_constant<bool, AllowComments_> allow_comments, 404   std::integral_constant<bool, AllowComments_> allow_comments,
405   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 405   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
406   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 406   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
407   bool allow_bad_utf16); 407   bool allow_bad_utf16);
408   408  
409   template<bool StackEmpty_, bool AllowComments_/*, 409   template<bool StackEmpty_, bool AllowComments_/*,
410   bool AllowTrailing_, bool AllowBadUTF8_*/> 410   bool AllowTrailing_, bool AllowBadUTF8_*/>
411   const char* parse_array(const char* p, 411   const char* parse_array(const char* p,
412   std::integral_constant<bool, StackEmpty_> stack_empty, 412   std::integral_constant<bool, StackEmpty_> stack_empty,
413   std::integral_constant<bool, AllowComments_> allow_comments, 413   std::integral_constant<bool, AllowComments_> allow_comments,
414   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing, 414   /*std::integral_constant<bool, AllowTrailing_>*/ bool allow_trailing,
415   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8, 415   /*std::integral_constant<bool, AllowBadUTF8_>*/ bool allow_bad_utf8,
416   bool allow_bad_utf16); 416   bool allow_bad_utf16);
417   417  
418   template<class Literal> 418   template<class Literal>
419   const char* parse_literal(const char* p, Literal literal); 419   const char* parse_literal(const char* p, Literal literal);
420   420  
421   template<bool StackEmpty_, bool IsKey_> 421   template<bool StackEmpty_, bool IsKey_>
422   const char* parse_string(const char* p, 422   const char* parse_string(const char* p,
423   std::integral_constant<bool, StackEmpty_> stack_empty, 423   std::integral_constant<bool, StackEmpty_> stack_empty,
424   std::integral_constant<bool, IsKey_> is_key, 424   std::integral_constant<bool, IsKey_> is_key,
425   bool allow_bad_utf8, 425   bool allow_bad_utf8,
426   bool allow_bad_utf16); 426   bool allow_bad_utf16);
427   427  
428   template<bool StackEmpty_> 428   template<bool StackEmpty_>
429   const char* parse_escaped( 429   const char* parse_escaped(
430   const char* p, 430   const char* p,
431   std::size_t& total, 431   std::size_t& total,
432   std::integral_constant<bool, StackEmpty_> stack_empty, 432   std::integral_constant<bool, StackEmpty_> stack_empty,
433   bool is_key, 433   bool is_key,
434   bool allow_bad_utf16); 434   bool allow_bad_utf16);
435   435  
436   template<bool StackEmpty_, char First_, number_precision Numbers_> 436   template<bool StackEmpty_, char First_, number_precision Numbers_>
437   const char* parse_number(const char* p, 437   const char* parse_number(const char* p,
438   std::integral_constant<bool, StackEmpty_> stack_empty, 438   std::integral_constant<bool, StackEmpty_> stack_empty,
439   std::integral_constant<char, First_> first, 439   std::integral_constant<char, First_> first,
440   std::integral_constant<number_precision, Numbers_> numbers); 440   std::integral_constant<number_precision, Numbers_> numbers);
441   441  
442   // intentionally private 442   // intentionally private
443   std::size_t 443   std::size_t
HITCBC 444   173075 depth() const noexcept 444   173075 depth() const noexcept
445   { 445   {
HITCBC 446   173075 return opt_.max_depth - depth_; 446   173075 return opt_.max_depth - depth_;
447   } 447   }
448   448  
449   public: 449   public:
450   /** Destructor. 450   /** Destructor.
451   451  
452   All dynamically allocated internal memory is freed. 452   All dynamically allocated internal memory is freed.
453   453  
454   @par Effects 454   @par Effects
455   @code 455   @code
456   handler().~Handler() 456   handler().~Handler()
457   @endcode 457   @endcode
458   458  
459   @par Complexity 459   @par Complexity
460   Same as `~Handler()`. 460   Same as `~Handler()`.
461   461  
462   @par Exception Safety 462   @par Exception Safety
463   Same as `~Handler()`. 463   Same as `~Handler()`.
464   */ 464   */
HITCBC 465   2164604 ~basic_parser() = default; 465   2164606 ~basic_parser() = default;
466   466  
467   /** Constructors. 467   /** Constructors.
468   468  
469   Overload **(1)** constructs the parser with the specified options, with 469   Overload **(1)** constructs the parser with the specified options, with
470   any additional arguments forwarded to the handler's constructor. 470   any additional arguments forwarded to the handler's constructor.
471   471  
472   `basic_parser` is not copyable or movable, so the copy constructor is 472   `basic_parser` is not copyable or movable, so the copy constructor is
473   deleted. 473   deleted.
474   474  
475   @par Complexity 475   @par Complexity
476   Same as `Handler( std::forward< Args >( args )... )`. 476   Same as `Handler( std::forward< Args >( args )... )`.
477   477  
478   @par Exception Safety 478   @par Exception Safety
479   Same as `Handler( std::forward< Args >( args )... )`. 479   Same as `Handler( std::forward< Args >( args )... )`.
480   480  
481   @param opt Configuration settings for the parser. If this structure is 481   @param opt Configuration settings for the parser. If this structure is
482   default constructed, the parser will accept only standard JSON. 482   default constructed, the parser will accept only standard JSON.
483   @param args Optional additional arguments forwarded to the handler's 483   @param args Optional additional arguments forwarded to the handler's
484   constructor. 484   constructor.
485   485  
486   @{ 486   @{
487   */ 487   */
488   template<class... Args> 488   template<class... Args>
489   explicit 489   explicit
490   basic_parser( 490   basic_parser(
491   parse_options const& opt, 491   parse_options const& opt,
492   Args&&... args); 492   Args&&... args);
493   493  
494   /// Overload 494   /// Overload
495   basic_parser( 495   basic_parser(
496   basic_parser const&) = delete; 496   basic_parser const&) = delete;
497   /// @} 497   /// @}
498   498  
499   /** Assignment. 499   /** Assignment.
500   500  
501   This type cannot be copied or moved. The copy assignment is deleted. 501   This type cannot be copied or moved. The copy assignment is deleted.
502   */ 502   */
503   basic_parser& operator=( 503   basic_parser& operator=(
504   basic_parser const&) = delete; 504   basic_parser const&) = delete;
505   505  
506   /** Return a reference to the handler. 506   /** Return a reference to the handler.
507   507  
508   This function provides access to the constructed 508   This function provides access to the constructed
509   instance of the handler owned by the parser. 509   instance of the handler owned by the parser.
510   510  
511   @par Complexity 511   @par Complexity
512   Constant. 512   Constant.
513   513  
514   @par Exception Safety 514   @par Exception Safety
515   No-throw guarantee. 515   No-throw guarantee.
516   516  
517   @{ 517   @{
518   */ 518   */
519   Handler& 519   Handler&
HITCBC 520   6310634 handler() noexcept 520   6310638 handler() noexcept
521   { 521   {
HITCBC 522   6310634 return h_; 522   6310638 return h_;
523   } 523   }
524   524  
525   Handler const& 525   Handler const&
HITCBC 526   24 handler() const noexcept 526   24 handler() const noexcept
527   { 527   {
HITCBC 528   24 return h_; 528   24 return h_;
529   } 529   }
530   /// @} 530   /// @}
531   531  
532   /** Return the last error. 532   /** Return the last error.
533   533  
534   This returns the last error code which 534   This returns the last error code which
535   was generated in the most recent call 535   was generated in the most recent call
536   to @ref write_some. 536   to @ref write_some.
537   537  
538   @par Complexity 538   @par Complexity
539   Constant. 539   Constant.
540   540  
541   @par Exception Safety 541   @par Exception Safety
542   No-throw guarantee. 542   No-throw guarantee.
543   */ 543   */
544   system::error_code 544   system::error_code
HITCBC 545   8 last_error() const noexcept 545   8 last_error() const noexcept
546   { 546   {
HITCBC 547   8 return ec_; 547   8 return ec_;
548   } 548   }
549   549  
550   /** Check if a complete JSON text has been parsed. 550   /** Check if a complete JSON text has been parsed.
551   551  
552   This function returns `true` when all of these conditions are met: 552   This function returns `true` when all of these conditions are met:
553   553  
554   @li A complete serialized JSON text has been presented to the parser, 554   @li A complete serialized JSON text has been presented to the parser,
555   and 555   and
556   @li No error or exception has occurred since the parser was 556   @li No error or exception has occurred since the parser was
557   constructed, or since the last call to @ref reset. 557   constructed, or since the last call to @ref reset.
558   558  
559   @par Complexity 559   @par Complexity
560   Constant. 560   Constant.
561   561  
562   @par Exception Safety 562   @par Exception Safety
563   No-throw guarantee. 563   No-throw guarantee.
564   */ 564   */
565   bool 565   bool
HITCBC 566   4078231 done() const noexcept 566   4078231 done() const noexcept
567   { 567   {
HITCBC 568   4078231 return done_; 568   4078231 return done_;
569   } 569   }
570   570  
571   /** Reset the state, to parse a new document. 571   /** Reset the state, to parse a new document.
572   572  
573   This function discards the current parsing 573   This function discards the current parsing
574   state, to prepare for parsing a new document. 574   state, to prepare for parsing a new document.
575   Dynamically allocated temporary memory used 575   Dynamically allocated temporary memory used
576   by the implementation is not deallocated. 576   by the implementation is not deallocated.
577   577  
578   @par Complexity 578   @par Complexity
579   Constant. 579   Constant.
580   580  
581   @par Exception Safety 581   @par Exception Safety
582   No-throw guarantee. 582   No-throw guarantee.
583   */ 583   */
584   void 584   void
585   reset() noexcept; 585   reset() noexcept;
586   586  
587   /** Indicate a parsing failure. 587   /** Indicate a parsing failure.
588   588  
589   This changes the state of the parser to indicate that the parse has 589   This changes the state of the parser to indicate that the parse has
590   failed. A parser implementation can use this to fail the parser if 590   failed. A parser implementation can use this to fail the parser if
591   needed due to external inputs. 591   needed due to external inputs.
592   592  
593   @attention 593   @attention
594   If `! ec.failed()`, an implementation-defined error code that indicates 594   If `! ec.failed()`, an implementation-defined error code that indicates
595   failure will be stored instead. 595   failure will be stored instead.
596   596  
597   @par Complexity 597   @par Complexity
598   Constant. 598   Constant.
599   599  
600   @par Exception Safety 600   @par Exception Safety
601   No-throw guarantee. 601   No-throw guarantee.
602   602  
603   @param ec The error code to set. 603   @param ec The error code to set.
604   */ 604   */
605   void 605   void
606   fail(system::error_code ec) noexcept; 606   fail(system::error_code ec) noexcept;
607   607  
608   /** Parse some of input characters as JSON, incrementally. 608   /** Parse some of input characters as JSON, incrementally.
609   609  
610   This function parses the JSON text in the specified buffer, calling the 610   This function parses the JSON text in the specified buffer, calling the
611   handler to emit each SAX parsing event. The parse proceeds from the 611   handler to emit each SAX parsing event. The parse proceeds from the
612   current state, which is at the beginning of a new JSON or in the middle 612   current state, which is at the beginning of a new JSON or in the middle
613   of the current JSON if any characters were already parsed. 613   of the current JSON if any characters were already parsed.
614   614  
615   The characters in the buffer are processed starting from the beginning, 615   The characters in the buffer are processed starting from the beginning,
616   until one of the following conditions is met: 616   until one of the following conditions is met:
617   617  
618   @li All of the characters in the buffer have been parsed, 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 619   @li Some of the characters in the buffer have been parsed and the JSON
620   is complete, or 620   is complete, or
621   @li A parsing error occurs. 621   @li A parsing error occurs.
622   622  
623   The supplied buffer does not need to contain the entire JSON. 623   The supplied buffer does not need to contain the entire JSON.
624   Subsequent calls can provide more serialized data, allowing JSON to be 624   Subsequent calls can provide more serialized data, allowing JSON to be
625   processed incrementally. The end of the serialized JSON can be 625   processed incrementally. The end of the serialized JSON can be
626   indicated by passing `more = false`. 626   indicated by passing `more = false`.
627   627  
628   @par Complexity 628   @par Complexity
629   Linear in `size`. 629   Linear in `size`.
630   630  
631   @par Exception Safety 631   @par Exception Safety
632   Basic guarantee. Calls to the handler may throw. 632   Basic guarantee. Calls to the handler may throw.
633   633  
634   Upon error or exception, subsequent calls will fail until @ref reset 634   Upon error or exception, subsequent calls will fail until @ref reset
635   is called to parse a new JSON. 635   is called to parse a new JSON.
636   636  
637   @return The number of characters successfully 637   @return The number of characters successfully
638   parsed, which may be smaller than `size`. 638   parsed, which may be smaller than `size`.
639   639  
640   @param more `true` if there are possibly more buffers in the current 640   @param more `true` if there are possibly more buffers in the current
641   JSON, otherwise `false`. 641   JSON, otherwise `false`.
642   642  
643   @param data A pointer to a buffer of `size` characters to parse. 643   @param data A pointer to a buffer of `size` characters to parse.
644   644  
645   @param size The number of characters pointed to by `data`. 645   @param size The number of characters pointed to by `data`.
646   646  
647   @param ec Set to the error, if any occurred. 647   @param ec Set to the error, if any occurred.
648   648  
649   @{ 649   @{
650   */ 650   */
651   std::size_t 651   std::size_t
652   write_some( 652   write_some(
653   bool more, 653   bool more,
654   char const* data, 654   char const* data,
655   std::size_t size, 655   std::size_t size,
656   system::error_code& ec); 656   system::error_code& ec);
657   657  
658   std::size_t 658   std::size_t
659   write_some( 659   write_some(
660   bool more, 660   bool more,
661   char const* data, 661   char const* data,
662   std::size_t size, 662   std::size_t size,
663   std::error_code& ec); 663   std::error_code& ec);
664   /// @} 664   /// @}
665   }; 665   };
666   666  
667   } // namespace json 667   } // namespace json
668   } // namespace boost 668   } // namespace boost
669   669  
670   #endif 670   #endif