1 // Tencent is pleased to support the open source community by making RapidJSON available.
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
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
8 // http://opensource.org/licenses/MIT
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.
15 #ifndef RAPIDJSON_READER_H_
16 #define RAPIDJSON_READER_H_
20 #include "allocators.h"
22 #include "encodedstream.h"
23 #include "internal/meta.h"
24 #include "internal/stack.h"
25 #include "internal/strtod.h"
28 #if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
30 #pragma intrinsic(_BitScanForward)
32 #ifdef RAPIDJSON_SSE42
33 #include <nmmintrin.h>
34 #elif defined(RAPIDJSON_SSE2)
35 #include <emmintrin.h>
40 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
41 RAPIDJSON_DIAG_OFF(4702) // unreachable code
46 RAPIDJSON_DIAG_OFF(old-style-cast)
47 RAPIDJSON_DIAG_OFF(padded)
48 RAPIDJSON_DIAG_OFF(switch-enum)
53 RAPIDJSON_DIAG_OFF(effc++)
56 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
57 #define RAPIDJSON_NOTHING /* deliberately empty */
58 #ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
59 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
60 RAPIDJSON_MULTILINEMACRO_BEGIN \
61 if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
62 RAPIDJSON_MULTILINEMACRO_END
64 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
65 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
68 /*! \def RAPIDJSON_PARSE_ERROR_NORETURN
69 \ingroup RAPIDJSON_ERRORS
70 \brief Macro to indicate a parse error.
71 \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
72 \param offset position of the error in JSON input (\c size_t)
74 This macros can be used as a customization point for the internal
75 error handling mechanism of RapidJSON.
77 A common usage model is to throw an exception instead of requiring the
78 caller to explicitly check the \ref rapidjson::GenericReader::Parse's
82 #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \
83 throw ParseException(parseErrorCode, #parseErrorCode, offset)
85 #include <stdexcept> // std::runtime_error
86 #include "rapidjson/error/error.h" // rapidjson::ParseResult
88 struct ParseException : std::runtime_error, rapidjson::ParseResult {
89 ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset)
90 : std::runtime_error(msg), ParseResult(code, offset) {}
93 #include "rapidjson/reader.h"
96 \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse
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
106 /*! \def RAPIDJSON_PARSE_ERROR
107 \ingroup RAPIDJSON_ERRORS
108 \brief (Internal) macro to indicate and handle a parse error.
109 \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
110 \param offset position of the error in JSON input (\c size_t)
112 Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing.
114 \see RAPIDJSON_PARSE_ERROR_NORETURN
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
125 #include "error/error.h" // ParseErrorCode, ParseResult
127 RAPIDJSON_NAMESPACE_BEGIN
129 ///////////////////////////////////////////////////////////////////////////////
132 /*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS
133 \ingroup RAPIDJSON_CONFIG
134 \brief User-defined kParseDefaultFlags definition.
136 User can define this as any \c ParseFlag combinations.
138 #ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS
139 #define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags
142 //! Combination of parseFlags
143 /*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream
146 kParseNoFlags = 0, //!< No flags are set.
147 kParseInsituFlag = 1, //!< In-situ(destructive) parsing.
148 kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings.
149 kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing.
150 kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error.
151 kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower).
152 kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments.
153 kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings.
154 kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.
155 kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
156 kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
159 ///////////////////////////////////////////////////////////////////////////////
162 /*! \class rapidjson::Handler
163 \brief Concept for receiving events from GenericReader upon parsing.
164 The functions return true if no error occurs. If they return false,
165 the event publisher should terminate the process.
173 bool Uint(unsigned i);
174 bool Int64(int64_t i);
175 bool Uint64(uint64_t i);
176 bool Double(double d);
177 /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
178 bool RawNumber(const Ch* str, SizeType length, bool copy);
179 bool String(const Ch* str, SizeType length, bool copy);
181 bool Key(const Ch* str, SizeType length, bool copy);
182 bool EndObject(SizeType memberCount);
184 bool EndArray(SizeType elementCount);
188 ///////////////////////////////////////////////////////////////////////////////
191 //! Default implementation of Handler.
192 /*! This can be used as base class of any reader handler.
193 \note implements Handler concept
195 template<typename Encoding = UTF8<>, typename Derived = void>
196 struct BaseReaderHandler {
197 typedef typename Encoding::Ch Ch;
199 typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override;
201 bool Default() { return true; }
202 bool Null() { return static_cast<Override&>(*this).Default(); }
203 bool Bool(bool) { return static_cast<Override&>(*this).Default(); }
204 bool Int(int) { return static_cast<Override&>(*this).Default(); }
205 bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); }
206 bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); }
207 bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); }
208 bool Double(double) { return static_cast<Override&>(*this).Default(); }
209 /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
210 bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
211 bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); }
212 bool StartObject() { return static_cast<Override&>(*this).Default(); }
213 bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
214 bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }
215 bool StartArray() { return static_cast<Override&>(*this).Default(); }
216 bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }
219 ///////////////////////////////////////////////////////////////////////////////
224 template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
225 class StreamLocalCopy;
227 //! Do copy optimization.
228 template<typename Stream>
229 class StreamLocalCopy<Stream, 1> {
231 StreamLocalCopy(Stream& original) : s(original), original_(original) {}
232 ~StreamLocalCopy() { original_ = s; }
237 StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
243 template<typename Stream>
244 class StreamLocalCopy<Stream, 0> {
246 StreamLocalCopy(Stream& original) : s(original) {}
251 StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
254 } // namespace internal
256 ///////////////////////////////////////////////////////////////////////////////
259 //! Skip the JSON white spaces in a stream.
260 /*! \param is A input stream for skipping white spaces.
261 \note This function has SSE2/SSE4.2 specialization.
263 template<typename InputStream>
264 void SkipWhitespace(InputStream& is) {
265 internal::StreamLocalCopy<InputStream> copy(is);
266 InputStream& s(copy.s);
268 typename InputStream::Ch c;
269 while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t')
273 inline const char* SkipWhitespace(const char* p, const char* end) {
274 while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
279 #ifdef RAPIDJSON_SSE42
280 //! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.
281 inline const char *SkipWhitespace_SIMD(const char* p) {
282 // Fast return for single non-whitespace
283 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
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')
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]));
301 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
302 const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
303 if (r != 0) { // some of characters is non-whitespace
304 #ifdef _MSC_VER // Find the index of first non-whitespace
305 unsigned long offset;
306 _BitScanForward(&offset, r);
309 return p + __builtin_ffs(r) - 1;
315 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
316 // Fast return for single non-whitespace
317 if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
322 // The middle of string using SIMD
323 static const char whitespace[16] = " \n\r\t";
324 const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
326 for (; p <= end - 16; p += 16) {
327 const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
328 const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
329 if (r != 0) { // some of characters is non-whitespace
330 #ifdef _MSC_VER // Find the index of first non-whitespace
331 unsigned long offset;
332 _BitScanForward(&offset, r);
335 return p + __builtin_ffs(r) - 1;
340 return SkipWhitespace(p, end);
343 #elif defined(RAPIDJSON_SSE2)
345 //! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
346 inline const char *SkipWhitespace_SIMD(const char* p) {
347 // Fast return for single non-whitespace
348 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
353 // 16-byte align to the next boundary
354 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
355 while (p != nextAligned)
356 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
361 // The rest of string
362 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
363 static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
366 const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
367 const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
368 const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
369 const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
372 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
373 __m128i x = _mm_cmpeq_epi8(s, w0);
374 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
375 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
376 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
377 unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
378 if (r != 0) { // some of characters may be non-whitespace
379 #ifdef _MSC_VER // Find the index of first non-whitespace
380 unsigned long offset;
381 _BitScanForward(&offset, r);
384 return p + __builtin_ffs(r) - 1;
390 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
391 // Fast return for single non-whitespace
392 if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
397 // The rest of string
398 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
399 static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
402 const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
403 const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
404 const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
405 const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
407 for (; p <= end - 16; p += 16) {
408 const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
409 __m128i x = _mm_cmpeq_epi8(s, w0);
410 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
411 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
412 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
413 unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
414 if (r != 0) { // some of characters may be non-whitespace
415 #ifdef _MSC_VER // Find the index of first non-whitespace
416 unsigned long offset;
417 _BitScanForward(&offset, r);
420 return p + __builtin_ffs(r) - 1;
425 return SkipWhitespace(p, end);
428 #endif // RAPIDJSON_SSE2
430 #ifdef RAPIDJSON_SIMD
431 //! Template function specialization for InsituStringStream
432 template<> inline void SkipWhitespace(InsituStringStream& is) {
433 is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
436 //! Template function specialization for StringStream
437 template<> inline void SkipWhitespace(StringStream& is) {
438 is.src_ = SkipWhitespace_SIMD(is.src_);
441 template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {
442 is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
444 #endif // RAPIDJSON_SIMD
446 ///////////////////////////////////////////////////////////////////////////////
449 //! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator.
450 /*! GenericReader parses JSON text from a stream, and send events synchronously to an
451 object implementing Handler concept.
453 It needs to allocate a stack for storing a single decoded string during
454 non-destructive parsing.
456 For in-situ parsing, the decoded string is directly written to the source
457 text string, no temporary buffer is required.
459 A GenericReader object can be reused for parsing multiple JSON text.
461 \tparam SourceEncoding Encoding of the input stream.
462 \tparam TargetEncoding Encoding of the parse output.
463 \tparam StackAllocator Allocator type for stack.
465 template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
466 class GenericReader {
468 typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type
471 /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
472 \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
474 GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {}
477 /*! \tparam parseFlags Combination of \ref ParseFlag.
478 \tparam InputStream Type of input stream, implementing Stream concept.
479 \tparam Handler Type of handler, implementing Handler concept.
480 \param is Input stream to be parsed.
481 \param handler The handler to receive events.
482 \return Whether the parsing is successful.
484 template <unsigned parseFlags, typename InputStream, typename Handler>
485 ParseResult Parse(InputStream& is, Handler& handler) {
486 if (parseFlags & kParseIterativeFlag)
487 return IterativeParse<parseFlags>(is, handler);
489 parseResult_.Clear();
491 ClearStackOnExit scope(*this);
493 SkipWhitespaceAndComments<parseFlags>(is);
494 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
496 if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) {
497 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
498 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
501 ParseValue<parseFlags>(is, handler);
502 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
504 if (!(parseFlags & kParseStopWhenDoneFlag)) {
505 SkipWhitespaceAndComments<parseFlags>(is);
506 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
508 if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) {
509 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
510 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
518 //! Parse JSON text (with \ref kParseDefaultFlags)
519 /*! \tparam InputStream Type of input stream, implementing Stream concept
520 \tparam Handler Type of handler, implementing Handler concept.
521 \param is Input stream to be parsed.
522 \param handler The handler to receive events.
523 \return Whether the parsing is successful.
525 template <typename InputStream, typename Handler>
526 ParseResult Parse(InputStream& is, Handler& handler) {
527 return Parse<kParseDefaultFlags>(is, handler);
530 //! Whether a parse error has occured in the last parsing.
531 bool HasParseError() const { return parseResult_.IsError(); }
533 //! Get the \ref ParseErrorCode of last parsing.
534 ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }
536 //! Get the position of last parsing error in input, 0 otherwise.
537 size_t GetErrorOffset() const { return parseResult_.Offset(); }
540 void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
543 // Prohibit copy constructor & assignment operator.
544 GenericReader(const GenericReader&);
545 GenericReader& operator=(const GenericReader&);
547 void ClearStack() { stack_.Clear(); }
549 // clear stack on any exit from ParseStream, e.g. due to exception
550 struct ClearStackOnExit {
551 explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
552 ~ClearStackOnExit() { r_.ClearStack(); }
555 ClearStackOnExit(const ClearStackOnExit&);
556 ClearStackOnExit& operator=(const ClearStackOnExit&);
559 template<unsigned parseFlags, typename InputStream>
560 void SkipWhitespaceAndComments(InputStream& is) {
563 if (parseFlags & kParseCommentsFlag) {
564 while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) {
565 if (Consume(is, '*')) {
567 if (RAPIDJSON_UNLIKELY(is.Peek() == '\0'))
568 RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
569 else if (Consume(is, '*')) {
570 if (Consume(is, '/'))
577 else if (RAPIDJSON_LIKELY(Consume(is, '/')))
578 while (is.Peek() != '\0' && is.Take() != '\n');
580 RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
587 // Parse object: { string : value, ... }
588 template<unsigned parseFlags, typename InputStream, typename Handler>
589 void ParseObject(InputStream& is, Handler& handler) {
590 RAPIDJSON_ASSERT(is.Peek() == '{');
591 is.Take(); // Skip '{'
593 if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
594 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
596 SkipWhitespaceAndComments<parseFlags>(is);
597 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
599 if (Consume(is, '}')) {
600 if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object
601 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
605 for (SizeType memberCount = 0;;) {
606 if (RAPIDJSON_UNLIKELY(is.Peek() != '"'))
607 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
609 ParseString<parseFlags>(is, handler, true);
610 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
612 SkipWhitespaceAndComments<parseFlags>(is);
613 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
615 if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))
616 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
618 SkipWhitespaceAndComments<parseFlags>(is);
619 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
621 ParseValue<parseFlags>(is, handler);
622 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
624 SkipWhitespaceAndComments<parseFlags>(is);
625 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
632 SkipWhitespaceAndComments<parseFlags>(is);
633 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
637 if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
638 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
641 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy
644 if (parseFlags & kParseTrailingCommasFlag) {
645 if (is.Peek() == '}') {
646 if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
647 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
655 // Parse array: [ value, ... ]
656 template<unsigned parseFlags, typename InputStream, typename Handler>
657 void ParseArray(InputStream& is, Handler& handler) {
658 RAPIDJSON_ASSERT(is.Peek() == '[');
659 is.Take(); // Skip '['
661 if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
662 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
664 SkipWhitespaceAndComments<parseFlags>(is);
665 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
667 if (Consume(is, ']')) {
668 if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array
669 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
673 for (SizeType elementCount = 0;;) {
674 ParseValue<parseFlags>(is, handler);
675 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
678 SkipWhitespaceAndComments<parseFlags>(is);
679 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
681 if (Consume(is, ',')) {
682 SkipWhitespaceAndComments<parseFlags>(is);
683 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
685 else if (Consume(is, ']')) {
686 if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
687 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
691 RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
693 if (parseFlags & kParseTrailingCommasFlag) {
694 if (is.Peek() == ']') {
695 if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
696 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
704 template<unsigned parseFlags, typename InputStream, typename Handler>
705 void ParseNull(InputStream& is, Handler& handler) {
706 RAPIDJSON_ASSERT(is.Peek() == 'n');
709 if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {
710 if (RAPIDJSON_UNLIKELY(!handler.Null()))
711 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
714 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
717 template<unsigned parseFlags, typename InputStream, typename Handler>
718 void ParseTrue(InputStream& is, Handler& handler) {
719 RAPIDJSON_ASSERT(is.Peek() == 't');
722 if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {
723 if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))
724 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
727 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
730 template<unsigned parseFlags, typename InputStream, typename Handler>
731 void ParseFalse(InputStream& is, Handler& handler) {
732 RAPIDJSON_ASSERT(is.Peek() == 'f');
735 if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {
736 if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))
737 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
740 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
743 template<typename InputStream>
744 RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
745 if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
753 // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
754 template<typename InputStream>
755 unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
756 unsigned codepoint = 0;
757 for (int i = 0; i < 4; i++) {
760 codepoint += static_cast<unsigned>(c);
761 if (c >= '0' && c <= '9')
763 else if (c >= 'A' && c <= 'F')
764 codepoint -= 'A' - 10;
765 else if (c >= 'a' && c <= 'f')
766 codepoint -= 'a' - 10;
768 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset);
769 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
776 template <typename CharType>
781 StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {}
782 RAPIDJSON_FORCEINLINE void Put(Ch c) {
783 *stack_.template Push<Ch>() = c;
787 RAPIDJSON_FORCEINLINE void* Push(SizeType count) {
789 return stack_.template Push<Ch>(count);
792 size_t Length() const { return length_; }
795 return stack_.template Pop<Ch>(length_);
799 StackStream(const StackStream&);
800 StackStream& operator=(const StackStream&);
802 internal::Stack<StackAllocator>& stack_;
806 // Parse string and generate String event. Different code paths for kParseInsituFlag.
807 template<unsigned parseFlags, typename InputStream, typename Handler>
808 void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
809 internal::StreamLocalCopy<InputStream> copy(is);
810 InputStream& s(copy.s);
812 RAPIDJSON_ASSERT(s.Peek() == '\"');
813 s.Take(); // Skip '\"'
815 bool success = false;
816 if (parseFlags & kParseInsituFlag) {
817 typename InputStream::Ch *head = s.PutBegin();
818 ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
819 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
820 size_t length = s.PutEnd(head) - 1;
821 RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
822 const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
823 success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
826 StackStream<typename TargetEncoding::Ch> stackStream(stack_);
827 ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
828 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
829 SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;
830 const typename TargetEncoding::Ch* const str = stackStream.Pop();
831 success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
833 if (RAPIDJSON_UNLIKELY(!success))
834 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
837 // Parse string to an output is
838 // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
839 template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
840 RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
841 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
842 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
843 static const char escape[256] = {
844 Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
845 Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
846 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
847 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
848 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
854 // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
855 if (!(parseFlags & kParseValidateEncodingFlag))
856 ScanCopyUnescapedString(is, os);
859 if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape
860 size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset
863 if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
865 os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
867 else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
869 unsigned codepoint = ParseHex4(is, escapeOffset);
870 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
871 if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
872 // Handle UTF-16 surrogate pair
873 if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
874 RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
875 unsigned codepoint2 = ParseHex4(is, escapeOffset);
876 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
877 if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
878 RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
879 codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
881 TEncoding::Encode(os, codepoint);
884 RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset);
886 else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote
888 os.Put('\0'); // null-terminate the string
891 else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
893 RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell());
895 RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell());
898 size_t offset = is.Tell();
899 if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
900 !Transcoder<SEncoding, TEncoding>::Validate(is, os) :
901 !Transcoder<SEncoding, TEncoding>::Transcode(is, os))))
902 RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset);
907 template<typename InputStream, typename OutputStream>
908 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {
909 // Do nothing for generic version
912 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
913 // StringStream -> StackStream<char>
914 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
915 const char* p = is.src_;
917 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
918 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
919 while (p != nextAligned)
920 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
927 // The rest of string using SIMD
928 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
929 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
930 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
931 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
932 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
933 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
936 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
937 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
938 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
939 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
940 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
941 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
942 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
944 #ifdef _MSC_VER // Find the index of first escaped
945 unsigned long offset;
946 _BitScanForward(&offset, r);
949 length = static_cast<SizeType>(__builtin_ffs(r) - 1);
951 char* q = reinterpret_cast<char*>(os.Push(length));
952 for (size_t i = 0; i < length; i++)
958 _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);
964 // InsituStringStream -> InsituStringStream
965 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
966 RAPIDJSON_ASSERT(&is == &os);
969 if (is.src_ == is.dst_) {
970 SkipUnescapedString(is);
977 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
978 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
979 while (p != nextAligned)
980 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
988 // The rest of string using SIMD
989 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
990 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
991 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
992 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
993 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
994 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
996 for (;; p += 16, q += 16) {
997 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
998 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
999 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1000 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
1001 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1002 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1003 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1005 #ifdef _MSC_VER // Find the index of first escaped
1006 unsigned long offset;
1007 _BitScanForward(&offset, r);
1010 length = static_cast<size_t>(__builtin_ffs(r) - 1);
1012 for (const char* pend = p + length; p != pend; )
1016 _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);
1023 // When read/write pointers are the same for insitu stream, just skip unescaped characters
1024 static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
1025 RAPIDJSON_ASSERT(is.src_ == is.dst_);
1028 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1029 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1030 for (; p != nextAligned; p++)
1031 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1032 is.src_ = is.dst_ = p;
1036 // The rest of string using SIMD
1037 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1038 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1039 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
1040 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1041 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1042 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1045 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1046 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1047 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1048 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
1049 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1050 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1051 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1053 #ifdef _MSC_VER // Find the index of first escaped
1054 unsigned long offset;
1055 _BitScanForward(&offset, r);
1058 length = static_cast<size_t>(__builtin_ffs(r) - 1);
1065 is.src_ = is.dst_ = p;
1069 template<typename InputStream, bool backup, bool pushOnTake>
1072 template<typename InputStream>
1073 class NumberStream<InputStream, false, false> {
1075 typedef typename InputStream::Ch Ch;
1077 NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; }
1080 RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
1081 RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
1082 RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
1083 RAPIDJSON_FORCEINLINE void Push(char) {}
1085 size_t Tell() { return is.Tell(); }
1086 size_t Length() { return 0; }
1087 const char* Pop() { return 0; }
1090 NumberStream& operator=(const NumberStream&);
1095 template<typename InputStream>
1096 class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
1097 typedef NumberStream<InputStream, false, false> Base;
1099 NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
1102 RAPIDJSON_FORCEINLINE Ch TakePush() {
1103 stackStream.Put(static_cast<char>(Base::is.Peek()));
1104 return Base::is.Take();
1107 RAPIDJSON_FORCEINLINE void Push(char c) {
1111 size_t Length() { return stackStream.Length(); }
1114 stackStream.Put('\0');
1115 return stackStream.Pop();
1119 StackStream<char> stackStream;
1122 template<typename InputStream>
1123 class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
1124 typedef NumberStream<InputStream, true, false> Base;
1126 NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
1129 RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
1132 template<unsigned parseFlags, typename InputStream, typename Handler>
1133 void ParseNumber(InputStream& is, Handler& handler) {
1134 internal::StreamLocalCopy<InputStream> copy(is);
1135 NumberStream<InputStream,
1136 ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
1137 ((parseFlags & kParseInsituFlag) == 0) :
1138 ((parseFlags & kParseFullPrecisionFlag) != 0),
1139 (parseFlags & kParseNumbersAsStringsFlag) != 0 &&
1140 (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);
1142 size_t startOffset = s.Tell();
1144 bool useNanOrInf = false;
1147 bool minus = Consume(s, '-');
1149 // Parse int: zero / ( digit1-9 *DIGIT )
1152 bool use64bit = false;
1153 int significandDigit = 0;
1154 if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {
1158 else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {
1159 i = static_cast<unsigned>(s.TakePush() - '0');
1162 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1163 if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648
1164 if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {
1170 i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1174 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1175 if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295
1176 if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {
1182 i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1186 // Parse NaN or Infinity here
1187 else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {
1189 if (RAPIDJSON_LIKELY(Consume(s, 'N') && Consume(s, 'a') && Consume(s, 'N'))) {
1190 d = std::numeric_limits<double>::quiet_NaN();
1192 else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) {
1193 d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
1194 if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
1195 && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y'))))
1196 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1199 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1202 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1205 bool useDouble = false;
1208 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1209 if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808
1210 if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {
1211 d = static_cast<double>(i64);
1215 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1219 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1220 if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615
1221 if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {
1222 d = static_cast<double>(i64);
1226 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1231 // Force double for big integer
1233 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1234 if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0
1235 RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
1236 d = d * 10 + (s.TakePush() - '0');
1240 // Parse frac = decimal-point 1*DIGIT
1242 size_t decimalPosition;
1243 if (Consume(s, '.')) {
1244 decimalPosition = s.Length();
1246 if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
1247 RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
1251 // Use i64 to store significand in 64-bit architecture
1255 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1256 if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
1259 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1266 d = static_cast<double>(i64);
1268 // Use double to store significand in 32-bit architecture
1269 d = static_cast<double>(use64bit ? i64 : i);
1274 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1275 if (significandDigit < 17) {
1276 d = d * 10.0 + (s.TakePush() - '0');
1278 if (RAPIDJSON_LIKELY(d > 0.0))
1286 decimalPosition = s.Length(); // decimal position at the end of integer.
1288 // Parse exp = e [ minus / plus ] 1*DIGIT
1290 if (Consume(s, 'e') || Consume(s, 'E')) {
1292 d = static_cast<double>(use64bit ? i64 : i);
1296 bool expMinus = false;
1297 if (Consume(s, '+'))
1299 else if (Consume(s, '-'))
1302 if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1303 exp = static_cast<int>(s.Take() - '0');
1305 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1306 exp = exp * 10 + static_cast<int>(s.Take() - '0');
1307 if (exp >= 214748364) { // Issue #313: prevent overflow exponent
1308 while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent
1313 else { // positive exp
1314 int maxExp = 308 - expFrac;
1315 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1316 exp = exp * 10 + static_cast<int>(s.Take() - '0');
1317 if (RAPIDJSON_UNLIKELY(exp > maxExp))
1318 RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
1323 RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());
1329 // Finish parsing, call event according to the type of number.
1332 if (parseFlags & kParseNumbersAsStringsFlag) {
1333 if (parseFlags & kParseInsituFlag) {
1334 s.Pop(); // Pop stack no matter if it will be used or not.
1335 typename InputStream::Ch* head = is.PutBegin();
1336 const size_t length = s.Tell() - startOffset;
1337 RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
1338 // unable to insert the \0 character here, it will erase the comma after this number
1339 const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
1340 cont = handler.RawNumber(str, SizeType(length), false);
1343 SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
1344 StringStream srcStream(s.Pop());
1345 StackStream<typename TargetEncoding::Ch> dstStream(stack_);
1346 while (numCharsToCopy--) {
1347 Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);
1349 dstStream.Put('\0');
1350 const typename TargetEncoding::Ch* str = dstStream.Pop();
1351 const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1;
1352 cont = handler.RawNumber(str, SizeType(length), true);
1356 size_t length = s.Length();
1357 const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not.
1360 int p = exp + expFrac;
1361 if (parseFlags & kParseFullPrecisionFlag)
1362 d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
1364 d = internal::StrtodNormalPrecision(d, p);
1366 cont = handler.Double(minus ? -d : d);
1368 else if (useNanOrInf) {
1369 cont = handler.Double(d);
1374 cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
1376 cont = handler.Uint64(i64);
1380 cont = handler.Int(static_cast<int32_t>(~i + 1));
1382 cont = handler.Uint(i);
1386 if (RAPIDJSON_UNLIKELY(!cont))
1387 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset);
1390 // Parse any JSON value
1391 template<unsigned parseFlags, typename InputStream, typename Handler>
1392 void ParseValue(InputStream& is, Handler& handler) {
1393 switch (is.Peek()) {
1394 case 'n': ParseNull <parseFlags>(is, handler); break;
1395 case 't': ParseTrue <parseFlags>(is, handler); break;
1396 case 'f': ParseFalse <parseFlags>(is, handler); break;
1397 case '"': ParseString<parseFlags>(is, handler); break;
1398 case '{': ParseObject<parseFlags>(is, handler); break;
1399 case '[': ParseArray <parseFlags>(is, handler); break;
1401 ParseNumber<parseFlags>(is, handler);
1407 // Iterative Parsing
1410 enum IterativeParsingState {
1411 IterativeParsingStartState = 0,
1412 IterativeParsingFinishState,
1413 IterativeParsingErrorState,
1416 IterativeParsingObjectInitialState,
1417 IterativeParsingMemberKeyState,
1418 IterativeParsingKeyValueDelimiterState,
1419 IterativeParsingMemberValueState,
1420 IterativeParsingMemberDelimiterState,
1421 IterativeParsingObjectFinishState,
1424 IterativeParsingArrayInitialState,
1425 IterativeParsingElementState,
1426 IterativeParsingElementDelimiterState,
1427 IterativeParsingArrayFinishState,
1429 // Single value state
1430 IterativeParsingValueState
1433 enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 };
1437 LeftBracketToken = 0,
1440 LeftCurlyBracketToken,
1441 RightCurlyBracketToken,
1455 RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
1457 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
1458 #define N NumberToken
1459 #define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1460 // Maps from ASCII to Token
1461 static const unsigned char tokenMap[256] = {
1464 N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F
1465 N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F
1467 N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F
1468 N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F
1469 N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F
1470 N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF
1476 if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
1477 return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);
1482 RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {
1483 // current state x one lookahead token -> new state
1484 static const char G[cIterativeParsingStateCount][kTokenCount] = {
1487 IterativeParsingArrayInitialState, // Left bracket
1488 IterativeParsingErrorState, // Right bracket
1489 IterativeParsingObjectInitialState, // Left curly bracket
1490 IterativeParsingErrorState, // Right curly bracket
1491 IterativeParsingErrorState, // Comma
1492 IterativeParsingErrorState, // Colon
1493 IterativeParsingValueState, // String
1494 IterativeParsingValueState, // False
1495 IterativeParsingValueState, // True
1496 IterativeParsingValueState, // Null
1497 IterativeParsingValueState // Number
1499 // Finish(sink state)
1501 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1502 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1503 IterativeParsingErrorState
1505 // Error(sink state)
1507 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1508 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1509 IterativeParsingErrorState
1513 IterativeParsingErrorState, // Left bracket
1514 IterativeParsingErrorState, // Right bracket
1515 IterativeParsingErrorState, // Left curly bracket
1516 IterativeParsingObjectFinishState, // Right curly bracket
1517 IterativeParsingErrorState, // Comma
1518 IterativeParsingErrorState, // Colon
1519 IterativeParsingMemberKeyState, // String
1520 IterativeParsingErrorState, // False
1521 IterativeParsingErrorState, // True
1522 IterativeParsingErrorState, // Null
1523 IterativeParsingErrorState // Number
1527 IterativeParsingErrorState, // Left bracket
1528 IterativeParsingErrorState, // Right bracket
1529 IterativeParsingErrorState, // Left curly bracket
1530 IterativeParsingErrorState, // Right curly bracket
1531 IterativeParsingErrorState, // Comma
1532 IterativeParsingKeyValueDelimiterState, // Colon
1533 IterativeParsingErrorState, // String
1534 IterativeParsingErrorState, // False
1535 IterativeParsingErrorState, // True
1536 IterativeParsingErrorState, // Null
1537 IterativeParsingErrorState // Number
1539 // KeyValueDelimiter
1541 IterativeParsingArrayInitialState, // Left bracket(push MemberValue state)
1542 IterativeParsingErrorState, // Right bracket
1543 IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state)
1544 IterativeParsingErrorState, // Right curly bracket
1545 IterativeParsingErrorState, // Comma
1546 IterativeParsingErrorState, // Colon
1547 IterativeParsingMemberValueState, // String
1548 IterativeParsingMemberValueState, // False
1549 IterativeParsingMemberValueState, // True
1550 IterativeParsingMemberValueState, // Null
1551 IterativeParsingMemberValueState // Number
1555 IterativeParsingErrorState, // Left bracket
1556 IterativeParsingErrorState, // Right bracket
1557 IterativeParsingErrorState, // Left curly bracket
1558 IterativeParsingObjectFinishState, // Right curly bracket
1559 IterativeParsingMemberDelimiterState, // Comma
1560 IterativeParsingErrorState, // Colon
1561 IterativeParsingErrorState, // String
1562 IterativeParsingErrorState, // False
1563 IterativeParsingErrorState, // True
1564 IterativeParsingErrorState, // Null
1565 IterativeParsingErrorState // Number
1569 IterativeParsingErrorState, // Left bracket
1570 IterativeParsingErrorState, // Right bracket
1571 IterativeParsingErrorState, // Left curly bracket
1572 IterativeParsingObjectFinishState, // Right curly bracket
1573 IterativeParsingErrorState, // Comma
1574 IterativeParsingErrorState, // Colon
1575 IterativeParsingMemberKeyState, // String
1576 IterativeParsingErrorState, // False
1577 IterativeParsingErrorState, // True
1578 IterativeParsingErrorState, // Null
1579 IterativeParsingErrorState // Number
1581 // ObjectFinish(sink state)
1583 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1584 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1585 IterativeParsingErrorState
1589 IterativeParsingArrayInitialState, // Left bracket(push Element state)
1590 IterativeParsingArrayFinishState, // Right bracket
1591 IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1592 IterativeParsingErrorState, // Right curly bracket
1593 IterativeParsingErrorState, // Comma
1594 IterativeParsingErrorState, // Colon
1595 IterativeParsingElementState, // String
1596 IterativeParsingElementState, // False
1597 IterativeParsingElementState, // True
1598 IterativeParsingElementState, // Null
1599 IterativeParsingElementState // Number
1603 IterativeParsingErrorState, // Left bracket
1604 IterativeParsingArrayFinishState, // Right bracket
1605 IterativeParsingErrorState, // Left curly bracket
1606 IterativeParsingErrorState, // Right curly bracket
1607 IterativeParsingElementDelimiterState, // Comma
1608 IterativeParsingErrorState, // Colon
1609 IterativeParsingErrorState, // String
1610 IterativeParsingErrorState, // False
1611 IterativeParsingErrorState, // True
1612 IterativeParsingErrorState, // Null
1613 IterativeParsingErrorState // Number
1617 IterativeParsingArrayInitialState, // Left bracket(push Element state)
1618 IterativeParsingArrayFinishState, // Right bracket
1619 IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1620 IterativeParsingErrorState, // Right curly bracket
1621 IterativeParsingErrorState, // Comma
1622 IterativeParsingErrorState, // Colon
1623 IterativeParsingElementState, // String
1624 IterativeParsingElementState, // False
1625 IterativeParsingElementState, // True
1626 IterativeParsingElementState, // Null
1627 IterativeParsingElementState // Number
1629 // ArrayFinish(sink state)
1631 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1632 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1633 IterativeParsingErrorState
1635 // Single Value (sink state)
1637 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1638 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1639 IterativeParsingErrorState
1643 return static_cast<IterativeParsingState>(G[state][token]);
1646 // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
1647 // May return a new state on state pop.
1648 template <unsigned parseFlags, typename InputStream, typename Handler>
1649 RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
1653 case IterativeParsingErrorState:
1656 case IterativeParsingObjectInitialState:
1657 case IterativeParsingArrayInitialState:
1659 // Push the state(Element or MemeberValue) if we are nested in another array or value of member.
1660 // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
1661 IterativeParsingState n = src;
1662 if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
1663 n = IterativeParsingElementState;
1664 else if (src == IterativeParsingKeyValueDelimiterState)
1665 n = IterativeParsingMemberValueState;
1666 // Push current state.
1667 *stack_.template Push<SizeType>(1) = n;
1668 // Initialize and push the member/element count.
1669 *stack_.template Push<SizeType>(1) = 0;
1671 bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
1672 // On handler short circuits the parsing.
1674 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1675 return IterativeParsingErrorState;
1683 case IterativeParsingMemberKeyState:
1684 ParseString<parseFlags>(is, handler, true);
1685 if (HasParseError())
1686 return IterativeParsingErrorState;
1690 case IterativeParsingKeyValueDelimiterState:
1691 RAPIDJSON_ASSERT(token == ColonToken);
1695 case IterativeParsingMemberValueState:
1696 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1697 ParseValue<parseFlags>(is, handler);
1698 if (HasParseError()) {
1699 return IterativeParsingErrorState;
1703 case IterativeParsingElementState:
1704 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1705 ParseValue<parseFlags>(is, handler);
1706 if (HasParseError()) {
1707 return IterativeParsingErrorState;
1711 case IterativeParsingMemberDelimiterState:
1712 case IterativeParsingElementDelimiterState:
1714 // Update member/element count.
1715 *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
1718 case IterativeParsingObjectFinishState:
1720 // Transit from delimiter is only allowed when trailing commas are enabled
1721 if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {
1722 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell());
1723 return IterativeParsingErrorState;
1725 // Get member count.
1726 SizeType c = *stack_.template Pop<SizeType>(1);
1727 // If the object is not empty, count the last member.
1728 if (src == IterativeParsingMemberValueState)
1730 // Restore the state.
1731 IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1732 // Transit to Finish state if this is the topmost scope.
1733 if (n == IterativeParsingStartState)
1734 n = IterativeParsingFinishState;
1736 bool hr = handler.EndObject(c);
1737 // On handler short circuits the parsing.
1739 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1740 return IterativeParsingErrorState;
1748 case IterativeParsingArrayFinishState:
1750 // Transit from delimiter is only allowed when trailing commas are enabled
1751 if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {
1752 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell());
1753 return IterativeParsingErrorState;
1755 // Get element count.
1756 SizeType c = *stack_.template Pop<SizeType>(1);
1757 // If the array is not empty, count the last element.
1758 if (src == IterativeParsingElementState)
1760 // Restore the state.
1761 IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1762 // Transit to Finish state if this is the topmost scope.
1763 if (n == IterativeParsingStartState)
1764 n = IterativeParsingFinishState;
1766 bool hr = handler.EndArray(c);
1767 // On handler short circuits the parsing.
1769 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1770 return IterativeParsingErrorState;
1779 // This branch is for IterativeParsingValueState actually.
1780 // Use `default:` rather than
1781 // `case IterativeParsingValueState:` is for code coverage.
1783 // The IterativeParsingStartState is not enumerated in this switch-case.
1784 // It is impossible for that case. And it can be caught by following assertion.
1786 // The IterativeParsingFinishState is not enumerated in this switch-case either.
1787 // It is a "derivative" state which cannot triggered from Predict() directly.
1788 // Therefore it cannot happen here. And it can be caught by following assertion.
1789 RAPIDJSON_ASSERT(dst == IterativeParsingValueState);
1791 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1792 ParseValue<parseFlags>(is, handler);
1793 if (HasParseError()) {
1794 return IterativeParsingErrorState;
1796 return IterativeParsingFinishState;
1800 template <typename InputStream>
1801 void HandleError(IterativeParsingState src, InputStream& is) {
1802 if (HasParseError()) {
1803 // Error flag has been set.
1808 case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
1809 case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
1810 case IterativeParsingObjectInitialState:
1811 case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
1812 case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
1813 case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
1814 case IterativeParsingKeyValueDelimiterState:
1815 case IterativeParsingArrayInitialState:
1816 case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return;
1817 default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
1821 template <unsigned parseFlags, typename InputStream, typename Handler>
1822 ParseResult IterativeParse(InputStream& is, Handler& handler) {
1823 parseResult_.Clear();
1824 ClearStackOnExit scope(*this);
1825 IterativeParsingState state = IterativeParsingStartState;
1827 SkipWhitespaceAndComments<parseFlags>(is);
1828 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
1829 while (is.Peek() != '\0') {
1830 Token t = Tokenize(is.Peek());
1831 IterativeParsingState n = Predict(state, t);
1832 IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
1834 if (d == IterativeParsingErrorState) {
1835 HandleError(state, is);
1841 // Do not further consume streams if a root JSON has been parsed.
1842 if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
1845 SkipWhitespaceAndComments<parseFlags>(is);
1846 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
1849 // Handle the end of file.
1850 if (state != IterativeParsingFinishState)
1851 HandleError(state, is);
1853 return parseResult_;
1856 static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string.
1857 internal::Stack<StackAllocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing.
1858 ParseResult parseResult_;
1859 }; // class GenericReader
1861 //! Reader with UTF8 encoding and default allocator.
1862 typedef GenericReader<UTF8<>, UTF8<> > Reader;
1864 RAPIDJSON_NAMESPACE_END
1879 #endif // RAPIDJSON_READER_H_