1e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Tencent is pleased to support the open source community by making RapidJSON available.
2e462795ff5d4c7359f9e8637c10544bb2de70107tturney//
3e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4e462795ff5d4c7359f9e8637c10544bb2de70107tturney//
5e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Licensed under the MIT License (the "License"); you may not use this file except
6e462795ff5d4c7359f9e8637c10544bb2de70107tturney// in compliance with the License. You may obtain a copy of the License at
7e462795ff5d4c7359f9e8637c10544bb2de70107tturney//
8e462795ff5d4c7359f9e8637c10544bb2de70107tturney// http://opensource.org/licenses/MIT
9e462795ff5d4c7359f9e8637c10544bb2de70107tturney//
10e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Unless required by applicable law or agreed to in writing, software distributed
11e462795ff5d4c7359f9e8637c10544bb2de70107tturney// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12e462795ff5d4c7359f9e8637c10544bb2de70107tturney// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13e462795ff5d4c7359f9e8637c10544bb2de70107tturney// specific language governing permissions and limitations under the License.
14e462795ff5d4c7359f9e8637c10544bb2de70107tturney
15e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifndef RAPIDJSON_READER_H_
16e462795ff5d4c7359f9e8637c10544bb2de70107tturney#define RAPIDJSON_READER_H_
17e462795ff5d4c7359f9e8637c10544bb2de70107tturney
18e462795ff5d4c7359f9e8637c10544bb2de70107tturney/*! \file reader.h */
19e462795ff5d4c7359f9e8637c10544bb2de70107tturney
20e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include "rapidjson.h"
21e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include "encodings.h"
22e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include "internal/meta.h"
23e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include "internal/stack.h"
24e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include "internal/strtod.h"
25e462795ff5d4c7359f9e8637c10544bb2de70107tturney
26e462795ff5d4c7359f9e8637c10544bb2de70107tturney#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
27e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include <intrin.h>
28e462795ff5d4c7359f9e8637c10544bb2de70107tturney#pragma intrinsic(_BitScanForward)
29e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
30e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifdef RAPIDJSON_SSE42
31e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include <nmmintrin.h>
32e462795ff5d4c7359f9e8637c10544bb2de70107tturney#elif defined(RAPIDJSON_SSE2)
33e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include <emmintrin.h>
34e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
35e462795ff5d4c7359f9e8637c10544bb2de70107tturney
36e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifdef _MSC_VER
37e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_DIAG_PUSH
38e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_DIAG_OFF(4127)  // conditional expression is constant
39e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_DIAG_OFF(4702)  // unreachable code
40e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
41e462795ff5d4c7359f9e8637c10544bb2de70107tturney
42e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifdef __GNUC__
43e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_DIAG_PUSH
44e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_DIAG_OFF(effc++)
45e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
46e462795ff5d4c7359f9e8637c10544bb2de70107tturney
47e462795ff5d4c7359f9e8637c10544bb2de70107tturney//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
48e462795ff5d4c7359f9e8637c10544bb2de70107tturney#define RAPIDJSON_NOTHING /* deliberately empty */
49e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
50e462795ff5d4c7359f9e8637c10544bb2de70107tturney#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
51e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_MULTILINEMACRO_BEGIN \
52e462795ff5d4c7359f9e8637c10544bb2de70107tturney    if (HasParseError()) { return value; } \
53e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_MULTILINEMACRO_END
54e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
55e462795ff5d4c7359f9e8637c10544bb2de70107tturney#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
56e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
57e462795ff5d4c7359f9e8637c10544bb2de70107tturney//!@endcond
58e462795ff5d4c7359f9e8637c10544bb2de70107tturney
59e462795ff5d4c7359f9e8637c10544bb2de70107tturney/*! \def RAPIDJSON_PARSE_ERROR_NORETURN
60e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \ingroup RAPIDJSON_ERRORS
61e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \brief Macro to indicate a parse error.
62e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
63e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \param offset  position of the error in JSON input (\c size_t)
64e462795ff5d4c7359f9e8637c10544bb2de70107tturney
65e462795ff5d4c7359f9e8637c10544bb2de70107tturney    This macros can be used as a customization point for the internal
66e462795ff5d4c7359f9e8637c10544bb2de70107tturney    error handling mechanism of RapidJSON.
67e462795ff5d4c7359f9e8637c10544bb2de70107tturney
68e462795ff5d4c7359f9e8637c10544bb2de70107tturney    A common usage model is to throw an exception instead of requiring the
69e462795ff5d4c7359f9e8637c10544bb2de70107tturney    caller to explicitly check the \ref rapidjson::GenericReader::Parse's
70e462795ff5d4c7359f9e8637c10544bb2de70107tturney    return value:
71e462795ff5d4c7359f9e8637c10544bb2de70107tturney
72e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \code
73e462795ff5d4c7359f9e8637c10544bb2de70107tturney    #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \
74e462795ff5d4c7359f9e8637c10544bb2de70107tturney       throw ParseException(parseErrorCode, #parseErrorCode, offset)
75e462795ff5d4c7359f9e8637c10544bb2de70107tturney
76e462795ff5d4c7359f9e8637c10544bb2de70107tturney    #include <stdexcept>               // std::runtime_error
77e462795ff5d4c7359f9e8637c10544bb2de70107tturney    #include "rapidjson/error/error.h" // rapidjson::ParseResult
78e462795ff5d4c7359f9e8637c10544bb2de70107tturney
79e462795ff5d4c7359f9e8637c10544bb2de70107tturney    struct ParseException : std::runtime_error, rapidjson::ParseResult {
80e462795ff5d4c7359f9e8637c10544bb2de70107tturney      ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset)
81e462795ff5d4c7359f9e8637c10544bb2de70107tturney        : std::runtime_error(msg), ParseResult(code, offset) {}
82e462795ff5d4c7359f9e8637c10544bb2de70107tturney    };
83e462795ff5d4c7359f9e8637c10544bb2de70107tturney
84e462795ff5d4c7359f9e8637c10544bb2de70107tturney    #include "rapidjson/reader.h"
85e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \endcode
86e462795ff5d4c7359f9e8637c10544bb2de70107tturney
87e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse
88e462795ff5d4c7359f9e8637c10544bb2de70107tturney */
89e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifndef RAPIDJSON_PARSE_ERROR_NORETURN
90e462795ff5d4c7359f9e8637c10544bb2de70107tturney#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
91e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_MULTILINEMACRO_BEGIN \
92e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
93e462795ff5d4c7359f9e8637c10544bb2de70107tturney    SetParseError(parseErrorCode, offset); \
94e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_MULTILINEMACRO_END
95e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
96e462795ff5d4c7359f9e8637c10544bb2de70107tturney
97e462795ff5d4c7359f9e8637c10544bb2de70107tturney/*! \def RAPIDJSON_PARSE_ERROR
98e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \ingroup RAPIDJSON_ERRORS
99e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \brief (Internal) macro to indicate and handle a parse error.
100e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
101e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \param offset  position of the error in JSON input (\c size_t)
102e462795ff5d4c7359f9e8637c10544bb2de70107tturney
103e462795ff5d4c7359f9e8637c10544bb2de70107tturney    Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing.
104e462795ff5d4c7359f9e8637c10544bb2de70107tturney
105e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \see RAPIDJSON_PARSE_ERROR_NORETURN
106e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \hideinitializer
107e462795ff5d4c7359f9e8637c10544bb2de70107tturney */
108e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifndef RAPIDJSON_PARSE_ERROR
109e462795ff5d4c7359f9e8637c10544bb2de70107tturney#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \
110e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_MULTILINEMACRO_BEGIN \
111e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
112e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
113e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_MULTILINEMACRO_END
114e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
115e462795ff5d4c7359f9e8637c10544bb2de70107tturney
116e462795ff5d4c7359f9e8637c10544bb2de70107tturney#include "error/error.h" // ParseErrorCode, ParseResult
117e462795ff5d4c7359f9e8637c10544bb2de70107tturney
118e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_NAMESPACE_BEGIN
119e462795ff5d4c7359f9e8637c10544bb2de70107tturney
120e462795ff5d4c7359f9e8637c10544bb2de70107tturney///////////////////////////////////////////////////////////////////////////////
121e462795ff5d4c7359f9e8637c10544bb2de70107tturney// ParseFlag
122e462795ff5d4c7359f9e8637c10544bb2de70107tturney
123e462795ff5d4c7359f9e8637c10544bb2de70107tturney/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS
124e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \ingroup RAPIDJSON_CONFIG
125e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \brief User-defined kParseDefaultFlags definition.
126e462795ff5d4c7359f9e8637c10544bb2de70107tturney
127e462795ff5d4c7359f9e8637c10544bb2de70107tturney    User can define this as any \c ParseFlag combinations.
128e462795ff5d4c7359f9e8637c10544bb2de70107tturney*/
129e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS
130e462795ff5d4c7359f9e8637c10544bb2de70107tturney#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags
131e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
132e462795ff5d4c7359f9e8637c10544bb2de70107tturney
133e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Combination of parseFlags
134e462795ff5d4c7359f9e8637c10544bb2de70107tturney/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream
135e462795ff5d4c7359f9e8637c10544bb2de70107tturney */
136e462795ff5d4c7359f9e8637c10544bb2de70107tturneyenum ParseFlag {
137e462795ff5d4c7359f9e8637c10544bb2de70107tturney    kParseNoFlags = 0,              //!< No flags are set.
138e462795ff5d4c7359f9e8637c10544bb2de70107tturney    kParseInsituFlag = 1,           //!< In-situ(destructive) parsing.
139e462795ff5d4c7359f9e8637c10544bb2de70107tturney    kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings.
140e462795ff5d4c7359f9e8637c10544bb2de70107tturney    kParseIterativeFlag = 4,        //!< Iterative(constant complexity in terms of function call stack size) parsing.
141e462795ff5d4c7359f9e8637c10544bb2de70107tturney    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.
142e462795ff5d4c7359f9e8637c10544bb2de70107tturney    kParseFullPrecisionFlag = 16,   //!< Parse number in full precision (but slower).
143e462795ff5d4c7359f9e8637c10544bb2de70107tturney    kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS  //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
144e462795ff5d4c7359f9e8637c10544bb2de70107tturney};
145e462795ff5d4c7359f9e8637c10544bb2de70107tturney
146e462795ff5d4c7359f9e8637c10544bb2de70107tturney///////////////////////////////////////////////////////////////////////////////
147e462795ff5d4c7359f9e8637c10544bb2de70107tturney// Handler
148e462795ff5d4c7359f9e8637c10544bb2de70107tturney
149e462795ff5d4c7359f9e8637c10544bb2de70107tturney/*! \class rapidjson::Handler
150e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \brief Concept for receiving events from GenericReader upon parsing.
151e462795ff5d4c7359f9e8637c10544bb2de70107tturney    The functions return true if no error occurs. If they return false,
152e462795ff5d4c7359f9e8637c10544bb2de70107tturney    the event publisher should terminate the process.
153e462795ff5d4c7359f9e8637c10544bb2de70107tturney\code
154e462795ff5d4c7359f9e8637c10544bb2de70107tturneyconcept Handler {
155e462795ff5d4c7359f9e8637c10544bb2de70107tturney    typename Ch;
156e462795ff5d4c7359f9e8637c10544bb2de70107tturney
157e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Null();
158e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Bool(bool b);
159e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Int(int i);
160e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Uint(unsigned i);
161e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Int64(int64_t i);
162e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Uint64(uint64_t i);
163e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Double(double d);
164e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool String(const Ch* str, SizeType length, bool copy);
165e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool StartObject();
166e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Key(const Ch* str, SizeType length, bool copy);
167e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool EndObject(SizeType memberCount);
168e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool StartArray();
169e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool EndArray(SizeType elementCount);
170e462795ff5d4c7359f9e8637c10544bb2de70107tturney};
171e462795ff5d4c7359f9e8637c10544bb2de70107tturney\endcode
172e462795ff5d4c7359f9e8637c10544bb2de70107tturney*/
173e462795ff5d4c7359f9e8637c10544bb2de70107tturney///////////////////////////////////////////////////////////////////////////////
174e462795ff5d4c7359f9e8637c10544bb2de70107tturney// BaseReaderHandler
175e462795ff5d4c7359f9e8637c10544bb2de70107tturney
176e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Default implementation of Handler.
177e462795ff5d4c7359f9e8637c10544bb2de70107tturney/*! This can be used as base class of any reader handler.
178e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \note implements Handler concept
179e462795ff5d4c7359f9e8637c10544bb2de70107tturney*/
180e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate<typename Encoding = UTF8<>, typename Derived = void>
181e462795ff5d4c7359f9e8637c10544bb2de70107tturneystruct BaseReaderHandler {
182e462795ff5d4c7359f9e8637c10544bb2de70107tturney    typedef typename Encoding::Ch Ch;
183e462795ff5d4c7359f9e8637c10544bb2de70107tturney
184e462795ff5d4c7359f9e8637c10544bb2de70107tturney    typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override;
185e462795ff5d4c7359f9e8637c10544bb2de70107tturney
186e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Default() { return true; }
187e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Null() { return static_cast<Override&>(*this).Default(); }
188e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Bool(bool) { return static_cast<Override&>(*this).Default(); }
189e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Int(int) { return static_cast<Override&>(*this).Default(); }
190e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); }
191e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); }
192e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); }
193e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Double(double) { return static_cast<Override&>(*this).Default(); }
194e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); }
195e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool StartObject() { return static_cast<Override&>(*this).Default(); }
196e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
197e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }
198e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool StartArray() { return static_cast<Override&>(*this).Default(); }
199e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }
200e462795ff5d4c7359f9e8637c10544bb2de70107tturney};
201e462795ff5d4c7359f9e8637c10544bb2de70107tturney
202e462795ff5d4c7359f9e8637c10544bb2de70107tturney///////////////////////////////////////////////////////////////////////////////
203e462795ff5d4c7359f9e8637c10544bb2de70107tturney// StreamLocalCopy
204e462795ff5d4c7359f9e8637c10544bb2de70107tturney
205e462795ff5d4c7359f9e8637c10544bb2de70107tturneynamespace internal {
206e462795ff5d4c7359f9e8637c10544bb2de70107tturney
207e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate<typename Stream, int = StreamTraits<Stream>::copyOptimization>
208e462795ff5d4c7359f9e8637c10544bb2de70107tturneyclass StreamLocalCopy;
209e462795ff5d4c7359f9e8637c10544bb2de70107tturney
210e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Do copy optimization.
211e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate<typename Stream>
212e462795ff5d4c7359f9e8637c10544bb2de70107tturneyclass StreamLocalCopy<Stream, 1> {
213e462795ff5d4c7359f9e8637c10544bb2de70107tturneypublic:
214fb108ff03df1052469bbfa169755bcd97be9cb95Chih-Hung Hsieh    explicit StreamLocalCopy(Stream& original) : s(original), original_(original) {}
215e462795ff5d4c7359f9e8637c10544bb2de70107tturney    ~StreamLocalCopy() { original_ = s; }
216e462795ff5d4c7359f9e8637c10544bb2de70107tturney
217e462795ff5d4c7359f9e8637c10544bb2de70107tturney    Stream s;
218e462795ff5d4c7359f9e8637c10544bb2de70107tturney
219e462795ff5d4c7359f9e8637c10544bb2de70107tturneyprivate:
220e462795ff5d4c7359f9e8637c10544bb2de70107tturney    StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
221e462795ff5d4c7359f9e8637c10544bb2de70107tturney
222e462795ff5d4c7359f9e8637c10544bb2de70107tturney    Stream& original_;
223e462795ff5d4c7359f9e8637c10544bb2de70107tturney};
224e462795ff5d4c7359f9e8637c10544bb2de70107tturney
225e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Keep reference.
226e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate<typename Stream>
227e462795ff5d4c7359f9e8637c10544bb2de70107tturneyclass StreamLocalCopy<Stream, 0> {
228e462795ff5d4c7359f9e8637c10544bb2de70107tturneypublic:
229fb108ff03df1052469bbfa169755bcd97be9cb95Chih-Hung Hsieh    explicit StreamLocalCopy(Stream& original) : s(original) {}
230e462795ff5d4c7359f9e8637c10544bb2de70107tturney
231e462795ff5d4c7359f9e8637c10544bb2de70107tturney    Stream& s;
232e462795ff5d4c7359f9e8637c10544bb2de70107tturney
233e462795ff5d4c7359f9e8637c10544bb2de70107tturneyprivate:
234e462795ff5d4c7359f9e8637c10544bb2de70107tturney    StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
235e462795ff5d4c7359f9e8637c10544bb2de70107tturney};
236e462795ff5d4c7359f9e8637c10544bb2de70107tturney
237e462795ff5d4c7359f9e8637c10544bb2de70107tturney} // namespace internal
238e462795ff5d4c7359f9e8637c10544bb2de70107tturney
239e462795ff5d4c7359f9e8637c10544bb2de70107tturney///////////////////////////////////////////////////////////////////////////////
240e462795ff5d4c7359f9e8637c10544bb2de70107tturney// SkipWhitespace
241e462795ff5d4c7359f9e8637c10544bb2de70107tturney
242e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Skip the JSON white spaces in a stream.
243e462795ff5d4c7359f9e8637c10544bb2de70107tturney/*! \param is A input stream for skipping white spaces.
244e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \note This function has SSE2/SSE4.2 specialization.
245e462795ff5d4c7359f9e8637c10544bb2de70107tturney*/
246e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate<typename InputStream>
247e462795ff5d4c7359f9e8637c10544bb2de70107tturneyvoid SkipWhitespace(InputStream& is) {
248e462795ff5d4c7359f9e8637c10544bb2de70107tturney    internal::StreamLocalCopy<InputStream> copy(is);
249e462795ff5d4c7359f9e8637c10544bb2de70107tturney    InputStream& s(copy.s);
250e462795ff5d4c7359f9e8637c10544bb2de70107tturney
251e462795ff5d4c7359f9e8637c10544bb2de70107tturney    while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t')
252e462795ff5d4c7359f9e8637c10544bb2de70107tturney        s.Take();
253e462795ff5d4c7359f9e8637c10544bb2de70107tturney}
254e462795ff5d4c7359f9e8637c10544bb2de70107tturney
255e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifdef RAPIDJSON_SSE42
256e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.
257e462795ff5d4c7359f9e8637c10544bb2de70107tturneyinline const char *SkipWhitespace_SIMD(const char* p) {
258e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Fast return for single non-whitespace
259e462795ff5d4c7359f9e8637c10544bb2de70107tturney    if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
260e462795ff5d4c7359f9e8637c10544bb2de70107tturney        ++p;
261e462795ff5d4c7359f9e8637c10544bb2de70107tturney    else
262e462795ff5d4c7359f9e8637c10544bb2de70107tturney        return p;
263e462795ff5d4c7359f9e8637c10544bb2de70107tturney
264e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // 16-byte align to the next boundary
265e462795ff5d4c7359f9e8637c10544bb2de70107tturney    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & ~15);
266e462795ff5d4c7359f9e8637c10544bb2de70107tturney    while (p != nextAligned)
267e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
268e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ++p;
269e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else
270e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return p;
271e462795ff5d4c7359f9e8637c10544bb2de70107tturney
272e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // The rest of string using SIMD
273e462795ff5d4c7359f9e8637c10544bb2de70107tturney    static const char whitespace[16] = " \n\r\t";
274e462795ff5d4c7359f9e8637c10544bb2de70107tturney    const __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]);
275e462795ff5d4c7359f9e8637c10544bb2de70107tturney
276e462795ff5d4c7359f9e8637c10544bb2de70107tturney    for (;; p += 16) {
277e462795ff5d4c7359f9e8637c10544bb2de70107tturney        const __m128i s = _mm_load_si128((const __m128i *)p);
278e462795ff5d4c7359f9e8637c10544bb2de70107tturney        const unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
279e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (r != 0) {   // some of characters is non-whitespace
280e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifdef _MSC_VER         // Find the index of first non-whitespace
281e462795ff5d4c7359f9e8637c10544bb2de70107tturney            unsigned long offset;
282e462795ff5d4c7359f9e8637c10544bb2de70107tturney            _BitScanForward(&offset, r);
283e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return p + offset;
284e462795ff5d4c7359f9e8637c10544bb2de70107tturney#else
285e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return p + __builtin_ffs(r) - 1;
286e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
287e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
288e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
289e462795ff5d4c7359f9e8637c10544bb2de70107tturney}
290e462795ff5d4c7359f9e8637c10544bb2de70107tturney
291e462795ff5d4c7359f9e8637c10544bb2de70107tturney#elif defined(RAPIDJSON_SSE2)
292e462795ff5d4c7359f9e8637c10544bb2de70107tturney
293e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
294e462795ff5d4c7359f9e8637c10544bb2de70107tturneyinline const char *SkipWhitespace_SIMD(const char* p) {
295e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Fast return for single non-whitespace
296e462795ff5d4c7359f9e8637c10544bb2de70107tturney    if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
297e462795ff5d4c7359f9e8637c10544bb2de70107tturney        ++p;
298e462795ff5d4c7359f9e8637c10544bb2de70107tturney    else
299e462795ff5d4c7359f9e8637c10544bb2de70107tturney        return p;
300e462795ff5d4c7359f9e8637c10544bb2de70107tturney
301e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // 16-byte align to the next boundary
302e462795ff5d4c7359f9e8637c10544bb2de70107tturney    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & ~15);
303e462795ff5d4c7359f9e8637c10544bb2de70107tturney    while (p != nextAligned)
304e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
305e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ++p;
306e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else
307e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return p;
308e462795ff5d4c7359f9e8637c10544bb2de70107tturney
309e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // The rest of string
310e462795ff5d4c7359f9e8637c10544bb2de70107tturney    static const char whitespaces[4][17] = {
311e462795ff5d4c7359f9e8637c10544bb2de70107tturney        "                ",
312e462795ff5d4c7359f9e8637c10544bb2de70107tturney        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
313e462795ff5d4c7359f9e8637c10544bb2de70107tturney        "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",
314e462795ff5d4c7359f9e8637c10544bb2de70107tturney        "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};
315e462795ff5d4c7359f9e8637c10544bb2de70107tturney
316e462795ff5d4c7359f9e8637c10544bb2de70107tturney        const __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]);
317e462795ff5d4c7359f9e8637c10544bb2de70107tturney        const __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]);
318e462795ff5d4c7359f9e8637c10544bb2de70107tturney        const __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]);
319e462795ff5d4c7359f9e8637c10544bb2de70107tturney        const __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]);
320e462795ff5d4c7359f9e8637c10544bb2de70107tturney
321e462795ff5d4c7359f9e8637c10544bb2de70107tturney    for (;; p += 16) {
322e462795ff5d4c7359f9e8637c10544bb2de70107tturney        const __m128i s = _mm_load_si128((const __m128i *)p);
323e462795ff5d4c7359f9e8637c10544bb2de70107tturney        __m128i x = _mm_cmpeq_epi8(s, w0);
324e462795ff5d4c7359f9e8637c10544bb2de70107tturney        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
325e462795ff5d4c7359f9e8637c10544bb2de70107tturney        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
326e462795ff5d4c7359f9e8637c10544bb2de70107tturney        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
327e462795ff5d4c7359f9e8637c10544bb2de70107tturney        unsigned short r = (unsigned short)~_mm_movemask_epi8(x);
328e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (r != 0) {   // some of characters may be non-whitespace
329e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifdef _MSC_VER         // Find the index of first non-whitespace
330e462795ff5d4c7359f9e8637c10544bb2de70107tturney            unsigned long offset;
331e462795ff5d4c7359f9e8637c10544bb2de70107tturney            _BitScanForward(&offset, r);
332e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return p + offset;
333e462795ff5d4c7359f9e8637c10544bb2de70107tturney#else
334e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return p + __builtin_ffs(r) - 1;
335e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
336e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
337e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
338e462795ff5d4c7359f9e8637c10544bb2de70107tturney}
339e462795ff5d4c7359f9e8637c10544bb2de70107tturney
340e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif // RAPIDJSON_SSE2
341e462795ff5d4c7359f9e8637c10544bb2de70107tturney
342e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifdef RAPIDJSON_SIMD
343e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Template function specialization for InsituStringStream
344e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate<> inline void SkipWhitespace(InsituStringStream& is) {
345e462795ff5d4c7359f9e8637c10544bb2de70107tturney    is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
346e462795ff5d4c7359f9e8637c10544bb2de70107tturney}
347e462795ff5d4c7359f9e8637c10544bb2de70107tturney
348e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Template function specialization for StringStream
349e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate<> inline void SkipWhitespace(StringStream& is) {
350e462795ff5d4c7359f9e8637c10544bb2de70107tturney    is.src_ = SkipWhitespace_SIMD(is.src_);
351e462795ff5d4c7359f9e8637c10544bb2de70107tturney}
352e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif // RAPIDJSON_SIMD
353e462795ff5d4c7359f9e8637c10544bb2de70107tturney
354e462795ff5d4c7359f9e8637c10544bb2de70107tturney///////////////////////////////////////////////////////////////////////////////
355e462795ff5d4c7359f9e8637c10544bb2de70107tturney// GenericReader
356e462795ff5d4c7359f9e8637c10544bb2de70107tturney
357e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator.
358e462795ff5d4c7359f9e8637c10544bb2de70107tturney/*! GenericReader parses JSON text from a stream, and send events synchronously to an
359e462795ff5d4c7359f9e8637c10544bb2de70107tturney    object implementing Handler concept.
360e462795ff5d4c7359f9e8637c10544bb2de70107tturney
361e462795ff5d4c7359f9e8637c10544bb2de70107tturney    It needs to allocate a stack for storing a single decoded string during
362e462795ff5d4c7359f9e8637c10544bb2de70107tturney    non-destructive parsing.
363e462795ff5d4c7359f9e8637c10544bb2de70107tturney
364e462795ff5d4c7359f9e8637c10544bb2de70107tturney    For in-situ parsing, the decoded string is directly written to the source
365e462795ff5d4c7359f9e8637c10544bb2de70107tturney    text string, no temporary buffer is required.
366e462795ff5d4c7359f9e8637c10544bb2de70107tturney
367e462795ff5d4c7359f9e8637c10544bb2de70107tturney    A GenericReader object can be reused for parsing multiple JSON text.
368e462795ff5d4c7359f9e8637c10544bb2de70107tturney
369e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \tparam SourceEncoding Encoding of the input stream.
370e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \tparam TargetEncoding Encoding of the parse output.
371e462795ff5d4c7359f9e8637c10544bb2de70107tturney    \tparam StackAllocator Allocator type for stack.
372e462795ff5d4c7359f9e8637c10544bb2de70107tturney*/
373e462795ff5d4c7359f9e8637c10544bb2de70107tturneytemplate <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
374e462795ff5d4c7359f9e8637c10544bb2de70107tturneyclass GenericReader {
375e462795ff5d4c7359f9e8637c10544bb2de70107tturneypublic:
376e462795ff5d4c7359f9e8637c10544bb2de70107tturney    typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type
377e462795ff5d4c7359f9e8637c10544bb2de70107tturney
378e462795ff5d4c7359f9e8637c10544bb2de70107tturney    //! Constructor.
379e462795ff5d4c7359f9e8637c10544bb2de70107tturney    /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
380e462795ff5d4c7359f9e8637c10544bb2de70107tturney        \param stackCapacity stack capacity in bytes for storing a single decoded string.  (Only use for non-destructive parsing)
381e462795ff5d4c7359f9e8637c10544bb2de70107tturney    */
382fb108ff03df1052469bbfa169755bcd97be9cb95Chih-Hung Hsieh    explicit GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {}
383e462795ff5d4c7359f9e8637c10544bb2de70107tturney
384e462795ff5d4c7359f9e8637c10544bb2de70107tturney    //! Parse JSON text.
385e462795ff5d4c7359f9e8637c10544bb2de70107tturney    /*! \tparam parseFlags Combination of \ref ParseFlag.
386e462795ff5d4c7359f9e8637c10544bb2de70107tturney        \tparam InputStream Type of input stream, implementing Stream concept.
387e462795ff5d4c7359f9e8637c10544bb2de70107tturney        \tparam Handler Type of handler, implementing Handler concept.
388e462795ff5d4c7359f9e8637c10544bb2de70107tturney        \param is Input stream to be parsed.
389e462795ff5d4c7359f9e8637c10544bb2de70107tturney        \param handler The handler to receive events.
390e462795ff5d4c7359f9e8637c10544bb2de70107tturney        \return Whether the parsing is successful.
391e462795ff5d4c7359f9e8637c10544bb2de70107tturney    */
392e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template <unsigned parseFlags, typename InputStream, typename Handler>
393e462795ff5d4c7359f9e8637c10544bb2de70107tturney    ParseResult Parse(InputStream& is, Handler& handler) {
394e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (parseFlags & kParseIterativeFlag)
395e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return IterativeParse<parseFlags>(is, handler);
396e462795ff5d4c7359f9e8637c10544bb2de70107tturney
397e462795ff5d4c7359f9e8637c10544bb2de70107tturney        parseResult_.Clear();
398e462795ff5d4c7359f9e8637c10544bb2de70107tturney
399e462795ff5d4c7359f9e8637c10544bb2de70107tturney        ClearStackOnExit scope(*this);
400e462795ff5d4c7359f9e8637c10544bb2de70107tturney
401e462795ff5d4c7359f9e8637c10544bb2de70107tturney        SkipWhitespace(is);
402e462795ff5d4c7359f9e8637c10544bb2de70107tturney
403e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (is.Peek() == '\0') {
404e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
405e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
406e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
407e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else {
408e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ParseValue<parseFlags>(is, handler);
409e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
410e462795ff5d4c7359f9e8637c10544bb2de70107tturney
411e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!(parseFlags & kParseStopWhenDoneFlag)) {
412e462795ff5d4c7359f9e8637c10544bb2de70107tturney                SkipWhitespace(is);
413e462795ff5d4c7359f9e8637c10544bb2de70107tturney
414e462795ff5d4c7359f9e8637c10544bb2de70107tturney                if (is.Peek() != '\0') {
415e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
416e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
417e462795ff5d4c7359f9e8637c10544bb2de70107tturney                }
418e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
419e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
420e462795ff5d4c7359f9e8637c10544bb2de70107tturney
421e462795ff5d4c7359f9e8637c10544bb2de70107tturney        return parseResult_;
422e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
423e462795ff5d4c7359f9e8637c10544bb2de70107tturney
424e462795ff5d4c7359f9e8637c10544bb2de70107tturney    //! Parse JSON text (with \ref kParseDefaultFlags)
425e462795ff5d4c7359f9e8637c10544bb2de70107tturney    /*! \tparam InputStream Type of input stream, implementing Stream concept
426e462795ff5d4c7359f9e8637c10544bb2de70107tturney        \tparam Handler Type of handler, implementing Handler concept.
427e462795ff5d4c7359f9e8637c10544bb2de70107tturney        \param is Input stream to be parsed.
428e462795ff5d4c7359f9e8637c10544bb2de70107tturney        \param handler The handler to receive events.
429e462795ff5d4c7359f9e8637c10544bb2de70107tturney        \return Whether the parsing is successful.
430e462795ff5d4c7359f9e8637c10544bb2de70107tturney    */
431e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template <typename InputStream, typename Handler>
432e462795ff5d4c7359f9e8637c10544bb2de70107tturney    ParseResult Parse(InputStream& is, Handler& handler) {
433e462795ff5d4c7359f9e8637c10544bb2de70107tturney        return Parse<kParseDefaultFlags>(is, handler);
434e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
435e462795ff5d4c7359f9e8637c10544bb2de70107tturney
436e462795ff5d4c7359f9e8637c10544bb2de70107tturney    //! Whether a parse error has occured in the last parsing.
437e462795ff5d4c7359f9e8637c10544bb2de70107tturney    bool HasParseError() const { return parseResult_.IsError(); }
438e462795ff5d4c7359f9e8637c10544bb2de70107tturney
439e462795ff5d4c7359f9e8637c10544bb2de70107tturney    //! Get the \ref ParseErrorCode of last parsing.
440e462795ff5d4c7359f9e8637c10544bb2de70107tturney    ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }
441e462795ff5d4c7359f9e8637c10544bb2de70107tturney
442e462795ff5d4c7359f9e8637c10544bb2de70107tturney    //! Get the position of last parsing error in input, 0 otherwise.
443e462795ff5d4c7359f9e8637c10544bb2de70107tturney    size_t GetErrorOffset() const { return parseResult_.Offset(); }
444e462795ff5d4c7359f9e8637c10544bb2de70107tturney
445e462795ff5d4c7359f9e8637c10544bb2de70107tturneyprotected:
446e462795ff5d4c7359f9e8637c10544bb2de70107tturney    void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
447e462795ff5d4c7359f9e8637c10544bb2de70107tturney
448e462795ff5d4c7359f9e8637c10544bb2de70107tturneyprivate:
449e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Prohibit copy constructor & assignment operator.
450e462795ff5d4c7359f9e8637c10544bb2de70107tturney    GenericReader(const GenericReader&);
451e462795ff5d4c7359f9e8637c10544bb2de70107tturney    GenericReader& operator=(const GenericReader&);
452e462795ff5d4c7359f9e8637c10544bb2de70107tturney
453e462795ff5d4c7359f9e8637c10544bb2de70107tturney    void ClearStack() { stack_.Clear(); }
454e462795ff5d4c7359f9e8637c10544bb2de70107tturney
455e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // clear stack on any exit from ParseStream, e.g. due to exception
456e462795ff5d4c7359f9e8637c10544bb2de70107tturney    struct ClearStackOnExit {
457e462795ff5d4c7359f9e8637c10544bb2de70107tturney        explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
458e462795ff5d4c7359f9e8637c10544bb2de70107tturney        ~ClearStackOnExit() { r_.ClearStack(); }
459e462795ff5d4c7359f9e8637c10544bb2de70107tturney    private:
460e462795ff5d4c7359f9e8637c10544bb2de70107tturney        GenericReader& r_;
461e462795ff5d4c7359f9e8637c10544bb2de70107tturney        ClearStackOnExit(const ClearStackOnExit&);
462e462795ff5d4c7359f9e8637c10544bb2de70107tturney        ClearStackOnExit& operator=(const ClearStackOnExit&);
463e462795ff5d4c7359f9e8637c10544bb2de70107tturney    };
464e462795ff5d4c7359f9e8637c10544bb2de70107tturney
465e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Parse object: { string : value, ... }
466e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<unsigned parseFlags, typename InputStream, typename Handler>
467e462795ff5d4c7359f9e8637c10544bb2de70107tturney    void ParseObject(InputStream& is, Handler& handler) {
468e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RAPIDJSON_ASSERT(is.Peek() == '{');
469e462795ff5d4c7359f9e8637c10544bb2de70107tturney        is.Take();  // Skip '{'
470e462795ff5d4c7359f9e8637c10544bb2de70107tturney
471e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (!handler.StartObject())
472e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
473e462795ff5d4c7359f9e8637c10544bb2de70107tturney
474e462795ff5d4c7359f9e8637c10544bb2de70107tturney        SkipWhitespace(is);
475e462795ff5d4c7359f9e8637c10544bb2de70107tturney
476e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (is.Peek() == '}') {
477e462795ff5d4c7359f9e8637c10544bb2de70107tturney            is.Take();
478e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!handler.EndObject(0))  // empty object
479e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
480e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return;
481e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
482e462795ff5d4c7359f9e8637c10544bb2de70107tturney
483e462795ff5d4c7359f9e8637c10544bb2de70107tturney        for (SizeType memberCount = 0;;) {
484e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (is.Peek() != '"')
485e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
486e462795ff5d4c7359f9e8637c10544bb2de70107tturney
487e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ParseString<parseFlags>(is, handler, true);
488e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
489e462795ff5d4c7359f9e8637c10544bb2de70107tturney
490e462795ff5d4c7359f9e8637c10544bb2de70107tturney            SkipWhitespace(is);
491e462795ff5d4c7359f9e8637c10544bb2de70107tturney
492e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (is.Take() != ':')
493e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
494e462795ff5d4c7359f9e8637c10544bb2de70107tturney
495e462795ff5d4c7359f9e8637c10544bb2de70107tturney            SkipWhitespace(is);
496e462795ff5d4c7359f9e8637c10544bb2de70107tturney
497e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ParseValue<parseFlags>(is, handler);
498e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
499e462795ff5d4c7359f9e8637c10544bb2de70107tturney
500e462795ff5d4c7359f9e8637c10544bb2de70107tturney            SkipWhitespace(is);
501e462795ff5d4c7359f9e8637c10544bb2de70107tturney
502e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ++memberCount;
503e462795ff5d4c7359f9e8637c10544bb2de70107tturney
504e462795ff5d4c7359f9e8637c10544bb2de70107tturney            switch (is.Take()) {
505e462795ff5d4c7359f9e8637c10544bb2de70107tturney                case ',': SkipWhitespace(is); break;
506e462795ff5d4c7359f9e8637c10544bb2de70107tturney                case '}':
507e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    if (!handler.EndObject(memberCount))
508e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
509e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    return;
510e462795ff5d4c7359f9e8637c10544bb2de70107tturney                default:  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
511e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
512e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
513e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
514e462795ff5d4c7359f9e8637c10544bb2de70107tturney
515e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Parse array: [ value, ... ]
516e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<unsigned parseFlags, typename InputStream, typename Handler>
517e462795ff5d4c7359f9e8637c10544bb2de70107tturney    void ParseArray(InputStream& is, Handler& handler) {
518e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RAPIDJSON_ASSERT(is.Peek() == '[');
519e462795ff5d4c7359f9e8637c10544bb2de70107tturney        is.Take();  // Skip '['
520e462795ff5d4c7359f9e8637c10544bb2de70107tturney
521e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (!handler.StartArray())
522e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
523e462795ff5d4c7359f9e8637c10544bb2de70107tturney
524e462795ff5d4c7359f9e8637c10544bb2de70107tturney        SkipWhitespace(is);
525e462795ff5d4c7359f9e8637c10544bb2de70107tturney
526e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (is.Peek() == ']') {
527e462795ff5d4c7359f9e8637c10544bb2de70107tturney            is.Take();
528e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!handler.EndArray(0)) // empty array
529e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
530e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return;
531e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
532e462795ff5d4c7359f9e8637c10544bb2de70107tturney
533e462795ff5d4c7359f9e8637c10544bb2de70107tturney        for (SizeType elementCount = 0;;) {
534e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ParseValue<parseFlags>(is, handler);
535e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
536e462795ff5d4c7359f9e8637c10544bb2de70107tturney
537e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ++elementCount;
538e462795ff5d4c7359f9e8637c10544bb2de70107tturney            SkipWhitespace(is);
539e462795ff5d4c7359f9e8637c10544bb2de70107tturney
540e462795ff5d4c7359f9e8637c10544bb2de70107tturney            switch (is.Take()) {
541e462795ff5d4c7359f9e8637c10544bb2de70107tturney                case ',': SkipWhitespace(is); break;
542e462795ff5d4c7359f9e8637c10544bb2de70107tturney                case ']':
543e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    if (!handler.EndArray(elementCount))
544e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
545e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    return;
546e462795ff5d4c7359f9e8637c10544bb2de70107tturney                default:  RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
547e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
548e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
549e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
550e462795ff5d4c7359f9e8637c10544bb2de70107tturney
551e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<unsigned parseFlags, typename InputStream, typename Handler>
552e462795ff5d4c7359f9e8637c10544bb2de70107tturney    void ParseNull(InputStream& is, Handler& handler) {
553e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RAPIDJSON_ASSERT(is.Peek() == 'n');
554e462795ff5d4c7359f9e8637c10544bb2de70107tturney        is.Take();
555e462795ff5d4c7359f9e8637c10544bb2de70107tturney
556e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l') {
557e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!handler.Null())
558e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
559e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
560e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else
561e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1);
562e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
563e462795ff5d4c7359f9e8637c10544bb2de70107tturney
564e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<unsigned parseFlags, typename InputStream, typename Handler>
565e462795ff5d4c7359f9e8637c10544bb2de70107tturney    void ParseTrue(InputStream& is, Handler& handler) {
566e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RAPIDJSON_ASSERT(is.Peek() == 't');
567e462795ff5d4c7359f9e8637c10544bb2de70107tturney        is.Take();
568e462795ff5d4c7359f9e8637c10544bb2de70107tturney
569e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e') {
570e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!handler.Bool(true))
571e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
572e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
573e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else
574e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1);
575e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
576e462795ff5d4c7359f9e8637c10544bb2de70107tturney
577e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<unsigned parseFlags, typename InputStream, typename Handler>
578e462795ff5d4c7359f9e8637c10544bb2de70107tturney    void ParseFalse(InputStream& is, Handler& handler) {
579e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RAPIDJSON_ASSERT(is.Peek() == 'f');
580e462795ff5d4c7359f9e8637c10544bb2de70107tturney        is.Take();
581e462795ff5d4c7359f9e8637c10544bb2de70107tturney
582e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e') {
583e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!handler.Bool(false))
584e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
585e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
586e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else
587e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1);
588e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
589e462795ff5d4c7359f9e8637c10544bb2de70107tturney
590e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
591e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<typename InputStream>
592e462795ff5d4c7359f9e8637c10544bb2de70107tturney    unsigned ParseHex4(InputStream& is) {
593e462795ff5d4c7359f9e8637c10544bb2de70107tturney        unsigned codepoint = 0;
594e462795ff5d4c7359f9e8637c10544bb2de70107tturney        for (int i = 0; i < 4; i++) {
595e462795ff5d4c7359f9e8637c10544bb2de70107tturney            Ch c = is.Take();
596e462795ff5d4c7359f9e8637c10544bb2de70107tturney            codepoint <<= 4;
597e462795ff5d4c7359f9e8637c10544bb2de70107tturney            codepoint += static_cast<unsigned>(c);
598e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (c >= '0' && c <= '9')
599e462795ff5d4c7359f9e8637c10544bb2de70107tturney                codepoint -= '0';
600e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else if (c >= 'A' && c <= 'F')
601e462795ff5d4c7359f9e8637c10544bb2de70107tturney                codepoint -= 'A' - 10;
602e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else if (c >= 'a' && c <= 'f')
603e462795ff5d4c7359f9e8637c10544bb2de70107tturney                codepoint -= 'a' - 10;
604e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else {
605e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, is.Tell() - 1);
606e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
607e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
608e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
609e462795ff5d4c7359f9e8637c10544bb2de70107tturney        return codepoint;
610e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
611e462795ff5d4c7359f9e8637c10544bb2de70107tturney
612e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template <typename CharType>
613e462795ff5d4c7359f9e8637c10544bb2de70107tturney    class StackStream {
614e462795ff5d4c7359f9e8637c10544bb2de70107tturney    public:
615e462795ff5d4c7359f9e8637c10544bb2de70107tturney        typedef CharType Ch;
616e462795ff5d4c7359f9e8637c10544bb2de70107tturney
617fb108ff03df1052469bbfa169755bcd97be9cb95Chih-Hung Hsieh        explicit StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {}
618e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RAPIDJSON_FORCEINLINE void Put(Ch c) {
619e462795ff5d4c7359f9e8637c10544bb2de70107tturney            *stack_.template Push<Ch>() = c;
620e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ++length_;
621e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
622e462795ff5d4c7359f9e8637c10544bb2de70107tturney        size_t Length() const { return length_; }
623e462795ff5d4c7359f9e8637c10544bb2de70107tturney        Ch* Pop() {
624e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return stack_.template Pop<Ch>(length_);
625e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
626e462795ff5d4c7359f9e8637c10544bb2de70107tturney
627e462795ff5d4c7359f9e8637c10544bb2de70107tturney    private:
628e462795ff5d4c7359f9e8637c10544bb2de70107tturney        StackStream(const StackStream&);
629e462795ff5d4c7359f9e8637c10544bb2de70107tturney        StackStream& operator=(const StackStream&);
630e462795ff5d4c7359f9e8637c10544bb2de70107tturney
631e462795ff5d4c7359f9e8637c10544bb2de70107tturney        internal::Stack<StackAllocator>& stack_;
632e462795ff5d4c7359f9e8637c10544bb2de70107tturney        SizeType length_;
633e462795ff5d4c7359f9e8637c10544bb2de70107tturney    };
634e462795ff5d4c7359f9e8637c10544bb2de70107tturney
635e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Parse string and generate String event. Different code paths for kParseInsituFlag.
636e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<unsigned parseFlags, typename InputStream, typename Handler>
637e462795ff5d4c7359f9e8637c10544bb2de70107tturney    void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
638e462795ff5d4c7359f9e8637c10544bb2de70107tturney        internal::StreamLocalCopy<InputStream> copy(is);
639e462795ff5d4c7359f9e8637c10544bb2de70107tturney        InputStream& s(copy.s);
640e462795ff5d4c7359f9e8637c10544bb2de70107tturney
641e462795ff5d4c7359f9e8637c10544bb2de70107tturney        bool success = false;
642e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (parseFlags & kParseInsituFlag) {
643e462795ff5d4c7359f9e8637c10544bb2de70107tturney            typename InputStream::Ch *head = s.PutBegin();
644e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
645e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
646e462795ff5d4c7359f9e8637c10544bb2de70107tturney            size_t length = s.PutEnd(head) - 1;
647e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
648e462795ff5d4c7359f9e8637c10544bb2de70107tturney            const typename TargetEncoding::Ch* const str = (typename TargetEncoding::Ch*)head;
649e462795ff5d4c7359f9e8637c10544bb2de70107tturney            success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
650e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
651e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else {
652e462795ff5d4c7359f9e8637c10544bb2de70107tturney            StackStream<typename TargetEncoding::Ch> stackStream(stack_);
653e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
654e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
655e462795ff5d4c7359f9e8637c10544bb2de70107tturney            SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;
656e462795ff5d4c7359f9e8637c10544bb2de70107tturney            const typename TargetEncoding::Ch* const str = stackStream.Pop();
657e462795ff5d4c7359f9e8637c10544bb2de70107tturney            success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
658e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
659e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (!success)
660e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
661e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
662e462795ff5d4c7359f9e8637c10544bb2de70107tturney
663e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Parse string to an output is
664e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
665e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
666e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
667e462795ff5d4c7359f9e8637c10544bb2de70107tturney//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
668e462795ff5d4c7359f9e8637c10544bb2de70107tturney#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
669e462795ff5d4c7359f9e8637c10544bb2de70107tturney        static const char escape[256] = {
670e462795ff5d4c7359f9e8637c10544bb2de70107tturney            Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
671e462795ff5d4c7359f9e8637c10544bb2de70107tturney            Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
672e462795ff5d4c7359f9e8637c10544bb2de70107tturney            0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
673e462795ff5d4c7359f9e8637c10544bb2de70107tturney            0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
674e462795ff5d4c7359f9e8637c10544bb2de70107tturney            Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
675e462795ff5d4c7359f9e8637c10544bb2de70107tturney        };
676e462795ff5d4c7359f9e8637c10544bb2de70107tturney#undef Z16
677e462795ff5d4c7359f9e8637c10544bb2de70107tturney//!@endcond
678e462795ff5d4c7359f9e8637c10544bb2de70107tturney
679e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RAPIDJSON_ASSERT(is.Peek() == '\"');
680e462795ff5d4c7359f9e8637c10544bb2de70107tturney        is.Take();  // Skip '\"'
681e462795ff5d4c7359f9e8637c10544bb2de70107tturney
682e462795ff5d4c7359f9e8637c10544bb2de70107tturney        for (;;) {
683e462795ff5d4c7359f9e8637c10544bb2de70107tturney            Ch c = is.Peek();
684e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (c == '\\') {    // Escape
685e462795ff5d4c7359f9e8637c10544bb2de70107tturney                is.Take();
686e462795ff5d4c7359f9e8637c10544bb2de70107tturney                Ch e = is.Take();
687e462795ff5d4c7359f9e8637c10544bb2de70107tturney                if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[(unsigned char)e]) {
688e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    os.Put(escape[(unsigned char)e]);
689e462795ff5d4c7359f9e8637c10544bb2de70107tturney                }
690e462795ff5d4c7359f9e8637c10544bb2de70107tturney                else if (e == 'u') {    // Unicode
691e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    unsigned codepoint = ParseHex4(is);
692e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
693e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    if (codepoint >= 0xD800 && codepoint <= 0xDBFF) {
694e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        // Handle UTF-16 surrogate pair
695e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        if (is.Take() != '\\' || is.Take() != 'u')
696e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2);
697e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        unsigned codepoint2 = ParseHex4(is);
698e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
699e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)
700e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2);
701e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
702e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    }
703e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    TEncoding::Encode(os, codepoint);
704e462795ff5d4c7359f9e8637c10544bb2de70107tturney                }
705e462795ff5d4c7359f9e8637c10544bb2de70107tturney                else
706e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1);
707e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
708e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else if (c == '"') {    // Closing double quote
709e462795ff5d4c7359f9e8637c10544bb2de70107tturney                is.Take();
710e462795ff5d4c7359f9e8637c10544bb2de70107tturney                os.Put('\0');   // null-terminate the string
711e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return;
712e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
713e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else if (c == '\0')
714e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell() - 1);
715e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
716e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1);
717e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else {
718e462795ff5d4c7359f9e8637c10544bb2de70107tturney                if (parseFlags & kParseValidateEncodingFlag ?
719e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    !Transcoder<SEncoding, TEncoding>::Validate(is, os) :
720e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    !Transcoder<SEncoding, TEncoding>::Transcode(is, os))
721e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell());
722e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
723e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
724e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
725e462795ff5d4c7359f9e8637c10544bb2de70107tturney
726e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<typename InputStream, bool backup>
727e462795ff5d4c7359f9e8637c10544bb2de70107tturney    class NumberStream;
728e462795ff5d4c7359f9e8637c10544bb2de70107tturney
729e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<typename InputStream>
730e462795ff5d4c7359f9e8637c10544bb2de70107tturney    class NumberStream<InputStream, false> {
731e462795ff5d4c7359f9e8637c10544bb2de70107tturney    public:
732e462795ff5d4c7359f9e8637c10544bb2de70107tturney        NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader;  }
733e462795ff5d4c7359f9e8637c10544bb2de70107tturney        ~NumberStream() {}
734e462795ff5d4c7359f9e8637c10544bb2de70107tturney
735e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
736e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
737e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
738e462795ff5d4c7359f9e8637c10544bb2de70107tturney        size_t Tell() { return is.Tell(); }
739e462795ff5d4c7359f9e8637c10544bb2de70107tturney        size_t Length() { return 0; }
740e462795ff5d4c7359f9e8637c10544bb2de70107tturney        const char* Pop() { return 0; }
741e462795ff5d4c7359f9e8637c10544bb2de70107tturney
742e462795ff5d4c7359f9e8637c10544bb2de70107tturney    protected:
743e462795ff5d4c7359f9e8637c10544bb2de70107tturney        NumberStream& operator=(const NumberStream&);
744e462795ff5d4c7359f9e8637c10544bb2de70107tturney
745e462795ff5d4c7359f9e8637c10544bb2de70107tturney        InputStream& is;
746e462795ff5d4c7359f9e8637c10544bb2de70107tturney    };
747e462795ff5d4c7359f9e8637c10544bb2de70107tturney
748e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<typename InputStream>
749e462795ff5d4c7359f9e8637c10544bb2de70107tturney    class NumberStream<InputStream, true> : public NumberStream<InputStream, false> {
750e462795ff5d4c7359f9e8637c10544bb2de70107tturney        typedef NumberStream<InputStream, false> Base;
751e462795ff5d4c7359f9e8637c10544bb2de70107tturney    public:
752e462795ff5d4c7359f9e8637c10544bb2de70107tturney        NumberStream(GenericReader& reader, InputStream& is) : NumberStream<InputStream, false>(reader, is), stackStream(reader.stack_) {}
753e462795ff5d4c7359f9e8637c10544bb2de70107tturney        ~NumberStream() {}
754e462795ff5d4c7359f9e8637c10544bb2de70107tturney
755e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RAPIDJSON_FORCEINLINE Ch TakePush() {
756e462795ff5d4c7359f9e8637c10544bb2de70107tturney            stackStream.Put((char)Base::is.Peek());
757e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return Base::is.Take();
758e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
759e462795ff5d4c7359f9e8637c10544bb2de70107tturney
760e462795ff5d4c7359f9e8637c10544bb2de70107tturney        size_t Length() { return stackStream.Length(); }
761e462795ff5d4c7359f9e8637c10544bb2de70107tturney
762e462795ff5d4c7359f9e8637c10544bb2de70107tturney        const char* Pop() {
763e462795ff5d4c7359f9e8637c10544bb2de70107tturney            stackStream.Put('\0');
764e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return stackStream.Pop();
765e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
766e462795ff5d4c7359f9e8637c10544bb2de70107tturney
767e462795ff5d4c7359f9e8637c10544bb2de70107tturney    private:
768e462795ff5d4c7359f9e8637c10544bb2de70107tturney        StackStream<char> stackStream;
769e462795ff5d4c7359f9e8637c10544bb2de70107tturney    };
770e462795ff5d4c7359f9e8637c10544bb2de70107tturney
771e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<unsigned parseFlags, typename InputStream, typename Handler>
772e462795ff5d4c7359f9e8637c10544bb2de70107tturney    void ParseNumber(InputStream& is, Handler& handler) {
773e462795ff5d4c7359f9e8637c10544bb2de70107tturney        internal::StreamLocalCopy<InputStream> copy(is);
774e462795ff5d4c7359f9e8637c10544bb2de70107tturney        NumberStream<InputStream, (parseFlags & kParseFullPrecisionFlag) != 0> s(*this, copy.s);
775e462795ff5d4c7359f9e8637c10544bb2de70107tturney
776e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Parse minus
777e462795ff5d4c7359f9e8637c10544bb2de70107tturney        bool minus = false;
778e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (s.Peek() == '-') {
779e462795ff5d4c7359f9e8637c10544bb2de70107tturney            minus = true;
780e462795ff5d4c7359f9e8637c10544bb2de70107tturney            s.Take();
781e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
782e462795ff5d4c7359f9e8637c10544bb2de70107tturney
783e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Parse int: zero / ( digit1-9 *DIGIT )
784e462795ff5d4c7359f9e8637c10544bb2de70107tturney        unsigned i = 0;
785e462795ff5d4c7359f9e8637c10544bb2de70107tturney        uint64_t i64 = 0;
786e462795ff5d4c7359f9e8637c10544bb2de70107tturney        bool use64bit = false;
787e462795ff5d4c7359f9e8637c10544bb2de70107tturney        int significandDigit = 0;
788e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (s.Peek() == '0') {
789e462795ff5d4c7359f9e8637c10544bb2de70107tturney            i = 0;
790e462795ff5d4c7359f9e8637c10544bb2de70107tturney            s.TakePush();
791e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
792e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else if (s.Peek() >= '1' && s.Peek() <= '9') {
793e462795ff5d4c7359f9e8637c10544bb2de70107tturney            i = static_cast<unsigned>(s.TakePush() - '0');
794e462795ff5d4c7359f9e8637c10544bb2de70107tturney
795e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (minus)
796e462795ff5d4c7359f9e8637c10544bb2de70107tturney                while (s.Peek() >= '0' && s.Peek() <= '9') {
797e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    if (i >= 214748364) { // 2^31 = 2147483648
798e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        if (i != 214748364 || s.Peek() > '8') {
799e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            i64 = i;
800e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            use64bit = true;
801e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            break;
802e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        }
803e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    }
804e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
805e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    significandDigit++;
806e462795ff5d4c7359f9e8637c10544bb2de70107tturney                }
807e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else
808e462795ff5d4c7359f9e8637c10544bb2de70107tturney                while (s.Peek() >= '0' && s.Peek() <= '9') {
809e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    if (i >= 429496729) { // 2^32 - 1 = 4294967295
810e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        if (i != 429496729 || s.Peek() > '5') {
811e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            i64 = i;
812e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            use64bit = true;
813e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            break;
814e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        }
815e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    }
816e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
817e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    significandDigit++;
818e462795ff5d4c7359f9e8637c10544bb2de70107tturney                }
819e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
820e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else
821e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
822e462795ff5d4c7359f9e8637c10544bb2de70107tturney
823e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Parse 64bit int
824e462795ff5d4c7359f9e8637c10544bb2de70107tturney        bool useDouble = false;
825e462795ff5d4c7359f9e8637c10544bb2de70107tturney        double d = 0.0;
826e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (use64bit) {
827e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (minus)
828e462795ff5d4c7359f9e8637c10544bb2de70107tturney                while (s.Peek() >= '0' && s.Peek() <= '9') {
829e462795ff5d4c7359f9e8637c10544bb2de70107tturney                     if (i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC)) // 2^63 = 9223372036854775808
830e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        if (i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8') {
831e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            d = i64;
832e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            useDouble = true;
833e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            break;
834e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        }
835e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
836e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    significandDigit++;
837e462795ff5d4c7359f9e8637c10544bb2de70107tturney                }
838e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else
839e462795ff5d4c7359f9e8637c10544bb2de70107tturney                while (s.Peek() >= '0' && s.Peek() <= '9') {
840e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    if (i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999)) // 2^64 - 1 = 18446744073709551615
841e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        if (i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5') {
842e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            d = i64;
843e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            useDouble = true;
844e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            break;
845e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        }
846e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
847e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    significandDigit++;
848e462795ff5d4c7359f9e8637c10544bb2de70107tturney                }
849e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
850e462795ff5d4c7359f9e8637c10544bb2de70107tturney
851e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Force double for big integer
852e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (useDouble) {
853e462795ff5d4c7359f9e8637c10544bb2de70107tturney            while (s.Peek() >= '0' && s.Peek() <= '9') {
854e462795ff5d4c7359f9e8637c10544bb2de70107tturney                if (d >= 1.7976931348623157e307) // DBL_MAX / 10.0
855e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell());
856e462795ff5d4c7359f9e8637c10544bb2de70107tturney                d = d * 10 + (s.TakePush() - '0');
857e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
858e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
859e462795ff5d4c7359f9e8637c10544bb2de70107tturney
860e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Parse frac = decimal-point 1*DIGIT
861e462795ff5d4c7359f9e8637c10544bb2de70107tturney        int expFrac = 0;
862e462795ff5d4c7359f9e8637c10544bb2de70107tturney        size_t decimalPosition;
863e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (s.Peek() == '.') {
864e462795ff5d4c7359f9e8637c10544bb2de70107tturney            s.Take();
865e462795ff5d4c7359f9e8637c10544bb2de70107tturney            decimalPosition = s.Length();
866e462795ff5d4c7359f9e8637c10544bb2de70107tturney
867e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!(s.Peek() >= '0' && s.Peek() <= '9'))
868e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
869e462795ff5d4c7359f9e8637c10544bb2de70107tturney
870e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!useDouble) {
871e462795ff5d4c7359f9e8637c10544bb2de70107tturney#if RAPIDJSON_64BIT
872e462795ff5d4c7359f9e8637c10544bb2de70107tturney                // Use i64 to store significand in 64-bit architecture
873e462795ff5d4c7359f9e8637c10544bb2de70107tturney                if (!use64bit)
874e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    i64 = i;
875e462795ff5d4c7359f9e8637c10544bb2de70107tturney
876e462795ff5d4c7359f9e8637c10544bb2de70107tturney                while (s.Peek() >= '0' && s.Peek() <= '9') {
877e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
878e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        break;
879e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    else {
880e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
881e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        --expFrac;
882e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        if (i64 != 0)
883e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            significandDigit++;
884e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    }
885e462795ff5d4c7359f9e8637c10544bb2de70107tturney                }
886e462795ff5d4c7359f9e8637c10544bb2de70107tturney
887e462795ff5d4c7359f9e8637c10544bb2de70107tturney                d = (double)i64;
888e462795ff5d4c7359f9e8637c10544bb2de70107tturney#else
889e462795ff5d4c7359f9e8637c10544bb2de70107tturney                // Use double to store significand in 32-bit architecture
890e462795ff5d4c7359f9e8637c10544bb2de70107tturney                d = use64bit ? (double)i64 : (double)i;
891e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
892e462795ff5d4c7359f9e8637c10544bb2de70107tturney                useDouble = true;
893e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
894e462795ff5d4c7359f9e8637c10544bb2de70107tturney
895e462795ff5d4c7359f9e8637c10544bb2de70107tturney            while (s.Peek() >= '0' && s.Peek() <= '9') {
896e462795ff5d4c7359f9e8637c10544bb2de70107tturney                if (significandDigit < 17) {
897e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    d = d * 10.0 + (s.TakePush() - '0');
898e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    --expFrac;
899e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    if (d > 0.0)
900e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        significandDigit++;
901e462795ff5d4c7359f9e8637c10544bb2de70107tturney                }
902e462795ff5d4c7359f9e8637c10544bb2de70107tturney                else
903e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    s.TakePush();
904e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
905e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
906e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else
907e462795ff5d4c7359f9e8637c10544bb2de70107tturney            decimalPosition = s.Length(); // decimal position at the end of integer.
908e462795ff5d4c7359f9e8637c10544bb2de70107tturney
909e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Parse exp = e [ minus / plus ] 1*DIGIT
910e462795ff5d4c7359f9e8637c10544bb2de70107tturney        int exp = 0;
911e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (s.Peek() == 'e' || s.Peek() == 'E') {
912e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!useDouble) {
913e462795ff5d4c7359f9e8637c10544bb2de70107tturney                d = use64bit ? i64 : i;
914e462795ff5d4c7359f9e8637c10544bb2de70107tturney                useDouble = true;
915e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
916e462795ff5d4c7359f9e8637c10544bb2de70107tturney            s.Take();
917e462795ff5d4c7359f9e8637c10544bb2de70107tturney
918e462795ff5d4c7359f9e8637c10544bb2de70107tturney            bool expMinus = false;
919e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (s.Peek() == '+')
920e462795ff5d4c7359f9e8637c10544bb2de70107tturney                s.Take();
921e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else if (s.Peek() == '-') {
922e462795ff5d4c7359f9e8637c10544bb2de70107tturney                s.Take();
923e462795ff5d4c7359f9e8637c10544bb2de70107tturney                expMinus = true;
924e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
925e462795ff5d4c7359f9e8637c10544bb2de70107tturney
926e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (s.Peek() >= '0' && s.Peek() <= '9') {
927e462795ff5d4c7359f9e8637c10544bb2de70107tturney                exp = s.Take() - '0';
928e462795ff5d4c7359f9e8637c10544bb2de70107tturney                if (expMinus) {
929e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    while (s.Peek() >= '0' && s.Peek() <= '9') {
930e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        exp = exp * 10 + (s.Take() - '0');
931e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        if (exp >= 214748364) {                         // Issue #313: prevent overflow exponent
932e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            while (s.Peek() >= '0' && s.Peek() <= '9')  // Consume the rest of exponent
933e462795ff5d4c7359f9e8637c10544bb2de70107tturney                                s.Take();
934e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        }
935e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    }
936e462795ff5d4c7359f9e8637c10544bb2de70107tturney                }
937e462795ff5d4c7359f9e8637c10544bb2de70107tturney                else {  // positive exp
938e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    int maxExp = 308 - expFrac;
939e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    while (s.Peek() >= '0' && s.Peek() <= '9') {
940e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        exp = exp * 10 + (s.Take() - '0');
941e462795ff5d4c7359f9e8637c10544bb2de70107tturney                        if (exp > maxExp)
942e462795ff5d4c7359f9e8637c10544bb2de70107tturney                            RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell());
943e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    }
944e462795ff5d4c7359f9e8637c10544bb2de70107tturney                }
945e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
946e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else
947e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());
948e462795ff5d4c7359f9e8637c10544bb2de70107tturney
949e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (expMinus)
950e462795ff5d4c7359f9e8637c10544bb2de70107tturney                exp = -exp;
951e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
952e462795ff5d4c7359f9e8637c10544bb2de70107tturney
953e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Finish parsing, call event according to the type of number.
954e462795ff5d4c7359f9e8637c10544bb2de70107tturney        bool cont = true;
955e462795ff5d4c7359f9e8637c10544bb2de70107tturney        size_t length = s.Length();
956e462795ff5d4c7359f9e8637c10544bb2de70107tturney        const char* decimal = s.Pop();  // Pop stack no matter if it will be used or not.
957e462795ff5d4c7359f9e8637c10544bb2de70107tturney
958e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (useDouble) {
959e462795ff5d4c7359f9e8637c10544bb2de70107tturney            int p = exp + expFrac;
960e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (parseFlags & kParseFullPrecisionFlag)
961e462795ff5d4c7359f9e8637c10544bb2de70107tturney                d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
962e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else
963e462795ff5d4c7359f9e8637c10544bb2de70107tturney                d = internal::StrtodNormalPrecision(d, p);
964e462795ff5d4c7359f9e8637c10544bb2de70107tturney
965e462795ff5d4c7359f9e8637c10544bb2de70107tturney            cont = handler.Double(minus ? -d : d);
966e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
967e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else {
968e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (use64bit) {
969e462795ff5d4c7359f9e8637c10544bb2de70107tturney                if (minus)
970e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
971e462795ff5d4c7359f9e8637c10544bb2de70107tturney                else
972e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    cont = handler.Uint64(i64);
973e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
974e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else {
975e462795ff5d4c7359f9e8637c10544bb2de70107tturney                if (minus)
976e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    cont = handler.Int(static_cast<int32_t>(~i + 1));
977e462795ff5d4c7359f9e8637c10544bb2de70107tturney                else
978e462795ff5d4c7359f9e8637c10544bb2de70107tturney                    cont = handler.Uint(i);
979e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
980e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
981e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (!cont)
982e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
983e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
984e462795ff5d4c7359f9e8637c10544bb2de70107tturney
985e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Parse any JSON value
986e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template<unsigned parseFlags, typename InputStream, typename Handler>
987e462795ff5d4c7359f9e8637c10544bb2de70107tturney    void ParseValue(InputStream& is, Handler& handler) {
988e462795ff5d4c7359f9e8637c10544bb2de70107tturney        switch (is.Peek()) {
989e462795ff5d4c7359f9e8637c10544bb2de70107tturney            case 'n': ParseNull  <parseFlags>(is, handler); break;
990e462795ff5d4c7359f9e8637c10544bb2de70107tturney            case 't': ParseTrue  <parseFlags>(is, handler); break;
991e462795ff5d4c7359f9e8637c10544bb2de70107tturney            case 'f': ParseFalse <parseFlags>(is, handler); break;
992e462795ff5d4c7359f9e8637c10544bb2de70107tturney            case '"': ParseString<parseFlags>(is, handler); break;
993e462795ff5d4c7359f9e8637c10544bb2de70107tturney            case '{': ParseObject<parseFlags>(is, handler); break;
994e462795ff5d4c7359f9e8637c10544bb2de70107tturney            case '[': ParseArray <parseFlags>(is, handler); break;
995e462795ff5d4c7359f9e8637c10544bb2de70107tturney            default : ParseNumber<parseFlags>(is, handler);
996e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
997e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
998e462795ff5d4c7359f9e8637c10544bb2de70107tturney
999e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Iterative Parsing
1000e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1001e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // States
1002e462795ff5d4c7359f9e8637c10544bb2de70107tturney    enum IterativeParsingState {
1003e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingStartState = 0,
1004e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingFinishState,
1005e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingErrorState,
1006e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1007e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Object states
1008e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingObjectInitialState,
1009e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingMemberKeyState,
1010e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingKeyValueDelimiterState,
1011e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingMemberValueState,
1012e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingMemberDelimiterState,
1013e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingObjectFinishState,
1014e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1015e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Array states
1016e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingArrayInitialState,
1017e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingElementState,
1018e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingElementDelimiterState,
1019e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingArrayFinishState,
1020e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1021e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Single value state
1022e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingValueState,
1023e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1024e462795ff5d4c7359f9e8637c10544bb2de70107tturney        cIterativeParsingStateCount
1025e462795ff5d4c7359f9e8637c10544bb2de70107tturney    };
1026e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1027e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Tokens
1028e462795ff5d4c7359f9e8637c10544bb2de70107tturney    enum Token {
1029e462795ff5d4c7359f9e8637c10544bb2de70107tturney        LeftBracketToken = 0,
1030e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RightBracketToken,
1031e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1032e462795ff5d4c7359f9e8637c10544bb2de70107tturney        LeftCurlyBracketToken,
1033e462795ff5d4c7359f9e8637c10544bb2de70107tturney        RightCurlyBracketToken,
1034e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1035e462795ff5d4c7359f9e8637c10544bb2de70107tturney        CommaToken,
1036e462795ff5d4c7359f9e8637c10544bb2de70107tturney        ColonToken,
1037e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1038e462795ff5d4c7359f9e8637c10544bb2de70107tturney        StringToken,
1039e462795ff5d4c7359f9e8637c10544bb2de70107tturney        FalseToken,
1040e462795ff5d4c7359f9e8637c10544bb2de70107tturney        TrueToken,
1041e462795ff5d4c7359f9e8637c10544bb2de70107tturney        NullToken,
1042e462795ff5d4c7359f9e8637c10544bb2de70107tturney        NumberToken,
1043e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1044e462795ff5d4c7359f9e8637c10544bb2de70107tturney        kTokenCount
1045e462795ff5d4c7359f9e8637c10544bb2de70107tturney    };
1046e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1047e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
1048e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1049e462795ff5d4c7359f9e8637c10544bb2de70107tturney//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
1050e462795ff5d4c7359f9e8637c10544bb2de70107tturney#define N NumberToken
1051e462795ff5d4c7359f9e8637c10544bb2de70107tturney#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1052e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Maps from ASCII to Token
1053e462795ff5d4c7359f9e8637c10544bb2de70107tturney        static const unsigned char tokenMap[256] = {
1054e462795ff5d4c7359f9e8637c10544bb2de70107tturney            N16, // 00~0F
1055e462795ff5d4c7359f9e8637c10544bb2de70107tturney            N16, // 10~1F
1056e462795ff5d4c7359f9e8637c10544bb2de70107tturney            N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F
1057e462795ff5d4c7359f9e8637c10544bb2de70107tturney            N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F
1058e462795ff5d4c7359f9e8637c10544bb2de70107tturney            N16, // 40~4F
1059e462795ff5d4c7359f9e8637c10544bb2de70107tturney            N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F
1060e462795ff5d4c7359f9e8637c10544bb2de70107tturney            N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F
1061e462795ff5d4c7359f9e8637c10544bb2de70107tturney            N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F
1062e462795ff5d4c7359f9e8637c10544bb2de70107tturney            N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF
1063e462795ff5d4c7359f9e8637c10544bb2de70107tturney        };
1064e462795ff5d4c7359f9e8637c10544bb2de70107tturney#undef N
1065e462795ff5d4c7359f9e8637c10544bb2de70107tturney#undef N16
1066e462795ff5d4c7359f9e8637c10544bb2de70107tturney//!@endcond
1067e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1068e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (sizeof(Ch) == 1 || unsigned(c) < 256)
1069e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return (Token)tokenMap[(unsigned char)c];
1070e462795ff5d4c7359f9e8637c10544bb2de70107tturney        else
1071e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return NumberToken;
1072e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
1073e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1074e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {
1075e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // current state x one lookahead token -> new state
1076e462795ff5d4c7359f9e8637c10544bb2de70107tturney        static const char G[cIterativeParsingStateCount][kTokenCount] = {
1077e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Start
1078e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1079e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingArrayInitialState,  // Left bracket
1080e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Right bracket
1081e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingObjectInitialState, // Left curly bracket
1082e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Right curly bracket
1083e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Comma
1084e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Colon
1085e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingValueState,         // String
1086e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingValueState,         // False
1087e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingValueState,         // True
1088e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingValueState,         // Null
1089e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingValueState          // Number
1090e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1091e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Finish(sink state)
1092e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1093e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1094e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1095e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState
1096e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1097e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Error(sink state)
1098e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1099e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1100e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1101e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState
1102e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1103e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // ObjectInitial
1104e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1105e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Left bracket
1106e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Right bracket
1107e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Left curly bracket
1108e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingObjectFinishState,  // Right curly bracket
1109e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Comma
1110e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Colon
1111e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingMemberKeyState,     // String
1112e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // False
1113e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // True
1114e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Null
1115e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState          // Number
1116e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1117e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // MemberKey
1118e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1119e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Left bracket
1120e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Right bracket
1121e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Left curly bracket
1122e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Right curly bracket
1123e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Comma
1124e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingKeyValueDelimiterState, // Colon
1125e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // String
1126e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // False
1127e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // True
1128e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Null
1129e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState              // Number
1130e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1131e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // KeyValueDelimiter
1132e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1133e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingArrayInitialState,      // Left bracket(push MemberValue state)
1134e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Right bracket
1135e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingObjectInitialState,     // Left curly bracket(push MemberValue state)
1136e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Right curly bracket
1137e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Comma
1138e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Colon
1139e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingMemberValueState,       // String
1140e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingMemberValueState,       // False
1141e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingMemberValueState,       // True
1142e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingMemberValueState,       // Null
1143e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingMemberValueState        // Number
1144e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1145e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // MemberValue
1146e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1147e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Left bracket
1148e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Right bracket
1149e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Left curly bracket
1150e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingObjectFinishState,      // Right curly bracket
1151e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingMemberDelimiterState,   // Comma
1152e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Colon
1153e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // String
1154e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // False
1155e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // True
1156e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Null
1157e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState              // Number
1158e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1159e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // MemberDelimiter
1160e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1161e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Left bracket
1162e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Right bracket
1163e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Left curly bracket
1164e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Right curly bracket
1165e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Comma
1166e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Colon
1167e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingMemberKeyState,     // String
1168e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // False
1169e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // True
1170e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,         // Null
1171e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState          // Number
1172e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1173e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // ObjectFinish(sink state)
1174e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1175e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1176e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1177e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState
1178e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1179e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // ArrayInitial
1180e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1181e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingArrayInitialState,      // Left bracket(push Element state)
1182e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingArrayFinishState,       // Right bracket
1183e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingObjectInitialState,     // Left curly bracket(push Element state)
1184e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Right curly bracket
1185e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Comma
1186e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Colon
1187e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingElementState,           // String
1188e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingElementState,           // False
1189e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingElementState,           // True
1190e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingElementState,           // Null
1191e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingElementState            // Number
1192e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1193e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Element
1194e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1195e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Left bracket
1196e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingArrayFinishState,       // Right bracket
1197e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Left curly bracket
1198e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Right curly bracket
1199e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingElementDelimiterState,  // Comma
1200e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Colon
1201e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // String
1202e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // False
1203e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // True
1204e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Null
1205e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState              // Number
1206e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1207e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // ElementDelimiter
1208e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1209e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingArrayInitialState,      // Left bracket(push Element state)
1210e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Right bracket
1211e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingObjectInitialState,     // Left curly bracket(push Element state)
1212e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Right curly bracket
1213e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Comma
1214e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState,             // Colon
1215e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingElementState,           // String
1216e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingElementState,           // False
1217e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingElementState,           // True
1218e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingElementState,           // Null
1219e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingElementState            // Number
1220e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1221e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // ArrayFinish(sink state)
1222e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1223e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1224e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1225e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState
1226e462795ff5d4c7359f9e8637c10544bb2de70107tturney            },
1227e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Single Value (sink state)
1228e462795ff5d4c7359f9e8637c10544bb2de70107tturney            {
1229e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1230e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1231e462795ff5d4c7359f9e8637c10544bb2de70107tturney                IterativeParsingErrorState
1232e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
1233e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }; // End of G
1234e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1235e462795ff5d4c7359f9e8637c10544bb2de70107tturney        return (IterativeParsingState)G[state][token];
1236e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
1237e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1238e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
1239e462795ff5d4c7359f9e8637c10544bb2de70107tturney    // May return a new state on state pop.
1240e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template <unsigned parseFlags, typename InputStream, typename Handler>
1241e462795ff5d4c7359f9e8637c10544bb2de70107tturney    RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
1242e462795ff5d4c7359f9e8637c10544bb2de70107tturney        (void)token;
1243e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1244e462795ff5d4c7359f9e8637c10544bb2de70107tturney        switch (dst) {
1245e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingErrorState:
1246e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return dst;
1247e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1248e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingObjectInitialState:
1249e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingArrayInitialState:
1250e462795ff5d4c7359f9e8637c10544bb2de70107tturney        {
1251e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Push the state(Element or MemeberValue) if we are nested in another array or value of member.
1252e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
1253e462795ff5d4c7359f9e8637c10544bb2de70107tturney            IterativeParsingState n = src;
1254e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
1255e462795ff5d4c7359f9e8637c10544bb2de70107tturney                n = IterativeParsingElementState;
1256e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else if (src == IterativeParsingKeyValueDelimiterState)
1257e462795ff5d4c7359f9e8637c10544bb2de70107tturney                n = IterativeParsingMemberValueState;
1258e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Push current state.
1259e462795ff5d4c7359f9e8637c10544bb2de70107tturney            *stack_.template Push<SizeType>(1) = n;
1260e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Initialize and push the member/element count.
1261e462795ff5d4c7359f9e8637c10544bb2de70107tturney            *stack_.template Push<SizeType>(1) = 0;
1262e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Call handler
1263e462795ff5d4c7359f9e8637c10544bb2de70107tturney            bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
1264e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // On handler short circuits the parsing.
1265e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!hr) {
1266e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1267e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return IterativeParsingErrorState;
1268e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
1269e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else {
1270e462795ff5d4c7359f9e8637c10544bb2de70107tturney                is.Take();
1271e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return dst;
1272e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
1273e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
1274e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1275e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingMemberKeyState:
1276e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ParseString<parseFlags>(is, handler, true);
1277e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (HasParseError())
1278e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return IterativeParsingErrorState;
1279e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else
1280e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return dst;
1281e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1282e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingKeyValueDelimiterState:
1283e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_ASSERT(token == ColonToken);
1284e462795ff5d4c7359f9e8637c10544bb2de70107tturney            is.Take();
1285e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return dst;
1286e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1287e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingMemberValueState:
1288e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1289e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ParseValue<parseFlags>(is, handler);
1290e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (HasParseError()) {
1291e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return IterativeParsingErrorState;
1292e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
1293e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return dst;
1294e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1295e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingElementState:
1296e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1297e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ParseValue<parseFlags>(is, handler);
1298e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (HasParseError()) {
1299e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return IterativeParsingErrorState;
1300e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
1301e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return dst;
1302e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1303e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingMemberDelimiterState:
1304e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingElementDelimiterState:
1305e462795ff5d4c7359f9e8637c10544bb2de70107tturney            is.Take();
1306e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Update member/element count.
1307e462795ff5d4c7359f9e8637c10544bb2de70107tturney            *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
1308e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return dst;
1309e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1310e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingObjectFinishState:
1311e462795ff5d4c7359f9e8637c10544bb2de70107tturney        {
1312e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Get member count.
1313e462795ff5d4c7359f9e8637c10544bb2de70107tturney            SizeType c = *stack_.template Pop<SizeType>(1);
1314e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // If the object is not empty, count the last member.
1315e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (src == IterativeParsingMemberValueState)
1316e462795ff5d4c7359f9e8637c10544bb2de70107tturney                ++c;
1317e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Restore the state.
1318e462795ff5d4c7359f9e8637c10544bb2de70107tturney            IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1319e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Transit to Finish state if this is the topmost scope.
1320e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (n == IterativeParsingStartState)
1321e462795ff5d4c7359f9e8637c10544bb2de70107tturney                n = IterativeParsingFinishState;
1322e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Call handler
1323e462795ff5d4c7359f9e8637c10544bb2de70107tturney            bool hr = handler.EndObject(c);
1324e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // On handler short circuits the parsing.
1325e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!hr) {
1326e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1327e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return IterativeParsingErrorState;
1328e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
1329e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else {
1330e462795ff5d4c7359f9e8637c10544bb2de70107tturney                is.Take();
1331e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return n;
1332e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
1333e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
1334e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1335e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingArrayFinishState:
1336e462795ff5d4c7359f9e8637c10544bb2de70107tturney        {
1337e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Get element count.
1338e462795ff5d4c7359f9e8637c10544bb2de70107tturney            SizeType c = *stack_.template Pop<SizeType>(1);
1339e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // If the array is not empty, count the last element.
1340e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (src == IterativeParsingElementState)
1341e462795ff5d4c7359f9e8637c10544bb2de70107tturney                ++c;
1342e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Restore the state.
1343e462795ff5d4c7359f9e8637c10544bb2de70107tturney            IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1344e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Transit to Finish state if this is the topmost scope.
1345e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (n == IterativeParsingStartState)
1346e462795ff5d4c7359f9e8637c10544bb2de70107tturney                n = IterativeParsingFinishState;
1347e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Call handler
1348e462795ff5d4c7359f9e8637c10544bb2de70107tturney            bool hr = handler.EndArray(c);
1349e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // On handler short circuits the parsing.
1350e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (!hr) {
1351e462795ff5d4c7359f9e8637c10544bb2de70107tturney                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1352e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return IterativeParsingErrorState;
1353e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
1354e462795ff5d4c7359f9e8637c10544bb2de70107tturney            else {
1355e462795ff5d4c7359f9e8637c10544bb2de70107tturney                is.Take();
1356e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return n;
1357e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
1358e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
1359e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1360e462795ff5d4c7359f9e8637c10544bb2de70107tturney        default:
1361e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // This branch is for IterativeParsingValueState actually.
1362e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Use `default:` rather than
1363e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // `case IterativeParsingValueState:` is for code coverage.
1364e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1365e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // The IterativeParsingStartState is not enumerated in this switch-case.
1366e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // It is impossible for that case. And it can be caught by following assertion.
1367e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1368e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // The IterativeParsingFinishState is not enumerated in this switch-case either.
1369e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // It is a "derivative" state which cannot triggered from Predict() directly.
1370e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Therefore it cannot happen here. And it can be caught by following assertion.
1371e462795ff5d4c7359f9e8637c10544bb2de70107tturney            RAPIDJSON_ASSERT(dst == IterativeParsingValueState);
1372e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1373e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1374e462795ff5d4c7359f9e8637c10544bb2de70107tturney            ParseValue<parseFlags>(is, handler);
1375e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (HasParseError()) {
1376e462795ff5d4c7359f9e8637c10544bb2de70107tturney                return IterativeParsingErrorState;
1377e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
1378e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return IterativeParsingFinishState;
1379e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
1380e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
1381e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1382e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template <typename InputStream>
1383e462795ff5d4c7359f9e8637c10544bb2de70107tturney    void HandleError(IterativeParsingState src, InputStream& is) {
1384e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (HasParseError()) {
1385e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Error flag has been set.
1386e462795ff5d4c7359f9e8637c10544bb2de70107tturney            return;
1387e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
1388e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1389e462795ff5d4c7359f9e8637c10544bb2de70107tturney        switch (src) {
1390e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingStartState:            RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
1391e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingFinishState:           RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
1392e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingObjectInitialState:
1393e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingMemberDelimiterState:  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
1394e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingMemberKeyState:        RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
1395e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingMemberValueState:      RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
1396e462795ff5d4c7359f9e8637c10544bb2de70107tturney        case IterativeParsingElementState:          RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
1397e462795ff5d4c7359f9e8637c10544bb2de70107tturney        default:                                    RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
1398e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
1399e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
1400e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1401e462795ff5d4c7359f9e8637c10544bb2de70107tturney    template <unsigned parseFlags, typename InputStream, typename Handler>
1402e462795ff5d4c7359f9e8637c10544bb2de70107tturney    ParseResult IterativeParse(InputStream& is, Handler& handler) {
1403e462795ff5d4c7359f9e8637c10544bb2de70107tturney        parseResult_.Clear();
1404e462795ff5d4c7359f9e8637c10544bb2de70107tturney        ClearStackOnExit scope(*this);
1405e462795ff5d4c7359f9e8637c10544bb2de70107tturney        IterativeParsingState state = IterativeParsingStartState;
1406e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1407e462795ff5d4c7359f9e8637c10544bb2de70107tturney        SkipWhitespace(is);
1408e462795ff5d4c7359f9e8637c10544bb2de70107tturney        while (is.Peek() != '\0') {
1409e462795ff5d4c7359f9e8637c10544bb2de70107tturney            Token t = Tokenize(is.Peek());
1410e462795ff5d4c7359f9e8637c10544bb2de70107tturney            IterativeParsingState n = Predict(state, t);
1411e462795ff5d4c7359f9e8637c10544bb2de70107tturney            IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
1412e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1413e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if (d == IterativeParsingErrorState) {
1414e462795ff5d4c7359f9e8637c10544bb2de70107tturney                HandleError(state, is);
1415e462795ff5d4c7359f9e8637c10544bb2de70107tturney                break;
1416e462795ff5d4c7359f9e8637c10544bb2de70107tturney            }
1417e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1418e462795ff5d4c7359f9e8637c10544bb2de70107tturney            state = d;
1419e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1420e462795ff5d4c7359f9e8637c10544bb2de70107tturney            // Do not further consume streams if a root JSON has been parsed.
1421e462795ff5d4c7359f9e8637c10544bb2de70107tturney            if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
1422e462795ff5d4c7359f9e8637c10544bb2de70107tturney                break;
1423e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1424e462795ff5d4c7359f9e8637c10544bb2de70107tturney            SkipWhitespace(is);
1425e462795ff5d4c7359f9e8637c10544bb2de70107tturney        }
1426e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1427e462795ff5d4c7359f9e8637c10544bb2de70107tturney        // Handle the end of file.
1428e462795ff5d4c7359f9e8637c10544bb2de70107tturney        if (state != IterativeParsingFinishState)
1429e462795ff5d4c7359f9e8637c10544bb2de70107tturney            HandleError(state, is);
1430e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1431e462795ff5d4c7359f9e8637c10544bb2de70107tturney        return parseResult_;
1432e462795ff5d4c7359f9e8637c10544bb2de70107tturney    }
1433e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1434e462795ff5d4c7359f9e8637c10544bb2de70107tturney    static const size_t kDefaultStackCapacity = 256;    //!< Default stack capacity in bytes for storing a single decoded string.
1435e462795ff5d4c7359f9e8637c10544bb2de70107tturney    internal::Stack<StackAllocator> stack_;  //!< A stack for storing decoded string temporarily during non-destructive parsing.
1436e462795ff5d4c7359f9e8637c10544bb2de70107tturney    ParseResult parseResult_;
1437e462795ff5d4c7359f9e8637c10544bb2de70107tturney}; // class GenericReader
1438e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1439e462795ff5d4c7359f9e8637c10544bb2de70107tturney//! Reader with UTF8 encoding and default allocator.
1440e462795ff5d4c7359f9e8637c10544bb2de70107tturneytypedef GenericReader<UTF8<>, UTF8<> > Reader;
1441e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1442e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_NAMESPACE_END
1443e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1444e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifdef __GNUC__
1445e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_DIAG_POP
1446e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
1447e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1448e462795ff5d4c7359f9e8637c10544bb2de70107tturney#ifdef _MSC_VER
1449e462795ff5d4c7359f9e8637c10544bb2de70107tturneyRAPIDJSON_DIAG_POP
1450e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif
1451e462795ff5d4c7359f9e8637c10544bb2de70107tturney
1452e462795ff5d4c7359f9e8637c10544bb2de70107tturney#endif // RAPIDJSON_READER_H_
1453