DeepCover Embedded Security in IoT: Public-key Secured Data Paths
Dependencies: MaximInterface
reader.h
00001 // Tencent is pleased to support the open source community by making RapidJSON available. 00002 // 00003 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 00004 // 00005 // Licensed under the MIT License (the "License"); you may not use this file except 00006 // in compliance with the License. You may obtain a copy of the License at 00007 // 00008 // http://opensource.org/licenses/MIT 00009 // 00010 // Unless required by applicable law or agreed to in writing, software distributed 00011 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00012 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 00013 // specific language governing permissions and limitations under the License. 00014 00015 #ifndef RAPIDJSON_READER_H_ 00016 #define RAPIDJSON_READER_H_ 00017 00018 /*! \file reader.h */ 00019 00020 #include "allocators.h" 00021 #include "stream.h" 00022 #include "encodedstream.h" 00023 #include "internal/meta.h" 00024 #include "internal/stack.h" 00025 #include "internal/strtod.h" 00026 #include <limits> 00027 00028 #if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) 00029 #include <intrin.h> 00030 #pragma intrinsic(_BitScanForward) 00031 #endif 00032 #ifdef RAPIDJSON_SSE42 00033 #include <nmmintrin.h> 00034 #elif defined(RAPIDJSON_SSE2) 00035 #include <emmintrin.h> 00036 #endif 00037 00038 #ifdef _MSC_VER 00039 RAPIDJSON_DIAG_PUSH 00040 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant 00041 RAPIDJSON_DIAG_OFF(4702) // unreachable code 00042 #endif 00043 00044 #ifdef __clang__ 00045 RAPIDJSON_DIAG_PUSH 00046 RAPIDJSON_DIAG_OFF(old-style-cast) 00047 RAPIDJSON_DIAG_OFF(padded) 00048 RAPIDJSON_DIAG_OFF(switch-enum) 00049 #endif 00050 00051 #ifdef __GNUC__ 00052 RAPIDJSON_DIAG_PUSH 00053 RAPIDJSON_DIAG_OFF(effc++) 00054 #endif 00055 00056 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 00057 #define RAPIDJSON_NOTHING /* deliberately empty */ 00058 #ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN 00059 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \ 00060 RAPIDJSON_MULTILINEMACRO_BEGIN \ 00061 if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \ 00062 RAPIDJSON_MULTILINEMACRO_END 00063 #endif 00064 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \ 00065 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING) 00066 //!@endcond 00067 00068 /*! \def RAPIDJSON_PARSE_ERROR_NORETURN 00069 \ingroup RAPIDJSON_ERRORS 00070 \brief Macro to indicate a parse error. 00071 \param parseErrorCode \ref rapidjson::ParseErrorCode of the error 00072 \param offset position of the error in JSON input (\c size_t) 00073 00074 This macros can be used as a customization point for the internal 00075 error handling mechanism of RapidJSON. 00076 00077 A common usage model is to throw an exception instead of requiring the 00078 caller to explicitly check the \ref rapidjson::GenericReader::Parse's 00079 return value: 00080 00081 \code 00082 #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \ 00083 throw ParseException(parseErrorCode, #parseErrorCode, offset) 00084 00085 #include <stdexcept> // std::runtime_error 00086 #include "rapidjson/error/error.h" // rapidjson::ParseResult 00087 00088 struct ParseException : std::runtime_error, rapidjson::ParseResult { 00089 ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset) 00090 : std::runtime_error(msg), ParseResult(code, offset) {} 00091 }; 00092 00093 #include "rapidjson/reader.h" 00094 \endcode 00095 00096 \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse 00097 */ 00098 #ifndef RAPIDJSON_PARSE_ERROR_NORETURN 00099 #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \ 00100 RAPIDJSON_MULTILINEMACRO_BEGIN \ 00101 RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \ 00102 SetParseError(parseErrorCode, offset); \ 00103 RAPIDJSON_MULTILINEMACRO_END 00104 #endif 00105 00106 /*! \def RAPIDJSON_PARSE_ERROR 00107 \ingroup RAPIDJSON_ERRORS 00108 \brief (Internal) macro to indicate and handle a parse error. 00109 \param parseErrorCode \ref rapidjson::ParseErrorCode of the error 00110 \param offset position of the error in JSON input (\c size_t) 00111 00112 Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing. 00113 00114 \see RAPIDJSON_PARSE_ERROR_NORETURN 00115 \hideinitializer 00116 */ 00117 #ifndef RAPIDJSON_PARSE_ERROR 00118 #define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \ 00119 RAPIDJSON_MULTILINEMACRO_BEGIN \ 00120 RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \ 00121 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \ 00122 RAPIDJSON_MULTILINEMACRO_END 00123 #endif 00124 00125 #include "error/error.h " // ParseErrorCode, ParseResult 00126 00127 RAPIDJSON_NAMESPACE_BEGIN 00128 00129 /////////////////////////////////////////////////////////////////////////////// 00130 // ParseFlag 00131 00132 /*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS 00133 \ingroup RAPIDJSON_CONFIG 00134 \brief User-defined kParseDefaultFlags definition. 00135 00136 User can define this as any \c ParseFlag combinations. 00137 */ 00138 #ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS 00139 #define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags 00140 #endif 00141 00142 //! Combination of parseFlags 00143 /*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream 00144 */ 00145 enum ParseFlag { 00146 kParseNoFlags = 0, //!< No flags are set. 00147 kParseInsituFlag = 1, //!< In-situ(destructive) parsing. 00148 kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings. 00149 kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing. 00150 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. 00151 kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower). 00152 kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments. 00153 kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings. 00154 kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays. 00155 kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles. 00156 kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS 00157 }; 00158 00159 /////////////////////////////////////////////////////////////////////////////// 00160 // Handler 00161 00162 /*! \class rapidjson::Handler 00163 \brief Concept for receiving events from GenericReader upon parsing. 00164 The functions return true if no error occurs. If they return false, 00165 the event publisher should terminate the process. 00166 \code 00167 concept Handler { 00168 typename Ch; 00169 00170 bool Null(); 00171 bool Bool(bool b); 00172 bool Int(int i); 00173 bool Uint(unsigned i); 00174 bool Int64(int64_t i); 00175 bool Uint64(uint64_t i); 00176 bool Double(double d); 00177 /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) 00178 bool RawNumber(const Ch* str, SizeType length, bool copy); 00179 bool String(const Ch* str, SizeType length, bool copy); 00180 bool StartObject(); 00181 bool Key(const Ch* str, SizeType length, bool copy); 00182 bool EndObject(SizeType memberCount); 00183 bool StartArray(); 00184 bool EndArray(SizeType elementCount); 00185 }; 00186 \endcode 00187 */ 00188 /////////////////////////////////////////////////////////////////////////////// 00189 // BaseReaderHandler 00190 00191 //! Default implementation of Handler. 00192 /*! This can be used as base class of any reader handler. 00193 \note implements Handler concept 00194 */ 00195 template<typename Encoding = UTF8<>, typename Derived = void> 00196 struct BaseReaderHandler { 00197 typedef typename Encoding::Ch Ch; 00198 00199 typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override; 00200 00201 bool Default() { return true; } 00202 bool Null() { return static_cast<Override&>(*this).Default(); } 00203 bool Bool(bool) { return static_cast<Override&>(*this).Default(); } 00204 bool Int(int) { return static_cast<Override&>(*this).Default(); } 00205 bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); } 00206 bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); } 00207 bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); } 00208 bool Double(double) { return static_cast<Override&>(*this).Default(); } 00209 /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) 00210 bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); } 00211 bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); } 00212 bool StartObject() { return static_cast<Override&>(*this).Default(); } 00213 bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); } 00214 bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); } 00215 bool StartArray() { return static_cast<Override&>(*this).Default(); } 00216 bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); } 00217 }; 00218 00219 /////////////////////////////////////////////////////////////////////////////// 00220 // StreamLocalCopy 00221 00222 namespace internal { 00223 00224 template<typename Stream, int = StreamTraits<Stream>::copyOptimization> 00225 class StreamLocalCopy; 00226 00227 //! Do copy optimization. 00228 template<typename Stream> 00229 class StreamLocalCopy<Stream, 1> { 00230 public: 00231 StreamLocalCopy(Stream& original) : s(original), original_(original) {} 00232 ~StreamLocalCopy() { original_ = s; } 00233 00234 Stream s; 00235 00236 private: 00237 StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; 00238 00239 Stream& original_; 00240 }; 00241 00242 //! Keep reference. 00243 template<typename Stream> 00244 class StreamLocalCopy<Stream, 0> { 00245 public: 00246 StreamLocalCopy(Stream& original) : s(original) {} 00247 00248 Stream& s; 00249 00250 private: 00251 StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */; 00252 }; 00253 00254 } // namespace internal 00255 00256 /////////////////////////////////////////////////////////////////////////////// 00257 // SkipWhitespace 00258 00259 //! Skip the JSON white spaces in a stream. 00260 /*! \param is A input stream for skipping white spaces. 00261 \note This function has SSE2/SSE4.2 specialization. 00262 */ 00263 template<typename InputStream> 00264 void SkipWhitespace(InputStream& is) { 00265 internal::StreamLocalCopy<InputStream> copy(is); 00266 InputStream& s(copy.s); 00267 00268 typename InputStream::Ch c; 00269 while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t') 00270 s.Take(); 00271 } 00272 00273 inline const char* SkipWhitespace(const char* p, const char* end) { 00274 while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) 00275 ++p; 00276 return p; 00277 } 00278 00279 #ifdef RAPIDJSON_SSE42 00280 //! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once. 00281 inline const char *SkipWhitespace_SIMD(const char* p) { 00282 // Fast return for single non-whitespace 00283 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') 00284 ++p; 00285 else 00286 return p; 00287 00288 // 16-byte align to the next boundary 00289 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); 00290 while (p != nextAligned) 00291 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') 00292 ++p; 00293 else 00294 return p; 00295 00296 // The rest of string using SIMD 00297 static const char whitespace[16] = " \n\r\t"; 00298 const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0])); 00299 00300 for (;; p += 16) { 00301 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); 00302 const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); 00303 if (r != 0) { // some of characters is non-whitespace 00304 #ifdef _MSC_VER // Find the index of first non-whitespace 00305 unsigned long offset; 00306 _BitScanForward(&offset, r); 00307 return p + offset; 00308 #else 00309 return p + __builtin_ffs(r) - 1; 00310 #endif 00311 } 00312 } 00313 } 00314 00315 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { 00316 // Fast return for single non-whitespace 00317 if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) 00318 ++p; 00319 else 00320 return p; 00321 00322 // The middle of string using SIMD 00323 static const char whitespace[16] = " \n\r\t"; 00324 const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0])); 00325 00326 for (; p <= end - 16; p += 16) { 00327 const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p)); 00328 const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY)); 00329 if (r != 0) { // some of characters is non-whitespace 00330 #ifdef _MSC_VER // Find the index of first non-whitespace 00331 unsigned long offset; 00332 _BitScanForward(&offset, r); 00333 return p + offset; 00334 #else 00335 return p + __builtin_ffs(r) - 1; 00336 #endif 00337 } 00338 } 00339 00340 return SkipWhitespace(p, end); 00341 } 00342 00343 #elif defined(RAPIDJSON_SSE2) 00344 00345 //! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once. 00346 inline const char *SkipWhitespace_SIMD(const char* p) { 00347 // Fast return for single non-whitespace 00348 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') 00349 ++p; 00350 else 00351 return p; 00352 00353 // 16-byte align to the next boundary 00354 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); 00355 while (p != nextAligned) 00356 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') 00357 ++p; 00358 else 00359 return p; 00360 00361 // The rest of string 00362 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } 00363 static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; 00364 #undef C16 00365 00366 const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0])); 00367 const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0])); 00368 const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0])); 00369 const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0])); 00370 00371 for (;; p += 16) { 00372 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); 00373 __m128i x = _mm_cmpeq_epi8(s, w0); 00374 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); 00375 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); 00376 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); 00377 unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x)); 00378 if (r != 0) { // some of characters may be non-whitespace 00379 #ifdef _MSC_VER // Find the index of first non-whitespace 00380 unsigned long offset; 00381 _BitScanForward(&offset, r); 00382 return p + offset; 00383 #else 00384 return p + __builtin_ffs(r) - 1; 00385 #endif 00386 } 00387 } 00388 } 00389 00390 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { 00391 // Fast return for single non-whitespace 00392 if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) 00393 ++p; 00394 else 00395 return p; 00396 00397 // The rest of string 00398 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c } 00399 static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') }; 00400 #undef C16 00401 00402 const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0])); 00403 const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0])); 00404 const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0])); 00405 const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0])); 00406 00407 for (; p <= end - 16; p += 16) { 00408 const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p)); 00409 __m128i x = _mm_cmpeq_epi8(s, w0); 00410 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1)); 00411 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2)); 00412 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3)); 00413 unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x)); 00414 if (r != 0) { // some of characters may be non-whitespace 00415 #ifdef _MSC_VER // Find the index of first non-whitespace 00416 unsigned long offset; 00417 _BitScanForward(&offset, r); 00418 return p + offset; 00419 #else 00420 return p + __builtin_ffs(r) - 1; 00421 #endif 00422 } 00423 } 00424 00425 return SkipWhitespace(p, end); 00426 } 00427 00428 #endif // RAPIDJSON_SSE2 00429 00430 #ifdef RAPIDJSON_SIMD 00431 //! Template function specialization for InsituStringStream 00432 template<> inline void SkipWhitespace(InsituStringStream& is) { 00433 is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_)); 00434 } 00435 00436 //! Template function specialization for StringStream 00437 template<> inline void SkipWhitespace(StringStream& is) { 00438 is.src_ = SkipWhitespace_SIMD(is.src_); 00439 } 00440 00441 template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) { 00442 is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_); 00443 } 00444 #endif // RAPIDJSON_SIMD 00445 00446 /////////////////////////////////////////////////////////////////////////////// 00447 // GenericReader 00448 00449 //! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator. 00450 /*! GenericReader parses JSON text from a stream, and send events synchronously to an 00451 object implementing Handler concept. 00452 00453 It needs to allocate a stack for storing a single decoded string during 00454 non-destructive parsing. 00455 00456 For in-situ parsing, the decoded string is directly written to the source 00457 text string, no temporary buffer is required. 00458 00459 A GenericReader object can be reused for parsing multiple JSON text. 00460 00461 \tparam SourceEncoding Encoding of the input stream. 00462 \tparam TargetEncoding Encoding of the parse output. 00463 \tparam StackAllocator Allocator type for stack. 00464 */ 00465 template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator> 00466 class GenericReader { 00467 public: 00468 typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type 00469 00470 //! Constructor. 00471 /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing) 00472 \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing) 00473 */ 00474 GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {} 00475 00476 //! Parse JSON text. 00477 /*! \tparam parseFlags Combination of \ref ParseFlag. 00478 \tparam InputStream Type of input stream, implementing Stream concept. 00479 \tparam Handler Type of handler, implementing Handler concept. 00480 \param is Input stream to be parsed. 00481 \param handler The handler to receive events. 00482 \return Whether the parsing is successful. 00483 */ 00484 template <unsigned parseFlags, typename InputStream, typename Handler> 00485 ParseResult Parse(InputStream& is, Handler& handler) { 00486 if (parseFlags & kParseIterativeFlag) 00487 return IterativeParse<parseFlags>(is, handler); 00488 00489 parseResult_.Clear(); 00490 00491 ClearStackOnExit scope(*this); 00492 00493 SkipWhitespaceAndComments<parseFlags>(is); 00494 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); 00495 00496 if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) { 00497 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell()); 00498 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); 00499 } 00500 else { 00501 ParseValue<parseFlags>(is, handler); 00502 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); 00503 00504 if (!(parseFlags & kParseStopWhenDoneFlag)) { 00505 SkipWhitespaceAndComments<parseFlags>(is); 00506 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); 00507 00508 if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) { 00509 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell()); 00510 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); 00511 } 00512 } 00513 } 00514 00515 return parseResult_; 00516 } 00517 00518 //! Parse JSON text (with \ref kParseDefaultFlags) 00519 /*! \tparam InputStream Type of input stream, implementing Stream concept 00520 \tparam Handler Type of handler, implementing Handler concept. 00521 \param is Input stream to be parsed. 00522 \param handler The handler to receive events. 00523 \return Whether the parsing is successful. 00524 */ 00525 template <typename InputStream, typename Handler> 00526 ParseResult Parse(InputStream& is, Handler& handler) { 00527 return Parse<kParseDefaultFlags>(is, handler); 00528 } 00529 00530 //! Whether a parse error has occured in the last parsing. 00531 bool HasParseError() const { return parseResult_.IsError(); } 00532 00533 //! Get the \ref ParseErrorCode of last parsing. 00534 ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); } 00535 00536 //! Get the position of last parsing error in input, 0 otherwise. 00537 size_t GetErrorOffset() const { return parseResult_.Offset(); } 00538 00539 protected: 00540 void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); } 00541 00542 private: 00543 // Prohibit copy constructor & assignment operator. 00544 GenericReader(const GenericReader&); 00545 GenericReader& operator=(const GenericReader&); 00546 00547 void ClearStack() { stack_.Clear(); } 00548 00549 // clear stack on any exit from ParseStream, e.g. due to exception 00550 struct ClearStackOnExit { 00551 explicit ClearStackOnExit(GenericReader& r) : r_(r) {} 00552 ~ClearStackOnExit() { r_.ClearStack(); } 00553 private: 00554 GenericReader& r_; 00555 ClearStackOnExit(const ClearStackOnExit&); 00556 ClearStackOnExit& operator=(const ClearStackOnExit&); 00557 }; 00558 00559 template<unsigned parseFlags, typename InputStream> 00560 void SkipWhitespaceAndComments(InputStream& is) { 00561 SkipWhitespace(is); 00562 00563 if (parseFlags & kParseCommentsFlag) { 00564 while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) { 00565 if (Consume(is, '*')) { 00566 while (true) { 00567 if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) 00568 RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); 00569 else if (Consume(is, '*')) { 00570 if (Consume(is, '/')) 00571 break; 00572 } 00573 else 00574 is.Take(); 00575 } 00576 } 00577 else if (RAPIDJSON_LIKELY(Consume(is, '/'))) 00578 while (is.Peek() != '\0' && is.Take() != '\n') {} 00579 else 00580 RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); 00581 00582 SkipWhitespace(is); 00583 } 00584 } 00585 } 00586 00587 // Parse object: { string : value, ... } 00588 template<unsigned parseFlags, typename InputStream, typename Handler> 00589 void ParseObject(InputStream& is, Handler& handler) { 00590 RAPIDJSON_ASSERT(is.Peek() == '{'); 00591 is.Take(); // Skip '{' 00592 00593 if (RAPIDJSON_UNLIKELY(!handler.StartObject())) 00594 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); 00595 00596 SkipWhitespaceAndComments<parseFlags>(is); 00597 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00598 00599 if (Consume(is, '}')) { 00600 if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object 00601 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); 00602 return; 00603 } 00604 00605 for (SizeType memberCount = 0;;) { 00606 if (RAPIDJSON_UNLIKELY(is.Peek() != '"')) 00607 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); 00608 00609 ParseString<parseFlags>(is, handler, true); 00610 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00611 00612 SkipWhitespaceAndComments<parseFlags>(is); 00613 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00614 00615 if (RAPIDJSON_UNLIKELY(!Consume(is, ':'))) 00616 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); 00617 00618 SkipWhitespaceAndComments<parseFlags>(is); 00619 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00620 00621 ParseValue<parseFlags>(is, handler); 00622 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00623 00624 SkipWhitespaceAndComments<parseFlags>(is); 00625 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00626 00627 ++memberCount; 00628 00629 switch (is.Peek()) { 00630 case ',': 00631 is.Take(); 00632 SkipWhitespaceAndComments<parseFlags>(is); 00633 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00634 break; 00635 case '}': 00636 is.Take(); 00637 if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) 00638 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); 00639 return; 00640 default: 00641 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy 00642 } 00643 00644 if (parseFlags & kParseTrailingCommasFlag) { 00645 if (is.Peek() == '}') { 00646 if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount))) 00647 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); 00648 is.Take(); 00649 return; 00650 } 00651 } 00652 } 00653 } 00654 00655 // Parse array: [ value, ... ] 00656 template<unsigned parseFlags, typename InputStream, typename Handler> 00657 void ParseArray(InputStream& is, Handler& handler) { 00658 RAPIDJSON_ASSERT(is.Peek() == '['); 00659 is.Take(); // Skip '[' 00660 00661 if (RAPIDJSON_UNLIKELY(!handler.StartArray())) 00662 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); 00663 00664 SkipWhitespaceAndComments<parseFlags>(is); 00665 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00666 00667 if (Consume(is, ']')) { 00668 if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array 00669 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); 00670 return; 00671 } 00672 00673 for (SizeType elementCount = 0;;) { 00674 ParseValue<parseFlags>(is, handler); 00675 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00676 00677 ++elementCount; 00678 SkipWhitespaceAndComments<parseFlags>(is); 00679 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00680 00681 if (Consume(is, ',')) { 00682 SkipWhitespaceAndComments<parseFlags>(is); 00683 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00684 } 00685 else if (Consume(is, ']')) { 00686 if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) 00687 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); 00688 return; 00689 } 00690 else 00691 RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); 00692 00693 if (parseFlags & kParseTrailingCommasFlag) { 00694 if (is.Peek() == ']') { 00695 if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount))) 00696 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); 00697 is.Take(); 00698 return; 00699 } 00700 } 00701 } 00702 } 00703 00704 template<unsigned parseFlags, typename InputStream, typename Handler> 00705 void ParseNull(InputStream& is, Handler& handler) { 00706 RAPIDJSON_ASSERT(is.Peek() == 'n'); 00707 is.Take(); 00708 00709 if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) { 00710 if (RAPIDJSON_UNLIKELY(!handler.Null())) 00711 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); 00712 } 00713 else 00714 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); 00715 } 00716 00717 template<unsigned parseFlags, typename InputStream, typename Handler> 00718 void ParseTrue(InputStream& is, Handler& handler) { 00719 RAPIDJSON_ASSERT(is.Peek() == 't'); 00720 is.Take(); 00721 00722 if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) { 00723 if (RAPIDJSON_UNLIKELY(!handler.Bool(true))) 00724 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); 00725 } 00726 else 00727 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); 00728 } 00729 00730 template<unsigned parseFlags, typename InputStream, typename Handler> 00731 void ParseFalse(InputStream& is, Handler& handler) { 00732 RAPIDJSON_ASSERT(is.Peek() == 'f'); 00733 is.Take(); 00734 00735 if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) { 00736 if (RAPIDJSON_UNLIKELY(!handler.Bool(false))) 00737 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); 00738 } 00739 else 00740 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); 00741 } 00742 00743 template<typename InputStream> 00744 RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) { 00745 if (RAPIDJSON_LIKELY(is.Peek() == expect)) { 00746 is.Take(); 00747 return true; 00748 } 00749 else 00750 return false; 00751 } 00752 00753 // Helper function to parse four hexidecimal digits in \uXXXX in ParseString(). 00754 template<typename InputStream> 00755 unsigned ParseHex4(InputStream& is, size_t escapeOffset) { 00756 unsigned codepoint = 0; 00757 for (int i = 0; i < 4; i++) { 00758 Ch c = is.Peek(); 00759 codepoint <<= 4; 00760 codepoint += static_cast<unsigned>(c); 00761 if (c >= '0' && c <= '9') 00762 codepoint -= '0'; 00763 else if (c >= 'A' && c <= 'F') 00764 codepoint -= 'A' - 10; 00765 else if (c >= 'a' && c <= 'f') 00766 codepoint -= 'a' - 10; 00767 else { 00768 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset); 00769 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0); 00770 } 00771 is.Take(); 00772 } 00773 return codepoint; 00774 } 00775 00776 template <typename CharType> 00777 class StackStream { 00778 public: 00779 typedef CharType Ch; 00780 00781 StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {} 00782 RAPIDJSON_FORCEINLINE void Put(Ch c) { 00783 *stack_.template Push<Ch>() = c; 00784 ++length_; 00785 } 00786 00787 RAPIDJSON_FORCEINLINE void* Push(SizeType count) { 00788 length_ += count; 00789 return stack_.template Push<Ch>(count); 00790 } 00791 00792 size_t Length() const { return length_; } 00793 00794 Ch* Pop() { 00795 return stack_.template Pop<Ch>(length_); 00796 } 00797 00798 private: 00799 StackStream(const StackStream&); 00800 StackStream& operator=(const StackStream&); 00801 00802 internal::Stack<StackAllocator>& stack_; 00803 SizeType length_; 00804 }; 00805 00806 // Parse string and generate String event. Different code paths for kParseInsituFlag. 00807 template<unsigned parseFlags, typename InputStream, typename Handler> 00808 void ParseString(InputStream& is, Handler& handler, bool isKey = false) { 00809 internal::StreamLocalCopy<InputStream> copy(is); 00810 InputStream& s(copy.s); 00811 00812 RAPIDJSON_ASSERT(s.Peek() == '\"'); 00813 s.Take(); // Skip '\"' 00814 00815 bool success = false; 00816 if (parseFlags & kParseInsituFlag) { 00817 typename InputStream::Ch *head = s.PutBegin(); 00818 ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s); 00819 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00820 size_t length = s.PutEnd(head) - 1; 00821 RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); 00822 const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head); 00823 success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false)); 00824 } 00825 else { 00826 StackStream<typename TargetEncoding::Ch> stackStream(stack_); 00827 ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream); 00828 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00829 SizeType length = static_cast<SizeType>(stackStream.Length()) - 1; 00830 const typename TargetEncoding::Ch* const str = stackStream.Pop(); 00831 success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true)); 00832 } 00833 if (RAPIDJSON_UNLIKELY(!success)) 00834 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); 00835 } 00836 00837 // Parse string to an output is 00838 // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation. 00839 template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream> 00840 RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) { 00841 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 00842 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 00843 static const char escape[256] = { 00844 Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/', 00845 Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, 00846 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0, 00847 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00848 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 00849 }; 00850 #undef Z16 00851 //!@endcond 00852 00853 for (;;) { 00854 // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation. 00855 if (!(parseFlags & kParseValidateEncodingFlag)) 00856 ScanCopyUnescapedString(is, os); 00857 00858 Ch c = is.Peek(); 00859 if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape 00860 size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset 00861 is.Take(); 00862 Ch e = is.Peek(); 00863 if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) { 00864 is.Take(); 00865 os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)])); 00866 } 00867 else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode 00868 is.Take(); 00869 unsigned codepoint = ParseHex4(is, escapeOffset); 00870 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00871 if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) { 00872 // Handle UTF-16 surrogate pair 00873 if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u'))) 00874 RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); 00875 unsigned codepoint2 = ParseHex4(is, escapeOffset); 00876 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; 00877 if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)) 00878 RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset); 00879 codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000; 00880 } 00881 TEncoding::Encode(os, codepoint); 00882 } 00883 else 00884 RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset); 00885 } 00886 else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote 00887 is.Take(); 00888 os.Put('\0'); // null-terminate the string 00889 return; 00890 } 00891 else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF 00892 if (c == '\0') 00893 RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell()); 00894 else 00895 RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell()); 00896 } 00897 else { 00898 size_t offset = is.Tell(); 00899 if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ? 00900 !Transcoder<SEncoding, TEncoding>::Validate(is, os) : 00901 !Transcoder<SEncoding, TEncoding>::Transcode(is, os)))) 00902 RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset); 00903 } 00904 } 00905 } 00906 00907 template<typename InputStream, typename OutputStream> 00908 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) { 00909 // Do nothing for generic version 00910 } 00911 00912 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) 00913 // StringStream -> StackStream<char> 00914 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) { 00915 const char* p = is.src_; 00916 00917 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) 00918 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); 00919 while (p != nextAligned) 00920 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) { 00921 is.src_ = p; 00922 return; 00923 } 00924 else 00925 os.Put(*p++); 00926 00927 // The rest of string using SIMD 00928 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; 00929 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; 00930 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; 00931 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0])); 00932 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0])); 00933 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0])); 00934 00935 for (;; p += 16) { 00936 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); 00937 const __m128i t1 = _mm_cmpeq_epi8(s, dq); 00938 const __m128i t2 = _mm_cmpeq_epi8(s, bs); 00939 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 00940 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); 00941 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x)); 00942 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped 00943 SizeType length; 00944 #ifdef _MSC_VER // Find the index of first escaped 00945 unsigned long offset; 00946 _BitScanForward(&offset, r); 00947 length = offset; 00948 #else 00949 length = static_cast<SizeType>(__builtin_ffs(r) - 1); 00950 #endif 00951 char* q = reinterpret_cast<char*>(os.Push(length)); 00952 for (size_t i = 0; i < length; i++) 00953 q[i] = p[i]; 00954 00955 p += length; 00956 break; 00957 } 00958 _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s); 00959 } 00960 00961 is.src_ = p; 00962 } 00963 00964 // InsituStringStream -> InsituStringStream 00965 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) { 00966 RAPIDJSON_ASSERT(&is == &os); 00967 (void)os; 00968 00969 if (is.src_ == is.dst_) { 00970 SkipUnescapedString(is); 00971 return; 00972 } 00973 00974 char* p = is.src_; 00975 char *q = is.dst_; 00976 00977 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) 00978 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); 00979 while (p != nextAligned) 00980 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) { 00981 is.src_ = p; 00982 is.dst_ = q; 00983 return; 00984 } 00985 else 00986 *q++ = *p++; 00987 00988 // The rest of string using SIMD 00989 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; 00990 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; 00991 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; 00992 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0])); 00993 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0])); 00994 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0])); 00995 00996 for (;; p += 16, q += 16) { 00997 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); 00998 const __m128i t1 = _mm_cmpeq_epi8(s, dq); 00999 const __m128i t2 = _mm_cmpeq_epi8(s, bs); 01000 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 01001 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); 01002 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x)); 01003 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped 01004 size_t length; 01005 #ifdef _MSC_VER // Find the index of first escaped 01006 unsigned long offset; 01007 _BitScanForward(&offset, r); 01008 length = offset; 01009 #else 01010 length = static_cast<size_t>(__builtin_ffs(r) - 1); 01011 #endif 01012 for (const char* pend = p + length; p != pend; ) 01013 *q++ = *p++; 01014 break; 01015 } 01016 _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s); 01017 } 01018 01019 is.src_ = p; 01020 is.dst_ = q; 01021 } 01022 01023 // When read/write pointers are the same for insitu stream, just skip unescaped characters 01024 static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) { 01025 RAPIDJSON_ASSERT(is.src_ == is.dst_); 01026 char* p = is.src_; 01027 01028 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash) 01029 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15)); 01030 for (; p != nextAligned; p++) 01031 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) { 01032 is.src_ = is.dst_ = p; 01033 return; 01034 } 01035 01036 // The rest of string using SIMD 01037 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' }; 01038 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }; 01039 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 }; 01040 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0])); 01041 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0])); 01042 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0])); 01043 01044 for (;; p += 16) { 01045 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p)); 01046 const __m128i t1 = _mm_cmpeq_epi8(s, dq); 01047 const __m128i t2 = _mm_cmpeq_epi8(s, bs); 01048 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19 01049 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3); 01050 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x)); 01051 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped 01052 size_t length; 01053 #ifdef _MSC_VER // Find the index of first escaped 01054 unsigned long offset; 01055 _BitScanForward(&offset, r); 01056 length = offset; 01057 #else 01058 length = static_cast<size_t>(__builtin_ffs(r) - 1); 01059 #endif 01060 p += length; 01061 break; 01062 } 01063 } 01064 01065 is.src_ = is.dst_ = p; 01066 } 01067 #endif 01068 01069 template<typename InputStream, bool backup, bool pushOnTake> 01070 class NumberStream; 01071 01072 template<typename InputStream> 01073 class NumberStream<InputStream, false, false> { 01074 public: 01075 typedef typename InputStream::Ch Ch; 01076 01077 NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; } 01078 ~NumberStream() {} 01079 01080 RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); } 01081 RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); } 01082 RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); } 01083 RAPIDJSON_FORCEINLINE void Push(char) {} 01084 01085 size_t Tell() { return is.Tell(); } 01086 size_t Length() { return 0; } 01087 const char* Pop() { return 0; } 01088 01089 protected: 01090 NumberStream& operator=(const NumberStream&); 01091 01092 InputStream& is; 01093 }; 01094 01095 template<typename InputStream> 01096 class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> { 01097 typedef NumberStream<InputStream, false, false> Base; 01098 public: 01099 NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {} 01100 ~NumberStream() {} 01101 01102 RAPIDJSON_FORCEINLINE Ch TakePush() { 01103 stackStream.Put(static_cast<char>(Base::is.Peek())); 01104 return Base::is.Take(); 01105 } 01106 01107 RAPIDJSON_FORCEINLINE void Push(char c) { 01108 stackStream.Put(c); 01109 } 01110 01111 size_t Length() { return stackStream.Length(); } 01112 01113 const char* Pop() { 01114 stackStream.Put('\0'); 01115 return stackStream.Pop(); 01116 } 01117 01118 private: 01119 StackStream<char> stackStream; 01120 }; 01121 01122 template<typename InputStream> 01123 class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> { 01124 typedef NumberStream<InputStream, true, false> Base; 01125 public: 01126 NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {} 01127 ~NumberStream() {} 01128 01129 RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); } 01130 }; 01131 01132 template<unsigned parseFlags, typename InputStream, typename Handler> 01133 void ParseNumber(InputStream& is, Handler& handler) { 01134 internal::StreamLocalCopy<InputStream> copy(is); 01135 NumberStream<InputStream, 01136 ((parseFlags & kParseNumbersAsStringsFlag) != 0) ? 01137 ((parseFlags & kParseInsituFlag) == 0) : 01138 ((parseFlags & kParseFullPrecisionFlag) != 0), 01139 (parseFlags & kParseNumbersAsStringsFlag) != 0 && 01140 (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s); 01141 01142 size_t startOffset = s.Tell(); 01143 double d = 0.0; 01144 bool useNanOrInf = false; 01145 01146 // Parse minus 01147 bool minus = Consume(s, '-'); 01148 01149 // Parse int: zero / ( digit1-9 *DIGIT ) 01150 unsigned i = 0; 01151 uint64_t i64 = 0; 01152 bool use64bit = false; 01153 int significandDigit = 0; 01154 if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) { 01155 i = 0; 01156 s.TakePush(); 01157 } 01158 else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) { 01159 i = static_cast<unsigned>(s.TakePush() - '0'); 01160 01161 if (minus) 01162 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { 01163 if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648 01164 if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) { 01165 i64 = i; 01166 use64bit = true; 01167 break; 01168 } 01169 } 01170 i = i * 10 + static_cast<unsigned>(s.TakePush() - '0'); 01171 significandDigit++; 01172 } 01173 else 01174 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { 01175 if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295 01176 if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) { 01177 i64 = i; 01178 use64bit = true; 01179 break; 01180 } 01181 } 01182 i = i * 10 + static_cast<unsigned>(s.TakePush() - '0'); 01183 significandDigit++; 01184 } 01185 } 01186 // Parse NaN or Infinity here 01187 else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) { 01188 useNanOrInf = true; 01189 if (RAPIDJSON_LIKELY(Consume(s, 'N') && Consume(s, 'a') && Consume(s, 'N'))) { 01190 d = std::numeric_limits<double>::quiet_NaN(); 01191 } 01192 else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) { 01193 d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity()); 01194 if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n') 01195 && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) 01196 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); 01197 } 01198 else 01199 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); 01200 } 01201 else 01202 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell()); 01203 01204 // Parse 64bit int 01205 bool useDouble = false; 01206 if (use64bit) { 01207 if (minus) 01208 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { 01209 if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808 01210 if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) { 01211 d = static_cast<double>(i64); 01212 useDouble = true; 01213 break; 01214 } 01215 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0'); 01216 significandDigit++; 01217 } 01218 else 01219 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { 01220 if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615 01221 if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) { 01222 d = static_cast<double>(i64); 01223 useDouble = true; 01224 break; 01225 } 01226 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0'); 01227 significandDigit++; 01228 } 01229 } 01230 01231 // Force double for big integer 01232 if (useDouble) { 01233 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { 01234 if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0 01235 RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); 01236 d = d * 10 + (s.TakePush() - '0'); 01237 } 01238 } 01239 01240 // Parse frac = decimal-point 1*DIGIT 01241 int expFrac = 0; 01242 size_t decimalPosition; 01243 if (Consume(s, '.')) { 01244 decimalPosition = s.Length(); 01245 01246 if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9'))) 01247 RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell()); 01248 01249 if (!useDouble) { 01250 #if RAPIDJSON_64BIT 01251 // Use i64 to store significand in 64-bit architecture 01252 if (!use64bit) 01253 i64 = i; 01254 01255 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { 01256 if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path 01257 break; 01258 else { 01259 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0'); 01260 --expFrac; 01261 if (i64 != 0) 01262 significandDigit++; 01263 } 01264 } 01265 01266 d = static_cast<double>(i64); 01267 #else 01268 // Use double to store significand in 32-bit architecture 01269 d = static_cast<double>(use64bit ? i64 : i); 01270 #endif 01271 useDouble = true; 01272 } 01273 01274 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { 01275 if (significandDigit < 17) { 01276 d = d * 10.0 + (s.TakePush() - '0'); 01277 --expFrac; 01278 if (RAPIDJSON_LIKELY(d > 0.0)) 01279 significandDigit++; 01280 } 01281 else 01282 s.TakePush(); 01283 } 01284 } 01285 else 01286 decimalPosition = s.Length(); // decimal position at the end of integer. 01287 01288 // Parse exp = e [ minus / plus ] 1*DIGIT 01289 int exp = 0; 01290 if (Consume(s, 'e') || Consume(s, 'E')) { 01291 if (!useDouble) { 01292 d = static_cast<double>(use64bit ? i64 : i); 01293 useDouble = true; 01294 } 01295 01296 bool expMinus = false; 01297 if (Consume(s, '+')) 01298 ; 01299 else if (Consume(s, '-')) 01300 expMinus = true; 01301 01302 if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { 01303 exp = static_cast<int>(s.Take() - '0'); 01304 if (expMinus) { 01305 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { 01306 exp = exp * 10 + static_cast<int>(s.Take() - '0'); 01307 if (exp >= 214748364) { // Issue #313: prevent overflow exponent 01308 while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent 01309 s.Take(); 01310 } 01311 } 01312 } 01313 else { // positive exp 01314 int maxExp = 308 - expFrac; 01315 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) { 01316 exp = exp * 10 + static_cast<int>(s.Take() - '0'); 01317 if (RAPIDJSON_UNLIKELY(exp > maxExp)) 01318 RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset); 01319 } 01320 } 01321 } 01322 else 01323 RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell()); 01324 01325 if (expMinus) 01326 exp = -exp; 01327 } 01328 01329 // Finish parsing, call event according to the type of number. 01330 bool cont = true; 01331 01332 if (parseFlags & kParseNumbersAsStringsFlag) { 01333 if (parseFlags & kParseInsituFlag) { 01334 s.Pop(); // Pop stack no matter if it will be used or not. 01335 typename InputStream::Ch* head = is.PutBegin(); 01336 const size_t length = s.Tell() - startOffset; 01337 RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); 01338 // unable to insert the \0 character here, it will erase the comma after this number 01339 const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head); 01340 cont = handler.RawNumber(str, SizeType(length), false); 01341 } 01342 else { 01343 SizeType numCharsToCopy = static_cast<SizeType>(s.Length()); 01344 StringStream srcStream(s.Pop()); 01345 StackStream<typename TargetEncoding::Ch> dstStream(stack_); 01346 while (numCharsToCopy--) { 01347 Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream); 01348 } 01349 dstStream.Put('\0'); 01350 const typename TargetEncoding::Ch* str = dstStream.Pop(); 01351 const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1; 01352 cont = handler.RawNumber(str, SizeType(length), true); 01353 } 01354 } 01355 else { 01356 size_t length = s.Length(); 01357 const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not. 01358 01359 if (useDouble) { 01360 int p = exp + expFrac; 01361 if (parseFlags & kParseFullPrecisionFlag) 01362 d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp); 01363 else 01364 d = internal::StrtodNormalPrecision(d, p); 01365 01366 cont = handler.Double(minus ? -d : d); 01367 } 01368 else if (useNanOrInf) { 01369 cont = handler.Double(d); 01370 } 01371 else { 01372 if (use64bit) { 01373 if (minus) 01374 cont = handler.Int64(static_cast<int64_t>(~i64 + 1)); 01375 else 01376 cont = handler.Uint64(i64); 01377 } 01378 else { 01379 if (minus) 01380 cont = handler.Int(static_cast<int32_t>(~i + 1)); 01381 else 01382 cont = handler.Uint(i); 01383 } 01384 } 01385 } 01386 if (RAPIDJSON_UNLIKELY(!cont)) 01387 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset); 01388 } 01389 01390 // Parse any JSON value 01391 template<unsigned parseFlags, typename InputStream, typename Handler> 01392 void ParseValue(InputStream& is, Handler& handler) { 01393 switch (is.Peek()) { 01394 case 'n': ParseNull <parseFlags>(is, handler); break; 01395 case 't': ParseTrue <parseFlags>(is, handler); break; 01396 case 'f': ParseFalse <parseFlags>(is, handler); break; 01397 case '"': ParseString<parseFlags>(is, handler); break; 01398 case '{': ParseObject<parseFlags>(is, handler); break; 01399 case '[': ParseArray <parseFlags>(is, handler); break; 01400 default : 01401 ParseNumber<parseFlags>(is, handler); 01402 break; 01403 01404 } 01405 } 01406 01407 // Iterative Parsing 01408 01409 // States 01410 enum IterativeParsingState { 01411 IterativeParsingStartState = 0, 01412 IterativeParsingFinishState, 01413 IterativeParsingErrorState, 01414 01415 // Object states 01416 IterativeParsingObjectInitialState, 01417 IterativeParsingMemberKeyState, 01418 IterativeParsingKeyValueDelimiterState, 01419 IterativeParsingMemberValueState, 01420 IterativeParsingMemberDelimiterState, 01421 IterativeParsingObjectFinishState, 01422 01423 // Array states 01424 IterativeParsingArrayInitialState, 01425 IterativeParsingElementState, 01426 IterativeParsingElementDelimiterState, 01427 IterativeParsingArrayFinishState, 01428 01429 // Single value state 01430 IterativeParsingValueState 01431 }; 01432 01433 enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 }; 01434 01435 // Tokens 01436 enum Token { 01437 LeftBracketToken = 0, 01438 RightBracketToken, 01439 01440 LeftCurlyBracketToken, 01441 RightCurlyBracketToken, 01442 01443 CommaToken, 01444 ColonToken, 01445 01446 StringToken, 01447 FalseToken, 01448 TrueToken, 01449 NullToken, 01450 NumberToken, 01451 01452 kTokenCount 01453 }; 01454 01455 RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) { 01456 01457 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 01458 #define N NumberToken 01459 #define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N 01460 // Maps from ASCII to Token 01461 static const unsigned char tokenMap[256] = { 01462 N16, // 00~0F 01463 N16, // 10~1F 01464 N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F 01465 N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F 01466 N16, // 40~4F 01467 N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F 01468 N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F 01469 N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F 01470 N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF 01471 }; 01472 #undef N 01473 #undef N16 01474 //!@endcond 01475 01476 if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) 01477 return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]); 01478 else 01479 return NumberToken; 01480 } 01481 01482 RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) { 01483 // current state x one lookahead token -> new state 01484 static const char G[cIterativeParsingStateCount][kTokenCount] = { 01485 // Start 01486 { 01487 IterativeParsingArrayInitialState, // Left bracket 01488 IterativeParsingErrorState, // Right bracket 01489 IterativeParsingObjectInitialState, // Left curly bracket 01490 IterativeParsingErrorState, // Right curly bracket 01491 IterativeParsingErrorState, // Comma 01492 IterativeParsingErrorState, // Colon 01493 IterativeParsingValueState, // String 01494 IterativeParsingValueState, // False 01495 IterativeParsingValueState, // True 01496 IterativeParsingValueState, // Null 01497 IterativeParsingValueState // Number 01498 }, 01499 // Finish(sink state) 01500 { 01501 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, 01502 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, 01503 IterativeParsingErrorState 01504 }, 01505 // Error(sink state) 01506 { 01507 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, 01508 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, 01509 IterativeParsingErrorState 01510 }, 01511 // ObjectInitial 01512 { 01513 IterativeParsingErrorState, // Left bracket 01514 IterativeParsingErrorState, // Right bracket 01515 IterativeParsingErrorState, // Left curly bracket 01516 IterativeParsingObjectFinishState, // Right curly bracket 01517 IterativeParsingErrorState, // Comma 01518 IterativeParsingErrorState, // Colon 01519 IterativeParsingMemberKeyState, // String 01520 IterativeParsingErrorState, // False 01521 IterativeParsingErrorState, // True 01522 IterativeParsingErrorState, // Null 01523 IterativeParsingErrorState // Number 01524 }, 01525 // MemberKey 01526 { 01527 IterativeParsingErrorState, // Left bracket 01528 IterativeParsingErrorState, // Right bracket 01529 IterativeParsingErrorState, // Left curly bracket 01530 IterativeParsingErrorState, // Right curly bracket 01531 IterativeParsingErrorState, // Comma 01532 IterativeParsingKeyValueDelimiterState, // Colon 01533 IterativeParsingErrorState, // String 01534 IterativeParsingErrorState, // False 01535 IterativeParsingErrorState, // True 01536 IterativeParsingErrorState, // Null 01537 IterativeParsingErrorState // Number 01538 }, 01539 // KeyValueDelimiter 01540 { 01541 IterativeParsingArrayInitialState, // Left bracket(push MemberValue state) 01542 IterativeParsingErrorState, // Right bracket 01543 IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state) 01544 IterativeParsingErrorState, // Right curly bracket 01545 IterativeParsingErrorState, // Comma 01546 IterativeParsingErrorState, // Colon 01547 IterativeParsingMemberValueState, // String 01548 IterativeParsingMemberValueState, // False 01549 IterativeParsingMemberValueState, // True 01550 IterativeParsingMemberValueState, // Null 01551 IterativeParsingMemberValueState // Number 01552 }, 01553 // MemberValue 01554 { 01555 IterativeParsingErrorState, // Left bracket 01556 IterativeParsingErrorState, // Right bracket 01557 IterativeParsingErrorState, // Left curly bracket 01558 IterativeParsingObjectFinishState, // Right curly bracket 01559 IterativeParsingMemberDelimiterState, // Comma 01560 IterativeParsingErrorState, // Colon 01561 IterativeParsingErrorState, // String 01562 IterativeParsingErrorState, // False 01563 IterativeParsingErrorState, // True 01564 IterativeParsingErrorState, // Null 01565 IterativeParsingErrorState // Number 01566 }, 01567 // MemberDelimiter 01568 { 01569 IterativeParsingErrorState, // Left bracket 01570 IterativeParsingErrorState, // Right bracket 01571 IterativeParsingErrorState, // Left curly bracket 01572 IterativeParsingObjectFinishState, // Right curly bracket 01573 IterativeParsingErrorState, // Comma 01574 IterativeParsingErrorState, // Colon 01575 IterativeParsingMemberKeyState, // String 01576 IterativeParsingErrorState, // False 01577 IterativeParsingErrorState, // True 01578 IterativeParsingErrorState, // Null 01579 IterativeParsingErrorState // Number 01580 }, 01581 // ObjectFinish(sink state) 01582 { 01583 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, 01584 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, 01585 IterativeParsingErrorState 01586 }, 01587 // ArrayInitial 01588 { 01589 IterativeParsingArrayInitialState, // Left bracket(push Element state) 01590 IterativeParsingArrayFinishState, // Right bracket 01591 IterativeParsingObjectInitialState, // Left curly bracket(push Element state) 01592 IterativeParsingErrorState, // Right curly bracket 01593 IterativeParsingErrorState, // Comma 01594 IterativeParsingErrorState, // Colon 01595 IterativeParsingElementState, // String 01596 IterativeParsingElementState, // False 01597 IterativeParsingElementState, // True 01598 IterativeParsingElementState, // Null 01599 IterativeParsingElementState // Number 01600 }, 01601 // Element 01602 { 01603 IterativeParsingErrorState, // Left bracket 01604 IterativeParsingArrayFinishState, // Right bracket 01605 IterativeParsingErrorState, // Left curly bracket 01606 IterativeParsingErrorState, // Right curly bracket 01607 IterativeParsingElementDelimiterState, // Comma 01608 IterativeParsingErrorState, // Colon 01609 IterativeParsingErrorState, // String 01610 IterativeParsingErrorState, // False 01611 IterativeParsingErrorState, // True 01612 IterativeParsingErrorState, // Null 01613 IterativeParsingErrorState // Number 01614 }, 01615 // ElementDelimiter 01616 { 01617 IterativeParsingArrayInitialState, // Left bracket(push Element state) 01618 IterativeParsingArrayFinishState, // Right bracket 01619 IterativeParsingObjectInitialState, // Left curly bracket(push Element state) 01620 IterativeParsingErrorState, // Right curly bracket 01621 IterativeParsingErrorState, // Comma 01622 IterativeParsingErrorState, // Colon 01623 IterativeParsingElementState, // String 01624 IterativeParsingElementState, // False 01625 IterativeParsingElementState, // True 01626 IterativeParsingElementState, // Null 01627 IterativeParsingElementState // Number 01628 }, 01629 // ArrayFinish(sink state) 01630 { 01631 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, 01632 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, 01633 IterativeParsingErrorState 01634 }, 01635 // Single Value (sink state) 01636 { 01637 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, 01638 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, 01639 IterativeParsingErrorState 01640 } 01641 }; // End of G 01642 01643 return static_cast<IterativeParsingState>(G[state][token]); 01644 } 01645 01646 // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit(). 01647 // May return a new state on state pop. 01648 template <unsigned parseFlags, typename InputStream, typename Handler> 01649 RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) { 01650 (void)token; 01651 01652 switch (dst) { 01653 case IterativeParsingErrorState: 01654 return dst; 01655 01656 case IterativeParsingObjectInitialState: 01657 case IterativeParsingArrayInitialState: 01658 { 01659 // Push the state(Element or MemeberValue) if we are nested in another array or value of member. 01660 // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop. 01661 IterativeParsingState n = src; 01662 if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState) 01663 n = IterativeParsingElementState; 01664 else if (src == IterativeParsingKeyValueDelimiterState) 01665 n = IterativeParsingMemberValueState; 01666 // Push current state. 01667 *stack_.template Push<SizeType>(1) = n; 01668 // Initialize and push the member/element count. 01669 *stack_.template Push<SizeType>(1) = 0; 01670 // Call handler 01671 bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray(); 01672 // On handler short circuits the parsing. 01673 if (!hr) { 01674 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); 01675 return IterativeParsingErrorState; 01676 } 01677 else { 01678 is.Take(); 01679 return dst; 01680 } 01681 } 01682 01683 case IterativeParsingMemberKeyState: 01684 ParseString<parseFlags>(is, handler, true); 01685 if (HasParseError()) 01686 return IterativeParsingErrorState; 01687 else 01688 return dst; 01689 01690 case IterativeParsingKeyValueDelimiterState: 01691 RAPIDJSON_ASSERT(token == ColonToken); 01692 is.Take(); 01693 return dst; 01694 01695 case IterativeParsingMemberValueState: 01696 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. 01697 ParseValue<parseFlags>(is, handler); 01698 if (HasParseError()) { 01699 return IterativeParsingErrorState; 01700 } 01701 return dst; 01702 01703 case IterativeParsingElementState: 01704 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. 01705 ParseValue<parseFlags>(is, handler); 01706 if (HasParseError()) { 01707 return IterativeParsingErrorState; 01708 } 01709 return dst; 01710 01711 case IterativeParsingMemberDelimiterState: 01712 case IterativeParsingElementDelimiterState: 01713 is.Take(); 01714 // Update member/element count. 01715 *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1; 01716 return dst; 01717 01718 case IterativeParsingObjectFinishState: 01719 { 01720 // Transit from delimiter is only allowed when trailing commas are enabled 01721 if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) { 01722 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell()); 01723 return IterativeParsingErrorState; 01724 } 01725 // Get member count. 01726 SizeType c = *stack_.template Pop<SizeType>(1); 01727 // If the object is not empty, count the last member. 01728 if (src == IterativeParsingMemberValueState) 01729 ++c; 01730 // Restore the state. 01731 IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1)); 01732 // Transit to Finish state if this is the topmost scope. 01733 if (n == IterativeParsingStartState) 01734 n = IterativeParsingFinishState; 01735 // Call handler 01736 bool hr = handler.EndObject(c); 01737 // On handler short circuits the parsing. 01738 if (!hr) { 01739 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); 01740 return IterativeParsingErrorState; 01741 } 01742 else { 01743 is.Take(); 01744 return n; 01745 } 01746 } 01747 01748 case IterativeParsingArrayFinishState: 01749 { 01750 // Transit from delimiter is only allowed when trailing commas are enabled 01751 if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) { 01752 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell()); 01753 return IterativeParsingErrorState; 01754 } 01755 // Get element count. 01756 SizeType c = *stack_.template Pop<SizeType>(1); 01757 // If the array is not empty, count the last element. 01758 if (src == IterativeParsingElementState) 01759 ++c; 01760 // Restore the state. 01761 IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1)); 01762 // Transit to Finish state if this is the topmost scope. 01763 if (n == IterativeParsingStartState) 01764 n = IterativeParsingFinishState; 01765 // Call handler 01766 bool hr = handler.EndArray(c); 01767 // On handler short circuits the parsing. 01768 if (!hr) { 01769 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell()); 01770 return IterativeParsingErrorState; 01771 } 01772 else { 01773 is.Take(); 01774 return n; 01775 } 01776 } 01777 01778 default: 01779 // This branch is for IterativeParsingValueState actually. 01780 // Use `default:` rather than 01781 // `case IterativeParsingValueState:` is for code coverage. 01782 01783 // The IterativeParsingStartState is not enumerated in this switch-case. 01784 // It is impossible for that case. And it can be caught by following assertion. 01785 01786 // The IterativeParsingFinishState is not enumerated in this switch-case either. 01787 // It is a "derivative" state which cannot triggered from Predict() directly. 01788 // Therefore it cannot happen here. And it can be caught by following assertion. 01789 RAPIDJSON_ASSERT(dst == IterativeParsingValueState); 01790 01791 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. 01792 ParseValue<parseFlags>(is, handler); 01793 if (HasParseError()) { 01794 return IterativeParsingErrorState; 01795 } 01796 return IterativeParsingFinishState; 01797 } 01798 } 01799 01800 template <typename InputStream> 01801 void HandleError(IterativeParsingState src, InputStream& is) { 01802 if (HasParseError()) { 01803 // Error flag has been set. 01804 return; 01805 } 01806 01807 switch (src) { 01808 case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return; 01809 case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return; 01810 case IterativeParsingObjectInitialState: 01811 case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return; 01812 case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return; 01813 case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return; 01814 case IterativeParsingKeyValueDelimiterState: 01815 case IterativeParsingArrayInitialState: 01816 case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return; 01817 default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return; 01818 } 01819 } 01820 01821 template <unsigned parseFlags, typename InputStream, typename Handler> 01822 ParseResult IterativeParse(InputStream& is, Handler& handler) { 01823 parseResult_.Clear(); 01824 ClearStackOnExit scope(*this); 01825 IterativeParsingState state = IterativeParsingStartState; 01826 01827 SkipWhitespaceAndComments<parseFlags>(is); 01828 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); 01829 while (is.Peek() != '\0') { 01830 Token t = Tokenize(is.Peek()); 01831 IterativeParsingState n = Predict(state, t); 01832 IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler); 01833 01834 if (d == IterativeParsingErrorState) { 01835 HandleError(state, is); 01836 break; 01837 } 01838 01839 state = d; 01840 01841 // Do not further consume streams if a root JSON has been parsed. 01842 if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState) 01843 break; 01844 01845 SkipWhitespaceAndComments<parseFlags>(is); 01846 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); 01847 } 01848 01849 // Handle the end of file. 01850 if (state != IterativeParsingFinishState) 01851 HandleError(state, is); 01852 01853 return parseResult_; 01854 } 01855 01856 static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string. 01857 internal::Stack<StackAllocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing. 01858 ParseResult parseResult_; 01859 }; // class GenericReader 01860 01861 //! Reader with UTF8 encoding and default allocator. 01862 typedef GenericReader<UTF8<>, UTF8<> > Reader; 01863 01864 RAPIDJSON_NAMESPACE_END 01865 01866 #ifdef __clang__ 01867 RAPIDJSON_DIAG_POP 01868 #endif 01869 01870 01871 #ifdef __GNUC__ 01872 RAPIDJSON_DIAG_POP 01873 #endif 01874 01875 #ifdef _MSC_VER 01876 RAPIDJSON_DIAG_POP 01877 #endif 01878 01879 #endif // RAPIDJSON_READER_H_
Generated on Tue Jul 12 2022 12:06:49 by 1.7.2