reader.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #ifndef RAPIDJSON_READER_H_
16 #define RAPIDJSON_READER_H_
17 
18 /*! \file reader.h */
19 
20 #include "allocators.h"
21 #include "stream.h"
22 #include "encodedstream.h"
23 #include "internal/meta.h"
24 #include "internal/stack.h"
25 #include "internal/strtod.h"
26 #include <limits>
27 
28 #if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
29 #include <intrin.h>
30 #pragma intrinsic(_BitScanForward)
31 #endif
32 #ifdef RAPIDJSON_SSE42
33 #include <nmmintrin.h>
34 #elif defined(RAPIDJSON_SSE2)
35 #include <emmintrin.h>
36 #elif defined(RAPIDJSON_NEON)
37 #include <arm_neon.h>
38 #endif
39 
40 #ifdef __clang__
41 RAPIDJSON_DIAG_PUSH
42 RAPIDJSON_DIAG_OFF(old-style-cast)
43 RAPIDJSON_DIAG_OFF(padded)
44 RAPIDJSON_DIAG_OFF(switch-enum)
45 #elif defined(_MSC_VER)
46 RAPIDJSON_DIAG_PUSH
47 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
48 RAPIDJSON_DIAG_OFF(4702) // unreachable code
49 #endif
50 
51 #ifdef __GNUC__
52 RAPIDJSON_DIAG_PUSH
53 RAPIDJSON_DIAG_OFF(effc++)
54 #endif
55 
56 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
57 #define RAPIDJSON_NOTHING /* deliberately empty */
58 #ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
59 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
60  RAPIDJSON_MULTILINEMACRO_BEGIN \
61  if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
62  RAPIDJSON_MULTILINEMACRO_END
63 #endif
64 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
65  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
66 //!@endcond
67 
68 /*! \def RAPIDJSON_PARSE_ERROR_NORETURN
69  \ingroup RAPIDJSON_ERRORS
70  \brief Macro to indicate a parse error.
71  \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
72  \param offset position of the error in JSON input (\c size_t)
73 
74  This macros can be used as a customization point for the internal
75  error handling mechanism of RapidJSON.
76 
77  A common usage model is to throw an exception instead of requiring the
78  caller to explicitly check the \ref rapidjson::GenericReader::Parse's
79  return value:
80 
81  \code
82  #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \
83  throw ParseException(parseErrorCode, #parseErrorCode, offset)
84 
85  #include <stdexcept> // std::runtime_error
86  #include "rapidjson/error/error.h" // rapidjson::ParseResult
87 
88  struct ParseException : std::runtime_error, rapidjson::ParseResult {
89  ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset)
90  : std::runtime_error(msg), ParseResult(code, offset) {}
91  };
92 
93  #include "rapidjson/reader.h"
94  \endcode
95 
96  \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse
97  */
98 #ifndef RAPIDJSON_PARSE_ERROR_NORETURN
99 #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
100  RAPIDJSON_MULTILINEMACRO_BEGIN \
101  RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
102  SetParseError(parseErrorCode, offset); \
103  RAPIDJSON_MULTILINEMACRO_END
104 #endif
105 
106 /*! \def RAPIDJSON_PARSE_ERROR
107  \ingroup RAPIDJSON_ERRORS
108  \brief (Internal) macro to indicate and handle a parse error.
109  \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
110  \param offset position of the error in JSON input (\c size_t)
111 
112  Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing.
113 
114  \see RAPIDJSON_PARSE_ERROR_NORETURN
115  \hideinitializer
116  */
117 #ifndef RAPIDJSON_PARSE_ERROR
118 #define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \
119  RAPIDJSON_MULTILINEMACRO_BEGIN \
120  RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
121  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
122  RAPIDJSON_MULTILINEMACRO_END
123 #endif
124 
125 #include "error/error.h" // ParseErrorCode, ParseResult
126 
127 RAPIDJSON_NAMESPACE_BEGIN
128 
129 ///////////////////////////////////////////////////////////////////////////////
130 // ParseFlag
131 
132 /*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS
133  \ingroup RAPIDJSON_CONFIG
134  \brief User-defined kParseDefaultFlags definition.
135 
136  User can define this as any \c ParseFlag combinations.
137 */
138 #ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS
139 #define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags
140 #endif
141 
142 //! Combination of parseFlags
143 /*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream
144  */
145 enum ParseFlag {
146  kParseNoFlags = 0, //!< No flags are set.
147  kParseInsituFlag = 1, //!< In-situ(destructive) parsing.
148  kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings.
149  kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing.
150  kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error.
151  kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower).
152  kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments.
153  kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings.
154  kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.
155  kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
156  kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
157 };
158 
159 ///////////////////////////////////////////////////////////////////////////////
160 // Handler
161 
162 /*! \class rapidjson::Handler
163  \brief Concept for receiving events from GenericReader upon parsing.
164  The functions return true if no error occurs. If they return false,
165  the event publisher should terminate the process.
166 \code
167 concept Handler {
168  typename Ch;
169 
170  bool Null();
171  bool Bool(bool b);
172  bool Int(int i);
173  bool Uint(unsigned i);
174  bool Int64(int64_t i);
175  bool Uint64(uint64_t i);
176  bool Double(double d);
177  /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
178  bool RawNumber(const Ch* str, SizeType length, bool copy);
179  bool String(const Ch* str, SizeType length, bool copy);
180  bool StartObject();
181  bool Key(const Ch* str, SizeType length, bool copy);
182  bool EndObject(SizeType memberCount);
183  bool StartArray();
184  bool EndArray(SizeType elementCount);
185 };
186 \endcode
187 */
188 ///////////////////////////////////////////////////////////////////////////////
189 // BaseReaderHandler
190 
191 //! Default implementation of Handler.
192 /*! This can be used as base class of any reader handler.
193  \note implements Handler concept
194 */
195 template<typename Encoding = UTF8<>, typename Derived = void>
196 struct BaseReaderHandler {
197  typedef typename Encoding::Ch Ch;
198 
199  typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override;
200 
201  bool Default() { return true; }
202  bool Null() { return static_cast<Override&>(*this).Default(); }
203  bool Bool(bool) { return static_cast<Override&>(*this).Default(); }
204  bool Int(int) { return static_cast<Override&>(*this).Default(); }
205  bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); }
206  bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); }
207  bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); }
208  bool Double(double) { return static_cast<Override&>(*this).Default(); }
209  /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
210  bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
211  bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); }
212  bool StartObject() { return static_cast<Override&>(*this).Default(); }
213  bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
214  bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }
215  bool StartArray() { return static_cast<Override&>(*this).Default(); }
216  bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }
217 };
218 
219 ///////////////////////////////////////////////////////////////////////////////
220 // StreamLocalCopy
221 
222 namespace internal {
223 
224 template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
225 class StreamLocalCopy;
226 
227 //! Do copy optimization.
228 template<typename Stream>
229 class StreamLocalCopy<Stream, 1> {
230 public:
231  StreamLocalCopy(Stream& original) : s(original), original_(original) {}
232  ~StreamLocalCopy() { original_ = s; }
233 
234  Stream s;
235 
236 private:
237  StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
238 
239  Stream& original_;
240 };
241 
242 //! Keep reference.
243 template<typename Stream>
244 class StreamLocalCopy<Stream, 0> {
245 public:
246  StreamLocalCopy(Stream& original) : s(original) {}
247 
248  Stream& s;
249 
250 private:
251  StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
252 };
253 
254 } // namespace internal
255 
256 ///////////////////////////////////////////////////////////////////////////////
257 // SkipWhitespace
258 
259 //! Skip the JSON white spaces in a stream.
260 /*! \param is A input stream for skipping white spaces.
261  \note This function has SSE2/SSE4.2 specialization.
262 */
263 template<typename InputStream>
264 void SkipWhitespace(InputStream& is) {
265  internal::StreamLocalCopy<InputStream> copy(is);
266  InputStream& s(copy.s);
267 
268  typename InputStream::Ch c;
269  while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t')
270  s.Take();
271 }
272 
273 inline const char* SkipWhitespace(const char* p, const char* end) {
274  while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
275  ++p;
276  return p;
277 }
278 
279 #ifdef RAPIDJSON_SSE42
280 //! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.
281 inline const char *SkipWhitespace_SIMD(const char* p) {
282  // Fast return for single non-whitespace
283  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
284  ++p;
285  else
286  return p;
287 
288  // 16-byte align to the next boundary
289  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
290  while (p != nextAligned)
291  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
292  ++p;
293  else
294  return p;
295 
296  // The rest of string using SIMD
297  static const char whitespace[16] = " \n\r\t";
298  const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
299 
300  for (;; p += 16) {
301  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
302  const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
303  if (r != 16) // some of characters is non-whitespace
304  return p + r;
305  }
306 }
307 
308 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
309  // Fast return for single non-whitespace
310  if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
311  ++p;
312  else
313  return p;
314 
315  // The middle of string using SIMD
316  static const char whitespace[16] = " \n\r\t";
317  const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
318 
319  for (; p <= end - 16; p += 16) {
320  const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
321  const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
322  if (r != 16) // some of characters is non-whitespace
323  return p + r;
324  }
325 
326  return SkipWhitespace(p, end);
327 }
328 
329 #elif defined(RAPIDJSON_SSE2)
330 
331 //! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
332 inline const char *SkipWhitespace_SIMD(const char* p) {
333  // Fast return for single non-whitespace
334  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
335  ++p;
336  else
337  return p;
338 
339  // 16-byte align to the next boundary
340  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
341  while (p != nextAligned)
342  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
343  ++p;
344  else
345  return p;
346 
347  // The rest of string
348  #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
349  static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
350  #undef C16
351 
352  const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
353  const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
354  const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
355  const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
356 
357  for (;; p += 16) {
358  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
359  __m128i x = _mm_cmpeq_epi8(s, w0);
360  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
361  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
362  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
363  unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
364  if (r != 0) { // some of characters may be non-whitespace
365 #ifdef _MSC_VER // Find the index of first non-whitespace
366  unsigned long offset;
367  _BitScanForward(&offset, r);
368  return p + offset;
369 #else
370  return p + __builtin_ffs(r) - 1;
371 #endif
372  }
373  }
374 }
375 
376 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
377  // Fast return for single non-whitespace
378  if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
379  ++p;
380  else
381  return p;
382 
383  // The rest of string
384  #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
385  static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
386  #undef C16
387 
388  const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
389  const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
390  const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
391  const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
392 
393  for (; p <= end - 16; p += 16) {
394  const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
395  __m128i x = _mm_cmpeq_epi8(s, w0);
396  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
397  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
398  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
399  unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
400  if (r != 0) { // some of characters may be non-whitespace
401 #ifdef _MSC_VER // Find the index of first non-whitespace
402  unsigned long offset;
403  _BitScanForward(&offset, r);
404  return p + offset;
405 #else
406  return p + __builtin_ffs(r) - 1;
407 #endif
408  }
409  }
410 
411  return SkipWhitespace(p, end);
412 }
413 
414 #elif defined(RAPIDJSON_NEON)
415 
416 //! Skip whitespace with ARM Neon instructions, testing 16 8-byte characters at once.
417 inline const char *SkipWhitespace_SIMD(const char* p) {
418  // Fast return for single non-whitespace
419  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
420  ++p;
421  else
422  return p;
423 
424  // 16-byte align to the next boundary
425  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
426  while (p != nextAligned)
427  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
428  ++p;
429  else
430  return p;
431 
432  const uint8x16_t w0 = vmovq_n_u8(' ');
433  const uint8x16_t w1 = vmovq_n_u8('\n');
434  const uint8x16_t w2 = vmovq_n_u8('\r');
435  const uint8x16_t w3 = vmovq_n_u8('\t');
436 
437  for (;; p += 16) {
438  const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
439  uint8x16_t x = vceqq_u8(s, w0);
440  x = vorrq_u8(x, vceqq_u8(s, w1));
441  x = vorrq_u8(x, vceqq_u8(s, w2));
442  x = vorrq_u8(x, vceqq_u8(s, w3));
443 
444  x = vmvnq_u8(x); // Negate
445  x = vrev64q_u8(x); // Rev in 64
446  uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
447  uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
448 
449  if (low == 0) {
450  if (high != 0) {
451  int lz =__builtin_clzll(high);;
452  return p + 8 + (lz >> 3);
453  }
454  } else {
455  int lz = __builtin_clzll(low);;
456  return p + (lz >> 3);
457  }
458  }
459 }
460 
461 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
462  // Fast return for single non-whitespace
463  if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
464  ++p;
465  else
466  return p;
467 
468  const uint8x16_t w0 = vmovq_n_u8(' ');
469  const uint8x16_t w1 = vmovq_n_u8('\n');
470  const uint8x16_t w2 = vmovq_n_u8('\r');
471  const uint8x16_t w3 = vmovq_n_u8('\t');
472 
473  for (; p <= end - 16; p += 16) {
474  const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
475  uint8x16_t x = vceqq_u8(s, w0);
476  x = vorrq_u8(x, vceqq_u8(s, w1));
477  x = vorrq_u8(x, vceqq_u8(s, w2));
478  x = vorrq_u8(x, vceqq_u8(s, w3));
479 
480  x = vmvnq_u8(x); // Negate
481  x = vrev64q_u8(x); // Rev in 64
482  uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
483  uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
484 
485  if (low == 0) {
486  if (high != 0) {
487  int lz = __builtin_clzll(high);
488  return p + 8 + (lz >> 3);
489  }
490  } else {
491  int lz = __builtin_clzll(low);
492  return p + (lz >> 3);
493  }
494  }
495 
496  return SkipWhitespace(p, end);
497 }
498 
499 #endif // RAPIDJSON_NEON
500 
501 #ifdef RAPIDJSON_SIMD
502 //! Template function specialization for InsituStringStream
503 template<> inline void SkipWhitespace(InsituStringStream& is) {
504  is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
505 }
506 
507 //! Template function specialization for StringStream
508 template<> inline void SkipWhitespace(StringStream& is) {
509  is.src_ = SkipWhitespace_SIMD(is.src_);
510 }
511 
512 template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {
513  is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
514 }
515 #endif // RAPIDJSON_SIMD
516 
517 ///////////////////////////////////////////////////////////////////////////////
518 // GenericReader
519 
520 //! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator.
521 /*! GenericReader parses JSON text from a stream, and send events synchronously to an
522  object implementing Handler concept.
523 
524  It needs to allocate a stack for storing a single decoded string during
525  non-destructive parsing.
526 
527  For in-situ parsing, the decoded string is directly written to the source
528  text string, no temporary buffer is required.
529 
530  A GenericReader object can be reused for parsing multiple JSON text.
531 
532  \tparam SourceEncoding Encoding of the input stream.
533  \tparam TargetEncoding Encoding of the parse output.
534  \tparam StackAllocator Allocator type for stack.
535 */
536 template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
537 class GenericReader {
538 public:
539  typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type
540 
541  //! Constructor.
542  /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
543  \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
544  */
545  GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) :
546  stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {}
547 
548  //! Parse JSON text.
549  /*! \tparam parseFlags Combination of \ref ParseFlag.
550  \tparam InputStream Type of input stream, implementing Stream concept.
551  \tparam Handler Type of handler, implementing Handler concept.
552  \param is Input stream to be parsed.
553  \param handler The handler to receive events.
554  \return Whether the parsing is successful.
555  */
556  template <unsigned parseFlags, typename InputStream, typename Handler>
557  ParseResult Parse(InputStream& is, Handler& handler) {
558  if (parseFlags & kParseIterativeFlag)
559  return IterativeParse<parseFlags>(is, handler);
560 
561  parseResult_.Clear();
562 
563  ClearStackOnExit scope(*this);
564 
565  SkipWhitespaceAndComments<parseFlags>(is);
566  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
567 
568  if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) {
570  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
571  }
572  else {
573  ParseValue<parseFlags>(is, handler);
574  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
575 
576  if (!(parseFlags & kParseStopWhenDoneFlag)) {
577  SkipWhitespaceAndComments<parseFlags>(is);
578  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
579 
580  if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) {
582  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
583  }
584  }
585  }
586 
587  return parseResult_;
588  }
589 
590  //! Parse JSON text (with \ref kParseDefaultFlags)
591  /*! \tparam InputStream Type of input stream, implementing Stream concept
592  \tparam Handler Type of handler, implementing Handler concept.
593  \param is Input stream to be parsed.
594  \param handler The handler to receive events.
595  \return Whether the parsing is successful.
596  */
597  template <typename InputStream, typename Handler>
598  ParseResult Parse(InputStream& is, Handler& handler) {
599  return Parse<kParseDefaultFlags>(is, handler);
600  }
601 
602  //! Initialize JSON text token-by-token parsing
603  /*!
604  */
606  parseResult_.Clear();
607  state_ = IterativeParsingStartState;
608  }
609 
610  //! Parse one token from JSON text
611  /*! \tparam InputStream Type of input stream, implementing Stream concept
612  \tparam Handler Type of handler, implementing Handler concept.
613  \param is Input stream to be parsed.
614  \param handler The handler to receive events.
615  \return Whether the parsing is successful.
616  */
617  template <unsigned parseFlags, typename InputStream, typename Handler>
618  bool IterativeParseNext(InputStream& is, Handler& handler) {
619  while (RAPIDJSON_LIKELY(is.Peek() != '\0')) {
620  SkipWhitespaceAndComments<parseFlags>(is);
621 
622  Token t = Tokenize(is.Peek());
623  IterativeParsingState n = Predict(state_, t);
624  IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
625 
626  // If we've finished or hit an error...
627  if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {
628  // Report errors.
629  if (d == IterativeParsingErrorState) {
630  HandleError(state_, is);
631  return false;
632  }
633 
634  // Transition to the finish state.
635  RAPIDJSON_ASSERT(d == IterativeParsingFinishState);
636  state_ = d;
637 
638  // If StopWhenDone is not set...
639  if (!(parseFlags & kParseStopWhenDoneFlag)) {
640  // ... and extra non-whitespace data is found...
641  SkipWhitespaceAndComments<parseFlags>(is);
642  if (is.Peek() != '\0') {
643  // ... this is considered an error.
644  HandleError(state_, is);
645  return false;
646  }
647  }
648 
649  // Success! We are done!
650  return true;
651  }
652 
653  // Transition to the new state.
654  state_ = d;
655 
656  // If we parsed anything other than a delimiter, we invoked the handler, so we can return true now.
657  if (!IsIterativeParsingDelimiterState(n))
658  return true;
659  }
660 
661  // We reached the end of file.
662  stack_.Clear();
663 
664  if (state_ != IterativeParsingFinishState) {
665  HandleError(state_, is);
666  return false;
667  }
668 
669  return true;
670  }
671 
672  //! Check if token-by-token parsing JSON text is complete
673  /*! \return Whether the JSON has been fully decoded.
674  */
675  RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const {
676  return IsIterativeParsingCompleteState(state_);
677  }
678 
679  //! Whether a parse error has occurred in the last parsing.
680  bool HasParseError() const { return parseResult_.IsError(); }
681 
682  //! Get the \ref ParseErrorCode of last parsing.
683  ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }
684 
685  //! Get the position of last parsing error in input, 0 otherwise.
686  size_t GetErrorOffset() const { return parseResult_.Offset(); }
687 
688 protected:
689  void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
690 
691 private:
692  // Prohibit copy constructor & assignment operator.
694  GenericReader& operator=(const GenericReader&);
695 
696  void ClearStack() { stack_.Clear(); }
697 
698  // clear stack on any exit from ParseStream, e.g. due to exception
699  struct ClearStackOnExit {
700  explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
701  ~ClearStackOnExit() { r_.ClearStack(); }
702  private:
703  GenericReader& r_;
704  ClearStackOnExit(const ClearStackOnExit&);
705  ClearStackOnExit& operator=(const ClearStackOnExit&);
706  };
707 
708  template<unsigned parseFlags, typename InputStream>
709  void SkipWhitespaceAndComments(InputStream& is) {
710  SkipWhitespace(is);
711 
712  if (parseFlags & kParseCommentsFlag) {
713  while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) {
714  if (Consume(is, '*')) {
715  while (true) {
716  if (RAPIDJSON_UNLIKELY(is.Peek() == '\0'))
718  else if (Consume(is, '*')) {
719  if (Consume(is, '/'))
720  break;
721  }
722  else
723  is.Take();
724  }
725  }
726  else if (RAPIDJSON_LIKELY(Consume(is, '/')))
727  while (is.Peek() != '\0' && is.Take() != '\n') {}
728  else
730 
731  SkipWhitespace(is);
732  }
733  }
734  }
735 
736  // Parse object: { string : value, ... }
737  template<unsigned parseFlags, typename InputStream, typename Handler>
738  void ParseObject(InputStream& is, Handler& handler) {
739  RAPIDJSON_ASSERT(is.Peek() == '{');
740  is.Take(); // Skip '{'
741 
742  if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
744 
745  SkipWhitespaceAndComments<parseFlags>(is);
746  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
747 
748  if (Consume(is, '}')) {
749  if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object
751  return;
752  }
753 
754  for (SizeType memberCount = 0;;) {
755  if (RAPIDJSON_UNLIKELY(is.Peek() != '"'))
757 
758  ParseString<parseFlags>(is, handler, true);
759  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
760 
761  SkipWhitespaceAndComments<parseFlags>(is);
762  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
763 
764  if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))
766 
767  SkipWhitespaceAndComments<parseFlags>(is);
768  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
769 
770  ParseValue<parseFlags>(is, handler);
771  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
772 
773  SkipWhitespaceAndComments<parseFlags>(is);
774  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
775 
776  ++memberCount;
777 
778  switch (is.Peek()) {
779  case ',':
780  is.Take();
781  SkipWhitespaceAndComments<parseFlags>(is);
782  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
783  break;
784  case '}':
785  is.Take();
786  if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
788  return;
789  default:
790  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy
791  }
792 
793  if (parseFlags & kParseTrailingCommasFlag) {
794  if (is.Peek() == '}') {
795  if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
797  is.Take();
798  return;
799  }
800  }
801  }
802  }
803 
804  // Parse array: [ value, ... ]
805  template<unsigned parseFlags, typename InputStream, typename Handler>
806  void ParseArray(InputStream& is, Handler& handler) {
807  RAPIDJSON_ASSERT(is.Peek() == '[');
808  is.Take(); // Skip '['
809 
810  if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
812 
813  SkipWhitespaceAndComments<parseFlags>(is);
814  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
815 
816  if (Consume(is, ']')) {
817  if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array
819  return;
820  }
821 
822  for (SizeType elementCount = 0;;) {
823  ParseValue<parseFlags>(is, handler);
824  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
825 
826  ++elementCount;
827  SkipWhitespaceAndComments<parseFlags>(is);
828  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
829 
830  if (Consume(is, ',')) {
831  SkipWhitespaceAndComments<parseFlags>(is);
832  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
833  }
834  else if (Consume(is, ']')) {
835  if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
837  return;
838  }
839  else
841 
842  if (parseFlags & kParseTrailingCommasFlag) {
843  if (is.Peek() == ']') {
844  if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
846  is.Take();
847  return;
848  }
849  }
850  }
851  }
852 
853  template<unsigned parseFlags, typename InputStream, typename Handler>
854  void ParseNull(InputStream& is, Handler& handler) {
855  RAPIDJSON_ASSERT(is.Peek() == 'n');
856  is.Take();
857 
858  if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {
859  if (RAPIDJSON_UNLIKELY(!handler.Null()))
861  }
862  else
864  }
865 
866  template<unsigned parseFlags, typename InputStream, typename Handler>
867  void ParseTrue(InputStream& is, Handler& handler) {
868  RAPIDJSON_ASSERT(is.Peek() == 't');
869  is.Take();
870 
871  if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {
872  if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))
874  }
875  else
877  }
878 
879  template<unsigned parseFlags, typename InputStream, typename Handler>
880  void ParseFalse(InputStream& is, Handler& handler) {
881  RAPIDJSON_ASSERT(is.Peek() == 'f');
882  is.Take();
883 
884  if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {
885  if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))
887  }
888  else
890  }
891 
892  template<typename InputStream>
893  RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
894  if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
895  is.Take();
896  return true;
897  }
898  else
899  return false;
900  }
901 
902  // Helper function to parse four hexadecimal digits in \uXXXX in ParseString().
903  template<typename InputStream>
904  unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
905  unsigned codepoint = 0;
906  for (int i = 0; i < 4; i++) {
907  Ch c = is.Peek();
908  codepoint <<= 4;
909  codepoint += static_cast<unsigned>(c);
910  if (c >= '0' && c <= '9')
911  codepoint -= '0';
912  else if (c >= 'A' && c <= 'F')
913  codepoint -= 'A' - 10;
914  else if (c >= 'a' && c <= 'f')
915  codepoint -= 'a' - 10;
916  else {
918  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
919  }
920  is.Take();
921  }
922  return codepoint;
923  }
924 
925  template <typename CharType>
926  class StackStream {
927  public:
928  typedef CharType Ch;
929 
930  StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {}
931  RAPIDJSON_FORCEINLINE void Put(Ch c) {
932  *stack_.template Push<Ch>() = c;
933  ++length_;
934  }
935 
936  RAPIDJSON_FORCEINLINE void* Push(SizeType count) {
937  length_ += count;
938  return stack_.template Push<Ch>(count);
939  }
940 
941  size_t Length() const { return length_; }
942 
943  Ch* Pop() {
944  return stack_.template Pop<Ch>(length_);
945  }
946 
947  private:
948  StackStream(const StackStream&);
949  StackStream& operator=(const StackStream&);
950 
951  internal::Stack<StackAllocator>& stack_;
952  SizeType length_;
953  };
954 
955  // Parse string and generate String event. Different code paths for kParseInsituFlag.
956  template<unsigned parseFlags, typename InputStream, typename Handler>
957  void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
958  internal::StreamLocalCopy<InputStream> copy(is);
959  InputStream& s(copy.s);
960 
961  RAPIDJSON_ASSERT(s.Peek() == '\"');
962  s.Take(); // Skip '\"'
963 
964  bool success = false;
965  if (parseFlags & kParseInsituFlag) {
966  typename InputStream::Ch *head = s.PutBegin();
967  ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
968  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
969  size_t length = s.PutEnd(head) - 1;
970  RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
971  const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
972  success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
973  }
974  else {
975  StackStream<typename TargetEncoding::Ch> stackStream(stack_);
976  ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
977  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
978  SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;
979  const typename TargetEncoding::Ch* const str = stackStream.Pop();
980  success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
981  }
982  if (RAPIDJSON_UNLIKELY(!success))
984  }
985 
986  // Parse string to an output is
987  // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
988  template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
989  RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
990 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
991 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
992  static const char escape[256] = {
993  Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
994  Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
995  0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
996  0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
997  Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
998  };
999 #undef Z16
1000 //!@endcond
1001 
1002  for (;;) {
1003  // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
1004  if (!(parseFlags & kParseValidateEncodingFlag))
1005  ScanCopyUnescapedString(is, os);
1006 
1007  Ch c = is.Peek();
1008  if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape
1009  size_t escapeOffset = is.Tell(); // For invalid escaping, report the initial '\\' as error offset
1010  is.Take();
1011  Ch e = is.Peek();
1012  if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
1013  is.Take();
1014  os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
1015  }
1016  else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
1017  is.Take();
1018  unsigned codepoint = ParseHex4(is, escapeOffset);
1019  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
1020  if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
1021  // Handle UTF-16 surrogate pair
1022  if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
1024  unsigned codepoint2 = ParseHex4(is, escapeOffset);
1025  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
1026  if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
1028  codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
1029  }
1030  TEncoding::Encode(os, codepoint);
1031  }
1032  else
1034  }
1035  else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote
1036  is.Take();
1037  os.Put('\0'); // null-terminate the string
1038  return;
1039  }
1040  else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
1041  if (c == '\0')
1043  else
1045  }
1046  else {
1047  size_t offset = is.Tell();
1048  if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
1052  }
1053  }
1054  }
1055 
1056  template<typename InputStream, typename OutputStream>
1057  static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {
1058  // Do nothing for generic version
1059  }
1060 
1061 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
1062  // StringStream -> StackStream<char>
1063  static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
1064  const char* p = is.src_;
1065 
1066  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1067  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1068  while (p != nextAligned)
1069  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1070  is.src_ = p;
1071  return;
1072  }
1073  else
1074  os.Put(*p++);
1075 
1076  // The rest of string using SIMD
1077  static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1078  static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1079  static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1080  const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1081  const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1082  const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1083 
1084  for (;; p += 16) {
1085  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1086  const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1087  const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1088  const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
1089  const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1090  unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1091  if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1092  SizeType length;
1093  #ifdef _MSC_VER // Find the index of first escaped
1094  unsigned long offset;
1095  _BitScanForward(&offset, r);
1096  length = offset;
1097  #else
1098  length = static_cast<SizeType>(__builtin_ffs(r) - 1);
1099  #endif
1100  if (length != 0) {
1101  char* q = reinterpret_cast<char*>(os.Push(length));
1102  for (size_t i = 0; i < length; i++)
1103  q[i] = p[i];
1104 
1105  p += length;
1106  }
1107  break;
1108  }
1109  _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);
1110  }
1111 
1112  is.src_ = p;
1113  }
1114 
1115  // InsituStringStream -> InsituStringStream
1116  static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
1117  RAPIDJSON_ASSERT(&is == &os);
1118  (void)os;
1119 
1120  if (is.src_ == is.dst_) {
1121  SkipUnescapedString(is);
1122  return;
1123  }
1124 
1125  char* p = is.src_;
1126  char *q = is.dst_;
1127 
1128  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1129  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1130  while (p != nextAligned)
1131  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1132  is.src_ = p;
1133  is.dst_ = q;
1134  return;
1135  }
1136  else
1137  *q++ = *p++;
1138 
1139  // The rest of string using SIMD
1140  static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1141  static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1142  static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1143  const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1144  const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1145  const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1146 
1147  for (;; p += 16, q += 16) {
1148  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1149  const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1150  const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1151  const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
1152  const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1153  unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1154  if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1155  size_t length;
1156 #ifdef _MSC_VER // Find the index of first escaped
1157  unsigned long offset;
1158  _BitScanForward(&offset, r);
1159  length = offset;
1160 #else
1161  length = static_cast<size_t>(__builtin_ffs(r) - 1);
1162 #endif
1163  for (const char* pend = p + length; p != pend; )
1164  *q++ = *p++;
1165  break;
1166  }
1167  _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);
1168  }
1169 
1170  is.src_ = p;
1171  is.dst_ = q;
1172  }
1173 
1174  // When read/write pointers are the same for insitu stream, just skip unescaped characters
1175  static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
1176  RAPIDJSON_ASSERT(is.src_ == is.dst_);
1177  char* p = is.src_;
1178 
1179  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1180  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1181  for (; p != nextAligned; p++)
1182  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1183  is.src_ = is.dst_ = p;
1184  return;
1185  }
1186 
1187  // The rest of string using SIMD
1188  static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1189  static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1190  static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1191  const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1192  const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1193  const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1194 
1195  for (;; p += 16) {
1196  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1197  const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1198  const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1199  const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
1200  const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1201  unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1202  if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1203  size_t length;
1204 #ifdef _MSC_VER // Find the index of first escaped
1205  unsigned long offset;
1206  _BitScanForward(&offset, r);
1207  length = offset;
1208 #else
1209  length = static_cast<size_t>(__builtin_ffs(r) - 1);
1210 #endif
1211  p += length;
1212  break;
1213  }
1214  }
1215 
1216  is.src_ = is.dst_ = p;
1217  }
1218 #elif defined(RAPIDJSON_NEON)
1219  // StringStream -> StackStream<char>
1220  static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
1221  const char* p = is.src_;
1222 
1223  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1224  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1225  while (p != nextAligned)
1226  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1227  is.src_ = p;
1228  return;
1229  }
1230  else
1231  os.Put(*p++);
1232 
1233  // The rest of string using SIMD
1234  const uint8x16_t s0 = vmovq_n_u8('"');
1235  const uint8x16_t s1 = vmovq_n_u8('\\');
1236  const uint8x16_t s2 = vmovq_n_u8('\b');
1237  const uint8x16_t s3 = vmovq_n_u8(32);
1238 
1239  for (;; p += 16) {
1240  const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
1241  uint8x16_t x = vceqq_u8(s, s0);
1242  x = vorrq_u8(x, vceqq_u8(s, s1));
1243  x = vorrq_u8(x, vceqq_u8(s, s2));
1244  x = vorrq_u8(x, vcltq_u8(s, s3));
1245 
1246  x = vrev64q_u8(x); // Rev in 64
1247  uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
1248  uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
1249 
1250  SizeType length = 0;
1251  bool escaped = false;
1252  if (low == 0) {
1253  if (high != 0) {
1254  unsigned lz = (unsigned)__builtin_clzll(high);;
1255  length = 8 + (lz >> 3);
1256  escaped = true;
1257  }
1258  } else {
1259  unsigned lz = (unsigned)__builtin_clzll(low);;
1260  length = lz >> 3;
1261  escaped = true;
1262  }
1263  if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped
1264  if (length != 0) {
1265  char* q = reinterpret_cast<char*>(os.Push(length));
1266  for (size_t i = 0; i < length; i++)
1267  q[i] = p[i];
1268 
1269  p += length;
1270  }
1271  break;
1272  }
1273  vst1q_u8(reinterpret_cast<uint8_t *>(os.Push(16)), s);
1274  }
1275 
1276  is.src_ = p;
1277  }
1278 
1279  // InsituStringStream -> InsituStringStream
1280  static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
1281  RAPIDJSON_ASSERT(&is == &os);
1282  (void)os;
1283 
1284  if (is.src_ == is.dst_) {
1285  SkipUnescapedString(is);
1286  return;
1287  }
1288 
1289  char* p = is.src_;
1290  char *q = is.dst_;
1291 
1292  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1293  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1294  while (p != nextAligned)
1295  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1296  is.src_ = p;
1297  is.dst_ = q;
1298  return;
1299  }
1300  else
1301  *q++ = *p++;
1302 
1303  // The rest of string using SIMD
1304  const uint8x16_t s0 = vmovq_n_u8('"');
1305  const uint8x16_t s1 = vmovq_n_u8('\\');
1306  const uint8x16_t s2 = vmovq_n_u8('\b');
1307  const uint8x16_t s3 = vmovq_n_u8(32);
1308 
1309  for (;; p += 16, q += 16) {
1310  const uint8x16_t s = vld1q_u8(reinterpret_cast<uint8_t *>(p));
1311  uint8x16_t x = vceqq_u8(s, s0);
1312  x = vorrq_u8(x, vceqq_u8(s, s1));
1313  x = vorrq_u8(x, vceqq_u8(s, s2));
1314  x = vorrq_u8(x, vcltq_u8(s, s3));
1315 
1316  x = vrev64q_u8(x); // Rev in 64
1317  uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
1318  uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
1319 
1320  SizeType length = 0;
1321  bool escaped = false;
1322  if (low == 0) {
1323  if (high != 0) {
1324  unsigned lz = (unsigned)__builtin_clzll(high);
1325  length = 8 + (lz >> 3);
1326  escaped = true;
1327  }
1328  } else {
1329  unsigned lz = (unsigned)__builtin_clzll(low);
1330  length = lz >> 3;
1331  escaped = true;
1332  }
1333  if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped
1334  for (const char* pend = p + length; p != pend; ) {
1335  *q++ = *p++;
1336  }
1337  break;
1338  }
1339  vst1q_u8(reinterpret_cast<uint8_t *>(q), s);
1340  }
1341 
1342  is.src_ = p;
1343  is.dst_ = q;
1344  }
1345 
1346  // When read/write pointers are the same for insitu stream, just skip unescaped characters
1347  static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
1348  RAPIDJSON_ASSERT(is.src_ == is.dst_);
1349  char* p = is.src_;
1350 
1351  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1352  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1353  for (; p != nextAligned; p++)
1354  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1355  is.src_ = is.dst_ = p;
1356  return;
1357  }
1358 
1359  // The rest of string using SIMD
1360  const uint8x16_t s0 = vmovq_n_u8('"');
1361  const uint8x16_t s1 = vmovq_n_u8('\\');
1362  const uint8x16_t s2 = vmovq_n_u8('\b');
1363  const uint8x16_t s3 = vmovq_n_u8(32);
1364 
1365  for (;; p += 16) {
1366  const uint8x16_t s = vld1q_u8(reinterpret_cast<uint8_t *>(p));
1367  uint8x16_t x = vceqq_u8(s, s0);
1368  x = vorrq_u8(x, vceqq_u8(s, s1));
1369  x = vorrq_u8(x, vceqq_u8(s, s2));
1370  x = vorrq_u8(x, vcltq_u8(s, s3));
1371 
1372  x = vrev64q_u8(x); // Rev in 64
1373  uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
1374  uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
1375 
1376  if (low == 0) {
1377  if (high != 0) {
1378  int lz = __builtin_clzll(high);
1379  p += 8 + (lz >> 3);
1380  break;
1381  }
1382  } else {
1383  int lz = __builtin_clzll(low);
1384  p += lz >> 3;
1385  break;
1386  }
1387  }
1388 
1389  is.src_ = is.dst_ = p;
1390  }
1391 #endif // RAPIDJSON_NEON
1392 
1393  template<typename InputStream, bool backup, bool pushOnTake>
1394  class NumberStream;
1395 
1396  template<typename InputStream>
1397  class NumberStream<InputStream, false, false> {
1398  public:
1399  typedef typename InputStream::Ch Ch;
1400 
1401  NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; }
1402 
1403  RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
1404  RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
1405  RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
1406  RAPIDJSON_FORCEINLINE void Push(char) {}
1407 
1408  size_t Tell() { return is.Tell(); }
1409  size_t Length() { return 0; }
1410  const char* Pop() { return 0; }
1411 
1412  protected:
1413  NumberStream& operator=(const NumberStream&);
1414 
1415  InputStream& is;
1416  };
1417 
1418  template<typename InputStream>
1419  class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
1420  typedef NumberStream<InputStream, false, false> Base;
1421  public:
1422  NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
1423 
1424  RAPIDJSON_FORCEINLINE Ch TakePush() {
1425  stackStream.Put(static_cast<char>(Base::is.Peek()));
1426  return Base::is.Take();
1427  }
1428 
1429  RAPIDJSON_FORCEINLINE void Push(char c) {
1430  stackStream.Put(c);
1431  }
1432 
1433  size_t Length() { return stackStream.Length(); }
1434 
1435  const char* Pop() {
1436  stackStream.Put('\0');
1437  return stackStream.Pop();
1438  }
1439 
1440  private:
1441  StackStream<char> stackStream;
1442  };
1443 
1444  template<typename InputStream>
1445  class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
1446  typedef NumberStream<InputStream, true, false> Base;
1447  public:
1448  NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
1449 
1450  RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
1451  };
1452 
1453  template<unsigned parseFlags, typename InputStream, typename Handler>
1454  void ParseNumber(InputStream& is, Handler& handler) {
1455  internal::StreamLocalCopy<InputStream> copy(is);
1456  NumberStream<InputStream,
1457  ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
1458  ((parseFlags & kParseInsituFlag) == 0) :
1459  ((parseFlags & kParseFullPrecisionFlag) != 0),
1460  (parseFlags & kParseNumbersAsStringsFlag) != 0 &&
1461  (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);
1462 
1463  size_t startOffset = s.Tell();
1464  double d = 0.0;
1465  bool useNanOrInf = false;
1466 
1467  // Parse minus
1468  bool minus = Consume(s, '-');
1469 
1470  // Parse int: zero / ( digit1-9 *DIGIT )
1471  unsigned i = 0;
1472  uint64_t i64 = 0;
1473  bool use64bit = false;
1474  int significandDigit = 0;
1475  if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {
1476  i = 0;
1477  s.TakePush();
1478  }
1479  else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {
1480  i = static_cast<unsigned>(s.TakePush() - '0');
1481 
1482  if (minus)
1483  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1484  if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648
1485  if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {
1486  i64 = i;
1487  use64bit = true;
1488  break;
1489  }
1490  }
1491  i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1492  significandDigit++;
1493  }
1494  else
1495  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1496  if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295
1497  if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {
1498  i64 = i;
1499  use64bit = true;
1500  break;
1501  }
1502  }
1503  i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1504  significandDigit++;
1505  }
1506  }
1507  // Parse NaN or Infinity here
1508  else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {
1509  if (Consume(s, 'N')) {
1510  if (Consume(s, 'a') && Consume(s, 'N')) {
1511  d = std::numeric_limits<double>::quiet_NaN();
1512  useNanOrInf = true;
1513  }
1514  }
1515  else if (RAPIDJSON_LIKELY(Consume(s, 'I'))) {
1516  if (Consume(s, 'n') && Consume(s, 'f')) {
1517  d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
1518  useNanOrInf = true;
1519 
1520  if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
1521  && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) {
1523  }
1524  }
1525  }
1526 
1527  if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
1529  }
1530  }
1531  else
1533 
1534  // Parse 64bit int
1535  bool useDouble = false;
1536  if (use64bit) {
1537  if (minus)
1538  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1539  if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808
1540  if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {
1541  d = static_cast<double>(i64);
1542  useDouble = true;
1543  break;
1544  }
1545  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1546  significandDigit++;
1547  }
1548  else
1549  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1550  if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615
1551  if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {
1552  d = static_cast<double>(i64);
1553  useDouble = true;
1554  break;
1555  }
1556  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1557  significandDigit++;
1558  }
1559  }
1560 
1561  // Force double for big integer
1562  if (useDouble) {
1563  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1564  d = d * 10 + (s.TakePush() - '0');
1565  }
1566  }
1567 
1568  // Parse frac = decimal-point 1*DIGIT
1569  int expFrac = 0;
1570  size_t decimalPosition;
1571  if (Consume(s, '.')) {
1572  decimalPosition = s.Length();
1573 
1574  if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
1576 
1577  if (!useDouble) {
1578 #if RAPIDJSON_64BIT
1579  // Use i64 to store significand in 64-bit architecture
1580  if (!use64bit)
1581  i64 = i;
1582 
1583  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1584  if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
1585  break;
1586  else {
1587  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1588  --expFrac;
1589  if (i64 != 0)
1590  significandDigit++;
1591  }
1592  }
1593 
1594  d = static_cast<double>(i64);
1595 #else
1596  // Use double to store significand in 32-bit architecture
1597  d = static_cast<double>(use64bit ? i64 : i);
1598 #endif
1599  useDouble = true;
1600  }
1601 
1602  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1603  if (significandDigit < 17) {
1604  d = d * 10.0 + (s.TakePush() - '0');
1605  --expFrac;
1606  if (RAPIDJSON_LIKELY(d > 0.0))
1607  significandDigit++;
1608  }
1609  else
1610  s.TakePush();
1611  }
1612  }
1613  else
1614  decimalPosition = s.Length(); // decimal position at the end of integer.
1615 
1616  // Parse exp = e [ minus / plus ] 1*DIGIT
1617  int exp = 0;
1618  if (Consume(s, 'e') || Consume(s, 'E')) {
1619  if (!useDouble) {
1620  d = static_cast<double>(use64bit ? i64 : i);
1621  useDouble = true;
1622  }
1623 
1624  bool expMinus = false;
1625  if (Consume(s, '+'))
1626  ;
1627  else if (Consume(s, '-'))
1628  expMinus = true;
1629 
1630  if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1631  exp = static_cast<int>(s.Take() - '0');
1632  if (expMinus) {
1633  // (exp + expFrac) must not underflow int => we're detecting when -exp gets
1634  // dangerously close to INT_MIN (a pessimistic next digit 9 would push it into
1635  // underflow territory):
1636  //
1637  // -(exp * 10 + 9) + expFrac >= INT_MIN
1638  // <=> exp <= (expFrac - INT_MIN - 9) / 10
1639  RAPIDJSON_ASSERT(expFrac <= 0);
1640  int maxExp = (expFrac + 2147483639) / 10;
1641 
1642  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1643  exp = exp * 10 + static_cast<int>(s.Take() - '0');
1644  if (RAPIDJSON_UNLIKELY(exp > maxExp)) {
1645  while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent
1646  s.Take();
1647  }
1648  }
1649  }
1650  else { // positive exp
1651  int maxExp = 308 - expFrac;
1652  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1653  exp = exp * 10 + static_cast<int>(s.Take() - '0');
1654  if (RAPIDJSON_UNLIKELY(exp > maxExp))
1656  }
1657  }
1658  }
1659  else
1661 
1662  if (expMinus)
1663  exp = -exp;
1664  }
1665 
1666  // Finish parsing, call event according to the type of number.
1667  bool cont = true;
1668 
1669  if (parseFlags & kParseNumbersAsStringsFlag) {
1670  if (parseFlags & kParseInsituFlag) {
1671  s.Pop(); // Pop stack no matter if it will be used or not.
1672  typename InputStream::Ch* head = is.PutBegin();
1673  const size_t length = s.Tell() - startOffset;
1674  RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
1675  // unable to insert the \0 character here, it will erase the comma after this number
1676  const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
1677  cont = handler.RawNumber(str, SizeType(length), false);
1678  }
1679  else {
1680  SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
1681  StringStream srcStream(s.Pop());
1682  StackStream<typename TargetEncoding::Ch> dstStream(stack_);
1683  while (numCharsToCopy--) {
1684  Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);
1685  }
1686  dstStream.Put('\0');
1687  const typename TargetEncoding::Ch* str = dstStream.Pop();
1688  const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1;
1689  cont = handler.RawNumber(str, SizeType(length), true);
1690  }
1691  }
1692  else {
1693  size_t length = s.Length();
1694  const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not.
1695 
1696  if (useDouble) {
1697  int p = exp + expFrac;
1698  if (parseFlags & kParseFullPrecisionFlag)
1699  d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
1700  else
1701  d = internal::StrtodNormalPrecision(d, p);
1702 
1703  // Use > max, instead of == inf, to fix bogus warning -Wfloat-equal
1704  if (d > (std::numeric_limits<double>::max)()) {
1705  // Overflow
1706  // TODO: internal::StrtodX should report overflow (or underflow)
1708  }
1709 
1710  cont = handler.Double(minus ? -d : d);
1711  }
1712  else if (useNanOrInf) {
1713  cont = handler.Double(d);
1714  }
1715  else {
1716  if (use64bit) {
1717  if (minus)
1718  cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
1719  else
1720  cont = handler.Uint64(i64);
1721  }
1722  else {
1723  if (minus)
1724  cont = handler.Int(static_cast<int32_t>(~i + 1));
1725  else
1726  cont = handler.Uint(i);
1727  }
1728  }
1729  }
1730  if (RAPIDJSON_UNLIKELY(!cont))
1732  }
1733 
1734  // Parse any JSON value
1735  template<unsigned parseFlags, typename InputStream, typename Handler>
1736  void ParseValue(InputStream& is, Handler& handler) {
1737  switch (is.Peek()) {
1738  case 'n': ParseNull <parseFlags>(is, handler); break;
1739  case 't': ParseTrue <parseFlags>(is, handler); break;
1740  case 'f': ParseFalse <parseFlags>(is, handler); break;
1741  case '"': ParseString<parseFlags>(is, handler); break;
1742  case '{': ParseObject<parseFlags>(is, handler); break;
1743  case '[': ParseArray <parseFlags>(is, handler); break;
1744  default :
1745  ParseNumber<parseFlags>(is, handler);
1746  break;
1747 
1748  }
1749  }
1750 
1751  // Iterative Parsing
1752 
1753  // States
1754  enum IterativeParsingState {
1755  IterativeParsingFinishState = 0, // sink states at top
1756  IterativeParsingErrorState, // sink states at top
1757  IterativeParsingStartState,
1758 
1759  // Object states
1760  IterativeParsingObjectInitialState,
1761  IterativeParsingMemberKeyState,
1762  IterativeParsingMemberValueState,
1763  IterativeParsingObjectFinishState,
1764 
1765  // Array states
1766  IterativeParsingArrayInitialState,
1767  IterativeParsingElementState,
1768  IterativeParsingArrayFinishState,
1769 
1770  // Single value state
1771  IterativeParsingValueState,
1772 
1773  // Delimiter states (at bottom)
1774  IterativeParsingElementDelimiterState,
1775  IterativeParsingMemberDelimiterState,
1776  IterativeParsingKeyValueDelimiterState,
1777 
1778  cIterativeParsingStateCount
1779  };
1780 
1781  // Tokens
1782  enum Token {
1783  LeftBracketToken = 0,
1784  RightBracketToken,
1785 
1786  LeftCurlyBracketToken,
1787  RightCurlyBracketToken,
1788 
1789  CommaToken,
1790  ColonToken,
1791 
1792  StringToken,
1793  FalseToken,
1794  TrueToken,
1795  NullToken,
1796  NumberToken,
1797 
1798  kTokenCount
1799  };
1800 
1801  RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) const {
1802 
1803 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
1804 #define N NumberToken
1805 #define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1806  // Maps from ASCII to Token
1807  static const unsigned char tokenMap[256] = {
1808  N16, // 00~0F
1809  N16, // 10~1F
1810  N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F
1811  N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F
1812  N16, // 40~4F
1813  N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F
1814  N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F
1815  N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F
1816  N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF
1817  };
1818 #undef N
1819 #undef N16
1820 //!@endcond
1821 
1822  if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
1823  return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);
1824  else
1825  return NumberToken;
1826  }
1827 
1828  RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) const {
1829  // current state x one lookahead token -> new state
1830  static const char G[cIterativeParsingStateCount][kTokenCount] = {
1831  // Finish(sink state)
1832  {
1833  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1834  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1835  IterativeParsingErrorState
1836  },
1837  // Error(sink state)
1838  {
1839  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1840  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1841  IterativeParsingErrorState
1842  },
1843  // Start
1844  {
1845  IterativeParsingArrayInitialState, // Left bracket
1846  IterativeParsingErrorState, // Right bracket
1847  IterativeParsingObjectInitialState, // Left curly bracket
1848  IterativeParsingErrorState, // Right curly bracket
1849  IterativeParsingErrorState, // Comma
1850  IterativeParsingErrorState, // Colon
1851  IterativeParsingValueState, // String
1852  IterativeParsingValueState, // False
1853  IterativeParsingValueState, // True
1854  IterativeParsingValueState, // Null
1855  IterativeParsingValueState // Number
1856  },
1857  // ObjectInitial
1858  {
1859  IterativeParsingErrorState, // Left bracket
1860  IterativeParsingErrorState, // Right bracket
1861  IterativeParsingErrorState, // Left curly bracket
1862  IterativeParsingObjectFinishState, // Right curly bracket
1863  IterativeParsingErrorState, // Comma
1864  IterativeParsingErrorState, // Colon
1865  IterativeParsingMemberKeyState, // String
1866  IterativeParsingErrorState, // False
1867  IterativeParsingErrorState, // True
1868  IterativeParsingErrorState, // Null
1869  IterativeParsingErrorState // Number
1870  },
1871  // MemberKey
1872  {
1873  IterativeParsingErrorState, // Left bracket
1874  IterativeParsingErrorState, // Right bracket
1875  IterativeParsingErrorState, // Left curly bracket
1876  IterativeParsingErrorState, // Right curly bracket
1877  IterativeParsingErrorState, // Comma
1878  IterativeParsingKeyValueDelimiterState, // Colon
1879  IterativeParsingErrorState, // String
1880  IterativeParsingErrorState, // False
1881  IterativeParsingErrorState, // True
1882  IterativeParsingErrorState, // Null
1883  IterativeParsingErrorState // Number
1884  },
1885  // MemberValue
1886  {
1887  IterativeParsingErrorState, // Left bracket
1888  IterativeParsingErrorState, // Right bracket
1889  IterativeParsingErrorState, // Left curly bracket
1890  IterativeParsingObjectFinishState, // Right curly bracket
1891  IterativeParsingMemberDelimiterState, // Comma
1892  IterativeParsingErrorState, // Colon
1893  IterativeParsingErrorState, // String
1894  IterativeParsingErrorState, // False
1895  IterativeParsingErrorState, // True
1896  IterativeParsingErrorState, // Null
1897  IterativeParsingErrorState // Number
1898  },
1899  // ObjectFinish(sink state)
1900  {
1901  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1902  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1903  IterativeParsingErrorState
1904  },
1905  // ArrayInitial
1906  {
1907  IterativeParsingArrayInitialState, // Left bracket(push Element state)
1908  IterativeParsingArrayFinishState, // Right bracket
1909  IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1910  IterativeParsingErrorState, // Right curly bracket
1911  IterativeParsingErrorState, // Comma
1912  IterativeParsingErrorState, // Colon
1913  IterativeParsingElementState, // String
1914  IterativeParsingElementState, // False
1915  IterativeParsingElementState, // True
1916  IterativeParsingElementState, // Null
1917  IterativeParsingElementState // Number
1918  },
1919  // Element
1920  {
1921  IterativeParsingErrorState, // Left bracket
1922  IterativeParsingArrayFinishState, // Right bracket
1923  IterativeParsingErrorState, // Left curly bracket
1924  IterativeParsingErrorState, // Right curly bracket
1925  IterativeParsingElementDelimiterState, // Comma
1926  IterativeParsingErrorState, // Colon
1927  IterativeParsingErrorState, // String
1928  IterativeParsingErrorState, // False
1929  IterativeParsingErrorState, // True
1930  IterativeParsingErrorState, // Null
1931  IterativeParsingErrorState // Number
1932  },
1933  // ArrayFinish(sink state)
1934  {
1935  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1936  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1937  IterativeParsingErrorState
1938  },
1939  // Single Value (sink state)
1940  {
1941  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1942  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1943  IterativeParsingErrorState
1944  },
1945  // ElementDelimiter
1946  {
1947  IterativeParsingArrayInitialState, // Left bracket(push Element state)
1948  IterativeParsingArrayFinishState, // Right bracket
1949  IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1950  IterativeParsingErrorState, // Right curly bracket
1951  IterativeParsingErrorState, // Comma
1952  IterativeParsingErrorState, // Colon
1953  IterativeParsingElementState, // String
1954  IterativeParsingElementState, // False
1955  IterativeParsingElementState, // True
1956  IterativeParsingElementState, // Null
1957  IterativeParsingElementState // Number
1958  },
1959  // MemberDelimiter
1960  {
1961  IterativeParsingErrorState, // Left bracket
1962  IterativeParsingErrorState, // Right bracket
1963  IterativeParsingErrorState, // Left curly bracket
1964  IterativeParsingObjectFinishState, // Right curly bracket
1965  IterativeParsingErrorState, // Comma
1966  IterativeParsingErrorState, // Colon
1967  IterativeParsingMemberKeyState, // String
1968  IterativeParsingErrorState, // False
1969  IterativeParsingErrorState, // True
1970  IterativeParsingErrorState, // Null
1971  IterativeParsingErrorState // Number
1972  },
1973  // KeyValueDelimiter
1974  {
1975  IterativeParsingArrayInitialState, // Left bracket(push MemberValue state)
1976  IterativeParsingErrorState, // Right bracket
1977  IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state)
1978  IterativeParsingErrorState, // Right curly bracket
1979  IterativeParsingErrorState, // Comma
1980  IterativeParsingErrorState, // Colon
1981  IterativeParsingMemberValueState, // String
1982  IterativeParsingMemberValueState, // False
1983  IterativeParsingMemberValueState, // True
1984  IterativeParsingMemberValueState, // Null
1985  IterativeParsingMemberValueState // Number
1986  },
1987  }; // End of G
1988 
1989  return static_cast<IterativeParsingState>(G[state][token]);
1990  }
1991 
1992  // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
1993  // May return a new state on state pop.
1994  template <unsigned parseFlags, typename InputStream, typename Handler>
1995  RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
1996  (void)token;
1997 
1998  switch (dst) {
1999  case IterativeParsingErrorState:
2000  return dst;
2001 
2002  case IterativeParsingObjectInitialState:
2003  case IterativeParsingArrayInitialState:
2004  {
2005  // Push the state(Element or MemeberValue) if we are nested in another array or value of member.
2006  // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
2007  IterativeParsingState n = src;
2008  if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
2009  n = IterativeParsingElementState;
2010  else if (src == IterativeParsingKeyValueDelimiterState)
2011  n = IterativeParsingMemberValueState;
2012  // Push current state.
2013  *stack_.template Push<SizeType>(1) = n;
2014  // Initialize and push the member/element count.
2015  *stack_.template Push<SizeType>(1) = 0;
2016  // Call handler
2017  bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
2018  // On handler short circuits the parsing.
2019  if (!hr) {
2021  return IterativeParsingErrorState;
2022  }
2023  else {
2024  is.Take();
2025  return dst;
2026  }
2027  }
2028 
2029  case IterativeParsingMemberKeyState:
2030  ParseString<parseFlags>(is, handler, true);
2031  if (HasParseError())
2032  return IterativeParsingErrorState;
2033  else
2034  return dst;
2035 
2036  case IterativeParsingKeyValueDelimiterState:
2037  RAPIDJSON_ASSERT(token == ColonToken);
2038  is.Take();
2039  return dst;
2040 
2041  case IterativeParsingMemberValueState:
2042  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
2043  ParseValue<parseFlags>(is, handler);
2044  if (HasParseError()) {
2045  return IterativeParsingErrorState;
2046  }
2047  return dst;
2048 
2049  case IterativeParsingElementState:
2050  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
2051  ParseValue<parseFlags>(is, handler);
2052  if (HasParseError()) {
2053  return IterativeParsingErrorState;
2054  }
2055  return dst;
2056 
2057  case IterativeParsingMemberDelimiterState:
2058  case IterativeParsingElementDelimiterState:
2059  is.Take();
2060  // Update member/element count.
2061  *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
2062  return dst;
2063 
2064  case IterativeParsingObjectFinishState:
2065  {
2066  // Transit from delimiter is only allowed when trailing commas are enabled
2067  if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {
2069  return IterativeParsingErrorState;
2070  }
2071  // Get member count.
2072  SizeType c = *stack_.template Pop<SizeType>(1);
2073  // If the object is not empty, count the last member.
2074  if (src == IterativeParsingMemberValueState)
2075  ++c;
2076  // Restore the state.
2077  IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
2078  // Transit to Finish state if this is the topmost scope.
2079  if (n == IterativeParsingStartState)
2080  n = IterativeParsingFinishState;
2081  // Call handler
2082  bool hr = handler.EndObject(c);
2083  // On handler short circuits the parsing.
2084  if (!hr) {
2086  return IterativeParsingErrorState;
2087  }
2088  else {
2089  is.Take();
2090  return n;
2091  }
2092  }
2093 
2094  case IterativeParsingArrayFinishState:
2095  {
2096  // Transit from delimiter is only allowed when trailing commas are enabled
2097  if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {
2099  return IterativeParsingErrorState;
2100  }
2101  // Get element count.
2102  SizeType c = *stack_.template Pop<SizeType>(1);
2103  // If the array is not empty, count the last element.
2104  if (src == IterativeParsingElementState)
2105  ++c;
2106  // Restore the state.
2107  IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
2108  // Transit to Finish state if this is the topmost scope.
2109  if (n == IterativeParsingStartState)
2110  n = IterativeParsingFinishState;
2111  // Call handler
2112  bool hr = handler.EndArray(c);
2113  // On handler short circuits the parsing.
2114  if (!hr) {
2116  return IterativeParsingErrorState;
2117  }
2118  else {
2119  is.Take();
2120  return n;
2121  }
2122  }
2123 
2124  default:
2125  // This branch is for IterativeParsingValueState actually.
2126  // Use `default:` rather than
2127  // `case IterativeParsingValueState:` is for code coverage.
2128 
2129  // The IterativeParsingStartState is not enumerated in this switch-case.
2130  // It is impossible for that case. And it can be caught by following assertion.
2131 
2132  // The IterativeParsingFinishState is not enumerated in this switch-case either.
2133  // It is a "derivative" state which cannot triggered from Predict() directly.
2134  // Therefore it cannot happen here. And it can be caught by following assertion.
2135  RAPIDJSON_ASSERT(dst == IterativeParsingValueState);
2136 
2137  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
2138  ParseValue<parseFlags>(is, handler);
2139  if (HasParseError()) {
2140  return IterativeParsingErrorState;
2141  }
2142  return IterativeParsingFinishState;
2143  }
2144  }
2145 
2146  template <typename InputStream>
2147  void HandleError(IterativeParsingState src, InputStream& is) {
2148  if (HasParseError()) {
2149  // Error flag has been set.
2150  return;
2151  }
2152 
2153  switch (src) {
2154  case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
2155  case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
2156  case IterativeParsingObjectInitialState:
2157  case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
2158  case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
2159  case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
2160  case IterativeParsingKeyValueDelimiterState:
2161  case IterativeParsingArrayInitialState:
2162  case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return;
2163  default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
2164  }
2165  }
2166 
2167  RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const {
2168  return s >= IterativeParsingElementDelimiterState;
2169  }
2170 
2171  RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const {
2172  return s <= IterativeParsingErrorState;
2173  }
2174 
2175  template <unsigned parseFlags, typename InputStream, typename Handler>
2176  ParseResult IterativeParse(InputStream& is, Handler& handler) {
2177  parseResult_.Clear();
2178  ClearStackOnExit scope(*this);
2179  IterativeParsingState state = IterativeParsingStartState;
2180 
2181  SkipWhitespaceAndComments<parseFlags>(is);
2182  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
2183  while (is.Peek() != '\0') {
2184  Token t = Tokenize(is.Peek());
2185  IterativeParsingState n = Predict(state, t);
2186  IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
2187 
2188  if (d == IterativeParsingErrorState) {
2189  HandleError(state, is);
2190  break;
2191  }
2192 
2193  state = d;
2194 
2195  // Do not further consume streams if a root JSON has been parsed.
2196  if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
2197  break;
2198 
2199  SkipWhitespaceAndComments<parseFlags>(is);
2200  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
2201  }
2202 
2203  // Handle the end of file.
2204  if (state != IterativeParsingFinishState)
2205  HandleError(state, is);
2206 
2207  return parseResult_;
2208  }
2209 
2210  static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string.
2211  internal::Stack<StackAllocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing.
2212  ParseResult parseResult_;
2213  IterativeParsingState state_;
2214 }; // class GenericReader
2215 
2216 //! Reader with UTF8 encoding and default allocator.
2218 
2219 RAPIDJSON_NAMESPACE_END
2220 
2221 #if defined(__clang__) || defined(_MSC_VER)
2222 RAPIDJSON_DIAG_POP
2223 #endif
2224 
2225 
2226 #ifdef __GNUC__
2227 RAPIDJSON_DIAG_POP
2228 #endif
2229 
2230 #endif // RAPIDJSON_READER_H_
Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
Definition: reader.h:155
Read-only string stream.
Definition: fwd.h:47
Iterative(constant complexity in terms of function call stack size) parsing.
Definition: reader.h:149
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
Parse all numbers (ints/doubles) as strings.
Definition: reader.h:153
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition: reader.h:557
Validate encoding of JSON strings.
Definition: reader.h:148
Invalid value.
Definition: error.h:70
The surrogate pair in string is invalid.
Definition: error.h:79
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:118
RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const
Check if token-by-token parsing JSON text is complete.
Definition: reader.h:675
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:289
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: fwd.h:88
Encoding conversion.
Definition: encodings.h:658
Missing a colon after a name of object member.
Definition: error.h:73
Incorrect hex digit after \u escape in string.
Definition: error.h:78
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
Definition: reader.h:683
Miss fraction part in number.
Definition: error.h:85
unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:384
bool RawNumber(const Ch *str, SizeType len, bool copy)
enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) ...
Definition: reader.h:210
ParseErrorCode
Error code of parsing.
Definition: error.h:64
GenericReader(StackAllocator *stackAllocator=0, size_t stackCapacity=kDefaultStackCapacity)
Constructor.
Definition: reader.h:545
void Clear()
Reset error code.
Definition: error.h:134
Represents an in-memory input byte stream.
Definition: memorystream.h:40
Missing a comma or &#39;]&#39; after an array element.
Definition: error.h:76
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition: reader.h:680
SourceEncoding::Ch Ch
SourceEncoding character type.
Definition: reader.h:539
The document root must not follow by other values.
Definition: error.h:68
const Ch * src_
Current read position.
Definition: stream.h:168
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)
Macro to indicate a parse error.
Definition: reader.h:99
Allow trailing commas at the end of objects and arrays.
Definition: reader.h:154
No flags are set.
Definition: reader.h:146
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:463
Unspecific syntax error.
Definition: error.h:89
Parse number in full precision (but slower).
Definition: reader.h:151
Missing a closing quotation mark in string.
Definition: error.h:81
Invalid escape character in string.
Definition: error.h:80
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
Missing a name for object member.
Definition: error.h:72
Type
Type of JSON value.
Definition: rapidjson.h:642
After parsing a complete JSON root from stream, stop further processing the rest of stream...
Definition: reader.h:150
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition: reader.h:264
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:476
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: reader.h:686
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS. ...
Definition: reader.h:156
ParseFlag
Combination of parseFlags.
Definition: reader.h:145
Allow one-line (//) and multi-line (/**/) comments.
Definition: reader.h:152
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:39
Parsing was terminated.
Definition: error.h:88
Number too big to be stored in double.
Definition: error.h:84
Default implementation of Handler.
Definition: fwd.h:85
Miss exponent in number.
Definition: error.h:86
void IterativeParseInit()
Initialize JSON text token-by-token parsing.
Definition: reader.h:605
In-situ(destructive) parsing.
Definition: reader.h:147
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text (with kParseDefaultFlags)
Definition: reader.h:598
UTF-8 encoding.
Definition: encodings.h:96
bool IterativeParseNext(InputStream &is, Handler &handler)
Parse one token from JSON text.
Definition: reader.h:618
The document is empty.
Definition: error.h:67
Missing a comma or &#39;}&#39; after an object member.
Definition: error.h:74
Invalid encoding in string.
Definition: error.h:82
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:406
#define RAPIDJSON_PARSE_DEFAULT_FLAGS
User-defined kParseDefaultFlags definition.
Definition: reader.h:139
A read-write string stream.
Definition: fwd.h:52