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>
36 #elif defined(RAPIDJSON_NEON)
42 RAPIDJSON_DIAG_OFF(old-style-cast)
43 RAPIDJSON_DIAG_OFF(padded)
44 RAPIDJSON_DIAG_OFF(switch-enum)
45 #elif defined(_MSC_VER)
47 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
48 RAPIDJSON_DIAG_OFF(4702) // unreachable code
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_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
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'))
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]));
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
326 return SkipWhitespace(p, end);
329 #elif defined(RAPIDJSON_SSE2)
331 //! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
332 inline const char *SkipWhitespace_SIMD(const char* p) {
333 // Fast return for single non-whitespace
334 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
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')
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') };
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]));
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);
370 return p + __builtin_ffs(r) - 1;
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'))
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') };
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]));
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);
406 return p + __builtin_ffs(r) - 1;
411 return SkipWhitespace(p, end);
414 #elif defined(RAPIDJSON_NEON)
416 //! Skip whitespace with ARM Neon instructions, testing 16 8-byte characters at once.
417 inline const char *SkipWhitespace_SIMD(const char* p) {
418 // Fast return for single non-whitespace
419 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
424 // 16-byte align to the next boundary
425 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
426 while (p != nextAligned)
427 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
432 const uint8x16_t w0 = vmovq_n_u8(' ');
433 const uint8x16_t w1 = vmovq_n_u8('\n');
434 const uint8x16_t w2 = vmovq_n_u8('\r');
435 const uint8x16_t w3 = vmovq_n_u8('\t');
438 const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
439 uint8x16_t x = vceqq_u8(s, w0);
440 x = vorrq_u8(x, vceqq_u8(s, w1));
441 x = vorrq_u8(x, vceqq_u8(s, w2));
442 x = vorrq_u8(x, vceqq_u8(s, w3));
444 x = vmvnq_u8(x); // Negate
445 x = vrev64q_u8(x); // Rev in 64
446 uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
447 uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
451 int lz =__builtin_clzll(high);;
452 return p + 8 + (lz >> 3);
455 int lz = __builtin_clzll(low);;
456 return p + (lz >> 3);
461 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
462 // Fast return for single non-whitespace
463 if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
468 const uint8x16_t w0 = vmovq_n_u8(' ');
469 const uint8x16_t w1 = vmovq_n_u8('\n');
470 const uint8x16_t w2 = vmovq_n_u8('\r');
471 const uint8x16_t w3 = vmovq_n_u8('\t');
473 for (; p <= end - 16; p += 16) {
474 const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
475 uint8x16_t x = vceqq_u8(s, w0);
476 x = vorrq_u8(x, vceqq_u8(s, w1));
477 x = vorrq_u8(x, vceqq_u8(s, w2));
478 x = vorrq_u8(x, vceqq_u8(s, w3));
480 x = vmvnq_u8(x); // Negate
481 x = vrev64q_u8(x); // Rev in 64
482 uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
483 uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
487 int lz = __builtin_clzll(high);
488 return p + 8 + (lz >> 3);
491 int lz = __builtin_clzll(low);
492 return p + (lz >> 3);
496 return SkipWhitespace(p, end);
499 #endif // RAPIDJSON_NEON
501 #ifdef RAPIDJSON_SIMD
502 //! Template function specialization for InsituStringStream
503 template<> inline void SkipWhitespace(InsituStringStream& is) {
504 is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
507 //! Template function specialization for StringStream
508 template<> inline void SkipWhitespace(StringStream& is) {
509 is.src_ = SkipWhitespace_SIMD(is.src_);
512 template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {
513 is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
515 #endif // RAPIDJSON_SIMD
517 ///////////////////////////////////////////////////////////////////////////////
520 //! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator.
521 /*! GenericReader parses JSON text from a stream, and send events synchronously to an
522 object implementing Handler concept.
524 It needs to allocate a stack for storing a single decoded string during
525 non-destructive parsing.
527 For in-situ parsing, the decoded string is directly written to the source
528 text string, no temporary buffer is required.
530 A GenericReader object can be reused for parsing multiple JSON text.
532 \tparam SourceEncoding Encoding of the input stream.
533 \tparam TargetEncoding Encoding of the parse output.
534 \tparam StackAllocator Allocator type for stack.
536 template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
537 class GenericReader {
539 typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type
542 /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
543 \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
545 GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) :
546 stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {}
549 /*! \tparam parseFlags Combination of \ref ParseFlag.
550 \tparam InputStream Type of input stream, implementing Stream concept.
551 \tparam Handler Type of handler, implementing Handler concept.
552 \param is Input stream to be parsed.
553 \param handler The handler to receive events.
554 \return Whether the parsing is successful.
556 template <unsigned parseFlags, typename InputStream, typename Handler>
557 ParseResult Parse(InputStream& is, Handler& handler) {
558 if (parseFlags & kParseIterativeFlag)
559 return IterativeParse<parseFlags>(is, handler);
561 parseResult_.Clear();
563 ClearStackOnExit scope(*this);
565 SkipWhitespaceAndComments<parseFlags>(is);
566 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
568 if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) {
569 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
570 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
573 ParseValue<parseFlags>(is, handler);
574 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
576 if (!(parseFlags & kParseStopWhenDoneFlag)) {
577 SkipWhitespaceAndComments<parseFlags>(is);
578 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
580 if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) {
581 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
582 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
590 //! Parse JSON text (with \ref kParseDefaultFlags)
591 /*! \tparam InputStream Type of input stream, implementing Stream concept
592 \tparam Handler Type of handler, implementing Handler concept.
593 \param is Input stream to be parsed.
594 \param handler The handler to receive events.
595 \return Whether the parsing is successful.
597 template <typename InputStream, typename Handler>
598 ParseResult Parse(InputStream& is, Handler& handler) {
599 return Parse<kParseDefaultFlags>(is, handler);
602 //! Initialize JSON text token-by-token parsing
605 void IterativeParseInit() {
606 parseResult_.Clear();
607 state_ = IterativeParsingStartState;
610 //! Parse one token from JSON text
611 /*! \tparam InputStream Type of input stream, implementing Stream concept
612 \tparam Handler Type of handler, implementing Handler concept.
613 \param is Input stream to be parsed.
614 \param handler The handler to receive events.
615 \return Whether the parsing is successful.
617 template <unsigned parseFlags, typename InputStream, typename Handler>
618 bool IterativeParseNext(InputStream& is, Handler& handler) {
619 while (RAPIDJSON_LIKELY(is.Peek() != '\0')) {
620 SkipWhitespaceAndComments<parseFlags>(is);
622 Token t = Tokenize(is.Peek());
623 IterativeParsingState n = Predict(state_, t);
624 IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
626 // If we've finished or hit an error...
627 if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {
629 if (d == IterativeParsingErrorState) {
630 HandleError(state_, is);
634 // Transition to the finish state.
635 RAPIDJSON_ASSERT(d == IterativeParsingFinishState);
638 // If StopWhenDone is not set...
639 if (!(parseFlags & kParseStopWhenDoneFlag)) {
640 // ... and extra non-whitespace data is found...
641 SkipWhitespaceAndComments<parseFlags>(is);
642 if (is.Peek() != '\0') {
643 // ... this is considered an error.
644 HandleError(state_, is);
649 // Success! We are done!
653 // Transition to the new state.
656 // If we parsed anything other than a delimiter, we invoked the handler, so we can return true now.
657 if (!IsIterativeParsingDelimiterState(n))
661 // We reached the end of file.
664 if (state_ != IterativeParsingFinishState) {
665 HandleError(state_, is);
672 //! Check if token-by-token parsing JSON text is complete
673 /*! \return Whether the JSON has been fully decoded.
675 RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const {
676 return IsIterativeParsingCompleteState(state_);
679 //! Whether a parse error has occurred in the last parsing.
680 bool HasParseError() const { return parseResult_.IsError(); }
682 //! Get the \ref ParseErrorCode of last parsing.
683 ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }
685 //! Get the position of last parsing error in input, 0 otherwise.
686 size_t GetErrorOffset() const { return parseResult_.Offset(); }
689 void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
692 // Prohibit copy constructor & assignment operator.
693 GenericReader(const GenericReader&);
694 GenericReader& operator=(const GenericReader&);
696 void ClearStack() { stack_.Clear(); }
698 // clear stack on any exit from ParseStream, e.g. due to exception
699 struct ClearStackOnExit {
700 explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
701 ~ClearStackOnExit() { r_.ClearStack(); }
704 ClearStackOnExit(const ClearStackOnExit&);
705 ClearStackOnExit& operator=(const ClearStackOnExit&);
708 template<unsigned parseFlags, typename InputStream>
709 void SkipWhitespaceAndComments(InputStream& is) {
712 if (parseFlags & kParseCommentsFlag) {
713 while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) {
714 if (Consume(is, '*')) {
716 if (RAPIDJSON_UNLIKELY(is.Peek() == '\0'))
717 RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
718 else if (Consume(is, '*')) {
719 if (Consume(is, '/'))
726 else if (RAPIDJSON_LIKELY(Consume(is, '/')))
727 while (is.Peek() != '\0' && is.Take() != '\n') {}
729 RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
736 // Parse object: { string : value, ... }
737 template<unsigned parseFlags, typename InputStream, typename Handler>
738 void ParseObject(InputStream& is, Handler& handler) {
739 RAPIDJSON_ASSERT(is.Peek() == '{');
740 is.Take(); // Skip '{'
742 if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
743 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
745 SkipWhitespaceAndComments<parseFlags>(is);
746 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
748 if (Consume(is, '}')) {
749 if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object
750 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
754 for (SizeType memberCount = 0;;) {
755 if (RAPIDJSON_UNLIKELY(is.Peek() != '"'))
756 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
758 ParseString<parseFlags>(is, handler, true);
759 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
761 SkipWhitespaceAndComments<parseFlags>(is);
762 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
764 if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))
765 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
767 SkipWhitespaceAndComments<parseFlags>(is);
768 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
770 ParseValue<parseFlags>(is, handler);
771 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
773 SkipWhitespaceAndComments<parseFlags>(is);
774 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
781 SkipWhitespaceAndComments<parseFlags>(is);
782 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
786 if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
787 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
790 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy
793 if (parseFlags & kParseTrailingCommasFlag) {
794 if (is.Peek() == '}') {
795 if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
796 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
804 // Parse array: [ value, ... ]
805 template<unsigned parseFlags, typename InputStream, typename Handler>
806 void ParseArray(InputStream& is, Handler& handler) {
807 RAPIDJSON_ASSERT(is.Peek() == '[');
808 is.Take(); // Skip '['
810 if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
811 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
813 SkipWhitespaceAndComments<parseFlags>(is);
814 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
816 if (Consume(is, ']')) {
817 if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array
818 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
822 for (SizeType elementCount = 0;;) {
823 ParseValue<parseFlags>(is, handler);
824 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
827 SkipWhitespaceAndComments<parseFlags>(is);
828 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
830 if (Consume(is, ',')) {
831 SkipWhitespaceAndComments<parseFlags>(is);
832 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
834 else if (Consume(is, ']')) {
835 if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
836 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
840 RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
842 if (parseFlags & kParseTrailingCommasFlag) {
843 if (is.Peek() == ']') {
844 if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
845 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
853 template<unsigned parseFlags, typename InputStream, typename Handler>
854 void ParseNull(InputStream& is, Handler& handler) {
855 RAPIDJSON_ASSERT(is.Peek() == 'n');
858 if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {
859 if (RAPIDJSON_UNLIKELY(!handler.Null()))
860 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
863 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
866 template<unsigned parseFlags, typename InputStream, typename Handler>
867 void ParseTrue(InputStream& is, Handler& handler) {
868 RAPIDJSON_ASSERT(is.Peek() == 't');
871 if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {
872 if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))
873 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
876 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
879 template<unsigned parseFlags, typename InputStream, typename Handler>
880 void ParseFalse(InputStream& is, Handler& handler) {
881 RAPIDJSON_ASSERT(is.Peek() == 'f');
884 if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {
885 if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))
886 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
889 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
892 template<typename InputStream>
893 RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
894 if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
902 // Helper function to parse four hexadecimal digits in \uXXXX in ParseString().
903 template<typename InputStream>
904 unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
905 unsigned codepoint = 0;
906 for (int i = 0; i < 4; i++) {
909 codepoint += static_cast<unsigned>(c);
910 if (c >= '0' && c <= '9')
912 else if (c >= 'A' && c <= 'F')
913 codepoint -= 'A' - 10;
914 else if (c >= 'a' && c <= 'f')
915 codepoint -= 'a' - 10;
917 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset);
918 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
925 template <typename CharType>
930 StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {}
931 RAPIDJSON_FORCEINLINE void Put(Ch c) {
932 *stack_.template Push<Ch>() = c;
936 RAPIDJSON_FORCEINLINE void* Push(SizeType count) {
938 return stack_.template Push<Ch>(count);
941 size_t Length() const { return length_; }
944 return stack_.template Pop<Ch>(length_);
948 StackStream(const StackStream&);
949 StackStream& operator=(const StackStream&);
951 internal::Stack<StackAllocator>& stack_;
955 // Parse string and generate String event. Different code paths for kParseInsituFlag.
956 template<unsigned parseFlags, typename InputStream, typename Handler>
957 void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
958 internal::StreamLocalCopy<InputStream> copy(is);
959 InputStream& s(copy.s);
961 RAPIDJSON_ASSERT(s.Peek() == '\"');
962 s.Take(); // Skip '\"'
964 bool success = false;
965 if (parseFlags & kParseInsituFlag) {
966 typename InputStream::Ch *head = s.PutBegin();
967 ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
968 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
969 size_t length = s.PutEnd(head) - 1;
970 RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
971 const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
972 success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
975 StackStream<typename TargetEncoding::Ch> stackStream(stack_);
976 ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
977 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
978 SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;
979 const typename TargetEncoding::Ch* const str = stackStream.Pop();
980 success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
982 if (RAPIDJSON_UNLIKELY(!success))
983 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
986 // Parse string to an output is
987 // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
988 template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
989 RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
990 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
991 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
992 static const char escape[256] = {
993 Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
994 Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
995 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
996 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
997 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
1003 // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
1004 if (!(parseFlags & kParseValidateEncodingFlag))
1005 ScanCopyUnescapedString(is, os);
1008 if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape
1009 size_t escapeOffset = is.Tell(); // For invalid escaping, report the initial '\\' as error offset
1012 if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
1014 os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
1016 else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
1018 unsigned codepoint = ParseHex4(is, escapeOffset);
1019 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
1020 if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
1021 // Handle UTF-16 surrogate pair
1022 if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
1023 RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
1024 unsigned codepoint2 = ParseHex4(is, escapeOffset);
1025 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
1026 if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
1027 RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
1028 codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
1030 TEncoding::Encode(os, codepoint);
1033 RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset);
1035 else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote
1037 os.Put('\0'); // null-terminate the string
1040 else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
1042 RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell());
1044 RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell());
1047 size_t offset = is.Tell();
1048 if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
1049 !Transcoder<SEncoding, TEncoding>::Validate(is, os) :
1050 !Transcoder<SEncoding, TEncoding>::Transcode(is, os))))
1051 RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset);
1056 template<typename InputStream, typename OutputStream>
1057 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {
1058 // Do nothing for generic version
1061 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
1062 // StringStream -> StackStream<char>
1063 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
1064 const char* p = is.src_;
1066 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1067 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1068 while (p != nextAligned)
1069 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1076 // The rest of string using SIMD
1077 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1078 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1079 static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1080 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1081 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1082 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1085 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1086 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1087 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1088 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
1089 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1090 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1091 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1093 #ifdef _MSC_VER // Find the index of first escaped
1094 unsigned long offset;
1095 _BitScanForward(&offset, r);
1098 length = static_cast<SizeType>(__builtin_ffs(r) - 1);
1101 char* q = reinterpret_cast<char*>(os.Push(length));
1102 for (size_t i = 0; i < length; i++)
1109 _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);
1115 // InsituStringStream -> InsituStringStream
1116 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
1117 RAPIDJSON_ASSERT(&is == &os);
1120 if (is.src_ == is.dst_) {
1121 SkipUnescapedString(is);
1128 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1129 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1130 while (p != nextAligned)
1131 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1139 // The rest of string using SIMD
1140 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1141 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1142 static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1143 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1144 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1145 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1147 for (;; p += 16, q += 16) {
1148 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1149 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1150 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1151 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
1152 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1153 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1154 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1156 #ifdef _MSC_VER // Find the index of first escaped
1157 unsigned long offset;
1158 _BitScanForward(&offset, r);
1161 length = static_cast<size_t>(__builtin_ffs(r) - 1);
1163 for (const char* pend = p + length; p != pend; )
1167 _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);
1174 // When read/write pointers are the same for insitu stream, just skip unescaped characters
1175 static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
1176 RAPIDJSON_ASSERT(is.src_ == is.dst_);
1179 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1180 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1181 for (; p != nextAligned; p++)
1182 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1183 is.src_ = is.dst_ = p;
1187 // The rest of string using SIMD
1188 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1189 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1190 static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1191 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1192 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1193 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1196 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1197 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1198 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1199 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
1200 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1201 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1202 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1204 #ifdef _MSC_VER // Find the index of first escaped
1205 unsigned long offset;
1206 _BitScanForward(&offset, r);
1209 length = static_cast<size_t>(__builtin_ffs(r) - 1);
1216 is.src_ = is.dst_ = p;
1218 #elif defined(RAPIDJSON_NEON)
1219 // StringStream -> StackStream<char>
1220 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
1221 const char* p = is.src_;
1223 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1224 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1225 while (p != nextAligned)
1226 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1233 // The rest of string using SIMD
1234 const uint8x16_t s0 = vmovq_n_u8('"');
1235 const uint8x16_t s1 = vmovq_n_u8('\\');
1236 const uint8x16_t s2 = vmovq_n_u8('\b');
1237 const uint8x16_t s3 = vmovq_n_u8(32);
1240 const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
1241 uint8x16_t x = vceqq_u8(s, s0);
1242 x = vorrq_u8(x, vceqq_u8(s, s1));
1243 x = vorrq_u8(x, vceqq_u8(s, s2));
1244 x = vorrq_u8(x, vcltq_u8(s, s3));
1246 x = vrev64q_u8(x); // Rev in 64
1247 uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
1248 uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
1250 SizeType length = 0;
1251 bool escaped = false;
1254 unsigned lz = (unsigned)__builtin_clzll(high);;
1255 length = 8 + (lz >> 3);
1259 unsigned lz = (unsigned)__builtin_clzll(low);;
1263 if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped
1265 char* q = reinterpret_cast<char*>(os.Push(length));
1266 for (size_t i = 0; i < length; i++)
1273 vst1q_u8(reinterpret_cast<uint8_t *>(os.Push(16)), s);
1279 // InsituStringStream -> InsituStringStream
1280 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
1281 RAPIDJSON_ASSERT(&is == &os);
1284 if (is.src_ == is.dst_) {
1285 SkipUnescapedString(is);
1292 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1293 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1294 while (p != nextAligned)
1295 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1303 // The rest of string using SIMD
1304 const uint8x16_t s0 = vmovq_n_u8('"');
1305 const uint8x16_t s1 = vmovq_n_u8('\\');
1306 const uint8x16_t s2 = vmovq_n_u8('\b');
1307 const uint8x16_t s3 = vmovq_n_u8(32);
1309 for (;; p += 16, q += 16) {
1310 const uint8x16_t s = vld1q_u8(reinterpret_cast<uint8_t *>(p));
1311 uint8x16_t x = vceqq_u8(s, s0);
1312 x = vorrq_u8(x, vceqq_u8(s, s1));
1313 x = vorrq_u8(x, vceqq_u8(s, s2));
1314 x = vorrq_u8(x, vcltq_u8(s, s3));
1316 x = vrev64q_u8(x); // Rev in 64
1317 uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
1318 uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
1320 SizeType length = 0;
1321 bool escaped = false;
1324 unsigned lz = (unsigned)__builtin_clzll(high);
1325 length = 8 + (lz >> 3);
1329 unsigned lz = (unsigned)__builtin_clzll(low);
1333 if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped
1334 for (const char* pend = p + length; p != pend; ) {
1339 vst1q_u8(reinterpret_cast<uint8_t *>(q), s);
1346 // When read/write pointers are the same for insitu stream, just skip unescaped characters
1347 static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
1348 RAPIDJSON_ASSERT(is.src_ == is.dst_);
1351 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1352 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1353 for (; p != nextAligned; p++)
1354 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1355 is.src_ = is.dst_ = p;
1359 // The rest of string using SIMD
1360 const uint8x16_t s0 = vmovq_n_u8('"');
1361 const uint8x16_t s1 = vmovq_n_u8('\\');
1362 const uint8x16_t s2 = vmovq_n_u8('\b');
1363 const uint8x16_t s3 = vmovq_n_u8(32);
1366 const uint8x16_t s = vld1q_u8(reinterpret_cast<uint8_t *>(p));
1367 uint8x16_t x = vceqq_u8(s, s0);
1368 x = vorrq_u8(x, vceqq_u8(s, s1));
1369 x = vorrq_u8(x, vceqq_u8(s, s2));
1370 x = vorrq_u8(x, vcltq_u8(s, s3));
1372 x = vrev64q_u8(x); // Rev in 64
1373 uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
1374 uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
1378 int lz = __builtin_clzll(high);
1383 int lz = __builtin_clzll(low);
1389 is.src_ = is.dst_ = p;
1391 #endif // RAPIDJSON_NEON
1393 template<typename InputStream, bool backup, bool pushOnTake>
1396 template<typename InputStream>
1397 class NumberStream<InputStream, false, false> {
1399 typedef typename InputStream::Ch Ch;
1401 NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; }
1403 RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
1404 RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
1405 RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
1406 RAPIDJSON_FORCEINLINE void Push(char) {}
1408 size_t Tell() { return is.Tell(); }
1409 size_t Length() { return 0; }
1410 const char* Pop() { return 0; }
1413 NumberStream& operator=(const NumberStream&);
1418 template<typename InputStream>
1419 class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
1420 typedef NumberStream<InputStream, false, false> Base;
1422 NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
1424 RAPIDJSON_FORCEINLINE Ch TakePush() {
1425 stackStream.Put(static_cast<char>(Base::is.Peek()));
1426 return Base::is.Take();
1429 RAPIDJSON_FORCEINLINE void Push(char c) {
1433 size_t Length() { return stackStream.Length(); }
1436 stackStream.Put('\0');
1437 return stackStream.Pop();
1441 StackStream<char> stackStream;
1444 template<typename InputStream>
1445 class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
1446 typedef NumberStream<InputStream, true, false> Base;
1448 NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
1450 RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
1453 template<unsigned parseFlags, typename InputStream, typename Handler>
1454 void ParseNumber(InputStream& is, Handler& handler) {
1455 internal::StreamLocalCopy<InputStream> copy(is);
1456 NumberStream<InputStream,
1457 ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
1458 ((parseFlags & kParseInsituFlag) == 0) :
1459 ((parseFlags & kParseFullPrecisionFlag) != 0),
1460 (parseFlags & kParseNumbersAsStringsFlag) != 0 &&
1461 (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);
1463 size_t startOffset = s.Tell();
1465 bool useNanOrInf = false;
1468 bool minus = Consume(s, '-');
1470 // Parse int: zero / ( digit1-9 *DIGIT )
1473 bool use64bit = false;
1474 int significandDigit = 0;
1475 if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {
1479 else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {
1480 i = static_cast<unsigned>(s.TakePush() - '0');
1483 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1484 if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648
1485 if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {
1491 i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1495 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1496 if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295
1497 if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {
1503 i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1507 // Parse NaN or Infinity here
1508 else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {
1509 if (Consume(s, 'N')) {
1510 if (Consume(s, 'a') && Consume(s, 'N')) {
1511 d = std::numeric_limits<double>::quiet_NaN();
1515 else if (RAPIDJSON_LIKELY(Consume(s, 'I'))) {
1516 if (Consume(s, 'n') && Consume(s, 'f')) {
1517 d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
1520 if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
1521 && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) {
1522 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1527 if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
1528 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1532 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1535 bool useDouble = false;
1538 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1539 if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808
1540 if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {
1541 d = static_cast<double>(i64);
1545 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1549 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1550 if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615
1551 if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {
1552 d = static_cast<double>(i64);
1556 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1561 // Force double for big integer
1563 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1564 d = d * 10 + (s.TakePush() - '0');
1568 // Parse frac = decimal-point 1*DIGIT
1570 size_t decimalPosition;
1571 if (Consume(s, '.')) {
1572 decimalPosition = s.Length();
1574 if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
1575 RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
1579 // Use i64 to store significand in 64-bit architecture
1583 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1584 if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
1587 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1594 d = static_cast<double>(i64);
1596 // Use double to store significand in 32-bit architecture
1597 d = static_cast<double>(use64bit ? i64 : i);
1602 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1603 if (significandDigit < 17) {
1604 d = d * 10.0 + (s.TakePush() - '0');
1606 if (RAPIDJSON_LIKELY(d > 0.0))
1614 decimalPosition = s.Length(); // decimal position at the end of integer.
1616 // Parse exp = e [ minus / plus ] 1*DIGIT
1618 if (Consume(s, 'e') || Consume(s, 'E')) {
1620 d = static_cast<double>(use64bit ? i64 : i);
1624 bool expMinus = false;
1625 if (Consume(s, '+'))
1627 else if (Consume(s, '-'))
1630 if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1631 exp = static_cast<int>(s.Take() - '0');
1633 // (exp + expFrac) must not underflow int => we're detecting when -exp gets
1634 // dangerously close to INT_MIN (a pessimistic next digit 9 would push it into
1635 // underflow territory):
1637 // -(exp * 10 + 9) + expFrac >= INT_MIN
1638 // <=> exp <= (expFrac - INT_MIN - 9) / 10
1639 RAPIDJSON_ASSERT(expFrac <= 0);
1640 int maxExp = (expFrac + 2147483639) / 10;
1642 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1643 exp = exp * 10 + static_cast<int>(s.Take() - '0');
1644 if (RAPIDJSON_UNLIKELY(exp > maxExp)) {
1645 while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent
1650 else { // positive exp
1651 int maxExp = 308 - expFrac;
1652 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1653 exp = exp * 10 + static_cast<int>(s.Take() - '0');
1654 if (RAPIDJSON_UNLIKELY(exp > maxExp))
1655 RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
1660 RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());
1666 // Finish parsing, call event according to the type of number.
1669 if (parseFlags & kParseNumbersAsStringsFlag) {
1670 if (parseFlags & kParseInsituFlag) {
1671 s.Pop(); // Pop stack no matter if it will be used or not.
1672 typename InputStream::Ch* head = is.PutBegin();
1673 const size_t length = s.Tell() - startOffset;
1674 RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
1675 // unable to insert the \0 character here, it will erase the comma after this number
1676 const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
1677 cont = handler.RawNumber(str, SizeType(length), false);
1680 SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
1681 StringStream srcStream(s.Pop());
1682 StackStream<typename TargetEncoding::Ch> dstStream(stack_);
1683 while (numCharsToCopy--) {
1684 Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);
1686 dstStream.Put('\0');
1687 const typename TargetEncoding::Ch* str = dstStream.Pop();
1688 const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1;
1689 cont = handler.RawNumber(str, SizeType(length), true);
1693 size_t length = s.Length();
1694 const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not.
1697 int p = exp + expFrac;
1698 if (parseFlags & kParseFullPrecisionFlag)
1699 d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
1701 d = internal::StrtodNormalPrecision(d, p);
1703 // Use > max, instead of == inf, to fix bogus warning -Wfloat-equal
1704 if (d > (std::numeric_limits<double>::max)()) {
1706 // TODO: internal::StrtodX should report overflow (or underflow)
1707 RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
1710 cont = handler.Double(minus ? -d : d);
1712 else if (useNanOrInf) {
1713 cont = handler.Double(d);
1718 cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
1720 cont = handler.Uint64(i64);
1724 cont = handler.Int(static_cast<int32_t>(~i + 1));
1726 cont = handler.Uint(i);
1730 if (RAPIDJSON_UNLIKELY(!cont))
1731 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset);
1734 // Parse any JSON value
1735 template<unsigned parseFlags, typename InputStream, typename Handler>
1736 void ParseValue(InputStream& is, Handler& handler) {
1737 switch (is.Peek()) {
1738 case 'n': ParseNull <parseFlags>(is, handler); break;
1739 case 't': ParseTrue <parseFlags>(is, handler); break;
1740 case 'f': ParseFalse <parseFlags>(is, handler); break;
1741 case '"': ParseString<parseFlags>(is, handler); break;
1742 case '{': ParseObject<parseFlags>(is, handler); break;
1743 case '[': ParseArray <parseFlags>(is, handler); break;
1745 ParseNumber<parseFlags>(is, handler);
1751 // Iterative Parsing
1754 enum IterativeParsingState {
1755 IterativeParsingFinishState = 0, // sink states at top
1756 IterativeParsingErrorState, // sink states at top
1757 IterativeParsingStartState,
1760 IterativeParsingObjectInitialState,
1761 IterativeParsingMemberKeyState,
1762 IterativeParsingMemberValueState,
1763 IterativeParsingObjectFinishState,
1766 IterativeParsingArrayInitialState,
1767 IterativeParsingElementState,
1768 IterativeParsingArrayFinishState,
1770 // Single value state
1771 IterativeParsingValueState,
1773 // Delimiter states (at bottom)
1774 IterativeParsingElementDelimiterState,
1775 IterativeParsingMemberDelimiterState,
1776 IterativeParsingKeyValueDelimiterState,
1778 cIterativeParsingStateCount
1783 LeftBracketToken = 0,
1786 LeftCurlyBracketToken,
1787 RightCurlyBracketToken,
1801 RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) const {
1803 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
1804 #define N NumberToken
1805 #define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1806 // Maps from ASCII to Token
1807 static const unsigned char tokenMap[256] = {
1810 N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F
1811 N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F
1813 N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F
1814 N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F
1815 N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F
1816 N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF
1822 if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
1823 return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);
1828 RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) const {
1829 // current state x one lookahead token -> new state
1830 static const char G[cIterativeParsingStateCount][kTokenCount] = {
1831 // Finish(sink state)
1833 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1834 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1835 IterativeParsingErrorState
1837 // Error(sink state)
1839 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1840 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1841 IterativeParsingErrorState
1845 IterativeParsingArrayInitialState, // Left bracket
1846 IterativeParsingErrorState, // Right bracket
1847 IterativeParsingObjectInitialState, // Left curly bracket
1848 IterativeParsingErrorState, // Right curly bracket
1849 IterativeParsingErrorState, // Comma
1850 IterativeParsingErrorState, // Colon
1851 IterativeParsingValueState, // String
1852 IterativeParsingValueState, // False
1853 IterativeParsingValueState, // True
1854 IterativeParsingValueState, // Null
1855 IterativeParsingValueState // Number
1859 IterativeParsingErrorState, // Left bracket
1860 IterativeParsingErrorState, // Right bracket
1861 IterativeParsingErrorState, // Left curly bracket
1862 IterativeParsingObjectFinishState, // Right curly bracket
1863 IterativeParsingErrorState, // Comma
1864 IterativeParsingErrorState, // Colon
1865 IterativeParsingMemberKeyState, // String
1866 IterativeParsingErrorState, // False
1867 IterativeParsingErrorState, // True
1868 IterativeParsingErrorState, // Null
1869 IterativeParsingErrorState // Number
1873 IterativeParsingErrorState, // Left bracket
1874 IterativeParsingErrorState, // Right bracket
1875 IterativeParsingErrorState, // Left curly bracket
1876 IterativeParsingErrorState, // Right curly bracket
1877 IterativeParsingErrorState, // Comma
1878 IterativeParsingKeyValueDelimiterState, // Colon
1879 IterativeParsingErrorState, // String
1880 IterativeParsingErrorState, // False
1881 IterativeParsingErrorState, // True
1882 IterativeParsingErrorState, // Null
1883 IterativeParsingErrorState // Number
1887 IterativeParsingErrorState, // Left bracket
1888 IterativeParsingErrorState, // Right bracket
1889 IterativeParsingErrorState, // Left curly bracket
1890 IterativeParsingObjectFinishState, // Right curly bracket
1891 IterativeParsingMemberDelimiterState, // Comma
1892 IterativeParsingErrorState, // Colon
1893 IterativeParsingErrorState, // String
1894 IterativeParsingErrorState, // False
1895 IterativeParsingErrorState, // True
1896 IterativeParsingErrorState, // Null
1897 IterativeParsingErrorState // Number
1899 // ObjectFinish(sink state)
1901 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1902 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1903 IterativeParsingErrorState
1907 IterativeParsingArrayInitialState, // Left bracket(push Element state)
1908 IterativeParsingArrayFinishState, // Right bracket
1909 IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1910 IterativeParsingErrorState, // Right curly bracket
1911 IterativeParsingErrorState, // Comma
1912 IterativeParsingErrorState, // Colon
1913 IterativeParsingElementState, // String
1914 IterativeParsingElementState, // False
1915 IterativeParsingElementState, // True
1916 IterativeParsingElementState, // Null
1917 IterativeParsingElementState // Number
1921 IterativeParsingErrorState, // Left bracket
1922 IterativeParsingArrayFinishState, // Right bracket
1923 IterativeParsingErrorState, // Left curly bracket
1924 IterativeParsingErrorState, // Right curly bracket
1925 IterativeParsingElementDelimiterState, // Comma
1926 IterativeParsingErrorState, // Colon
1927 IterativeParsingErrorState, // String
1928 IterativeParsingErrorState, // False
1929 IterativeParsingErrorState, // True
1930 IterativeParsingErrorState, // Null
1931 IterativeParsingErrorState // Number
1933 // ArrayFinish(sink state)
1935 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1936 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1937 IterativeParsingErrorState
1939 // Single Value (sink state)
1941 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1942 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1943 IterativeParsingErrorState
1947 IterativeParsingArrayInitialState, // Left bracket(push Element state)
1948 IterativeParsingArrayFinishState, // Right bracket
1949 IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1950 IterativeParsingErrorState, // Right curly bracket
1951 IterativeParsingErrorState, // Comma
1952 IterativeParsingErrorState, // Colon
1953 IterativeParsingElementState, // String
1954 IterativeParsingElementState, // False
1955 IterativeParsingElementState, // True
1956 IterativeParsingElementState, // Null
1957 IterativeParsingElementState // Number
1961 IterativeParsingErrorState, // Left bracket
1962 IterativeParsingErrorState, // Right bracket
1963 IterativeParsingErrorState, // Left curly bracket
1964 IterativeParsingObjectFinishState, // Right curly bracket
1965 IterativeParsingErrorState, // Comma
1966 IterativeParsingErrorState, // Colon
1967 IterativeParsingMemberKeyState, // String
1968 IterativeParsingErrorState, // False
1969 IterativeParsingErrorState, // True
1970 IterativeParsingErrorState, // Null
1971 IterativeParsingErrorState // Number
1973 // KeyValueDelimiter
1975 IterativeParsingArrayInitialState, // Left bracket(push MemberValue state)
1976 IterativeParsingErrorState, // Right bracket
1977 IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state)
1978 IterativeParsingErrorState, // Right curly bracket
1979 IterativeParsingErrorState, // Comma
1980 IterativeParsingErrorState, // Colon
1981 IterativeParsingMemberValueState, // String
1982 IterativeParsingMemberValueState, // False
1983 IterativeParsingMemberValueState, // True
1984 IterativeParsingMemberValueState, // Null
1985 IterativeParsingMemberValueState // Number
1989 return static_cast<IterativeParsingState>(G[state][token]);
1992 // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
1993 // May return a new state on state pop.
1994 template <unsigned parseFlags, typename InputStream, typename Handler>
1995 RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
1999 case IterativeParsingErrorState:
2002 case IterativeParsingObjectInitialState:
2003 case IterativeParsingArrayInitialState:
2005 // Push the state(Element or MemeberValue) if we are nested in another array or value of member.
2006 // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
2007 IterativeParsingState n = src;
2008 if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
2009 n = IterativeParsingElementState;
2010 else if (src == IterativeParsingKeyValueDelimiterState)
2011 n = IterativeParsingMemberValueState;
2012 // Push current state.
2013 *stack_.template Push<SizeType>(1) = n;
2014 // Initialize and push the member/element count.
2015 *stack_.template Push<SizeType>(1) = 0;
2017 bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
2018 // On handler short circuits the parsing.
2020 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
2021 return IterativeParsingErrorState;
2029 case IterativeParsingMemberKeyState:
2030 ParseString<parseFlags>(is, handler, true);
2031 if (HasParseError())
2032 return IterativeParsingErrorState;
2036 case IterativeParsingKeyValueDelimiterState:
2037 RAPIDJSON_ASSERT(token == ColonToken);
2041 case IterativeParsingMemberValueState:
2042 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
2043 ParseValue<parseFlags>(is, handler);
2044 if (HasParseError()) {
2045 return IterativeParsingErrorState;
2049 case IterativeParsingElementState:
2050 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
2051 ParseValue<parseFlags>(is, handler);
2052 if (HasParseError()) {
2053 return IterativeParsingErrorState;
2057 case IterativeParsingMemberDelimiterState:
2058 case IterativeParsingElementDelimiterState:
2060 // Update member/element count.
2061 *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
2064 case IterativeParsingObjectFinishState:
2066 // Transit from delimiter is only allowed when trailing commas are enabled
2067 if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {
2068 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell());
2069 return IterativeParsingErrorState;
2071 // Get member count.
2072 SizeType c = *stack_.template Pop<SizeType>(1);
2073 // If the object is not empty, count the last member.
2074 if (src == IterativeParsingMemberValueState)
2076 // Restore the state.
2077 IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
2078 // Transit to Finish state if this is the topmost scope.
2079 if (n == IterativeParsingStartState)
2080 n = IterativeParsingFinishState;
2082 bool hr = handler.EndObject(c);
2083 // On handler short circuits the parsing.
2085 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
2086 return IterativeParsingErrorState;
2094 case IterativeParsingArrayFinishState:
2096 // Transit from delimiter is only allowed when trailing commas are enabled
2097 if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {
2098 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell());
2099 return IterativeParsingErrorState;
2101 // Get element count.
2102 SizeType c = *stack_.template Pop<SizeType>(1);
2103 // If the array is not empty, count the last element.
2104 if (src == IterativeParsingElementState)
2106 // Restore the state.
2107 IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
2108 // Transit to Finish state if this is the topmost scope.
2109 if (n == IterativeParsingStartState)
2110 n = IterativeParsingFinishState;
2112 bool hr = handler.EndArray(c);
2113 // On handler short circuits the parsing.
2115 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
2116 return IterativeParsingErrorState;
2125 // This branch is for IterativeParsingValueState actually.
2126 // Use `default:` rather than
2127 // `case IterativeParsingValueState:` is for code coverage.
2129 // The IterativeParsingStartState is not enumerated in this switch-case.
2130 // It is impossible for that case. And it can be caught by following assertion.
2132 // The IterativeParsingFinishState is not enumerated in this switch-case either.
2133 // It is a "derivative" state which cannot triggered from Predict() directly.
2134 // Therefore it cannot happen here. And it can be caught by following assertion.
2135 RAPIDJSON_ASSERT(dst == IterativeParsingValueState);
2137 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
2138 ParseValue<parseFlags>(is, handler);
2139 if (HasParseError()) {
2140 return IterativeParsingErrorState;
2142 return IterativeParsingFinishState;
2146 template <typename InputStream>
2147 void HandleError(IterativeParsingState src, InputStream& is) {
2148 if (HasParseError()) {
2149 // Error flag has been set.
2154 case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
2155 case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
2156 case IterativeParsingObjectInitialState:
2157 case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
2158 case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
2159 case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
2160 case IterativeParsingKeyValueDelimiterState:
2161 case IterativeParsingArrayInitialState:
2162 case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return;
2163 default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
2167 RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const {
2168 return s >= IterativeParsingElementDelimiterState;
2171 RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const {
2172 return s <= IterativeParsingErrorState;
2175 template <unsigned parseFlags, typename InputStream, typename Handler>
2176 ParseResult IterativeParse(InputStream& is, Handler& handler) {
2177 parseResult_.Clear();
2178 ClearStackOnExit scope(*this);
2179 IterativeParsingState state = IterativeParsingStartState;
2181 SkipWhitespaceAndComments<parseFlags>(is);
2182 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
2183 while (is.Peek() != '\0') {
2184 Token t = Tokenize(is.Peek());
2185 IterativeParsingState n = Predict(state, t);
2186 IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
2188 if (d == IterativeParsingErrorState) {
2189 HandleError(state, is);
2195 // Do not further consume streams if a root JSON has been parsed.
2196 if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
2199 SkipWhitespaceAndComments<parseFlags>(is);
2200 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
2203 // Handle the end of file.
2204 if (state != IterativeParsingFinishState)
2205 HandleError(state, is);
2207 return parseResult_;
2210 static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string.
2211 internal::Stack<StackAllocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing.
2212 ParseResult parseResult_;
2213 IterativeParsingState state_;
2214 }; // class GenericReader
2216 //! Reader with UTF8 encoding and default allocator.
2217 typedef GenericReader<UTF8<>, UTF8<> > Reader;
2219 RAPIDJSON_NAMESPACE_END
2221 #if defined(__clang__) || defined(_MSC_VER)
2230 #endif // RAPIDJSON_READER_H_