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