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