identt
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 
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 #endif
37 
38 #ifdef _MSC_VER
39 RAPIDJSON_DIAG_PUSH
40 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
41 RAPIDJSON_DIAG_OFF(4702) // unreachable code
42 #endif
43 
44 #ifdef __clang__
45 RAPIDJSON_DIAG_PUSH
46 RAPIDJSON_DIAG_OFF(old-style-cast)
47 RAPIDJSON_DIAG_OFF(padded)
48 RAPIDJSON_DIAG_OFF(switch-enum)
49 #endif
50 
51 #ifdef __GNUC__
52 RAPIDJSON_DIAG_PUSH
53 RAPIDJSON_DIAG_OFF(effc++)
54 #endif
55 
57 #define RAPIDJSON_NOTHING /* deliberately empty */
58 #ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
59 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
60  RAPIDJSON_MULTILINEMACRO_BEGIN \
61  if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
62  RAPIDJSON_MULTILINEMACRO_END
63 #endif
64 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
65  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
66 
98 #ifndef RAPIDJSON_PARSE_ERROR_NORETURN
99 #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
100  RAPIDJSON_MULTILINEMACRO_BEGIN \
101  RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
102  SetParseError(parseErrorCode, offset); \
103  RAPIDJSON_MULTILINEMACRO_END
104 #endif
105 
117 #ifndef RAPIDJSON_PARSE_ERROR
118 #define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \
119  RAPIDJSON_MULTILINEMACRO_BEGIN \
120  RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
121  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
122  RAPIDJSON_MULTILINEMACRO_END
123 #endif
124 
125 #include "error/error.h" // ParseErrorCode, ParseResult
126 
128 
130 // ParseFlag
131 
138 #ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS
139 #define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags
140 #endif
141 
143 
145 enum ParseFlag {
156  kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS
157 };
158 
160 // Handler
161 
178 
188 // BaseReaderHandler
190 
192 
195 template<typename Encoding = UTF8<>, typename Derived = void>
196 struct BaseReaderHandler {
197  typedef typename Encoding::Ch Ch;
198 
199  typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override;
200 
201  bool Default() { return true; }
202  bool Null() { return static_cast<Override&>(*this).Default(); }
203  bool Bool(bool) { return static_cast<Override&>(*this).Default(); }
204  bool Int(int) { return static_cast<Override&>(*this).Default(); }
205  bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); }
206  bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); }
207  bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); }
208  bool Double(double) { return static_cast<Override&>(*this).Default(); }
210  bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
211  bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); }
212  bool StartObject() { return static_cast<Override&>(*this).Default(); }
213  bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
214  bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }
215  bool StartArray() { return static_cast<Override&>(*this).Default(); }
216  bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }
217 };
218 
220 // StreamLocalCopy
221 
222 namespace internal {
223 
224 template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
226 
228 template<typename Stream>
229 class StreamLocalCopy<Stream, 1> {
230 public:
231  StreamLocalCopy(Stream& original) : s(original), original_(original) {}
232  ~StreamLocalCopy() { original_ = s; }
233 
234  Stream s;
235 
236 private:
237  StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
238 
239  Stream& original_;
240 };
241 
243 template<typename Stream>
244 class StreamLocalCopy<Stream, 0> {
245 public:
246  StreamLocalCopy(Stream& original) : s(original) {}
247 
248  Stream& s;
249 
250 private:
251  StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
252 };
253 
254 } // namespace internal
255 
257 // SkipWhitespace
258 
260 
263 template<typename InputStream>
264 void SkipWhitespace(InputStream& is) {
266  InputStream& s(copy.s);
267 
268  typename InputStream::Ch c;
269  while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t')
270  s.Take();
271 }
272 
273 inline const char* SkipWhitespace(const char* p, const char* end) {
274  while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
275  ++p;
276  return p;
277 }
278 
279 #ifdef RAPIDJSON_SSE42
280 inline const char *SkipWhitespace_SIMD(const char* p) {
282  // Fast return for single non-whitespace
283  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
284  ++p;
285  else
286  return p;
287 
288  // 16-byte align to the next boundary
289  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
290  while (p != nextAligned)
291  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
292  ++p;
293  else
294  return p;
295 
296  // The rest of string using SIMD
297  static const char whitespace[16] = " \n\r\t";
298  const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
299 
300  for (;; p += 16) {
301  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
302  const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
303  if (r != 16) // some of characters is non-whitespace
304  return p + r;
305  }
306 }
307 
308 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
309  // Fast return for single non-whitespace
310  if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
311  ++p;
312  else
313  return p;
314 
315  // The middle of string using SIMD
316  static const char whitespace[16] = " \n\r\t";
317  const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
318 
319  for (; p <= end - 16; p += 16) {
320  const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
321  const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
322  if (r != 16) // some of characters is non-whitespace
323  return p + r;
324  }
325 
326  return SkipWhitespace(p, end);
327 }
328 
329 #elif defined(RAPIDJSON_SSE2)
330 
332 inline const char *SkipWhitespace_SIMD(const char* p) {
333  // Fast return for single non-whitespace
334  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
335  ++p;
336  else
337  return p;
338 
339  // 16-byte align to the next boundary
340  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
341  while (p != nextAligned)
342  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
343  ++p;
344  else
345  return p;
346 
347  // The rest of string
348  #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
349  static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
350  #undef C16
351 
352  const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
353  const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
354  const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
355  const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
356 
357  for (;; p += 16) {
358  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
359  __m128i x = _mm_cmpeq_epi8(s, w0);
360  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
361  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
362  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
363  unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
364  if (r != 0) { // some of characters may be non-whitespace
365 #ifdef _MSC_VER // Find the index of first non-whitespace
366  unsigned long offset;
367  _BitScanForward(&offset, r);
368  return p + offset;
369 #else
370  return p + __builtin_ffs(r) - 1;
371 #endif
372  }
373  }
374 }
375 
376 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
377  // Fast return for single non-whitespace
378  if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
379  ++p;
380  else
381  return p;
382 
383  // The rest of string
384  #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
385  static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
386  #undef C16
387 
388  const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
389  const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
390  const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
391  const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
392 
393  for (; p <= end - 16; p += 16) {
394  const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
395  __m128i x = _mm_cmpeq_epi8(s, w0);
396  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
397  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
398  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
399  unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
400  if (r != 0) { // some of characters may be non-whitespace
401 #ifdef _MSC_VER // Find the index of first non-whitespace
402  unsigned long offset;
403  _BitScanForward(&offset, r);
404  return p + offset;
405 #else
406  return p + __builtin_ffs(r) - 1;
407 #endif
408  }
409  }
410 
411  return SkipWhitespace(p, end);
412 }
413 
414 #endif // RAPIDJSON_SSE2
415 
416 #ifdef RAPIDJSON_SIMD
417 template<> inline void SkipWhitespace(InsituStringStream& is) {
419  is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
420 }
421 
423 template<> inline void SkipWhitespace(StringStream& is) {
424  is.src_ = SkipWhitespace_SIMD(is.src_);
425 }
426 
427 template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {
428  is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
429 }
430 #endif // RAPIDJSON_SIMD
431 
433 // GenericReader
434 
436 
451 template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
452 class GenericReader {
453 public:
454  typedef typename SourceEncoding::Ch Ch;
455 
457 
460  GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {}
461 
463 
470  template <unsigned parseFlags, typename InputStream, typename Handler>
471  ParseResult Parse(InputStream& is, Handler& handler) {
472  if (parseFlags & kParseIterativeFlag)
473  return IterativeParse<parseFlags>(is, handler);
474 
475  parseResult_.Clear();
476 
477  ClearStackOnExit scope(*this);
478 
479  SkipWhitespaceAndComments<parseFlags>(is);
480  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
481 
482  if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) {
484  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
485  }
486  else {
487  ParseValue<parseFlags>(is, handler);
488  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
489 
490  if (!(parseFlags & kParseStopWhenDoneFlag)) {
491  SkipWhitespaceAndComments<parseFlags>(is);
492  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
493 
494  if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) {
496  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
497  }
498  }
499  }
500 
501  return parseResult_;
502  }
503 
505 
511  template <typename InputStream, typename Handler>
512  ParseResult Parse(InputStream& is, Handler& handler) {
513  return Parse<kParseDefaultFlags>(is, handler);
514  }
515 
517  bool HasParseError() const { return parseResult_.IsError(); }
518 
520  ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }
521 
523  size_t GetErrorOffset() const { return parseResult_.Offset(); }
524 
525 protected:
526  void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
527 
528 private:
529  // Prohibit copy constructor & assignment operator.
531  GenericReader& operator=(const GenericReader&);
532 
533  void ClearStack() { stack_.Clear(); }
534 
535  // clear stack on any exit from ParseStream, e.g. due to exception
536  struct ClearStackOnExit {
537  explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
538  ~ClearStackOnExit() { r_.ClearStack(); }
539  private:
540  GenericReader& r_;
541  ClearStackOnExit(const ClearStackOnExit&);
542  ClearStackOnExit& operator=(const ClearStackOnExit&);
543  };
544 
545  template<unsigned parseFlags, typename InputStream>
546  void SkipWhitespaceAndComments(InputStream& is) {
547  SkipWhitespace(is);
548 
549  if (parseFlags & kParseCommentsFlag) {
550  while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) {
551  if (Consume(is, '*')) {
552  while (true) {
553  if (RAPIDJSON_UNLIKELY(is.Peek() == '\0'))
555  else if (Consume(is, '*')) {
556  if (Consume(is, '/'))
557  break;
558  }
559  else
560  is.Take();
561  }
562  }
563  else if (RAPIDJSON_LIKELY(Consume(is, '/')))
564  while (is.Peek() != '\0' && is.Take() != '\n') {}
565  else
567 
568  SkipWhitespace(is);
569  }
570  }
571  }
572 
573  // Parse object: { string : value, ... }
574  template<unsigned parseFlags, typename InputStream, typename Handler>
575  void ParseObject(InputStream& is, Handler& handler) {
576  RAPIDJSON_ASSERT(is.Peek() == '{');
577  is.Take(); // Skip '{'
578 
579  if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
581 
582  SkipWhitespaceAndComments<parseFlags>(is);
583  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
584 
585  if (Consume(is, '}')) {
586  if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object
588  return;
589  }
590 
591  for (SizeType memberCount = 0;;) {
592  if (RAPIDJSON_UNLIKELY(is.Peek() != '"'))
594 
595  ParseString<parseFlags>(is, handler, true);
596  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
597 
598  SkipWhitespaceAndComments<parseFlags>(is);
599  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
600 
601  if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))
603 
604  SkipWhitespaceAndComments<parseFlags>(is);
605  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
606 
607  ParseValue<parseFlags>(is, handler);
608  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
609 
610  SkipWhitespaceAndComments<parseFlags>(is);
611  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
612 
613  ++memberCount;
614 
615  switch (is.Peek()) {
616  case ',':
617  is.Take();
618  SkipWhitespaceAndComments<parseFlags>(is);
619  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
620  break;
621  case '}':
622  is.Take();
623  if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
625  return;
626  default:
627  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy
628  }
629 
630  if (parseFlags & kParseTrailingCommasFlag) {
631  if (is.Peek() == '}') {
632  if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
634  is.Take();
635  return;
636  }
637  }
638  }
639  }
640 
641  // Parse array: [ value, ... ]
642  template<unsigned parseFlags, typename InputStream, typename Handler>
643  void ParseArray(InputStream& is, Handler& handler) {
644  RAPIDJSON_ASSERT(is.Peek() == '[');
645  is.Take(); // Skip '['
646 
647  if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
649 
650  SkipWhitespaceAndComments<parseFlags>(is);
651  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
652 
653  if (Consume(is, ']')) {
654  if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array
656  return;
657  }
658 
659  for (SizeType elementCount = 0;;) {
660  ParseValue<parseFlags>(is, handler);
661  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
662 
663  ++elementCount;
664  SkipWhitespaceAndComments<parseFlags>(is);
665  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
666 
667  if (Consume(is, ',')) {
668  SkipWhitespaceAndComments<parseFlags>(is);
669  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
670  }
671  else if (Consume(is, ']')) {
672  if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
674  return;
675  }
676  else
678 
679  if (parseFlags & kParseTrailingCommasFlag) {
680  if (is.Peek() == ']') {
681  if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
683  is.Take();
684  return;
685  }
686  }
687  }
688  }
689 
690  template<unsigned parseFlags, typename InputStream, typename Handler>
691  void ParseNull(InputStream& is, Handler& handler) {
692  RAPIDJSON_ASSERT(is.Peek() == 'n');
693  is.Take();
694 
695  if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {
696  if (RAPIDJSON_UNLIKELY(!handler.Null()))
698  }
699  else
701  }
702 
703  template<unsigned parseFlags, typename InputStream, typename Handler>
704  void ParseTrue(InputStream& is, Handler& handler) {
705  RAPIDJSON_ASSERT(is.Peek() == 't');
706  is.Take();
707 
708  if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {
709  if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))
711  }
712  else
714  }
715 
716  template<unsigned parseFlags, typename InputStream, typename Handler>
717  void ParseFalse(InputStream& is, Handler& handler) {
718  RAPIDJSON_ASSERT(is.Peek() == 'f');
719  is.Take();
720 
721  if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {
722  if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))
724  }
725  else
727  }
728 
729  template<typename InputStream>
730  RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
731  if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
732  is.Take();
733  return true;
734  }
735  else
736  return false;
737  }
738 
739  // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
740  template<typename InputStream>
741  unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
742  unsigned codepoint = 0;
743  for (int i = 0; i < 4; i++) {
744  Ch c = is.Peek();
745  codepoint <<= 4;
746  codepoint += static_cast<unsigned>(c);
747  if (c >= '0' && c <= '9')
748  codepoint -= '0';
749  else if (c >= 'A' && c <= 'F')
750  codepoint -= 'A' - 10;
751  else if (c >= 'a' && c <= 'f')
752  codepoint -= 'a' - 10;
753  else {
755  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
756  }
757  is.Take();
758  }
759  return codepoint;
760  }
761 
762  template <typename CharType>
763  class StackStream {
764  public:
765  typedef CharType Ch;
766 
767  StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {}
768  RAPIDJSON_FORCEINLINE void Put(Ch c) {
769  *stack_.template Push<Ch>() = c;
770  ++length_;
771  }
772 
773  RAPIDJSON_FORCEINLINE void* Push(SizeType count) {
774  length_ += count;
775  return stack_.template Push<Ch>(count);
776  }
777 
778  size_t Length() const { return length_; }
779 
780  Ch* Pop() {
781  return stack_.template Pop<Ch>(length_);
782  }
783 
784  private:
785  StackStream(const StackStream&);
786  StackStream& operator=(const StackStream&);
787 
789  SizeType length_;
790  };
791 
792  // Parse string and generate String event. Different code paths for kParseInsituFlag.
793  template<unsigned parseFlags, typename InputStream, typename Handler>
794  void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
796  InputStream& s(copy.s);
797 
798  RAPIDJSON_ASSERT(s.Peek() == '\"');
799  s.Take(); // Skip '\"'
800 
801  bool success = false;
802  if (parseFlags & kParseInsituFlag) {
803  typename InputStream::Ch *head = s.PutBegin();
804  ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
805  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
806  size_t length = s.PutEnd(head) - 1;
807  RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
808  const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
809  success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
810  }
811  else {
812  StackStream<typename TargetEncoding::Ch> stackStream(stack_);
813  ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
814  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
815  SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;
816  const typename TargetEncoding::Ch* const str = stackStream.Pop();
817  success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
818  }
819  if (RAPIDJSON_UNLIKELY(!success))
821  }
822 
823  // Parse string to an output is
824  // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
825  template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
826  RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
828 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
829  static const char escape[256] = {
830  Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
831  Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
832  0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
833  0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
834  Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
835  };
836 #undef Z16
837 
839  for (;;) {
840  // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
841  if (!(parseFlags & kParseValidateEncodingFlag))
842  ScanCopyUnescapedString(is, os);
843 
844  Ch c = is.Peek();
845  if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape
846  size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset
847  is.Take();
848  Ch e = is.Peek();
849  if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
850  is.Take();
851  os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
852  }
853  else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
854  is.Take();
855  unsigned codepoint = ParseHex4(is, escapeOffset);
856  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
857  if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
858  // Handle UTF-16 surrogate pair
859  if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
861  unsigned codepoint2 = ParseHex4(is, escapeOffset);
862  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
863  if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
865  codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
866  }
867  TEncoding::Encode(os, codepoint);
868  }
869  else
871  }
872  else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote
873  is.Take();
874  os.Put('\0'); // null-terminate the string
875  return;
876  }
877  else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
878  if (c == '\0')
880  else
882  }
883  else {
884  size_t offset = is.Tell();
885  if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
889  }
890  }
891  }
892 
893  template<typename InputStream, typename OutputStream>
894  static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {
895  // Do nothing for generic version
896  }
897 
898 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
899  // StringStream -> StackStream<char>
900  static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
901  const char* p = is.src_;
902 
903  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
904  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
905  while (p != nextAligned)
906  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
907  is.src_ = p;
908  return;
909  }
910  else
911  os.Put(*p++);
912 
913  // The rest of string using SIMD
914  static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
915  static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
916  static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
917  const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
918  const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
919  const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
920 
921  for (;; p += 16) {
922  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
923  const __m128i t1 = _mm_cmpeq_epi8(s, dq);
924  const __m128i t2 = _mm_cmpeq_epi8(s, bs);
925  const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
926  const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
927  unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
928  if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
929  SizeType length;
930  #ifdef _MSC_VER // Find the index of first escaped
931  unsigned long offset;
932  _BitScanForward(&offset, r);
933  length = offset;
934  #else
935  length = static_cast<SizeType>(__builtin_ffs(r) - 1);
936  #endif
937  char* q = reinterpret_cast<char*>(os.Push(length));
938  for (size_t i = 0; i < length; i++)
939  q[i] = p[i];
940 
941  p += length;
942  break;
943  }
944  _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);
945  }
946 
947  is.src_ = p;
948  }
949 
950  // InsituStringStream -> InsituStringStream
951  static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
952  RAPIDJSON_ASSERT(&is == &os);
953  (void)os;
954 
955  if (is.src_ == is.dst_) {
956  SkipUnescapedString(is);
957  return;
958  }
959 
960  char* p = is.src_;
961  char *q = is.dst_;
962 
963  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
964  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
965  while (p != nextAligned)
966  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
967  is.src_ = p;
968  is.dst_ = q;
969  return;
970  }
971  else
972  *q++ = *p++;
973 
974  // The rest of string using SIMD
975  static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
976  static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
977  static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
978  const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
979  const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
980  const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
981 
982  for (;; p += 16, q += 16) {
983  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
984  const __m128i t1 = _mm_cmpeq_epi8(s, dq);
985  const __m128i t2 = _mm_cmpeq_epi8(s, bs);
986  const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
987  const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
988  unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
989  if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
990  size_t length;
991 #ifdef _MSC_VER // Find the index of first escaped
992  unsigned long offset;
993  _BitScanForward(&offset, r);
994  length = offset;
995 #else
996  length = static_cast<size_t>(__builtin_ffs(r) - 1);
997 #endif
998  for (const char* pend = p + length; p != pend; )
999  *q++ = *p++;
1000  break;
1001  }
1002  _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);
1003  }
1004 
1005  is.src_ = p;
1006  is.dst_ = q;
1007  }
1008 
1009  // When read/write pointers are the same for insitu stream, just skip unescaped characters
1010  static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
1011  RAPIDJSON_ASSERT(is.src_ == is.dst_);
1012  char* p = is.src_;
1013 
1014  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1015  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1016  for (; p != nextAligned; p++)
1017  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1018  is.src_ = is.dst_ = p;
1019  return;
1020  }
1021 
1022  // The rest of string using SIMD
1023  static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1024  static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1025  static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
1026  const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1027  const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1028  const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1029 
1030  for (;; p += 16) {
1031  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1032  const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1033  const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1034  const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
1035  const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1036  unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1037  if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1038  size_t length;
1039 #ifdef _MSC_VER // Find the index of first escaped
1040  unsigned long offset;
1041  _BitScanForward(&offset, r);
1042  length = offset;
1043 #else
1044  length = static_cast<size_t>(__builtin_ffs(r) - 1);
1045 #endif
1046  p += length;
1047  break;
1048  }
1049  }
1050 
1051  is.src_ = is.dst_ = p;
1052  }
1053 #endif
1054 
1055  template<typename InputStream, bool backup, bool pushOnTake>
1056  class NumberStream;
1057 
1058  template<typename InputStream>
1059  class NumberStream<InputStream, false, false> {
1060  public:
1061  typedef typename InputStream::Ch Ch;
1062 
1063  NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; }
1064 
1065  RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
1066  RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
1067  RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
1068  RAPIDJSON_FORCEINLINE void Push(char) {}
1069 
1070  size_t Tell() { return is.Tell(); }
1071  size_t Length() { return 0; }
1072  const char* Pop() { return 0; }
1073 
1074  protected:
1075  NumberStream& operator=(const NumberStream&);
1076 
1077  InputStream& is;
1078  };
1079 
1080  template<typename InputStream>
1081  class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
1082  typedef NumberStream<InputStream, false, false> Base;
1083  public:
1084  NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
1085 
1086  RAPIDJSON_FORCEINLINE Ch TakePush() {
1087  stackStream.Put(static_cast<char>(Base::is.Peek()));
1088  return Base::is.Take();
1089  }
1090 
1091  RAPIDJSON_FORCEINLINE void Push(char c) {
1092  stackStream.Put(c);
1093  }
1094 
1095  size_t Length() { return stackStream.Length(); }
1096 
1097  const char* Pop() {
1098  stackStream.Put('\0');
1099  return stackStream.Pop();
1100  }
1101 
1102  private:
1103  StackStream<char> stackStream;
1104  };
1105 
1106  template<typename InputStream>
1107  class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
1108  typedef NumberStream<InputStream, true, false> Base;
1109  public:
1110  NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
1111 
1112  RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
1113  };
1114 
1115  template<unsigned parseFlags, typename InputStream, typename Handler>
1116  void ParseNumber(InputStream& is, Handler& handler) {
1118  NumberStream<InputStream,
1119  ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
1120  ((parseFlags & kParseInsituFlag) == 0) :
1121  ((parseFlags & kParseFullPrecisionFlag) != 0),
1122  (parseFlags & kParseNumbersAsStringsFlag) != 0 &&
1123  (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);
1124 
1125  size_t startOffset = s.Tell();
1126  double d = 0.0;
1127  bool useNanOrInf = false;
1128 
1129  // Parse minus
1130  bool minus = Consume(s, '-');
1131 
1132  // Parse int: zero / ( digit1-9 *DIGIT )
1133  unsigned i = 0;
1134  uint64_t i64 = 0;
1135  bool use64bit = false;
1136  int significandDigit = 0;
1137  if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {
1138  i = 0;
1139  s.TakePush();
1140  }
1141  else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {
1142  i = static_cast<unsigned>(s.TakePush() - '0');
1143 
1144  if (minus)
1145  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1146  if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648
1147  if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {
1148  i64 = i;
1149  use64bit = true;
1150  break;
1151  }
1152  }
1153  i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1154  significandDigit++;
1155  }
1156  else
1157  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1158  if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295
1159  if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {
1160  i64 = i;
1161  use64bit = true;
1162  break;
1163  }
1164  }
1165  i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1166  significandDigit++;
1167  }
1168  }
1169  // Parse NaN or Infinity here
1170  else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {
1171  useNanOrInf = true;
1172  if (RAPIDJSON_LIKELY(Consume(s, 'N') && Consume(s, 'a') && Consume(s, 'N'))) {
1173  d = std::numeric_limits<double>::quiet_NaN();
1174  }
1175  else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) {
1176  d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
1177  if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
1178  && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y'))))
1180  }
1181  else
1183  }
1184  else
1186 
1187  // Parse 64bit int
1188  bool useDouble = false;
1189  if (use64bit) {
1190  if (minus)
1191  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1192  if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808
1193  if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {
1194  d = static_cast<double>(i64);
1195  useDouble = true;
1196  break;
1197  }
1198  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1199  significandDigit++;
1200  }
1201  else
1202  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1203  if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615
1204  if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {
1205  d = static_cast<double>(i64);
1206  useDouble = true;
1207  break;
1208  }
1209  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1210  significandDigit++;
1211  }
1212  }
1213 
1214  // Force double for big integer
1215  if (useDouble) {
1216  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1217  if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0
1219  d = d * 10 + (s.TakePush() - '0');
1220  }
1221  }
1222 
1223  // Parse frac = decimal-point 1*DIGIT
1224  int expFrac = 0;
1225  size_t decimalPosition;
1226  if (Consume(s, '.')) {
1227  decimalPosition = s.Length();
1228 
1229  if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
1231 
1232  if (!useDouble) {
1233 #if RAPIDJSON_64BIT
1234  // Use i64 to store significand in 64-bit architecture
1235  if (!use64bit)
1236  i64 = i;
1237 
1238  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1239  if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
1240  break;
1241  else {
1242  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1243  --expFrac;
1244  if (i64 != 0)
1245  significandDigit++;
1246  }
1247  }
1248 
1249  d = static_cast<double>(i64);
1250 #else
1251  // Use double to store significand in 32-bit architecture
1252  d = static_cast<double>(use64bit ? i64 : i);
1253 #endif
1254  useDouble = true;
1255  }
1256 
1257  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1258  if (significandDigit < 17) {
1259  d = d * 10.0 + (s.TakePush() - '0');
1260  --expFrac;
1261  if (RAPIDJSON_LIKELY(d > 0.0))
1262  significandDigit++;
1263  }
1264  else
1265  s.TakePush();
1266  }
1267  }
1268  else
1269  decimalPosition = s.Length(); // decimal position at the end of integer.
1270 
1271  // Parse exp = e [ minus / plus ] 1*DIGIT
1272  int exp = 0;
1273  if (Consume(s, 'e') || Consume(s, 'E')) {
1274  if (!useDouble) {
1275  d = static_cast<double>(use64bit ? i64 : i);
1276  useDouble = true;
1277  }
1278 
1279  bool expMinus = false;
1280  if (Consume(s, '+'))
1281  ;
1282  else if (Consume(s, '-'))
1283  expMinus = true;
1284 
1285  if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1286  exp = static_cast<int>(s.Take() - '0');
1287  if (expMinus) {
1288  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1289  exp = exp * 10 + static_cast<int>(s.Take() - '0');
1290  if (exp >= 214748364) { // Issue #313: prevent overflow exponent
1291  while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent
1292  s.Take();
1293  }
1294  }
1295  }
1296  else { // positive exp
1297  int maxExp = 308 - expFrac;
1298  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1299  exp = exp * 10 + static_cast<int>(s.Take() - '0');
1300  if (RAPIDJSON_UNLIKELY(exp > maxExp))
1302  }
1303  }
1304  }
1305  else
1307 
1308  if (expMinus)
1309  exp = -exp;
1310  }
1311 
1312  // Finish parsing, call event according to the type of number.
1313  bool cont = true;
1314 
1315  if (parseFlags & kParseNumbersAsStringsFlag) {
1316  if (parseFlags & kParseInsituFlag) {
1317  s.Pop(); // Pop stack no matter if it will be used or not.
1318  typename InputStream::Ch* head = is.PutBegin();
1319  const size_t length = s.Tell() - startOffset;
1320  RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
1321  // unable to insert the \0 character here, it will erase the comma after this number
1322  const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
1323  cont = handler.RawNumber(str, SizeType(length), false);
1324  }
1325  else {
1326  SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
1327  StringStream srcStream(s.Pop());
1328  StackStream<typename TargetEncoding::Ch> dstStream(stack_);
1329  while (numCharsToCopy--) {
1330  Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);
1331  }
1332  dstStream.Put('\0');
1333  const typename TargetEncoding::Ch* str = dstStream.Pop();
1334  const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1;
1335  cont = handler.RawNumber(str, SizeType(length), true);
1336  }
1337  }
1338  else {
1339  size_t length = s.Length();
1340  const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not.
1341 
1342  if (useDouble) {
1343  int p = exp + expFrac;
1344  if (parseFlags & kParseFullPrecisionFlag)
1345  d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
1346  else
1347  d = internal::StrtodNormalPrecision(d, p);
1348 
1349  cont = handler.Double(minus ? -d : d);
1350  }
1351  else if (useNanOrInf) {
1352  cont = handler.Double(d);
1353  }
1354  else {
1355  if (use64bit) {
1356  if (minus)
1357  cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
1358  else
1359  cont = handler.Uint64(i64);
1360  }
1361  else {
1362  if (minus)
1363  cont = handler.Int(static_cast<int32_t>(~i + 1));
1364  else
1365  cont = handler.Uint(i);
1366  }
1367  }
1368  }
1369  if (RAPIDJSON_UNLIKELY(!cont))
1371  }
1372 
1373  // Parse any JSON value
1374  template<unsigned parseFlags, typename InputStream, typename Handler>
1375  void ParseValue(InputStream& is, Handler& handler) {
1376  switch (is.Peek()) {
1377  case 'n': ParseNull <parseFlags>(is, handler); break;
1378  case 't': ParseTrue <parseFlags>(is, handler); break;
1379  case 'f': ParseFalse <parseFlags>(is, handler); break;
1380  case '"': ParseString<parseFlags>(is, handler); break;
1381  case '{': ParseObject<parseFlags>(is, handler); break;
1382  case '[': ParseArray <parseFlags>(is, handler); break;
1383  default :
1384  ParseNumber<parseFlags>(is, handler);
1385  break;
1386 
1387  }
1388  }
1389 
1390  // Iterative Parsing
1391 
1392  // States
1393  enum IterativeParsingState {
1394  IterativeParsingStartState = 0,
1395  IterativeParsingFinishState,
1396  IterativeParsingErrorState,
1397 
1398  // Object states
1399  IterativeParsingObjectInitialState,
1400  IterativeParsingMemberKeyState,
1401  IterativeParsingKeyValueDelimiterState,
1402  IterativeParsingMemberValueState,
1403  IterativeParsingMemberDelimiterState,
1404  IterativeParsingObjectFinishState,
1405 
1406  // Array states
1407  IterativeParsingArrayInitialState,
1408  IterativeParsingElementState,
1409  IterativeParsingElementDelimiterState,
1410  IterativeParsingArrayFinishState,
1411 
1412  // Single value state
1413  IterativeParsingValueState
1414  };
1415 
1416  enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 };
1417 
1418  // Tokens
1419  enum Token {
1420  LeftBracketToken = 0,
1421  RightBracketToken,
1422 
1423  LeftCurlyBracketToken,
1424  RightCurlyBracketToken,
1425 
1426  CommaToken,
1427  ColonToken,
1428 
1429  StringToken,
1430  FalseToken,
1431  TrueToken,
1432  NullToken,
1433  NumberToken,
1434 
1435  kTokenCount
1436  };
1437 
1438  RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
1439 
1441 #define N NumberToken
1442 #define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1443  // Maps from ASCII to Token
1444  static const unsigned char tokenMap[256] = {
1445  N16, // 00~0F
1446  N16, // 10~1F
1447  N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F
1448  N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F
1449  N16, // 40~4F
1450  N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F
1451  N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F
1452  N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F
1453  N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF
1454  };
1455 #undef N
1456 #undef N16
1457 
1459  if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
1460  return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);
1461  else
1462  return NumberToken;
1463  }
1464 
1465  RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {
1466  // current state x one lookahead token -> new state
1467  static const char G[cIterativeParsingStateCount][kTokenCount] = {
1468  // Start
1469  {
1470  IterativeParsingArrayInitialState, // Left bracket
1471  IterativeParsingErrorState, // Right bracket
1472  IterativeParsingObjectInitialState, // Left curly bracket
1473  IterativeParsingErrorState, // Right curly bracket
1474  IterativeParsingErrorState, // Comma
1475  IterativeParsingErrorState, // Colon
1476  IterativeParsingValueState, // String
1477  IterativeParsingValueState, // False
1478  IterativeParsingValueState, // True
1479  IterativeParsingValueState, // Null
1480  IterativeParsingValueState // Number
1481  },
1482  // Finish(sink state)
1483  {
1484  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1485  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1486  IterativeParsingErrorState
1487  },
1488  // Error(sink state)
1489  {
1490  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1491  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1492  IterativeParsingErrorState
1493  },
1494  // ObjectInitial
1495  {
1496  IterativeParsingErrorState, // Left bracket
1497  IterativeParsingErrorState, // Right bracket
1498  IterativeParsingErrorState, // Left curly bracket
1499  IterativeParsingObjectFinishState, // Right curly bracket
1500  IterativeParsingErrorState, // Comma
1501  IterativeParsingErrorState, // Colon
1502  IterativeParsingMemberKeyState, // String
1503  IterativeParsingErrorState, // False
1504  IterativeParsingErrorState, // True
1505  IterativeParsingErrorState, // Null
1506  IterativeParsingErrorState // Number
1507  },
1508  // MemberKey
1509  {
1510  IterativeParsingErrorState, // Left bracket
1511  IterativeParsingErrorState, // Right bracket
1512  IterativeParsingErrorState, // Left curly bracket
1513  IterativeParsingErrorState, // Right curly bracket
1514  IterativeParsingErrorState, // Comma
1515  IterativeParsingKeyValueDelimiterState, // Colon
1516  IterativeParsingErrorState, // String
1517  IterativeParsingErrorState, // False
1518  IterativeParsingErrorState, // True
1519  IterativeParsingErrorState, // Null
1520  IterativeParsingErrorState // Number
1521  },
1522  // KeyValueDelimiter
1523  {
1524  IterativeParsingArrayInitialState, // Left bracket(push MemberValue state)
1525  IterativeParsingErrorState, // Right bracket
1526  IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state)
1527  IterativeParsingErrorState, // Right curly bracket
1528  IterativeParsingErrorState, // Comma
1529  IterativeParsingErrorState, // Colon
1530  IterativeParsingMemberValueState, // String
1531  IterativeParsingMemberValueState, // False
1532  IterativeParsingMemberValueState, // True
1533  IterativeParsingMemberValueState, // Null
1534  IterativeParsingMemberValueState // Number
1535  },
1536  // MemberValue
1537  {
1538  IterativeParsingErrorState, // Left bracket
1539  IterativeParsingErrorState, // Right bracket
1540  IterativeParsingErrorState, // Left curly bracket
1541  IterativeParsingObjectFinishState, // Right curly bracket
1542  IterativeParsingMemberDelimiterState, // Comma
1543  IterativeParsingErrorState, // Colon
1544  IterativeParsingErrorState, // String
1545  IterativeParsingErrorState, // False
1546  IterativeParsingErrorState, // True
1547  IterativeParsingErrorState, // Null
1548  IterativeParsingErrorState // Number
1549  },
1550  // MemberDelimiter
1551  {
1552  IterativeParsingErrorState, // Left bracket
1553  IterativeParsingErrorState, // Right bracket
1554  IterativeParsingErrorState, // Left curly bracket
1555  IterativeParsingObjectFinishState, // Right curly bracket
1556  IterativeParsingErrorState, // Comma
1557  IterativeParsingErrorState, // Colon
1558  IterativeParsingMemberKeyState, // String
1559  IterativeParsingErrorState, // False
1560  IterativeParsingErrorState, // True
1561  IterativeParsingErrorState, // Null
1562  IterativeParsingErrorState // Number
1563  },
1564  // ObjectFinish(sink state)
1565  {
1566  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1567  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1568  IterativeParsingErrorState
1569  },
1570  // ArrayInitial
1571  {
1572  IterativeParsingArrayInitialState, // Left bracket(push Element state)
1573  IterativeParsingArrayFinishState, // Right bracket
1574  IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1575  IterativeParsingErrorState, // Right curly bracket
1576  IterativeParsingErrorState, // Comma
1577  IterativeParsingErrorState, // Colon
1578  IterativeParsingElementState, // String
1579  IterativeParsingElementState, // False
1580  IterativeParsingElementState, // True
1581  IterativeParsingElementState, // Null
1582  IterativeParsingElementState // Number
1583  },
1584  // Element
1585  {
1586  IterativeParsingErrorState, // Left bracket
1587  IterativeParsingArrayFinishState, // Right bracket
1588  IterativeParsingErrorState, // Left curly bracket
1589  IterativeParsingErrorState, // Right curly bracket
1590  IterativeParsingElementDelimiterState, // Comma
1591  IterativeParsingErrorState, // Colon
1592  IterativeParsingErrorState, // String
1593  IterativeParsingErrorState, // False
1594  IterativeParsingErrorState, // True
1595  IterativeParsingErrorState, // Null
1596  IterativeParsingErrorState // Number
1597  },
1598  // ElementDelimiter
1599  {
1600  IterativeParsingArrayInitialState, // Left bracket(push Element state)
1601  IterativeParsingArrayFinishState, // Right bracket
1602  IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1603  IterativeParsingErrorState, // Right curly bracket
1604  IterativeParsingErrorState, // Comma
1605  IterativeParsingErrorState, // Colon
1606  IterativeParsingElementState, // String
1607  IterativeParsingElementState, // False
1608  IterativeParsingElementState, // True
1609  IterativeParsingElementState, // Null
1610  IterativeParsingElementState // Number
1611  },
1612  // ArrayFinish(sink state)
1613  {
1614  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1615  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1616  IterativeParsingErrorState
1617  },
1618  // Single Value (sink state)
1619  {
1620  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1621  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1622  IterativeParsingErrorState
1623  }
1624  }; // End of G
1625 
1626  return static_cast<IterativeParsingState>(G[state][token]);
1627  }
1628 
1629  // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
1630  // May return a new state on state pop.
1631  template <unsigned parseFlags, typename InputStream, typename Handler>
1632  RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
1633  (void)token;
1634 
1635  switch (dst) {
1636  case IterativeParsingErrorState:
1637  return dst;
1638 
1639  case IterativeParsingObjectInitialState:
1640  case IterativeParsingArrayInitialState:
1641  {
1642  // Push the state(Element or MemeberValue) if we are nested in another array or value of member.
1643  // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
1644  IterativeParsingState n = src;
1645  if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
1646  n = IterativeParsingElementState;
1647  else if (src == IterativeParsingKeyValueDelimiterState)
1648  n = IterativeParsingMemberValueState;
1649  // Push current state.
1650  *stack_.template Push<SizeType>(1) = n;
1651  // Initialize and push the member/element count.
1652  *stack_.template Push<SizeType>(1) = 0;
1653  // Call handler
1654  bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
1655  // On handler short circuits the parsing.
1656  if (!hr) {
1658  return IterativeParsingErrorState;
1659  }
1660  else {
1661  is.Take();
1662  return dst;
1663  }
1664  }
1665 
1666  case IterativeParsingMemberKeyState:
1667  ParseString<parseFlags>(is, handler, true);
1668  if (HasParseError())
1669  return IterativeParsingErrorState;
1670  else
1671  return dst;
1672 
1673  case IterativeParsingKeyValueDelimiterState:
1674  RAPIDJSON_ASSERT(token == ColonToken);
1675  is.Take();
1676  return dst;
1677 
1678  case IterativeParsingMemberValueState:
1679  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1680  ParseValue<parseFlags>(is, handler);
1681  if (HasParseError()) {
1682  return IterativeParsingErrorState;
1683  }
1684  return dst;
1685 
1686  case IterativeParsingElementState:
1687  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1688  ParseValue<parseFlags>(is, handler);
1689  if (HasParseError()) {
1690  return IterativeParsingErrorState;
1691  }
1692  return dst;
1693 
1694  case IterativeParsingMemberDelimiterState:
1695  case IterativeParsingElementDelimiterState:
1696  is.Take();
1697  // Update member/element count.
1698  *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
1699  return dst;
1700 
1701  case IterativeParsingObjectFinishState:
1702  {
1703  // Transit from delimiter is only allowed when trailing commas are enabled
1704  if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {
1706  return IterativeParsingErrorState;
1707  }
1708  // Get member count.
1709  SizeType c = *stack_.template Pop<SizeType>(1);
1710  // If the object is not empty, count the last member.
1711  if (src == IterativeParsingMemberValueState)
1712  ++c;
1713  // Restore the state.
1714  IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1715  // Transit to Finish state if this is the topmost scope.
1716  if (n == IterativeParsingStartState)
1717  n = IterativeParsingFinishState;
1718  // Call handler
1719  bool hr = handler.EndObject(c);
1720  // On handler short circuits the parsing.
1721  if (!hr) {
1723  return IterativeParsingErrorState;
1724  }
1725  else {
1726  is.Take();
1727  return n;
1728  }
1729  }
1730 
1731  case IterativeParsingArrayFinishState:
1732  {
1733  // Transit from delimiter is only allowed when trailing commas are enabled
1734  if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {
1736  return IterativeParsingErrorState;
1737  }
1738  // Get element count.
1739  SizeType c = *stack_.template Pop<SizeType>(1);
1740  // If the array is not empty, count the last element.
1741  if (src == IterativeParsingElementState)
1742  ++c;
1743  // Restore the state.
1744  IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1745  // Transit to Finish state if this is the topmost scope.
1746  if (n == IterativeParsingStartState)
1747  n = IterativeParsingFinishState;
1748  // Call handler
1749  bool hr = handler.EndArray(c);
1750  // On handler short circuits the parsing.
1751  if (!hr) {
1753  return IterativeParsingErrorState;
1754  }
1755  else {
1756  is.Take();
1757  return n;
1758  }
1759  }
1760 
1761  default:
1762  // This branch is for IterativeParsingValueState actually.
1763  // Use `default:` rather than
1764  // `case IterativeParsingValueState:` is for code coverage.
1765 
1766  // The IterativeParsingStartState is not enumerated in this switch-case.
1767  // It is impossible for that case. And it can be caught by following assertion.
1768 
1769  // The IterativeParsingFinishState is not enumerated in this switch-case either.
1770  // It is a "derivative" state which cannot triggered from Predict() directly.
1771  // Therefore it cannot happen here. And it can be caught by following assertion.
1772  RAPIDJSON_ASSERT(dst == IterativeParsingValueState);
1773 
1774  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1775  ParseValue<parseFlags>(is, handler);
1776  if (HasParseError()) {
1777  return IterativeParsingErrorState;
1778  }
1779  return IterativeParsingFinishState;
1780  }
1781  }
1782 
1783  template <typename InputStream>
1784  void HandleError(IterativeParsingState src, InputStream& is) {
1785  if (HasParseError()) {
1786  // Error flag has been set.
1787  return;
1788  }
1789 
1790  switch (src) {
1791  case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
1792  case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
1793  case IterativeParsingObjectInitialState:
1794  case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
1795  case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
1796  case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
1797  case IterativeParsingKeyValueDelimiterState:
1798  case IterativeParsingArrayInitialState:
1799  case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return;
1800  default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
1801  }
1802  }
1803 
1804  template <unsigned parseFlags, typename InputStream, typename Handler>
1805  ParseResult IterativeParse(InputStream& is, Handler& handler) {
1806  parseResult_.Clear();
1807  ClearStackOnExit scope(*this);
1808  IterativeParsingState state = IterativeParsingStartState;
1809 
1810  SkipWhitespaceAndComments<parseFlags>(is);
1811  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
1812  while (is.Peek() != '\0') {
1813  Token t = Tokenize(is.Peek());
1814  IterativeParsingState n = Predict(state, t);
1815  IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
1816 
1817  if (d == IterativeParsingErrorState) {
1818  HandleError(state, is);
1819  break;
1820  }
1821 
1822  state = d;
1823 
1824  // Do not further consume streams if a root JSON has been parsed.
1825  if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
1826  break;
1827 
1828  SkipWhitespaceAndComments<parseFlags>(is);
1829  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
1830  }
1831 
1832  // Handle the end of file.
1833  if (state != IterativeParsingFinishState)
1834  HandleError(state, is);
1835 
1836  return parseResult_;
1837  }
1838 
1839  static const size_t kDefaultStackCapacity = 256;
1841  ParseResult parseResult_;
1842 }; // class GenericReader
1843 
1846 
1848 
1849 #ifdef __clang__
1850 RAPIDJSON_DIAG_POP
1851 #endif
1852 
1853 
1854 #ifdef __GNUC__
1855 RAPIDJSON_DIAG_POP
1856 #endif
1857 
1858 #ifdef _MSC_VER
1859 RAPIDJSON_DIAG_POP
1860 #endif
1861 
1862 #endif // RAPIDJSON_READER_H_
bool RawNumber(const Ch *str, SizeType len, bool copy)
enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) ...
Definition: reader.h:210
Encoding conversion.
Definition: encodings.h:658
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition: reader.h:471
Invalid value.
Definition: error.h:70
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:380
Iterative(constant complexity in terms of function call stack size) parsing.
Definition: reader.h:149
Represents an in-memory input byte stream.
Definition: memorystream.h:40
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:402
Parsing was terminated.
Definition: error.h:88
Missing a comma or &#39;}&#39; after an object member.
Definition: error.h:74
#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: fwd.h:85
Read-only string stream.
Definition: fwd.h:47
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:119
GenericReader< UTF8<>, UTF8<> > Reader
Reader with UTF8 encoding and default allocator.
Definition: reader.h:1845
The document is empty.
Definition: error.h:67
Missing a comma or &#39;]&#39; after an array element.
Definition: error.h:76
const Ch * src_
Current read position.
Definition: stream.h:124
No flags are set.
Definition: reader.h:146
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text (with kParseDefaultFlags)
Definition: reader.h:512
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: reader.h:517
Missing a name for object member.
Definition: error.h:72
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
Allow trailing commas at the end of objects and arrays.
Definition: reader.h:154
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:116
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)
Macro to indicate a parse error.
Definition: reader.h:99
Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
Definition: reader.h:155
A read-write string stream.
Definition: fwd.h:52
Number too big to be stored in double.
Definition: error.h:84
Parse all numbers (ints/doubles) as strings.
Definition: reader.h:153
After parsing a complete JSON root from stream, stop further processing the rest of stream...
Definition: reader.h:150
SourceEncoding::Ch Ch
SourceEncoding character type.
Definition: reader.h:454
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS. ...
Definition: reader.h:156
Parse number in full precision (but slower).
Definition: reader.h:151
UTF-8 encoding.
Definition: encodings.h:96
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: fwd.h:88
ParseFlag
Combination of parseFlags.
Definition: reader.h:145
ParseErrorCode
Error code of parsing.
Definition: error.h:64
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:39
Miss exponent in number.
Definition: error.h:86
Invalid escape character in string.
Definition: error.h:80
Invalid encoding in string.
Definition: error.h:82
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:455
Definition: document.h:399
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition: reader.h:264
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: reader.h:523
Validate encoding of JSON strings.
Definition: reader.h:148
Miss fraction part in number.
Definition: error.h:85
Incorrect hex digit after \u escape in string.
Definition: error.h:78
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:118
void Clear()
Reset error code.
Definition: error.h:128
Unspecific syntax error.
Definition: error.h:89
The surrogate pair in string is invalid.
Definition: error.h:79
Missing a colon after a name of object member.
Definition: error.h:73
Type
Type of JSON value.
Definition: rapidjson.h:603
GenericReader(StackAllocator *stackAllocator=0, size_t stackCapacity=kDefaultStackCapacity)
Constructor.
Definition: reader.h:460
Definition: reader.h:225
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:468
Missing a closing quotation mark in string.
Definition: error.h:81
The document root must not follow by other values.
Definition: error.h:68
In-situ(destructive) parsing.
Definition: reader.h:147
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
Definition: reader.h:520
Allow one-line (//) and multi-line (/**/) comments.
Definition: reader.h:152