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