reader.h

Engine/source/persistence/rapidjson/reader.h

More...

Classes:

Namespaces:

namespace

Public Defines

define
RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) 

(Internal) macro to indicate and handle a parse error.

define
RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)     RAPIDJSON_MULTILINEMACRO_BEGIN \
    (!HasParseError()); /* Error can only be assigned once */ \
    SetParseError(parseErrorCode, offset); \
    RAPIDJSON_MULTILINEMACRO_END

Macro to indicate a parse error.

Public Enumerations

enum
ParseFlag {
  kParseNoFlags = 0
  kParseInsituFlag = 1
  kParseValidateEncodingFlag = 2
  kParseIterativeFlag = 4
  kParseStopWhenDoneFlag = 8
  kParseFullPrecisionFlag = 16
  kParseCommentsFlag = 32
  kParseNumbersAsStringsFlag = 64
  kParseTrailingCommasFlag = 128
  kParseNanAndInfFlag = 256
  kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS
}

Combination of parseFlags.

Public Typedefs

Reader 

Reader with UTF8 encoding and default allocator.

Public Functions

const char *
SkipWhitespace(const char * p, const char * end)
SkipWhitespace(InputStream & is)

Skip the JSON white spaces in a stream.

Detailed Description

Public Defines

RAPIDJSON_PARSE_DEFAULT_FLAGS() 
RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) 

(Internal) macro to indicate and handle a parse error.

Parameters:

parseErrorCode

rapidjson::ParseErrorCode of the error

offset

position of the error in JSON input (

size_t
)

Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing.

RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)     RAPIDJSON_MULTILINEMACRO_BEGIN \
    (!HasParseError()); /* Error can only be assigned once */ \
    SetParseError(parseErrorCode, offset); \
    RAPIDJSON_MULTILINEMACRO_END

Macro to indicate a parse error.

Parameters:

parseErrorCode

rapidjson::ParseErrorCode of the error

offset

position of the error in JSON input (

size_t
)

This macros can be used as a customization point for the internal error handling mechanism of RapidJSON.

A common usage model is to throw an exception instead of requiring the caller to explicitly check the rapidjson::GenericReader::Parse's return value:

#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \
   throw ParseException(parseErrorCode, #parseErrorCode, offset)

#include <stdexcept>               // std::runtime_error
#include "rapidjson/error/error.h" // rapidjson::ParseResult

struct ParseException : std::runtime_error, rapidjson::ParseResult {
  ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset)
    : std::runtime_error(msg), ParseResult(code, offset) {}
};

#include "rapidjson/reader.h"

see:

RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse

Public Enumerations

ParseFlag

Enumerator

kParseNoFlags = 0

No flags are set.

kParseInsituFlag = 1

In-situ(destructive) parsing.

kParseValidateEncodingFlag = 2

Validate encoding of JSON strings.

kParseIterativeFlag = 4

Iterative(constant complexity in terms of function call stack size) parsing.

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.

kParseFullPrecisionFlag = 16

Parse number in full precision (but slower).

kParseCommentsFlag = 32

