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