Allow one-line (//) and multi-line (/‍**/) comments.

kParseNumbersAsStringsFlag = 64

Parse all numbers (ints/doubles) as strings.

kParseTrailingCommasFlag = 128

Allow trailing commas at the end of objects and arrays.

kParseNanAndInfFlag = 256

Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.

kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS

Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS.

Combination of parseFlags.

Public Typedefs

typedef GenericReader< UTF8<>, UTF8<> > Reader 

Reader with UTF8 encoding and default allocator.

Public Functions

SkipWhitespace(const char * p, const char * end)

SkipWhitespace(InputStream & is)

Skip the JSON white spaces in a stream.

Parameters:

is

A input stream for skipping white spaces.

note:

This function has SSE2/SSE4.2 specialization.

   1
   2// Tencent is pleased to support the open source community by making RapidJSON available.
   3//
   4// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
   5//
   6// Licensed under the MIT License (the "License"); you may not use this file except
   7// in compliance with the License. You may obtain a copy of the License at
   8//
   9// http://opensource.org/licenses/MIT
  10//
  11// Unless required by applicable law or agreed to in writing, software distributed
  12// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13// CONDITIONS OF ANY KIND, either express or implied. See the License for the
  14// specific language governing permissions and limitations under the License.
  15
  16#ifndef RAPIDJSON_READER_H_
  17#define RAPIDJSON_READER_H_
  18
  19/*! \file reader.h */
  20
  21#include "allocators.h"
  22#include "stream.h"
  23#include "encodedstream.h"
  24#include "internal/meta.h"
  25#include "internal/stack.h"
  26#include "internal/strtod.h"
  27#include <limits>
  28
  29#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
  30#include <intrin.h>
  31#pragma intrinsic(_BitScanForward)
  32#endif
  33#ifdef RAPIDJSON_SSE42
  34#include <nmmintrin.h>
  35#elif defined(RAPIDJSON_SSE2)
  36#include <emmintrin.h>
  37#elif defined(RAPIDJSON_NEON)
  38#include <arm_neon.h>
  39#endif
  40
  41#ifdef __clang__
  42RAPIDJSON_DIAG_PUSH
  43RAPIDJSON_DIAG_OFF(old-style-cast)
  44RAPIDJSON_DIAG_OFF(padded)
  45RAPIDJSON_DIAG_OFF(switch-enum)
  46#elif defined(_MSC_VER)
  47RAPIDJSON_DIAG_PUSH
  48RAPIDJSON_DIAG_OFF(4127)  // conditional expression is constant
  49RAPIDJSON_DIAG_OFF(4702)  // unreachable code
  50#endif
  51
  52#ifdef __GNUC__
  53RAPIDJSON_DIAG_PUSH
  54RAPIDJSON_DIAG_OFF(effc++)
  55#endif
  56
  57//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
  58#define RAPIDJSON_NOTHING /* deliberately empty */
  59#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
  60#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
  61    RAPIDJSON_MULTILINEMACRO_BEGIN \
  62    if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
  63    RAPIDJSON_MULTILINEMACRO_END
  64#endif
  65#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
  66    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
  67//!@endcond
  68
  69/*! \def RAPIDJSON_PARSE_ERROR_NORETURN
  70    \ingroup RAPIDJSON_ERRORS
  71    \brief Macro to indicate a parse error.
  72    \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
  73    \param offset  position of the error in JSON input (\c size_t)
  74
  75    This macros can be used as a customization point for the internal
  76    error handling mechanism of RapidJSON.
  77
  78    A common usage model is to throw an exception instead of requiring the
  79    caller to explicitly check the \ref rapidjson::GenericReader::Parse's
  80    return value:
  81
  82    \code
  83    #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \
  84       throw ParseException(parseErrorCode, #parseErrorCode, offset)
  85
  86    #include <stdexcept>               // std::runtime_error
  87    #include "rapidjson/error/error.h" // rapidjson::ParseResult
  88
  89    struct ParseException : std::runtime_error, rapidjson::ParseResult {
  90      ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset)
  91        : std::runtime_error(msg), ParseResult(code, offset) {}
  92    };
  93
  94    #include "rapidjson/reader.h"
  95    \endcode
  96
  97    \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse
  98 */
  99#ifndef RAPIDJSON_PARSE_ERROR_NORETURN
 100#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
 101    RAPIDJSON_MULTILINEMACRO_BEGIN \
 102    RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
 103    SetParseError(parseErrorCode, offset); \
 104    RAPIDJSON_MULTILINEMACRO_END
 105#endif
 106
 107/*! \def RAPIDJSON_PARSE_ERROR
 108    \ingroup RAPIDJSON_ERRORS
 109    \brief (Internal) macro to indicate and handle a parse error.
 110    \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
 111    \param offset  position of the error in JSON input (\c size_t)
 112
 113    Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing.
 114
 115    \see RAPIDJSON_PARSE_ERROR_NORETURN
 116    \hideinitializer
 117 */
 118#ifndef RAPIDJSON_PARSE_ERROR
 119#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \
 120    RAPIDJSON_MULTILINEMACRO_BEGIN \
 121    RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
 122    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
 123    RAPIDJSON_MULTILINEMACRO_END
 124#endif
 125
 126#include "error/error.h" // ParseErrorCode, ParseResult
 127
 128RAPIDJSON_NAMESPACE_BEGIN
 129
 130///////////////////////////////////////////////////////////////////////////////
 131// ParseFlag
 132
 133/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS
 134    \ingroup RAPIDJSON_CONFIG
 135    \brief User-defined kParseDefaultFlags definition.
 136
 137    User can define this as any \c ParseFlag combinations.
 138*/
 139#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS
 140#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags
 141#endif
 142
 143//! Combination of parseFlags
 144/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream
 145 */
 146enum ParseFlag {
 147    kParseNoFlags = 0,              //!< No flags are set.
 148    kParseInsituFlag = 1,           //!< In-situ(destructive) parsing.
 149    kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings.
 150    kParseIterativeFlag = 4,        //!< Iterative(constant complexity in terms of function call stack size) parsing.
 151    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.
 152    kParseFullPrecisionFlag = 16,   //!< Parse number in full precision (but slower).
 153    kParseCommentsFlag = 32,        //!< Allow one-line (//) and multi-line (/**/) comments.
 154    kParseNumbersAsStringsFlag = 64,    //!< Parse all numbers (ints/doubles) as strings.
 155    kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.
 156    kParseNanAndInfFlag = 256,      //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
 157    kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS  //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
 158};
 159
 160///////////////////////////////////////////////////////////////////////////////
 161// Handler
 162
 163/*! \class rapidjson::Handler
 164    \brief Concept for receiving events from GenericReader upon parsing.
 165    The functions return true if no error occurs. If they return false,
 166    the event publisher should terminate the process.
 167\code
 168concept Handler {
 169    typename Ch;
 170
 171    bool Null();
 172    bool Bool(bool b);
 173    bool Int(int i);
 174    bool Uint(unsigned i);
 175    bool Int64(int64_t i);
 176    bool Uint64(uint64_t i);
 177    bool Double(double d);
 178    /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
 179    bool RawNumber(const Ch* str, SizeType length, bool copy);
 180    bool String(const Ch* str, SizeType length, bool copy);
 181    bool StartObject();
 182    bool Key(const Ch* str, SizeType length, bool copy);
 183    bool EndObject(SizeType memberCount);
 184    bool StartArray();
 185    bool EndArray(SizeType elementCount);
 186};
 187\endcode
 188*/
 189///////////////////////////////////////////////////////////////////////////////
 190// BaseReaderHandler
 191
 192//! Default implementation of Handler.
 193/*! This can be used as base class of any reader handler.
 194    \note implements Handler concept
 195*/
 196template<typename Encoding = UTF8<>, typename Derived = void>
 197struct BaseReaderHandler {
 198    typedef typename Encoding::Ch Ch;
 199
 200    typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override;
 201
 202    bool Default() { return true; }
 203    bool Null() { return static_cast<Override&>(*this).Default(); }
 204    bool Bool(bool) { return static_cast<Override&>(*this).Default(); }
 205    bool Int(int) { return static_cast<Override&>(*this).Default(); }
 206    bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); }
 207    bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); }
 208    bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); }
 209    bool Double(double) { return static_cast<Override&>(*this).Default(); }
 210    /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
 211    bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
 212    bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); }
 213    bool StartObject() { return static_cast<Override&>(*this).Default(); }
 214    bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
 215    bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }
 216    bool StartArray() { return static_cast<Override&>(*this).Default(); }
 217    bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }
 218};
 219
 220///////////////////////////////////////////////////////////////////////////////
 221// StreamLocalCopy
 222
 223namespace internal {
 224
 225template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
 226class StreamLocalCopy;
 227
 228//! Do copy optimization.
 229template<typename Stream>
 230class StreamLocalCopy<Stream, 1> {
 231public:
 232    StreamLocalCopy(Stream& original) : s(original), original_(original) {}
 233    ~StreamLocalCopy() { original_ = s; }
 234
 235    Stream s;
 236
 237private:
 238    StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
 239
 240    Stream& original_;
 241};
 242
 243//! Keep reference.
 244template<typename Stream>
 245class StreamLocalCopy<Stream, 0> {
 246public:
 247    StreamLocalCopy(Stream& original) : s(original) {}
 248
 249    Stream& s;
 250
 251private:
 252    StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
 253};
 254
 255} // namespace internal
 256
 257///////////////////////////////////////////////////////////////////////////////
 258// SkipWhitespace
 259
 260//! Skip the JSON white spaces in a stream.
 261/*! \param is A input stream for skipping white spaces.
 262    \note This function has SSE2/SSE4.2 specialization.
 263*/
 264template<typename InputStream>
 265void SkipWhitespace(InputStream& is) {
 266    internal::StreamLocalCopy<InputStream> copy(is);
 267    InputStream& s(copy.s);
 268
 269    typename InputStream::Ch c;
 270    while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t')
 271        s.Take();
 272}
 273
 274inline const char* SkipWhitespace(const char* p, const char* end) {
 275    while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
 276        ++p;
 277    return p;
 278}
 279
 280#ifdef RAPIDJSON_SSE42
 281//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.
 282inline const char *SkipWhitespace_SIMD(const char* p) {
 283    // Fast return for single non-whitespace
 284    if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
 285        ++p;
 286    else
 287        return p;
 288
 289    // 16-byte align to the next boundary
 290    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
 291    while (p != nextAligned)
 292        if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
 293            ++p;
 294        else
 295            return p;
 296
 297    // The rest of string using SIMD
 298    static const char whitespace[16] = " \n\r\t";
 299    const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
 300
 301    for (;; p += 16) {
 302        const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
 303        const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
 304        if (r != 16)    // some of characters is non-whitespace
 305            return p + r;
 306    }
 307}
 308
 309inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
 310    // Fast return for single non-whitespace
 311    if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
 312        ++p;
 313    else
 314        return p;
 315
 316    // The middle of string using SIMD
 317    static const char whitespace[16] = " \n\r\t";
 318    const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
 319
 320    for (; p <= end - 16; p += 16) {
 321        const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
 322        const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
 323        if (r != 16)    // some of characters is non-whitespace
 324            return p + r;
 325    }
 326
 327    return SkipWhitespace(p, end);
 328}
 329
 330#elif defined(RAPIDJSON_SSE2)
 331
 332//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
 333inline const char *SkipWhitespace_SIMD(const char* p) {
 334    // Fast return for single non-whitespace
 335    if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
 336        ++p;
 337    else
 338        return p;
 339
 340    // 16-byte align to the next boundary
 341    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
 342    while (p != nextAligned)
 343        if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
 344            ++p;
 345        else
 346            return p;
 347
 348    // The rest of string
 349    #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
 350    static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
 351    #undef C16
 352
 353    const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
 354    const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
 355    const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
 356    const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
 357
 358    for (;; p += 16) {
 359        const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
 360        __m128i x = _mm_cmpeq_epi8(s, w0);
 361        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
 362        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
 363        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
 364        unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
 365        if (r != 0) {   // some of characters may be non-whitespace
 366#ifdef _MSC_VER         // Find the index of first non-whitespace
 367            unsigned long offset;
 368            _BitScanForward(&offset, r);
 369            return p + offset;
 370#else
 371            return p + __builtin_ffs(r) - 1;
 372#endif
 373        }
 374    }
 375}
 376
 377inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
 378    // Fast return for single non-whitespace
 379    if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
 380        ++p;
 381    else
 382        return p;
 383
 384    // The rest of string
 385    #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
 386    static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
 387    #undef C16
 388
 389    const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
 390    const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
 391    const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
 392    const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
 393
 394    for (; p <= end - 16; p += 16) {
 395        const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
 396        __m128i x = _mm_cmpeq_epi8(s, w0);
 397        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
 398        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
 399        x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
 400        unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
 401        if (r != 0) {   // some of characters may be non-whitespace
 402#ifdef _MSC_VER         // Find the index of first non-whitespace
 403            unsigned long offset;
 404            _BitScanForward(&offset, r);
 405            return p + offset;
 406#else
 407            return p + __builtin_ffs(r) - 1;
 408#endif
 409        }
 410    }
 411
 412    return SkipWhitespace(p, end);
 413}
 414
 415#elif defined(RAPIDJSON_NEON)
 416
 417//! Skip whitespace with ARM Neon instructions, testing 16 8-byte characters at once.
 418inline const char *SkipWhitespace_SIMD(const char* p) {
 419    // Fast return for single non-whitespace
 420    if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
 421        ++p;
 422    else
 423        return p;
 424
 425    // 16-byte align to the next boundary
 426    const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
 427    while (p != nextAligned)
 428        if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
 429            ++p;
 430        else
 431            return p;
 432
 433    const uint8x16_t w0 = vmovq_n_u8(' ');
 434    const uint8x16_t w1 = vmovq_n_u8('\n');
 435    const uint8x16_t w2 = vmovq_n_u8('\r');
 436    const uint8x16_t w3 = vmovq_n_u8('\t');
 437
 438    for (;; p += 16) {
 439        const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
 440        uint8x16_t x = vceqq_u8(s, w0);
 441        x = vorrq_u8(x, vceqq_u8(s, w1));
 442        x = vorrq_u8(x, vceqq_u8(s, w2));
 443        x = vorrq_u8(x, vceqq_u8(s, w3));
 444
 445        x = vmvnq_u8(x);                       // Negate
 446        x = vrev64q_u8(x);                     // Rev in 64
 447        uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
 448        uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
 449
 450        if (low == 0) {
 451            if (high != 0) {
 452                int lz =__builtin_clzll(high);;
 453                return p + 8 + (lz >> 3);
 454            }
 455        } else {
 456            int lz = __builtin_clzll(low);;
 457            return p + (lz >> 3);
 458        }
 459    }
 460}
 461
 462inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
 463    // Fast return for single non-whitespace
 464    if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
 465        ++p;
 466    else
 467        return p;
 468
 469    const uint8x16_t w0 = vmovq_n_u8(' ');
 470    const uint8x16_t w1 = vmovq_n_u8('\n');
 471    const uint8x16_t w2 = vmovq_n_u8('\r');
 472    const uint8x16_t w3 = vmovq_n_u8('\t');
 473
 474    for (; p <= end - 16; p += 16) {
 475        const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
 476        uint8x16_t x = vceqq_u8(s, w0);
 477        x = vorrq_u8(x, vceqq_u8(s, w1));
 478        x = vorrq_u8(x, vceqq_u8(s, w2));
 479        x = vorrq_u8(x, vceqq_u8(s, w3));
 480
 481        x = vmvnq_u8(x);                       // Negate
 482        x = vrev64q_u8(x);                     // Rev in 64
 483        uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
 484        uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
 485
 486        if (low == 0) {
 487            if (high != 0) {
 488                int lz = __builtin_clzll(high);
 489                return p + 8 + (lz >> 3);
 490            }
 491        } else {
 492            int lz = __builtin_clzll(low);
 493            return p + (lz >> 3);
 494        }
 495    }
 496
 497    return SkipWhitespace(p, end);
 498}
 499
 500#endif // RAPIDJSON_NEON
 501
 502#ifdef RAPIDJSON_SIMD
 503//! Template function specialization for InsituStringStream
 504template<> inline void SkipWhitespace(InsituStringStream& is) {
 505    is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
 506}
 507
 508//! Template function specialization for StringStream
 509template<> inline void SkipWhitespace(StringStream& is) {
 510    is.src_ = SkipWhitespace_SIMD(is.src_);
 511}
 512
 513template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {
 514    is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
 515}
 516#endif // RAPIDJSON_SIMD
 517
 518///////////////////////////////////////////////////////////////////////////////
 519// GenericReader
 520
 521//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator.
 522/*! GenericReader parses JSON text from a stream, and send events synchronously to an
 523    object implementing Handler concept.
 524
 525    It needs to allocate a stack for storing a single decoded string during
 526    non-destructive parsing.
 527
 528    For in-situ parsing, the decoded string is directly written to the source
 529    text string, no temporary buffer is required.
 530
 531    A GenericReader object can be reused for parsing multiple JSON text.
 532
 533    \tparam SourceEncoding Encoding of the input stream.
 534    \tparam TargetEncoding Encoding of the parse output.
 535    \tparam StackAllocator Allocator type for stack.
 536*/
 537template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
 538class GenericReader {
 539public:
 540    typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type
 541
 542    //! Constructor.
 543    /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
 544        \param stackCapacity stack capacity in bytes for storing a single decoded string.  (Only use for non-destructive parsing)
 545    */
 546    GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) :
 547        stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {}
 548
 549    //! Parse JSON text.
 550    /*! \tparam parseFlags Combination of \ref ParseFlag.
 551        \tparam InputStream Type of input stream, implementing Stream concept.
 552        \tparam Handler Type of handler, implementing Handler concept.
 553        \param is Input stream to be parsed.
 554        \param handler The handler to receive events.
 555        \return Whether the parsing is successful.
 556    */
 557    template <unsigned parseFlags, typename InputStream, typename Handler>
 558    ParseResult Parse(InputStream& is, Handler& handler) {
 559        if (parseFlags & kParseIterativeFlag)
 560            return IterativeParse<parseFlags>(is, handler);
 561
 562        parseResult_.Clear();
 563
 564        ClearStackOnExit scope(*this);
 565
 566        SkipWhitespaceAndComments<parseFlags>(is);
 567        RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
 568
 569        if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) {
 570            RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
 571            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
 572        }
 573        else {
 574            ParseValue<parseFlags>(is, handler);
 575            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
 576
 577            if (!(parseFlags & kParseStopWhenDoneFlag)) {
 578                SkipWhitespaceAndComments<parseFlags>(is);
 579                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
 580
 581                if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) {
 582                    RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
 583                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
 584                }
 585            }
 586        }
 587
 588        return parseResult_;
 589    }
 590
 591    //! Parse JSON text (with \ref kParseDefaultFlags)
 592    /*! \tparam InputStream Type of input stream, implementing Stream concept
 593        \tparam Handler Type of handler, implementing Handler concept.
 594        \param is Input stream to be parsed.
 595        \param handler The handler to receive events.
 596        \return Whether the parsing is successful.
 597    */
 598    template <typename InputStream, typename Handler>
 599    ParseResult Parse(InputStream& is, Handler& handler) {
 600        return Parse<kParseDefaultFlags>(is, handler);
 601    }
 602
 603    //! Initialize JSON text token-by-token parsing
 604    /*!
 605     */
 606    void IterativeParseInit() {
 607        parseResult_.Clear();
 608        state_ = IterativeParsingStartState;
 609    }
 610
 611    //! Parse one token from JSON text
 612    /*! \tparam InputStream Type of input stream, implementing Stream concept
 613        \tparam Handler Type of handler, implementing Handler concept.
 614        \param is Input stream to be parsed.
 615        \param handler The handler to receive events.
 616        \return Whether the parsing is successful.
 617     */
 618    template <unsigned parseFlags, typename InputStream, typename Handler>
 619    bool IterativeParseNext(InputStream& is, Handler& handler) {
 620        while (RAPIDJSON_LIKELY(is.Peek() != '\0')) {
 621            SkipWhitespaceAndComments<parseFlags>(is);
 622
 623            Token t = Tokenize(is.Peek());
 624            IterativeParsingState n = Predict(state_, t);
 625            IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
 626
 627            // If we've finished or hit an error...
 628            if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {
 629                // Report errors.
 630                if (d == IterativeParsingErrorState) {
 631                    HandleError(state_, is);
 632                    return false;
 633                }
 634
 635                // Transition to the finish state.
 636                RAPIDJSON_ASSERT(d == IterativeParsingFinishState);
 637                state_ = d;
 638
 639                // If StopWhenDone is not set...
 640                if (!(parseFlags & kParseStopWhenDoneFlag)) {
 641                    // ... and extra non-whitespace data is found...
 642                    SkipWhitespaceAndComments<parseFlags>(is);
 643                    if (is.Peek() != '\0') {
 644                        // ... this is considered an error.
 645                        HandleError(state_, is);
 646                        return false;
 647                    }
 648                }
 649
 650                // Success! We are done!
 651                return true;
 652            }
 653
 654            // Transition to the new state.
 655            state_ = d;
 656
 657            // If we parsed anything other than a delimiter, we invoked the handler, so we can return true now.
 658            if (!IsIterativeParsingDelimiterState(n))
 659                return true;
 660        }
 661
 662        // We reached the end of file.
 663        stack_.Clear();
 664
 665        if (state_ != IterativeParsingFinishState) {
 666            HandleError(state_, is);
 667            return false;
 668        }
 669
 670        return true;
 671    }
 672
 673    //! Check if token-by-token parsing JSON text is complete
 674    /*! \return Whether the JSON has been fully decoded.
 675     */
 676    RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const {
 677        return IsIterativeParsingCompleteState(state_);
 678    }
 679
 680    //! Whether a parse error has occurred in the last parsing.
 681    bool HasParseError() const { return parseResult_.IsError(); }
 682
 683    //! Get the \ref ParseErrorCode of last parsing.
 684    ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }
 685
 686    //! Get the position of last parsing error in input, 0 otherwise.
 687    size_t GetErrorOffset() const { return parseResult_._Offset(); }
 688
 689protected:
 690    void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
 691
 692private:
 693    // Prohibit copy constructor & assignment operator.
 694    GenericReader(const GenericReader&);
 695    GenericReader& operator=(const GenericReader&);
 696
 697    void ClearStack() { stack_.Clear(); }
 698
 699    // clear stack on any exit from ParseStream, e.g. due to exception
 700    struct ClearStackOnExit {
 701        explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
 702        ~ClearStackOnExit() { r_.ClearStack(); }
 703    private:
 704        GenericReader& r_;
 705        ClearStackOnExit(const ClearStackOnExit&);
 706        ClearStackOnExit& operator=(const ClearStackOnExit&);
 707    };
 708
 709    template<unsigned parseFlags, typename InputStream>
 710    void SkipWhitespaceAndComments(InputStream& is) {
 711        SkipWhitespace(is);
 712
 713        if (parseFlags & kParseCommentsFlag) {
 714            while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) {
 715                if (Consume(is, '*')) {
 716                    while (true) {
 717                        if (RAPIDJSON_UNLIKELY(is.Peek() == '\0'))
 718                            RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
 719                        else if (Consume(is, '*')) {
 720                            if (Consume(is, '/'))
 721                                break;
 722                        }
 723                        else
 724                            is.Take();
 725                    }
 726                }
 727                else if (RAPIDJSON_LIKELY(Consume(is, '/')))
 728                    while (is.Peek() != '\0' && is.Take() != '\n') {}
 729                else
 730                    RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
 731
 732                SkipWhitespace(is);
 733            }
 734        }
 735    }
 736
 737    // Parse object: { string : value, ... }
 738    template<unsigned parseFlags, typename InputStream, typename Handler>
 739    void ParseObject(InputStream& is, Handler& handler) {
 740        RAPIDJSON_ASSERT(is.Peek() == '{');
 741        is.Take();  // Skip '{'
 742
 743        if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
 744            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 745
 746        SkipWhitespaceAndComments<parseFlags>(is);
 747        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 748
 749        if (Consume(is, '}')) {
 750            if (RAPIDJSON_UNLIKELY(!handler.EndObject(0)))  // empty object
 751                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 752            return;
 753        }
 754
 755        for (SizeType memberCount = 0;;) {
 756            if (RAPIDJSON_UNLIKELY(is.Peek() != '"'))
 757                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
 758
 759            ParseString<parseFlags>(is, handler, true);
 760            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 761
 762            SkipWhitespaceAndComments<parseFlags>(is);
 763            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 764
 765            if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))
 766                RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
 767
 768            SkipWhitespaceAndComments<parseFlags>(is);
 769            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 770
 771            ParseValue<parseFlags>(is, handler);
 772            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 773
 774            SkipWhitespaceAndComments<parseFlags>(is);
 775            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 776
 777            ++memberCount;
 778
 779            switch (is.Peek()) {
 780                case ',':
 781                    is.Take();
 782                    SkipWhitespaceAndComments<parseFlags>(is);
 783                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 784                    break;
 785                case '}':
 786                    is.Take();
 787                    if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
 788                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 789                    return;
 790                default:
 791                    RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy
 792            }
 793
 794            if (parseFlags & kParseTrailingCommasFlag) {
 795                if (is.Peek() == '}') {
 796                    if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
 797                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 798                    is.Take();
 799                    return;
 800                }
 801            }
 802        }
 803    }
 804
 805    // Parse array: [ value, ... ]
 806    template<unsigned parseFlags, typename InputStream, typename Handler>
 807    void ParseArray(InputStream& is, Handler& handler) {
 808        RAPIDJSON_ASSERT(is.Peek() == '[');
 809        is.Take();  // Skip '['
 810
 811        if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
 812            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 813
 814        SkipWhitespaceAndComments<parseFlags>(is);
 815        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 816
 817        if (Consume(is, ']')) {
 818            if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array
 819                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 820            return;
 821        }
 822
 823        for (SizeType elementCount = 0;;) {
 824            ParseValue<parseFlags>(is, handler);
 825            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 826
 827            ++elementCount;
 828            SkipWhitespaceAndComments<parseFlags>(is);
 829            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 830
 831            if (Consume(is, ',')) {
 832                SkipWhitespaceAndComments<parseFlags>(is);
 833                RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 834            }
 835            else if (Consume(is, ']')) {
 836                if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
 837                    RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 838                return;
 839            }
 840            else
 841                RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
 842
 843            if (parseFlags & kParseTrailingCommasFlag) {
 844                if (is.Peek() == ']') {
 845                    if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
 846                        RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 847                    is.Take();
 848                    return;
 849                }
 850            }
 851        }
 852    }
 853
 854    template<unsigned parseFlags, typename InputStream, typename Handler>
 855    void ParseNull(InputStream& is, Handler& handler) {
 856        RAPIDJSON_ASSERT(is.Peek() == 'n');
 857        is.Take();
 858
 859        if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {
 860            if (RAPIDJSON_UNLIKELY(!handler.Null()))
 861                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 862        }
 863        else
 864            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
 865    }
 866
 867    template<unsigned parseFlags, typename InputStream, typename Handler>
 868    void ParseTrue(InputStream& is, Handler& handler) {
 869        RAPIDJSON_ASSERT(is.Peek() == 't');
 870        is.Take();
 871
 872        if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {
 873            if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))
 874                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 875        }
 876        else
 877            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
 878    }
 879
 880    template<unsigned parseFlags, typename InputStream, typename Handler>
 881    void ParseFalse(InputStream& is, Handler& handler) {
 882        RAPIDJSON_ASSERT(is.Peek() == 'f');
 883        is.Take();
 884
 885        if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {
 886            if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))
 887                RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
 888        }
 889        else
 890            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
 891    }
 892
 893    template<typename InputStream>
 894    RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
 895        if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
 896            is.Take();
 897            return true;
 898        }
 899        else
 900            return false;
 901    }
 902
 903    // Helper function to parse four hexadecimal digits in \uXXXX in ParseString().
 904    template<typename InputStream>
 905    unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
 906        unsigned codepoint = 0;
 907        for (int i = 0; i < 4; i++) {
 908            Ch c = is.Peek();
 909            codepoint <<= 4;
 910            codepoint += static_cast<unsigned>(c);
 911            if (c >= '0' && c <= '9')
 912                codepoint -= '0';
 913            else if (c >= 'A' && c <= 'F')
 914                codepoint -= 'A' - 10;
 915            else if (c >= 'a' && c <= 'f')
 916                codepoint -= 'a' - 10;
 917            else {
 918                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset);
 919                RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
 920            }
 921            is.Take();
 922        }
 923        return codepoint;
 924    }
 925
 926    template <typename CharType>
 927    class StackStream {
 928    public:
 929        typedef CharType Ch;
 930
 931        StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {}
 932        RAPIDJSON_FORCEINLINE void Put(Ch c) {
 933            *stack_.template Push<Ch>() = c;
 934            ++length_;
 935        }
 936
 937        RAPIDJSON_FORCEINLINE void* Push(SizeType count) {
 938            length_ += count;
 939            return stack_.template Push<Ch>(count);
 940        }
 941
 942        size_t Length() const { return length_; }
 943
 944        Ch* Pop() {
 945            return stack_.template Pop<Ch>(length_);
 946        }
 947
 948    private:
 949        StackStream(const StackStream&);
 950        StackStream& operator=(const StackStream&);
 951
 952        internal::Stack<StackAllocator>& stack_;
 953        SizeType length_;
 954    };
 955
 956    // Parse string and generate String event. Different code paths for kParseInsituFlag.
 957    template<unsigned parseFlags, typename InputStream, typename Handler>
 958    void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
 959        internal::StreamLocalCopy<InputStream> copy(is);
 960        InputStream& s(copy.s);
 961
 962        RAPIDJSON_ASSERT(s.Peek() == '\"');
 963        s.Take();  // Skip '\"'
 964
 965        bool success = false;
 966        if (parseFlags & kParseInsituFlag) {
 967            typename InputStream::Ch *head = s.PutBegin();
 968            ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
 969            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 970            size_t length = s.PutEnd(head) - 1;
 971            RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
 972            const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
 973            success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
 974        }
 975        else {
 976            StackStream<typename TargetEncoding::Ch> stackStream(stack_);
 977            ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
 978            RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
 979            SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;
 980            const typename TargetEncoding::Ch* const str = stackStream.Pop();
 981            success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
 982        }
 983        if (RAPIDJSON_UNLIKELY(!success))
 984            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
 985    }
 986
 987    // Parse string to an output is
 988    // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
 989    template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
 990    RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
 991//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
 992#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 993        static const char escape[256] = {
 994            Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
 995            Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
 996            0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
 997            0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 998            Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
 999        };
1000#undef Z16
1001//!@endcond
1002
1003        for (;;) {
1004            // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
1005            if (!(parseFlags & kParseValidateEncodingFlag))
1006                ScanCopyUnescapedString(is, os);
1007
1008            Ch c = is.Peek();
1009            if (RAPIDJSON_UNLIKELY(c == '\\')) {    // Escape
1010                size_t escapeOffset = is.Tell();    // For invalid escaping, report the initial '\\' as error offset
1011                is.Take();
1012                Ch e = is.Peek();
1013                if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
1014                    is.Take();
1015                    os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
1016                }
1017                else if (RAPIDJSON_LIKELY(e == 'u')) {    // Unicode
1018                    is.Take();
1019                    unsigned codepoint = ParseHex4(is, escapeOffset);
1020                    RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
1021                    if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
1022                        // Handle UTF-16 surrogate pair
1023                        if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
1024                            RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
1025                        unsigned codepoint2 = ParseHex4(is, escapeOffset);
1026                        RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
1027                        if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
1028                            RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
1029                        codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
1030                    }
1031                    TEncoding::Encode(os, codepoint);
1032                }
1033                else
1034                    RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset);
1035            }
1036            else if (RAPIDJSON_UNLIKELY(c == '"')) {    // Closing double quote
1037                is.Take();
1038                os.Put('\0');   // null-terminate the string
1039                return;
1040            }
1041            else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
1042                if (c == '\0')
1043                    RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell());
1044                else
1045                    RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell());
1046            }
1047            else {
1048                size_t offset = is.Tell();
1049                if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
1050                    !Transcoder<SEncoding, TEncoding>::Validate(is, os) :
1051                    !Transcoder<SEncoding, TEncoding>::Transcode(is, os))))
1052                    RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset);
1053            }
1054        }
1055    }
1056
1057    template<typename InputStream, typename OutputStream>
1058    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {
1059            // Do nothing for generic version
1060    }
1061
1062#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
1063    // StringStream -> StackStream<char>
1064    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
1065        const char* p = is.src_;
1066
1067        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1068        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1069        while (p != nextAligned)
1070            if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1071                is.src_ = p;
1072                return;
1073            }
1074            else
1075                os.Put(*p++);
1076
1077        // The rest of string using SIMD
1078        static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1079        static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1080        static const char space[16]  = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1081        const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1082        const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1083        const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1084
1085        for (;; p += 16) {
1086            const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1087            const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1088            const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1089            const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
1090            const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1091            unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1092            if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped
1093                SizeType length;
1094    #ifdef _MSC_VER         // Find the index of first escaped
1095                unsigned long offset;
1096                _BitScanForward(&offset, r);
1097                length = offset;
1098    #else
1099                length = static_cast<SizeType>(__builtin_ffs(r) - 1);
1100    #endif
1101                if (length != 0) {
1102                    char* q = reinterpret_cast<char*>(os.Push(length));
1103                    for (size_t i = 0; i < length; i++)
1104                        q[i] = p[i];
1105
1106                    p += length;
1107                }
1108                break;
1109            }
1110            _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);
1111        }
1112
1113        is.src_ = p;
1114    }
1115
1116    // InsituStringStream -> InsituStringStream
1117    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
1118        RAPIDJSON_ASSERT(&is == &os);
1119        (void)os;
1120
1121        if (is.src_ == is.dst_) {
1122            SkipUnescapedString(is);
1123            return;
1124        }
1125
1126        char* p = is.src_;
1127        char *q = is.dst_;
1128
1129        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1130        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1131        while (p != nextAligned)
1132            if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1133                is.src_ = p;
1134                is.dst_ = q;
1135                return;
1136            }
1137            else
1138                *q++ = *p++;
1139
1140        // The rest of string using SIMD
1141        static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1142        static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1143        static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1144        const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1145        const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1146        const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1147
1148        for (;; p += 16, q += 16) {
1149            const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1150            const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1151            const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1152            const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
1153            const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1154            unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1155            if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped
1156                size_t length;
1157#ifdef _MSC_VER         // Find the index of first escaped
1158                unsigned long offset;
1159                _BitScanForward(&offset, r);
1160                length = offset;
1161#else
1162                length = static_cast<size_t>(__builtin_ffs(r) - 1);
1163#endif
1164                for (const char* pend = p + length; p != pend; )
1165                    *q++ = *p++;
1166                break;
1167            }
1168            _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);
1169        }
1170
1171        is.src_ = p;
1172        is.dst_ = q;
1173    }
1174
1175    // When read/write pointers are the same for insitu stream, just skip unescaped characters
1176    static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
1177        RAPIDJSON_ASSERT(is.src_ == is.dst_);
1178        char* p = is.src_;
1179
1180        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1181        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1182        for (; p != nextAligned; p++)
1183            if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1184                is.src_ = is.dst_ = p;
1185                return;
1186            }
1187
1188        // The rest of string using SIMD
1189        static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1190        static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1191        static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1192        const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1193        const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1194        const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1195
1196        for (;; p += 16) {
1197            const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1198            const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1199            const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1200            const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
1201            const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1202            unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1203            if (RAPIDJSON_UNLIKELY(r != 0)) {   // some of characters is escaped
1204                size_t length;
1205#ifdef _MSC_VER         // Find the index of first escaped
1206                unsigned long offset;
1207                _BitScanForward(&offset, r);
1208                length = offset;
1209#else
1210                length = static_cast<size_t>(__builtin_ffs(r) - 1);
1211#endif
1212                p += length;
1213                break;
1214            }
1215        }
1216
1217        is.src_ = is.dst_ = p;
1218    }
1219#elif defined(RAPIDJSON_NEON)
1220    // StringStream -> StackStream<char>
1221    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
1222        const char* p = is.src_;
1223
1224        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1225        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1226        while (p != nextAligned)
1227            if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1228                is.src_ = p;
1229                return;
1230            }
1231            else
1232                os.Put(*p++);
1233
1234        // The rest of string using SIMD
1235        const uint8x16_t s0 = vmovq_n_u8('"');
1236        const uint8x16_t s1 = vmovq_n_u8('\\');
1237        const uint8x16_t s2 = vmovq_n_u8('\b');
1238        const uint8x16_t s3 = vmovq_n_u8(32);
1239
1240        for (;; p += 16) {
1241            const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
1242            uint8x16_t x = vceqq_u8(s, s0);
1243            x = vorrq_u8(x, vceqq_u8(s, s1));
1244            x = vorrq_u8(x, vceqq_u8(s, s2));
1245            x = vorrq_u8(x, vcltq_u8(s, s3));
1246
1247            x = vrev64q_u8(x);                     // Rev in 64
1248            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
1249            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
1250
1251            SizeType length = 0;
1252            bool escaped = false;
1253            if (low == 0) {
1254                if (high != 0) {
1255                    unsigned lz = (unsigned)__builtin_clzll(high);;
1256                    length = 8 + (lz >> 3);
1257                    escaped = true;
1258                }
1259            } else {
1260                unsigned lz = (unsigned)__builtin_clzll(low);;
1261                length = lz >> 3;
1262                escaped = true;
1263            }
1264            if (RAPIDJSON_UNLIKELY(escaped)) {   // some of characters is escaped
1265                if (length != 0) {
1266                    char* q = reinterpret_cast<char*>(os.Push(length));
1267                    for (size_t i = 0; i < length; i++)
1268                        q[i] = p[i];
1269
1270                    p += length;
1271                }
1272                break;
1273            }
1274            vst1q_u8(reinterpret_cast<uint8_t *>(os.Push(16)), s);
1275        }
1276
1277        is.src_ = p;
1278    }
1279
1280    // InsituStringStream -> InsituStringStream
1281    static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
1282        RAPIDJSON_ASSERT(&is == &os);
1283        (void)os;
1284
1285        if (is.src_ == is.dst_) {
1286            SkipUnescapedString(is);
1287            return;
1288        }
1289
1290        char* p = is.src_;
1291        char *q = is.dst_;
1292
1293        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1294        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1295        while (p != nextAligned)
1296            if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1297                is.src_ = p;
1298                is.dst_ = q;
1299                return;
1300            }
1301            else
1302                *q++ = *p++;
1303
1304        // The rest of string using SIMD
1305        const uint8x16_t s0 = vmovq_n_u8('"');
1306        const uint8x16_t s1 = vmovq_n_u8('\\');
1307        const uint8x16_t s2 = vmovq_n_u8('\b');
1308        const uint8x16_t s3 = vmovq_n_u8(32);
1309
1310        for (;; p += 16, q += 16) {
1311            const uint8x16_t s = vld1q_u8(reinterpret_cast<uint8_t *>(p));
1312            uint8x16_t x = vceqq_u8(s, s0);
1313            x = vorrq_u8(x, vceqq_u8(s, s1));
1314            x = vorrq_u8(x, vceqq_u8(s, s2));
1315            x = vorrq_u8(x, vcltq_u8(s, s3));
1316
1317            x = vrev64q_u8(x);                     // Rev in 64
1318            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
1319            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
1320
1321            SizeType length = 0;
1322            bool escaped = false;
1323            if (low == 0) {
1324                if (high != 0) {
1325                    unsigned lz = (unsigned)__builtin_clzll(high);
1326                    length = 8 + (lz >> 3);
1327                    escaped = true;
1328                }
1329            } else {
1330                unsigned lz = (unsigned)__builtin_clzll(low);
1331                length = lz >> 3;
1332                escaped = true;
1333            }
1334            if (RAPIDJSON_UNLIKELY(escaped)) {   // some of characters is escaped
1335                for (const char* pend = p + length; p != pend; ) {
1336                    *q++ = *p++;
1337                }
1338                break;
1339            }
1340            vst1q_u8(reinterpret_cast<uint8_t *>(q), s);
1341        }
1342
1343        is.src_ = p;
1344        is.dst_ = q;
1345    }
1346
1347    // When read/write pointers are the same for insitu stream, just skip unescaped characters
1348    static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
1349        RAPIDJSON_ASSERT(is.src_ == is.dst_);
1350        char* p = is.src_;
1351
1352        // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1353        const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1354        for (; p != nextAligned; p++)
1355            if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1356                is.src_ = is.dst_ = p;
1357                return;
1358            }
1359
1360        // The rest of string using SIMD
1361        const uint8x16_t s0 = vmovq_n_u8('"');
1362        const uint8x16_t s1 = vmovq_n_u8('\\');
1363        const uint8x16_t s2 = vmovq_n_u8('\b');
1364        const uint8x16_t s3 = vmovq_n_u8(32);
1365
1366        for (;; p += 16) {
1367            const uint8x16_t s = vld1q_u8(reinterpret_cast<uint8_t *>(p));
1368            uint8x16_t x = vceqq_u8(s, s0);
1369            x = vorrq_u8(x, vceqq_u8(s, s1));
1370            x = vorrq_u8(x, vceqq_u8(s, s2));
1371            x = vorrq_u8(x, vcltq_u8(s, s3));
1372
1373            x = vrev64q_u8(x);                     // Rev in 64
1374            uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0);   // extract
1375            uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1);  // extract
1376
1377            if (low == 0) {
1378                if (high != 0) {
1379                    int lz = __builtin_clzll(high);
1380                    p += 8 + (lz >> 3);
1381                    break;
1382                }
1383            } else {
1384                int lz = __builtin_clzll(low);
1385                p += lz >> 3;
1386                break;
1387            }
1388        }
1389
1390        is.src_ = is.dst_ = p;
1391    }
1392#endif // RAPIDJSON_NEON
1393
1394    template<typename InputStream, bool backup, bool pushOnTake>
1395    class NumberStream;
1396
1397    template<typename InputStream>
1398    class NumberStream<InputStream, false, false> {
1399    public:
1400        typedef typename InputStream::Ch Ch;
1401
1402        NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader;  }
1403
1404        RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
1405        RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
1406        RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
1407        RAPIDJSON_FORCEINLINE void Push(char) {}
1408
1409        size_t Tell() { return is.Tell(); }
1410        size_t Length() { return 0; }
1411        const char* Pop() { return 0; }
1412
1413    protected:
1414        NumberStream& operator=(const NumberStream&);
1415
1416        InputStream& is;
1417    };
1418
1419    template<typename InputStream>
1420    class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
1421        typedef NumberStream<InputStream, false, false> Base;
1422    public:
1423        NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
1424
1425        RAPIDJSON_FORCEINLINE Ch TakePush() {
1426            stackStream.Put(static_cast<char>(Base::is.Peek()));
1427            return Base::is.Take();
1428        }
1429
1430        RAPIDJSON_FORCEINLINE void Push(char c) {
1431            stackStream.Put(c);
1432        }
1433
1434        size_t Length() { return stackStream.Length(); }
1435
1436        const char* Pop() {
1437            stackStream.Put('\0');
1438            return stackStream.Pop();
1439        }
1440
1441    private:
1442        StackStream<char> stackStream;
1443    };
1444
1445    template<typename InputStream>
1446    class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
1447        typedef NumberStream<InputStream, true, false> Base;
1448    public:
1449        NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
1450
1451        RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
1452    };
1453
1454    template<unsigned parseFlags, typename InputStream, typename Handler>
1455    void ParseNumber(InputStream& is, Handler& handler) {
1456        internal::StreamLocalCopy<InputStream> copy(is);
1457        NumberStream<InputStream,
1458            ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
1459                ((parseFlags & kParseInsituFlag) == 0) :
1460                ((parseFlags & kParseFullPrecisionFlag) != 0),
1461            (parseFlags & kParseNumbersAsStringsFlag) != 0 &&
1462                (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);
1463
1464        size_t startOffset = s.Tell();
1465        double d = 0.0;
1466        bool useNanOrInf = false;
1467
1468        // Parse minus
1469        bool minus = Consume(s, '-');
1470
1471        // Parse int: zero / ( digit1-9 *DIGIT )
1472        unsigned i = 0;
1473        uint64_t i64 = 0;
1474        bool use64bit = false;
1475        int significandDigit = 0;
1476        if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {
1477            i = 0;
1478            s.TakePush();
1479        }
1480        else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {
1481            i = static_cast<unsigned>(s.TakePush() - '0');
1482
1483            if (minus)
1484                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1485                    if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648
1486                        if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {
1487                            i64 = i;
1488                            use64bit = true;
1489                            break;
1490                        }
1491                    }
1492                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1493                    significandDigit++;
1494                }
1495            else
1496                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1497                    if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295
1498                        if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {
1499                            i64 = i;
1500                            use64bit = true;
1501                            break;
1502                        }
1503                    }
1504                    i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1505                    significandDigit++;
1506                }
1507        }
1508        // Parse NaN or Infinity here
1509        else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {
1510            if (Consume(s, 'N')) {
1511                if (Consume(s, 'a') && Consume(s, 'N')) {
1512                    d = std::numeric_limits<double>::quiet_NaN();
1513                    useNanOrInf = true;
1514                }
1515            }
1516            else if (RAPIDJSON_LIKELY(Consume(s, 'I'))) {
1517                if (Consume(s, 'n') && Consume(s, 'f')) {
1518                    d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
1519                    useNanOrInf = true;
1520
1521                    if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
1522                                                                && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) {
1523                        RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1524                    }
1525                }
1526            }
1527
1528            if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
1529                RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1530            }
1531        }
1532        else
1533            RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1534
1535        // Parse 64bit int
1536        bool useDouble = false;
1537        if (use64bit) {
1538            if (minus)
1539                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1540                     if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808
1541                        if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {
1542                            d = static_cast<double>(i64);
1543                            useDouble = true;
1544                            break;
1545                        }
1546                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1547                    significandDigit++;
1548                }
1549            else
1550                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1551                    if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615
1552                        if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {
1553                            d = static_cast<double>(i64);
1554                            useDouble = true;
1555                            break;
1556                        }
1557                    i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1558                    significandDigit++;
1559                }
1560        }
1561
1562        // Force double for big integer
1563        if (useDouble) {
1564            while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1565                d = d * 10 + (s.TakePush() - '0');
1566            }
1567        }
1568
1569        // Parse frac = decimal-point 1*DIGIT
1570        int expFrac = 0;
1571        size_t decimalPosition;
1572        if (Consume(s, '.')) {
1573            decimalPosition = s.Length();
1574
1575            if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
1576                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
1577
1578            if (!useDouble) {
1579#if RAPIDJSON_64BIT
1580                // Use i64 to store significand in 64-bit architecture
1581                if (!use64bit)
1582                    i64 = i;
1583
1584                while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1585                    if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
1586                        break;
1587                    else {
1588                        i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1589                        --expFrac;
1590                        if (i64 != 0)
1591                            significandDigit++;
1592                    }
1593                }
1594
1595                d = static_cast<double>(i64);
1596#else
1597                // Use double to store significand in 32-bit architecture
1598                d = static_cast<double>(use64bit ? i64 : i);
1599#endif
1600                useDouble = true;
1601            }
1602
1603            while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1604                if (significandDigit < 17) {
1605                    d = d * 10.0 + (s.TakePush() - '0');
1606                    --expFrac;
1607                    if (RAPIDJSON_LIKELY(d > 0.0))
1608                        significandDigit++;
1609                }
1610                else
1611                    s.TakePush();
1612            }
1613        }
1614        else
1615            decimalPosition = s.Length(); // decimal position at the end of integer.
1616
1617        // Parse exp = e [ minus / plus ] 1*DIGIT
1618        int exp = 0;
1619        if (Consume(s, 'e') || Consume(s, 'E')) {
1620            if (!useDouble) {
1621                d = static_cast<double>(use64bit ? i64 : i);
1622                useDouble = true;
1623            }
1624
1625            bool expMinus = false;
1626            if (Consume(s, '+'))
1627                ;
1628            else if (Consume(s, '-'))
1629                expMinus = true;
1630
1631            if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1632                exp = static_cast<int>(s.Take() - '0');
1633                if (expMinus) {
1634                    // (exp + expFrac) must not underflow int => we're detecting when -exp gets
1635                    // dangerously close to INT_MIN (a pessimistic next digit 9 would push it into
1636                    // underflow territory):
1637                    //
1638                    //        -(exp * 10 + 9) + expFrac >= INT_MIN
1639                    //   <=>  exp <= (expFrac - INT_MIN - 9) / 10
1640                    RAPIDJSON_ASSERT(expFrac <= 0);
1641                    int maxExp = (expFrac + 2147483639) / 10;
1642
1643                    while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1644                        exp = exp * 10 + static_cast<int>(s.Take() - '0');
1645                        if (RAPIDJSON_UNLIKELY(exp > maxExp)) {
1646                            while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9'))  // Consume the rest of exponent
1647                                s.Take();
1648                        }
1649                    }
1650                }
1651                else {  // positive exp
1652                    int maxExp = 308 - expFrac;
1653                    while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1654                        exp = exp * 10 + static_cast<int>(s.Take() - '0');
1655                        if (RAPIDJSON_UNLIKELY(exp > maxExp))
1656                            RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
1657                    }
1658                }
1659            }
1660            else
1661                RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());
1662
1663            if (expMinus)
1664                exp = -exp;
1665        }
1666
1667        // Finish parsing, call event according to the type of number.
1668        bool cont = true;
1669
1670        if (parseFlags & kParseNumbersAsStringsFlag) {
1671            if (parseFlags & kParseInsituFlag) {
1672                s.Pop();  // Pop stack no matter if it will be used or not.
1673                typename InputStream::Ch* head = is.PutBegin();
1674                const size_t length = s.Tell() - startOffset;
1675                RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
1676                // unable to insert the \0 character here, it will erase the comma after this number
1677                const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
1678                cont = handler.RawNumber(str, SizeType(length), false);
1679            }
1680            else {
1681                SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
1682                StringStream srcStream(s.Pop());
1683                StackStream<typename TargetEncoding::Ch> dstStream(stack_);
1684                while (numCharsToCopy--) {
1685                    Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);
1686                }
1687                dstStream.Put('\0');
1688                const typename TargetEncoding::Ch* str = dstStream.Pop();
1689                const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1;
1690                cont = handler.RawNumber(str, SizeType(length), true);
1691            }
1692        }
1693        else {
1694           size_t length = s.Length();
1695           const char* decimal = s.Pop();  // Pop stack no matter if it will be used or not.
1696
1697           if (useDouble) {
1698               int p = exp + expFrac;
1699               if (parseFlags & kParseFullPrecisionFlag)
1700                   d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
1701               else
1702                   d = internal::StrtodNormalPrecision(d, p);
1703
1704               // Use > max, instead of == inf, to fix bogus warning -Wfloat-equal
1705               if (d > (std::numeric_limits<double>::max)()) {
1706                   // Overflow
1707                   // TODO: internal::StrtodX should report overflow (or underflow)
1708                   RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
1709               }
1710
1711               cont = handler.Double(minus ? -d : d);
1712           }
1713           else if (useNanOrInf) {
1714               cont = handler.Double(d);
1715           }
1716           else {
1717               if (use64bit) {
1718                   if (minus)
1719                       cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
1720                   else
1721                       cont = handler.Uint64(i64);
1722               }
1723               else {
1724                   if (minus)
1725                       cont = handler.Int(static_cast<int32_t>(~<a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1aa42a9a9cb6e2b93d7f825c395af871bf">i</a> + 1));
1726                   else
1727                       cont = handler.Uint(i);
1728               }
1729           }
1730        }
1731        if (RAPIDJSON_UNLIKELY(!cont))
1732            RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset);
1733    }
1734
1735    // Parse any JSON value
1736    template<unsigned parseFlags, typename InputStream, typename Handler>
1737    void ParseValue(InputStream& is, Handler& handler) {
1738        switch (is.Peek()) {
1739            case 'n': ParseNull  <parseFlags>(is, handler); break;
1740            case 't': ParseTrue  <parseFlags>(is, handler); break;
1741            case 'f': ParseFalse <parseFlags>(is, handler); break;
1742            case '"': ParseString<parseFlags>(is, handler); break;
1743            case '{': ParseObject<parseFlags>(is, handler); break;
1744            case '[': ParseArray <parseFlags>(is, handler); break;
1745            default :
1746                      ParseNumber<parseFlags>(is, handler);
1747                      break;
1748
1749        }
1750    }
1751
1752    // Iterative Parsing
1753
1754    // States
1755    enum IterativeParsingState {
1756        IterativeParsingFinishState = 0, // sink states at top
1757        IterativeParsingErrorState,      // sink states at top
1758        IterativeParsingStartState,
1759
1760        // Object states
1761        IterativeParsingObjectInitialState,
1762        IterativeParsingMemberKeyState,
1763        IterativeParsingMemberValueState,
1764        IterativeParsingObjectFinishState,
1765
1766        // Array states
1767        IterativeParsingArrayInitialState,
1768        IterativeParsingElementState,
1769        IterativeParsingArrayFinishState,
1770
1771        // Single value state
1772        IterativeParsingValueState,
1773
1774        // Delimiter states (at bottom)
1775        IterativeParsingElementDelimiterState,
1776        IterativeParsingMemberDelimiterState,
1777        IterativeParsingKeyValueDelimiterState,
1778
1779        cIterativeParsingStateCount
1780    };
1781
1782    // Tokens
1783    enum Token {
1784        LeftBracketToken = 0,
1785        RightBracketToken,
1786
1787        LeftCurlyBracketToken,
1788        RightCurlyBracketToken,
1789
1790        CommaToken,
1791        ColonToken,
1792
1793        StringToken,
1794        FalseToken,
1795        TrueToken,
1796        NullToken,
1797        NumberToken,
1798
1799        kTokenCount
1800    };
1801
1802    RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) const {
1803
1804//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
1805#define N NumberToken
1806#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1807        // Maps from ASCII to Token
1808        static const unsigned char tokenMap[256] = {
1809            N16, // 00~0F
1810            N16, // 10~1F
1811            N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F
1812            N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F
1813            N16, // 40~4F
1814            N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F
1815            N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F
1816            N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F
1817            N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF
1818        };
1819#undef N
1820#undef N16
1821//!@endcond
1822
1823        if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
1824            return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);
1825        else
1826            return NumberToken;
1827    }
1828
1829    RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) const {
1830        // current state x one lookahead token -> new state
1831        static const char G[cIterativeParsingStateCount][kTokenCount] = {
1832            // Finish(sink state)
1833            {
1834                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1835                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1836                IterativeParsingErrorState
1837            },
1838            // Error(sink state)
1839            {
1840                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1841                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1842                IterativeParsingErrorState
1843            },
1844            // Start
1845            {
1846                IterativeParsingArrayInitialState,  // Left bracket
1847                IterativeParsingErrorState,         // Right bracket
1848                IterativeParsingObjectInitialState, // Left curly bracket
1849                IterativeParsingErrorState,         // Right curly bracket
1850                IterativeParsingErrorState,         // Comma
1851                IterativeParsingErrorState,         // Colon
1852                IterativeParsingValueState,         // String
1853                IterativeParsingValueState,         // False
1854                IterativeParsingValueState,         // True
1855                IterativeParsingValueState,         // Null
1856                IterativeParsingValueState          // Number
1857            },
1858            // ObjectInitial
1859            {
1860                IterativeParsingErrorState,         // Left bracket
1861                IterativeParsingErrorState,         // Right bracket
1862                IterativeParsingErrorState,         // Left curly bracket
1863                IterativeParsingObjectFinishState,  // Right curly bracket
1864                IterativeParsingErrorState,         // Comma
1865                IterativeParsingErrorState,         // Colon
1866                IterativeParsingMemberKeyState,     // String
1867                IterativeParsingErrorState,         // False
1868                IterativeParsingErrorState,         // True
1869                IterativeParsingErrorState,         // Null
1870                IterativeParsingErrorState          // Number
1871            },
1872            // MemberKey
1873            {
1874                IterativeParsingErrorState,             // Left bracket
1875                IterativeParsingErrorState,             // Right bracket
1876                IterativeParsingErrorState,             // Left curly bracket
1877                IterativeParsingErrorState,             // Right curly bracket
1878                IterativeParsingErrorState,             // Comma
1879                IterativeParsingKeyValueDelimiterState, // Colon
1880                IterativeParsingErrorState,             // String
1881                IterativeParsingErrorState,             // False
1882                IterativeParsingErrorState,             // True
1883                IterativeParsingErrorState,             // Null
1884                IterativeParsingErrorState              // Number
1885            },
1886            // MemberValue
1887            {
1888                IterativeParsingErrorState,             // Left bracket
1889                IterativeParsingErrorState,             // Right bracket
1890                IterativeParsingErrorState,             // Left curly bracket
1891                IterativeParsingObjectFinishState,      // Right curly bracket
1892                IterativeParsingMemberDelimiterState,   // Comma
1893                IterativeParsingErrorState,             // Colon
1894                IterativeParsingErrorState,             // String
1895                IterativeParsingErrorState,             // False
1896                IterativeParsingErrorState,             // True
1897                IterativeParsingErrorState,             // Null
1898                IterativeParsingErrorState              // Number
1899            },
1900            // ObjectFinish(sink state)
1901            {
1902                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1903                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1904                IterativeParsingErrorState
1905            },
1906            // ArrayInitial
1907            {
1908                IterativeParsingArrayInitialState,      // Left bracket(push Element state)
1909                IterativeParsingArrayFinishState,       // Right bracket
1910                IterativeParsingObjectInitialState,     // Left curly bracket(push Element state)
1911                IterativeParsingErrorState,             // Right curly bracket
1912                IterativeParsingErrorState,             // Comma
1913                IterativeParsingErrorState,             // Colon
1914                IterativeParsingElementState,           // String
1915                IterativeParsingElementState,           // False
1916                IterativeParsingElementState,           // True
1917                IterativeParsingElementState,           // Null
1918                IterativeParsingElementState            // Number
1919            },
1920            // Element
1921            {
1922                IterativeParsingErrorState,             // Left bracket
1923                IterativeParsingArrayFinishState,       // Right bracket
1924                IterativeParsingErrorState,             // Left curly bracket
1925                IterativeParsingErrorState,             // Right curly bracket
1926                IterativeParsingElementDelimiterState,  // Comma
1927                IterativeParsingErrorState,             // Colon
1928                IterativeParsingErrorState,             // String
1929                IterativeParsingErrorState,             // False
1930                IterativeParsingErrorState,             // True
1931                IterativeParsingErrorState,             // Null
1932                IterativeParsingErrorState              // Number
1933            },
1934            // ArrayFinish(sink state)
1935            {
1936                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1937                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1938                IterativeParsingErrorState
1939            },
1940            // Single Value (sink state)
1941            {
1942                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1943                IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1944                IterativeParsingErrorState
1945            },
1946            // ElementDelimiter
1947            {
1948                IterativeParsingArrayInitialState,      // Left bracket(push Element state)
1949                IterativeParsingArrayFinishState,       // Right bracket
1950                IterativeParsingObjectInitialState,     // Left curly bracket(push Element state)
1951                IterativeParsingErrorState,             // Right curly bracket
1952                IterativeParsingErrorState,             // Comma
1953                IterativeParsingErrorState,             // Colon
1954                IterativeParsingElementState,           // String
1955                IterativeParsingElementState,           // False
1956                IterativeParsingElementState,           // True
1957                IterativeParsingElementState,           // Null
1958                IterativeParsingElementState            // Number
1959            },
1960            // MemberDelimiter
1961            {
1962                IterativeParsingErrorState,         // Left bracket
1963                IterativeParsingErrorState,         // Right bracket
1964                IterativeParsingErrorState,         // Left curly bracket
1965                IterativeParsingObjectFinishState,  // Right curly bracket
1966                IterativeParsingErrorState,         // Comma
1967                IterativeParsingErrorState,         // Colon
1968                IterativeParsingMemberKeyState,     // String
1969                IterativeParsingErrorState,         // False
1970                IterativeParsingErrorState,         // True
1971                IterativeParsingErrorState,         // Null
1972                IterativeParsingErrorState          // Number
1973            },
1974            // KeyValueDelimiter
1975            {
1976                IterativeParsingArrayInitialState,      // Left bracket(push MemberValue state)
1977                IterativeParsingErrorState,             // Right bracket
1978                IterativeParsingObjectInitialState,     // Left curly bracket(push MemberValue state)
1979                IterativeParsingErrorState,             // Right curly bracket
1980                IterativeParsingErrorState,             // Comma
1981                IterativeParsingErrorState,             // Colon
1982                IterativeParsingMemberValueState,       // String
1983                IterativeParsingMemberValueState,       // False
1984                IterativeParsingMemberValueState,       // True
1985                IterativeParsingMemberValueState,       // Null
1986                IterativeParsingMemberValueState        // Number
1987            },
1988        }; // End of G
1989
1990        return static_cast<IterativeParsingState>(G[state][token]);
1991    }
1992
1993    // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
1994    // May return a new state on state pop.
1995    template <unsigned parseFlags, typename InputStream, typename Handler>
1996    RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
1997        (void)token;
1998
1999        switch (dst) {
2000        case IterativeParsingErrorState:
2001            return dst;
2002
2003        case IterativeParsingObjectInitialState:
2004        case IterativeParsingArrayInitialState:
2005        {
2006            // Push the state(Element or MemeberValue) if we are nested in another array or value of member.
2007            // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
2008            IterativeParsingState n = src;
2009            if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
2010                n = IterativeParsingElementState;
2011            else if (src == IterativeParsingKeyValueDelimiterState)
2012                n = IterativeParsingMemberValueState;
2013            // Push current state.
2014            *stack_.template Push<SizeType>(1) = n;
2015            // Initialize and push the member/element count.
2016            *stack_.template Push<SizeType>(1) = 0;
2017            // Call handler
2018            bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
2019            // On handler short circuits the parsing.
2020            if (!hr) {
2021                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
2022                return IterativeParsingErrorState;
2023            }
2024            else {
2025                is.Take();
2026                return dst;
2027            }
2028        }
2029
2030        case IterativeParsingMemberKeyState:
2031            ParseString<parseFlags>(is, handler, true);
2032            if (HasParseError())
2033                return IterativeParsingErrorState;
2034            else
2035                return dst;
2036
2037        case IterativeParsingKeyValueDelimiterState:
2038            RAPIDJSON_ASSERT(token == ColonToken);
2039            is.Take();
2040            return dst;
2041
2042        case IterativeParsingMemberValueState:
2043            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
2044            ParseValue<parseFlags>(is, handler);
2045            if (HasParseError()) {
2046                return IterativeParsingErrorState;
2047            }
2048            return dst;
2049
2050        case IterativeParsingElementState:
2051            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
2052            ParseValue<parseFlags>(is, handler);
2053            if (HasParseError()) {
2054                return IterativeParsingErrorState;
2055            }
2056            return dst;
2057
2058        case IterativeParsingMemberDelimiterState:
2059        case IterativeParsingElementDelimiterState:
2060            is.Take();
2061            // Update member/element count.
2062            *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
2063            return dst;
2064
2065        case IterativeParsingObjectFinishState:
2066        {
2067            // Transit from delimiter is only allowed when trailing commas are enabled
2068            if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {
2069                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell());
2070                return IterativeParsingErrorState;
2071            }
2072            // Get member count.
2073            SizeType c = *stack_.template Pop<SizeType>(1);
2074            // If the object is not empty, count the last member.
2075            if (src == IterativeParsingMemberValueState)
2076                ++c;
2077            // Restore the state.
2078            IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
2079            // Transit to Finish state if this is the topmost scope.
2080            if (n == IterativeParsingStartState)
2081                n = IterativeParsingFinishState;
2082            // Call handler
2083            bool hr = handler.EndObject(c);
2084            // On handler short circuits the parsing.
2085            if (!hr) {
2086                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
2087                return IterativeParsingErrorState;
2088            }
2089            else {
2090                is.Take();
2091                return n;
2092            }
2093        }
2094
2095        case IterativeParsingArrayFinishState:
2096        {
2097            // Transit from delimiter is only allowed when trailing commas are enabled
2098            if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {
2099                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell());
2100                return IterativeParsingErrorState;
2101            }
2102            // Get element count.
2103            SizeType c = *stack_.template Pop<SizeType>(1);
2104            // If the array is not empty, count the last element.
2105            if (src == IterativeParsingElementState)
2106                ++c;
2107            // Restore the state.
2108            IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
2109            // Transit to Finish state if this is the topmost scope.
2110            if (n == IterativeParsingStartState)
2111                n = IterativeParsingFinishState;
2112            // Call handler
2113            bool hr = handler.EndArray(c);
2114            // On handler short circuits the parsing.
2115            if (!hr) {
2116                RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
2117                return IterativeParsingErrorState;
2118            }
2119            else {
2120                is.Take();
2121                return n;
2122            }
2123        }
2124
2125        default:
2126            // This branch is for IterativeParsingValueState actually.
2127            // Use `default:` rather than
2128            // `case IterativeParsingValueState:` is for code coverage.
2129
2130            // The IterativeParsingStartState is not enumerated in this switch-case.
2131            // It is impossible for that case. And it can be caught by following assertion.
2132
2133            // The IterativeParsingFinishState is not enumerated in this switch-case either.
2134            // It is a "derivative" state which cannot triggered from Predict() directly.
2135            // Therefore it cannot happen here. And it can be caught by following assertion.
2136            RAPIDJSON_ASSERT(dst == IterativeParsingValueState);
2137
2138            // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
2139            ParseValue<parseFlags>(is, handler);
2140            if (HasParseError()) {
2141                return IterativeParsingErrorState;
2142            }
2143            return IterativeParsingFinishState;
2144        }
2145    }
2146
2147    template <typename InputStream>
2148    void HandleError(IterativeParsingState src, InputStream& is) {
2149        if (HasParseError()) {
2150            // Error flag has been set.
2151            return;
2152        }
2153
2154        switch (src) {
2155        case IterativeParsingStartState:            RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
2156        case IterativeParsingFinishState:           RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
2157        case IterativeParsingObjectInitialState:
2158        case IterativeParsingMemberDelimiterState:  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
2159        case IterativeParsingMemberKeyState:        RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
2160        case IterativeParsingMemberValueState:      RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
2161        case IterativeParsingKeyValueDelimiterState:
2162        case IterativeParsingArrayInitialState:
2163        case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return;
2164        default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
2165        }
2166    }
2167
2168    RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const {
2169        return s >= IterativeParsingElementDelimiterState;
2170    }
2171
2172    RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const {
2173        return s <= IterativeParsingErrorState;
2174    }
2175
2176    template <unsigned parseFlags, typename InputStream, typename Handler>
2177    ParseResult IterativeParse(InputStream& is, Handler& handler) {
2178        parseResult_.Clear();
2179        ClearStackOnExit scope(*this);
2180        IterativeParsingState state = IterativeParsingStartState;
2181
2182        SkipWhitespaceAndComments<parseFlags>(is);
2183        RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
2184        while (is.Peek() != '\0') {
2185            Token t = Tokenize(is.Peek());
2186            IterativeParsingState n = Predict(state, t);
2187            IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
2188
2189            if (d == IterativeParsingErrorState) {
2190                HandleError(state, is);
2191                break;
2192            }
2193
2194            state = d;
2195
2196            // Do not further consume streams if a root JSON has been parsed.
2197            if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
2198                break;
2199
2200            SkipWhitespaceAndComments<parseFlags>(is);
2201            RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
2202        }
2203
2204        // Handle the end of file.
2205        if (state != IterativeParsingFinishState)
2206            HandleError(state, is);
2207
2208        return parseResult_;
2209    }
2210
2211    static const size_t kDefaultStackCapacity = 256;    //!< Default stack capacity in bytes for storing a single decoded string.
2212    internal::Stack<StackAllocator> stack_;  //!< A stack for storing decoded string temporarily during non-destructive parsing.
2213    ParseResult parseResult_;
2214    IterativeParsingState state_;
2215}; // class GenericReader
2216
2217//! Reader with UTF8 encoding and default allocator.
2218typedef GenericReader<UTF8<>, UTF8<> > Reader;
2219
2220RAPIDJSON_NAMESPACE_END
2221
2222#if defined(__clang__) || defined(_MSC_VER)
2223RAPIDJSON_DIAG_POP
2224#endif
2225
2226
2227#ifdef __GNUC__
2228RAPIDJSON_DIAG_POP
2229#endif
2230
2231#endif // RAPIDJSON_READER_H_
2232