载入中...
搜索中...
未找到
reader.h
浏览该文件的文档.
1// Tencent is pleased to support the open source community by making RapidJSON available.
2//
3// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4//
5// Licensed under the MIT License (the "License"); you may not use this file except
6// in compliance with the License. You may obtain a copy of the License at
7//
8// http://opensource.org/licenses/MIT
9//
10// Unless required by applicable law or agreed to in writing, software distributed
11// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13// specific language governing permissions and limitations under the License.
14
15#ifndef RAPIDJSON_READER_H_
16#define RAPIDJSON_READER_H_
17
18/*! \file reader.h */
19
20#include "allocators.h"
21#include "stream.h"
22#include "encodedstream.h"
23#include "internal/meta.h"
24#include "internal/stack.h"
25#include "internal/strtod.h"
26#include <limits>
27#include <cmath>
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#endif
38
39#ifdef _MSC_VER
40RAPIDJSON_DIAG_PUSH
41RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
42RAPIDJSON_DIAG_OFF(4702) // unreachable code
43#endif
44
45#ifdef __clang__
46RAPIDJSON_DIAG_PUSH
47RAPIDJSON_DIAG_OFF(old-style-cast)
48RAPIDJSON_DIAG_OFF(padded)
49RAPIDJSON_DIAG_OFF(switch-enum)
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 */
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
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>
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_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
304 if (r != 0) { // some of characters is non-whitespace
305#ifdef _MSC_VER // Find the index of first non-whitespace
306 unsigned long offset;
307 _BitScanForward(&offset, r);
308 return p + offset;
309#else
310 return p + __builtin_ffs(r) - 1;
311#endif
312 }
313 }
314}
315
316inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
317 // Fast return for single non-whitespace
318 if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
319 ++p;
320 else
321 return p;
322
323 // The middle of string using SIMD
324 static const char whitespace[16] = " \n\r\t";
325 const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
326
327 for (; p <= end - 16; p += 16) {
328 const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
329 const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
330 if (r != 0) { // some of characters is non-whitespace
331#ifdef _MSC_VER // Find the index of first non-whitespace
332 unsigned long offset;
333 _BitScanForward(&offset, r);
334 return p + offset;
335#else
336 return p + __builtin_ffs(r) - 1;
337#endif
338 }
339 }
340
341 return SkipWhitespace(p, end);
342}
343
344#elif defined(RAPIDJSON_SSE2)
345
346//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
347inline const char *SkipWhitespace_SIMD(const char* p) {
348 // Fast return for single non-whitespace
349 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
350 ++p;
351 else
352 return p;
353
354 // 16-byte align to the next boundary
355 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
356 while (p != nextAligned)
357 if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
358 ++p;
359 else
360 return p;
361
362 // The rest of string
363 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
364 static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
365 #undef C16
366
367 const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
368 const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
369 const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
370 const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
371
372 for (;; p += 16) {
373 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
374 __m128i x = _mm_cmpeq_epi8(s, w0);
375 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
376 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
377 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
378 unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
379 if (r != 0) { // some of characters may be non-whitespace
380#ifdef _MSC_VER // Find the index of first non-whitespace
381 unsigned long offset;
382 _BitScanForward(&offset, r);
383 return p + offset;
384#else
385 return p + __builtin_ffs(r) - 1;
386#endif
387 }
388 }
389}
390
391inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
392 // Fast return for single non-whitespace
393 if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
394 ++p;
395 else
396 return p;
397
398 // The rest of string
399 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
400 static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
401 #undef C16
402
403 const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
404 const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
405 const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
406 const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
407
408 for (; p <= end - 16; p += 16) {
409 const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
410 __m128i x = _mm_cmpeq_epi8(s, w0);
411 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
412 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
413 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
414 unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
415 if (r != 0) { // some of characters may be non-whitespace
416#ifdef _MSC_VER // Find the index of first non-whitespace
417 unsigned long offset;
418 _BitScanForward(&offset, r);
419 return p + offset;
420#else
421 return p + __builtin_ffs(r) - 1;
422#endif
423 }
424 }
425
426 return SkipWhitespace(p, end);
427}
428
429#endif // RAPIDJSON_SSE2
430
431#ifdef RAPIDJSON_SIMD
432//! Template function specialization for InsituStringStream
433template<> inline void SkipWhitespace(InsituStringStream& is) {
434 is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
435}
436
437//! Template function specialization for StringStream
438template<> inline void SkipWhitespace(StringStream& is) {
439 is.src_ = SkipWhitespace_SIMD(is.src_);
440}
441
442template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {
443 is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
444}
445#endif // RAPIDJSON_SIMD
446
447///////////////////////////////////////////////////////////////////////////////
448// GenericReader
449
450//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator.
451/*! GenericReader parses JSON text from a stream, and send events synchronously to an
452 object implementing Handler concept.
453
454 It needs to allocate a stack for storing a single decoded string during
455 non-destructive parsing.
456
457 For in-situ parsing, the decoded string is directly written to the source
458 text string, no temporary buffer is required.
459
460 A GenericReader object can be reused for parsing multiple JSON text.
461
462 \tparam SourceEncoding Encoding of the input stream.
463 \tparam TargetEncoding Encoding of the parse output.
464 \tparam StackAllocator Allocator type for stack.
465*/
466template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
468public:
469 typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type
470
471 //! Constructor.
472 /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
473 \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
474 */
475 GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {}
476
477 //! Parse JSON text.
478 /*! \tparam parseFlags Combination of \ref ParseFlag.
479 \tparam InputStream Type of input stream, implementing Stream concept.
480 \tparam Handler Type of handler, implementing Handler concept.
481 \param is Input stream to be parsed.
482 \param handler The handler to receive events.
483 \return Whether the parsing is successful.
484 */
485 template <unsigned parseFlags, typename InputStream, typename Handler>
486 ParseResult Parse(InputStream& is, Handler& handler) {
487 if (parseFlags & kParseIterativeFlag)
488 return IterativeParse<parseFlags>(is, handler);
489
490 parseResult_.Clear();
491
492 ClearStackOnExit scope(*this);
493
494 SkipWhitespaceAndComments<parseFlags>(is);
495 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
496
497 if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) {
499 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
500 }
501 else {
502 ParseValue<parseFlags>(is, handler);
503 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
504
505 if (!(parseFlags & kParseStopWhenDoneFlag)) {
506 SkipWhitespaceAndComments<parseFlags>(is);
507 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
508
509 if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) {
511 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
512 }
513 }
514 }
515
516 return parseResult_;
517 }
518
519 //! Parse JSON text (with \ref kParseDefaultFlags)
520 /*! \tparam InputStream Type of input stream, implementing Stream concept
521 \tparam Handler Type of handler, implementing Handler concept.
522 \param is Input stream to be parsed.
523 \param handler The handler to receive events.
524 \return Whether the parsing is successful.
525 */
526 template <typename InputStream, typename Handler>
527 ParseResult Parse(InputStream& is, Handler& handler) {
528 return Parse<kParseDefaultFlags>(is, handler);
529 }
530
531 //! Whether a parse error has occured in the last parsing.
532 bool HasParseError() const { return parseResult_.IsError(); }
533
534 //! Get the \ref ParseErrorCode of last parsing.
535 ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }
536
537 //! Get the position of last parsing error in input, 0 otherwise.
538 size_t GetErrorOffset() const { return parseResult_.Offset(); }
539
540protected:
541 void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
542
543private:
544 // Prohibit copy constructor & assignment operator.
545 GenericReader(const GenericReader&);
546 GenericReader& operator=(const GenericReader&);
547
548 void ClearStack() { stack_.Clear(); }
549
550 // clear stack on any exit from ParseStream, e.g. due to exception
551 struct ClearStackOnExit {
552 explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
553 ~ClearStackOnExit() { r_.ClearStack(); }
554 private:
555 GenericReader& r_;
556 ClearStackOnExit(const ClearStackOnExit&);
557 ClearStackOnExit& operator=(const ClearStackOnExit&);
558 };
559
560 template<unsigned parseFlags, typename InputStream>
561 void SkipWhitespaceAndComments(InputStream& is) {
562 SkipWhitespace(is);
563
564 if (parseFlags & kParseCommentsFlag) {
565 while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) {
566 if (Consume(is, '*')) {
567 while (true) {
568 if (RAPIDJSON_UNLIKELY(is.Peek() == '\0'))
569 RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
570 else if (Consume(is, '*')) {
571 if (Consume(is, '/'))
572 break;
573 }
574 else
575 is.Take();
576 }
577 }
578 else if (RAPIDJSON_LIKELY(Consume(is, '/')))
579 while (is.Peek() != '\0' && is.Take() != '\n');
580 else
581 RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
582
583 SkipWhitespace(is);
584 }
585 }
586 }
587
588 // Parse object: { string : value, ... }
589 template<unsigned parseFlags, typename InputStream, typename Handler>
590 void ParseObject(InputStream& is, Handler& handler) {
591 RAPIDJSON_ASSERT(is.Peek() == '{');
592 is.Take(); // Skip '{'
593
594 if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
595 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
596
597 SkipWhitespaceAndComments<parseFlags>(is);
598 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
599
600 if (Consume(is, '}')) {
601 if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object
602 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
603 return;
604 }
605
606 for (SizeType memberCount = 0;;) {
607 if (RAPIDJSON_UNLIKELY(is.Peek() != '"'))
608 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
609
610 ParseString<parseFlags>(is, handler, true);
611 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
612
613 SkipWhitespaceAndComments<parseFlags>(is);
614 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
615
616 if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))
617 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
618
619 SkipWhitespaceAndComments<parseFlags>(is);
620 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
621
622 ParseValue<parseFlags>(is, handler);
623 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
624
625 SkipWhitespaceAndComments<parseFlags>(is);
626 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
627
628 ++memberCount;
629
630 switch (is.Peek()) {
631 case ',':
632 is.Take();
633 SkipWhitespaceAndComments<parseFlags>(is);
634 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
635 break;
636 case '}':
637 is.Take();
638 if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
639 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
640 return;
641 default:
642 RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy
643 }
644
645 if (parseFlags & kParseTrailingCommasFlag) {
646 if (is.Peek() == '}') {
647 if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
648 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
649 is.Take();
650 return;
651 }
652 }
653 }
654 }
655
656 // Parse array: [ value, ... ]
657 template<unsigned parseFlags, typename InputStream, typename Handler>
658 void ParseArray(InputStream& is, Handler& handler) {
659 RAPIDJSON_ASSERT(is.Peek() == '[');
660 is.Take(); // Skip '['
661
662 if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
663 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
664
665 SkipWhitespaceAndComments<parseFlags>(is);
666 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
667
668 if (Consume(is, ']')) {
669 if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array
670 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
671 return;
672 }
673
674 for (SizeType elementCount = 0;;) {
675 ParseValue<parseFlags>(is, handler);
676 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
677
678 ++elementCount;
679 SkipWhitespaceAndComments<parseFlags>(is);
680 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
681
682 if (Consume(is, ',')) {
683 SkipWhitespaceAndComments<parseFlags>(is);
684 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
685 }
686 else if (Consume(is, ']')) {
687 if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
688 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
689 return;
690 }
691 else
692 RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
693
694 if (parseFlags & kParseTrailingCommasFlag) {
695 if (is.Peek() == ']') {
696 if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
697 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
698 is.Take();
699 return;
700 }
701 }
702 }
703 }
704
705 template<unsigned parseFlags, typename InputStream, typename Handler>
706 void ParseNull(InputStream& is, Handler& handler) {
707 RAPIDJSON_ASSERT(is.Peek() == 'n');
708 is.Take();
709
710 if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {
711 if (RAPIDJSON_UNLIKELY(!handler.Null()))
712 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
713 }
714 else
715 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
716 }
717
718 template<unsigned parseFlags, typename InputStream, typename Handler>
719 void ParseTrue(InputStream& is, Handler& handler) {
720 RAPIDJSON_ASSERT(is.Peek() == 't');
721 is.Take();
722
723 if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {
724 if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))
725 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
726 }
727 else
728 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
729 }
730
731 template<unsigned parseFlags, typename InputStream, typename Handler>
732 void ParseFalse(InputStream& is, Handler& handler) {
733 RAPIDJSON_ASSERT(is.Peek() == 'f');
734 is.Take();
735
736 if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {
737 if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))
738 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
739 }
740 else
741 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
742 }
743
744 template<typename InputStream>
745 RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
746 if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
747 is.Take();
748 return true;
749 }
750 else
751 return false;
752 }
753
754 // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
755 template<typename InputStream>
756 unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
757 unsigned codepoint = 0;
758 for (int i = 0; i < 4; i++) {
759 Ch c = is.Peek();
760 codepoint <<= 4;
761 codepoint += static_cast<unsigned>(c);
762 if (c >= '0' && c <= '9')
763 codepoint -= '0';
764 else if (c >= 'A' && c <= 'F')
765 codepoint -= 'A' - 10;
766 else if (c >= 'a' && c <= 'f')
767 codepoint -= 'a' - 10;
768 else {
769 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset);
770 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
771 }
772 is.Take();
773 }
774 return codepoint;
775 }
776
777 template <typename CharType>
778 class StackStream {
779 public:
780 typedef CharType Ch;
781
782 StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {}
783 RAPIDJSON_FORCEINLINE void Put(Ch c) {
784 *stack_.template Push<Ch>() = c;
785 ++length_;
786 }
787
788 RAPIDJSON_FORCEINLINE void* Push(SizeType count) {
789 length_ += count;
790 return stack_.template Push<Ch>(count);
791 }
792
793 size_t Length() const { return length_; }
794
795 Ch* Pop() {
796 return stack_.template Pop<Ch>(length_);
797 }
798
799 private:
800 StackStream(const StackStream&);
801 StackStream& operator=(const StackStream&);
802
803 internal::Stack<StackAllocator>& stack_;
804 SizeType length_;
805 };
806
807 // Parse string and generate String event. Different code paths for kParseInsituFlag.
808 template<unsigned parseFlags, typename InputStream, typename Handler>
809 void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
810 internal::StreamLocalCopy<InputStream> copy(is);
811 InputStream& s(copy.s);
812
813 RAPIDJSON_ASSERT(s.Peek() == '\"');
814 s.Take(); // Skip '\"'
815
816 bool success = false;
817 if (parseFlags & kParseInsituFlag) {
818 typename InputStream::Ch *head = s.PutBegin();
819 ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
820 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
821 size_t length = s.PutEnd(head) - 1;
822 RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
823 const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
824 success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
825 }
826 else {
827 StackStream<typename TargetEncoding::Ch> stackStream(stack_);
828 ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
829 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
830 SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;
831 const typename TargetEncoding::Ch* const str = stackStream.Pop();
832 success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
833 }
834 if (RAPIDJSON_UNLIKELY(!success))
835 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
836 }
837
838 // Parse string to an output is
839 // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
840 template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
841 RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
842//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
843#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
844 static const char escape[256] = {
845 Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
846 Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
847 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
848 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
849 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
850 };
851#undef Z16
852//!@endcond
853
854 for (;;) {
855 // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
856 if (!(parseFlags & kParseValidateEncodingFlag))
857 ScanCopyUnescapedString(is, os);
858
859 Ch c = is.Peek();
860 if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape
861 size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset
862 is.Take();
863 Ch e = is.Peek();
864 if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
865 is.Take();
866 os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
867 }
868 else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
869 is.Take();
870 unsigned codepoint = ParseHex4(is, escapeOffset);
871 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
872 if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
873 // Handle UTF-16 surrogate pair
874 if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
875 RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
876 unsigned codepoint2 = ParseHex4(is, escapeOffset);
877 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
878 if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
879 RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
880 codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
881 }
882 TEncoding::Encode(os, codepoint);
883 }
884 else
885 RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset);
886 }
887 else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote
888 is.Take();
889 os.Put('\0'); // null-terminate the string
890 return;
891 }
892 else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
893 if (c == '\0')
894 RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell());
895 else
896 RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell());
897 }
898 else {
899 size_t offset = is.Tell();
900 if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
901 !Transcoder<SEncoding, TEncoding>::Validate(is, os) :
902 !Transcoder<SEncoding, TEncoding>::Transcode(is, os))))
904 }
905 }
906 }
907
908 template<typename InputStream, typename OutputStream>
909 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {
910 // Do nothing for generic version
911 }
912
913#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
914 // StringStream -> StackStream<char>
915 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
916 const char* p = is.src_;
917
918 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
919 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
920 while (p != nextAligned)
921 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
922 is.src_ = p;
923 return;
924 }
925 else
926 os.Put(*p++);
927
928 // The rest of string using SIMD
929 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
930 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
931 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
932 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
933 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
934 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
935
936 for (;; p += 16) {
937 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
938 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
939 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
940 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
941 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
942 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
943 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
944 SizeType length;
945 #ifdef _MSC_VER // Find the index of first escaped
946 unsigned long offset;
947 _BitScanForward(&offset, r);
948 length = offset;
949 #else
950 length = static_cast<SizeType>(__builtin_ffs(r) - 1);
951 #endif
952 char* q = reinterpret_cast<char*>(os.Push(length));
953 for (size_t i = 0; i < length; i++)
954 q[i] = p[i];
955
956 p += length;
957 break;
958 }
959 _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);
960 }
961
962 is.src_ = p;
963 }
964
965 // InsituStringStream -> InsituStringStream
966 static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
967 RAPIDJSON_ASSERT(&is == &os);
968 (void)os;
969
970 if (is.src_ == is.dst_) {
971 SkipUnescapedString(is);
972 return;
973 }
974
975 char* p = is.src_;
976 char *q = is.dst_;
977
978 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
979 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
980 while (p != nextAligned)
981 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
982 is.src_ = p;
983 is.dst_ = q;
984 return;
985 }
986 else
987 *q++ = *p++;
988
989 // The rest of string using SIMD
990 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
991 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
992 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
993 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
994 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
995 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
996
997 for (;; p += 16, q += 16) {
998 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
999 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1000 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1001 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
1002 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1003 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1004 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1005 size_t length;
1006#ifdef _MSC_VER // Find the index of first escaped
1007 unsigned long offset;
1008 _BitScanForward(&offset, r);
1009 length = offset;
1010#else
1011 length = static_cast<size_t>(__builtin_ffs(r) - 1);
1012#endif
1013 for (const char* pend = p + length; p != pend; )
1014 *q++ = *p++;
1015 break;
1016 }
1017 _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);
1018 }
1019
1020 is.src_ = p;
1021 is.dst_ = q;
1022 }
1023
1024 // When read/write pointers are the same for insitu stream, just skip unescaped characters
1025 static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
1026 RAPIDJSON_ASSERT(is.src_ == is.dst_);
1027 char* p = is.src_;
1028
1029 // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1030 const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1031 for (; p != nextAligned; p++)
1032 if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1033 is.src_ = is.dst_ = p;
1034 return;
1035 }
1036
1037 // The rest of string using SIMD
1038 static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1039 static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1040 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
1041 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1042 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1043 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1044
1045 for (;; p += 16) {
1046 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1047 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1048 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1049 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
1050 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1051 unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1052 if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1053 size_t length;
1054#ifdef _MSC_VER // Find the index of first escaped
1055 unsigned long offset;
1056 _BitScanForward(&offset, r);
1057 length = offset;
1058#else
1059 length = static_cast<size_t>(__builtin_ffs(r) - 1);
1060#endif
1061 p += length;
1062 break;
1063 }
1064 }
1065
1066 is.src_ = is.dst_ = p;
1067 }
1068#endif
1069
1070 template<typename InputStream, bool backup, bool pushOnTake>
1071 class NumberStream;
1072
1073 template<typename InputStream>
1074 class NumberStream<InputStream, false, false> {
1075 public:
1076 typedef typename InputStream::Ch Ch;
1077
1078 NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; }
1079 ~NumberStream() {}
1080
1081 RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
1082 RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
1083 RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
1084 RAPIDJSON_FORCEINLINE void Push(char) {}
1085
1086 size_t Tell() { return is.Tell(); }
1087 size_t Length() { return 0; }
1088 const char* Pop() { return 0; }
1089
1090 protected:
1091 NumberStream& operator=(const NumberStream&);
1092
1093 InputStream& is;
1094 };
1095
1096 template<typename InputStream>
1097 class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
1098 typedef NumberStream<InputStream, false, false> Base;
1099 public:
1100 NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
1101 ~NumberStream() {}
1102
1103 RAPIDJSON_FORCEINLINE Ch TakePush() {
1104 stackStream.Put(static_cast<char>(Base::is.Peek()));
1105 return Base::is.Take();
1106 }
1107
1108 RAPIDJSON_FORCEINLINE void Push(char c) {
1109 stackStream.Put(c);
1110 }
1111
1112 size_t Length() { return stackStream.Length(); }
1113
1114 const char* Pop() {
1115 stackStream.Put('\0');
1116 return stackStream.Pop();
1117 }
1118
1119 private:
1120 StackStream<char> stackStream;
1121 };
1122
1123 template<typename InputStream>
1124 class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
1125 typedef NumberStream<InputStream, true, false> Base;
1126 public:
1127 NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
1128 ~NumberStream() {}
1129
1130 RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
1131 };
1132
1133 template<unsigned parseFlags, typename InputStream, typename Handler>
1134 void ParseNumber(InputStream& is, Handler& handler) {
1135 internal::StreamLocalCopy<InputStream> copy(is);
1136 NumberStream<InputStream,
1137 ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
1138 ((parseFlags & kParseInsituFlag) == 0) :
1139 ((parseFlags & kParseFullPrecisionFlag) != 0),
1140 (parseFlags & kParseNumbersAsStringsFlag) != 0 &&
1141 (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);
1142
1143 size_t startOffset = s.Tell();
1144 double d = 0.0;
1145 bool useNanOrInf = false;
1146
1147 // Parse minus
1148 bool minus = Consume(s, '-');
1149
1150 // Parse int: zero / ( digit1-9 *DIGIT )
1151 unsigned i = 0;
1152 uint64_t i64 = 0;
1153 bool use64bit = false;
1154 int significandDigit = 0;
1155 if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {
1156 i = 0;
1157 s.TakePush();
1158 }
1159 else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {
1160 i = static_cast<unsigned>(s.TakePush() - '0');
1161
1162 if (minus)
1163 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1164 if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648
1165 if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {
1166 i64 = i;
1167 use64bit = true;
1168 break;
1169 }
1170 }
1171 i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1172 significandDigit++;
1173 }
1174 else
1175 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1176 if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295
1177 if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {
1178 i64 = i;
1179 use64bit = true;
1180 break;
1181 }
1182 }
1183 i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1184 significandDigit++;
1185 }
1186 }
1187 // Parse NaN or Infinity here
1188 else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {
1189 useNanOrInf = true;
1190 if (RAPIDJSON_LIKELY(Consume(s, 'N') && Consume(s, 'a') && Consume(s, 'N'))) {
1191 d = std::numeric_limits<double>::quiet_NaN();
1192 }
1193 else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) {
1194 d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
1195 if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
1196 && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y'))))
1197 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1198 }
1199 else
1200 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1201 }
1202 else
1203 RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
1204
1205 // Parse 64bit int
1206 bool useDouble = false;
1207 if (use64bit) {
1208 if (minus)
1209 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1210 if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808
1211 if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {
1212 d = static_cast<double>(i64);
1213 useDouble = true;
1214 break;
1215 }
1216 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1217 significandDigit++;
1218 }
1219 else
1220 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1221 if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615
1222 if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {
1223 d = static_cast<double>(i64);
1224 useDouble = true;
1225 break;
1226 }
1227 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1228 significandDigit++;
1229 }
1230 }
1231
1232 // Force double for big integer
1233 if (useDouble) {
1234 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1235 d = d * 10 + (s.TakePush() - '0');
1236 }
1237 }
1238
1239 // Parse frac = decimal-point 1*DIGIT
1240 int expFrac = 0;
1241 size_t decimalPosition;
1242 if (Consume(s, '.')) {
1243 decimalPosition = s.Length();
1244
1245 if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
1246 RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
1247
1248 if (!useDouble) {
1249#if RAPIDJSON_64BIT
1250 // Use i64 to store significand in 64-bit architecture
1251 if (!use64bit)
1252 i64 = i;
1253
1254 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1255 if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
1256 break;
1257 else {
1258 i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1259 --expFrac;
1260 if (i64 != 0)
1261 significandDigit++;
1262 }
1263 }
1264
1265 d = static_cast<double>(i64);
1266#else
1267 // Use double to store significand in 32-bit architecture
1268 d = static_cast<double>(use64bit ? i64 : i);
1269#endif
1270 useDouble = true;
1271 }
1272
1273 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1274 if (significandDigit < 17) {
1275 d = d * 10.0 + (s.TakePush() - '0');
1276 --expFrac;
1277 if (RAPIDJSON_LIKELY(d > 0.0))
1278 significandDigit++;
1279 }
1280 else
1281 s.TakePush();
1282 }
1283 }
1284 else
1285 decimalPosition = s.Length(); // decimal position at the end of integer.
1286
1287 // Parse exp = e [ minus / plus ] 1*DIGIT
1288 int exp = 0;
1289 if (Consume(s, 'e') || Consume(s, 'E')) {
1290 if (!useDouble) {
1291 d = static_cast<double>(use64bit ? i64 : i);
1292 useDouble = true;
1293 }
1294
1295 bool expMinus = false;
1296 if (Consume(s, '+'))
1297 ;
1298 else if (Consume(s, '-'))
1299 expMinus = true;
1300
1301 if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1302 exp = static_cast<int>(s.Take() - '0');
1303 if (expMinus) {
1304 // (exp + expFrac) must not underflow int => we're detecting when -exp gets
1305 // dangerously close to INT_MIN (a pessimistic next digit 9 would push it into
1306 // underflow territory):
1307 //
1308 // -(exp * 10 + 9) + expFrac >= INT_MIN
1309 // <=> exp <= (expFrac - INT_MIN - 9) / 10
1310 RAPIDJSON_ASSERT(expFrac <= 0);
1311 int maxExp = (expFrac + 2147483639) / 10;
1312
1313 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1314 exp = exp * 10 + static_cast<int>(s.Take() - '0');
1315 if (RAPIDJSON_UNLIKELY(exp > maxExp)) {
1316 while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent
1317 s.Take();
1318 }
1319 }
1320 }
1321 else { // positive exp
1322 int maxExp = 308 - expFrac;
1323 while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1324 exp = exp * 10 + static_cast<int>(s.Take() - '0');
1325 if (RAPIDJSON_UNLIKELY(exp > maxExp))
1326 RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
1327 }
1328 }
1329 }
1330 else
1331 RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());
1332
1333 if (expMinus)
1334 exp = -exp;
1335 }
1336
1337 // Finish parsing, call event according to the type of number.
1338 bool cont = true;
1339
1340 if (parseFlags & kParseNumbersAsStringsFlag) {
1341 if (parseFlags & kParseInsituFlag) {
1342 s.Pop(); // Pop stack no matter if it will be used or not.
1343 typename InputStream::Ch* head = is.PutBegin();
1344 const size_t length = s.Tell() - startOffset;
1345 RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
1346 // unable to insert the \0 character here, it will erase the comma after this number
1347 const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
1348 cont = handler.RawNumber(str, SizeType(length), false);
1349 }
1350 else {
1351 SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
1352 StringStream srcStream(s.Pop());
1353 StackStream<typename TargetEncoding::Ch> dstStream(stack_);
1354 while (numCharsToCopy--) {
1355 Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);
1356 }
1357 dstStream.Put('\0');
1358 const typename TargetEncoding::Ch* str = dstStream.Pop();
1359 const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1;
1360 cont = handler.RawNumber(str, SizeType(length), true);
1361 }
1362 }
1363 else {
1364 size_t length = s.Length();
1365 const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not.
1366
1367 if (useDouble) {
1368 int p = exp + expFrac;
1369 if (parseFlags & kParseFullPrecisionFlag)
1370 d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
1371 else
1372 d = internal::StrtodNormalPrecision(d, p);
1373
1374 if (std::isinf(d)) {
1375 // Overflow
1376 // TODO: internal::StrtodX should report overflow (or underflow)
1377 RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
1378 }
1379
1380 cont = handler.Double(minus ? -d : d);
1381 }
1382 else if (useNanOrInf) {
1383 cont = handler.Double(d);
1384 }
1385 else {
1386 if (use64bit) {
1387 if (minus)
1388 cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
1389 else
1390 cont = handler.Uint64(i64);
1391 }
1392 else {
1393 if (minus)
1394 cont = handler.Int(static_cast<int32_t>(~i + 1));
1395 else
1396 cont = handler.Uint(i);
1397 }
1398 }
1399 }
1400 if (RAPIDJSON_UNLIKELY(!cont))
1401 RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset);
1402 }
1403
1404 // Parse any JSON value
1405 template<unsigned parseFlags, typename InputStream, typename Handler>
1406 void ParseValue(InputStream& is, Handler& handler) {
1407 switch (is.Peek()) {
1408 case 'n': ParseNull <parseFlags>(is, handler); break;
1409 case 't': ParseTrue <parseFlags>(is, handler); break;
1410 case 'f': ParseFalse <parseFlags>(is, handler); break;
1411 case '"': ParseString<parseFlags>(is, handler); break;
1412 case '{': ParseObject<parseFlags>(is, handler); break;
1413 case '[': ParseArray <parseFlags>(is, handler); break;
1414 default :
1415 ParseNumber<parseFlags>(is, handler);
1416 break;
1417
1418 }
1419 }
1420
1421 // Iterative Parsing
1422
1423 // States
1424 enum IterativeParsingState {
1425 IterativeParsingStartState = 0,
1426 IterativeParsingFinishState,
1427 IterativeParsingErrorState,
1428
1429 // Object states
1430 IterativeParsingObjectInitialState,
1431 IterativeParsingMemberKeyState,
1432 IterativeParsingKeyValueDelimiterState,
1433 IterativeParsingMemberValueState,
1434 IterativeParsingMemberDelimiterState,
1435 IterativeParsingObjectFinishState,
1436
1437 // Array states
1438 IterativeParsingArrayInitialState,
1439 IterativeParsingElementState,
1440 IterativeParsingElementDelimiterState,
1441 IterativeParsingArrayFinishState,
1442
1443 // Single value state
1444 IterativeParsingValueState
1445 };
1446
1447 enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 };
1448
1449 // Tokens
1450 enum Token {
1451 LeftBracketToken = 0,
1452 RightBracketToken,
1453
1454 LeftCurlyBracketToken,
1455 RightCurlyBracketToken,
1456
1457 CommaToken,
1458 ColonToken,
1459
1460 StringToken,
1461 FalseToken,
1462 TrueToken,
1463 NullToken,
1464 NumberToken,
1465
1466 kTokenCount
1467 };
1468
1469 RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
1470
1471//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
1472#define N NumberToken
1473#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1474 // Maps from ASCII to Token
1475 static const unsigned char tokenMap[256] = {
1476 N16, // 00~0F
1477 N16, // 10~1F
1478 N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F
1479 N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F
1480 N16, // 40~4F
1481 N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F
1482 N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F
1483 N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F
1484 N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF
1485 };
1486#undef N
1487#undef N16
1488//!@endcond
1489
1490 if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
1491 return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);
1492 else
1493 return NumberToken;
1494 }
1495
1496 RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {
1497 // current state x one lookahead token -> new state
1498 static const char G[cIterativeParsingStateCount][kTokenCount] = {
1499 // Start
1500 {
1501 IterativeParsingArrayInitialState, // Left bracket
1502 IterativeParsingErrorState, // Right bracket
1503 IterativeParsingObjectInitialState, // Left curly bracket
1504 IterativeParsingErrorState, // Right curly bracket
1505 IterativeParsingErrorState, // Comma
1506 IterativeParsingErrorState, // Colon
1507 IterativeParsingValueState, // String
1508 IterativeParsingValueState, // False
1509 IterativeParsingValueState, // True
1510 IterativeParsingValueState, // Null
1511 IterativeParsingValueState // Number
1512 },
1513 // Finish(sink state)
1514 {
1515 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1516 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1517 IterativeParsingErrorState
1518 },
1519 // Error(sink state)
1520 {
1521 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1522 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1523 IterativeParsingErrorState
1524 },
1525 // ObjectInitial
1526 {
1527 IterativeParsingErrorState, // Left bracket
1528 IterativeParsingErrorState, // Right bracket
1529 IterativeParsingErrorState, // Left curly bracket
1530 IterativeParsingObjectFinishState, // Right curly bracket
1531 IterativeParsingErrorState, // Comma
1532 IterativeParsingErrorState, // Colon
1533 IterativeParsingMemberKeyState, // String
1534 IterativeParsingErrorState, // False
1535 IterativeParsingErrorState, // True
1536 IterativeParsingErrorState, // Null
1537 IterativeParsingErrorState // Number
1538 },
1539 // MemberKey
1540 {
1541 IterativeParsingErrorState, // Left bracket
1542 IterativeParsingErrorState, // Right bracket
1543 IterativeParsingErrorState, // Left curly bracket
1544 IterativeParsingErrorState, // Right curly bracket
1545 IterativeParsingErrorState, // Comma
1546 IterativeParsingKeyValueDelimiterState, // Colon
1547 IterativeParsingErrorState, // String
1548 IterativeParsingErrorState, // False
1549 IterativeParsingErrorState, // True
1550 IterativeParsingErrorState, // Null
1551 IterativeParsingErrorState // Number
1552 },
1553 // KeyValueDelimiter
1554 {
1555 IterativeParsingArrayInitialState, // Left bracket(push MemberValue state)
1556 IterativeParsingErrorState, // Right bracket
1557 IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state)
1558 IterativeParsingErrorState, // Right curly bracket
1559 IterativeParsingErrorState, // Comma
1560 IterativeParsingErrorState, // Colon
1561 IterativeParsingMemberValueState, // String
1562 IterativeParsingMemberValueState, // False
1563 IterativeParsingMemberValueState, // True
1564 IterativeParsingMemberValueState, // Null
1565 IterativeParsingMemberValueState // Number
1566 },
1567 // MemberValue
1568 {
1569 IterativeParsingErrorState, // Left bracket
1570 IterativeParsingErrorState, // Right bracket
1571 IterativeParsingErrorState, // Left curly bracket
1572 IterativeParsingObjectFinishState, // Right curly bracket
1573 IterativeParsingMemberDelimiterState, // Comma
1574 IterativeParsingErrorState, // Colon
1575 IterativeParsingErrorState, // String
1576 IterativeParsingErrorState, // False
1577 IterativeParsingErrorState, // True
1578 IterativeParsingErrorState, // Null
1579 IterativeParsingErrorState // Number
1580 },
1581 // MemberDelimiter
1582 {
1583 IterativeParsingErrorState, // Left bracket
1584 IterativeParsingErrorState, // Right bracket
1585 IterativeParsingErrorState, // Left curly bracket
1586 IterativeParsingObjectFinishState, // Right curly bracket
1587 IterativeParsingErrorState, // Comma
1588 IterativeParsingErrorState, // Colon
1589 IterativeParsingMemberKeyState, // String
1590 IterativeParsingErrorState, // False
1591 IterativeParsingErrorState, // True
1592 IterativeParsingErrorState, // Null
1593 IterativeParsingErrorState // Number
1594 },
1595 // ObjectFinish(sink state)
1596 {
1597 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1598 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1599 IterativeParsingErrorState
1600 },
1601 // ArrayInitial
1602 {
1603 IterativeParsingArrayInitialState, // Left bracket(push Element state)
1604 IterativeParsingArrayFinishState, // Right bracket
1605 IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1606 IterativeParsingErrorState, // Right curly bracket
1607 IterativeParsingErrorState, // Comma
1608 IterativeParsingErrorState, // Colon
1609 IterativeParsingElementState, // String
1610 IterativeParsingElementState, // False
1611 IterativeParsingElementState, // True
1612 IterativeParsingElementState, // Null
1613 IterativeParsingElementState // Number
1614 },
1615 // Element
1616 {
1617 IterativeParsingErrorState, // Left bracket
1618 IterativeParsingArrayFinishState, // Right bracket
1619 IterativeParsingErrorState, // Left curly bracket
1620 IterativeParsingErrorState, // Right curly bracket
1621 IterativeParsingElementDelimiterState, // Comma
1622 IterativeParsingErrorState, // Colon
1623 IterativeParsingErrorState, // String
1624 IterativeParsingErrorState, // False
1625 IterativeParsingErrorState, // True
1626 IterativeParsingErrorState, // Null
1627 IterativeParsingErrorState // Number
1628 },
1629 // ElementDelimiter
1630 {
1631 IterativeParsingArrayInitialState, // Left bracket(push Element state)
1632 IterativeParsingArrayFinishState, // Right bracket
1633 IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1634 IterativeParsingErrorState, // Right curly bracket
1635 IterativeParsingErrorState, // Comma
1636 IterativeParsingErrorState, // Colon
1637 IterativeParsingElementState, // String
1638 IterativeParsingElementState, // False
1639 IterativeParsingElementState, // True
1640 IterativeParsingElementState, // Null
1641 IterativeParsingElementState // Number
1642 },
1643 // ArrayFinish(sink state)
1644 {
1645 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1646 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1647 IterativeParsingErrorState
1648 },
1649 // Single Value (sink state)
1650 {
1651 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1652 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1653 IterativeParsingErrorState
1654 }
1655 }; // End of G
1656
1657 return static_cast<IterativeParsingState>(G[state][token]);
1658 }
1659
1660 // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
1661 // May return a new state on state pop.
1662 template <unsigned parseFlags, typename InputStream, typename Handler>
1663 RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
1664 (void)token;
1665
1666 switch (dst) {
1667 case IterativeParsingErrorState:
1668 return dst;
1669
1670 case IterativeParsingObjectInitialState:
1671 case IterativeParsingArrayInitialState:
1672 {
1673 // Push the state(Element or MemeberValue) if we are nested in another array or value of member.
1674 // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
1675 IterativeParsingState n = src;
1676 if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
1677 n = IterativeParsingElementState;
1678 else if (src == IterativeParsingKeyValueDelimiterState)
1679 n = IterativeParsingMemberValueState;
1680 // Push current state.
1681 *stack_.template Push<SizeType>(1) = n;
1682 // Initialize and push the member/element count.
1683 *stack_.template Push<SizeType>(1) = 0;
1684 // Call handler
1685 bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
1686 // On handler short circuits the parsing.
1687 if (!hr) {
1688 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1689 return IterativeParsingErrorState;
1690 }
1691 else {
1692 is.Take();
1693 return dst;
1694 }
1695 }
1696
1697 case IterativeParsingMemberKeyState:
1698 ParseString<parseFlags>(is, handler, true);
1699 if (HasParseError())
1700 return IterativeParsingErrorState;
1701 else
1702 return dst;
1703
1704 case IterativeParsingKeyValueDelimiterState:
1705 RAPIDJSON_ASSERT(token == ColonToken);
1706 is.Take();
1707 return dst;
1708
1709 case IterativeParsingMemberValueState:
1710 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1711 ParseValue<parseFlags>(is, handler);
1712 if (HasParseError()) {
1713 return IterativeParsingErrorState;
1714 }
1715 return dst;
1716
1717 case IterativeParsingElementState:
1718 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1719 ParseValue<parseFlags>(is, handler);
1720 if (HasParseError()) {
1721 return IterativeParsingErrorState;
1722 }
1723 return dst;
1724
1725 case IterativeParsingMemberDelimiterState:
1726 case IterativeParsingElementDelimiterState:
1727 is.Take();
1728 // Update member/element count.
1729 *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
1730 return dst;
1731
1732 case IterativeParsingObjectFinishState:
1733 {
1734 // Transit from delimiter is only allowed when trailing commas are enabled
1735 if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {
1736 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell());
1737 return IterativeParsingErrorState;
1738 }
1739 // Get member count.
1740 SizeType c = *stack_.template Pop<SizeType>(1);
1741 // If the object is not empty, count the last member.
1742 if (src == IterativeParsingMemberValueState)
1743 ++c;
1744 // Restore the state.
1745 IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1746 // Transit to Finish state if this is the topmost scope.
1747 if (n == IterativeParsingStartState)
1748 n = IterativeParsingFinishState;
1749 // Call handler
1750 bool hr = handler.EndObject(c);
1751 // On handler short circuits the parsing.
1752 if (!hr) {
1753 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1754 return IterativeParsingErrorState;
1755 }
1756 else {
1757 is.Take();
1758 return n;
1759 }
1760 }
1761
1762 case IterativeParsingArrayFinishState:
1763 {
1764 // Transit from delimiter is only allowed when trailing commas are enabled
1765 if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {
1766 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell());
1767 return IterativeParsingErrorState;
1768 }
1769 // Get element count.
1770 SizeType c = *stack_.template Pop<SizeType>(1);
1771 // If the array is not empty, count the last element.
1772 if (src == IterativeParsingElementState)
1773 ++c;
1774 // Restore the state.
1775 IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1776 // Transit to Finish state if this is the topmost scope.
1777 if (n == IterativeParsingStartState)
1778 n = IterativeParsingFinishState;
1779 // Call handler
1780 bool hr = handler.EndArray(c);
1781 // On handler short circuits the parsing.
1782 if (!hr) {
1783 RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1784 return IterativeParsingErrorState;
1785 }
1786 else {
1787 is.Take();
1788 return n;
1789 }
1790 }
1791
1792 default:
1793 // This branch is for IterativeParsingValueState actually.
1794 // Use `default:` rather than
1795 // `case IterativeParsingValueState:` is for code coverage.
1796
1797 // The IterativeParsingStartState is not enumerated in this switch-case.
1798 // It is impossible for that case. And it can be caught by following assertion.
1799
1800 // The IterativeParsingFinishState is not enumerated in this switch-case either.
1801 // It is a "derivative" state which cannot triggered from Predict() directly.
1802 // Therefore it cannot happen here. And it can be caught by following assertion.
1803 RAPIDJSON_ASSERT(dst == IterativeParsingValueState);
1804
1805 // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1806 ParseValue<parseFlags>(is, handler);
1807 if (HasParseError()) {
1808 return IterativeParsingErrorState;
1809 }
1810 return IterativeParsingFinishState;
1811 }
1812 }
1813
1814 template <typename InputStream>
1815 void HandleError(IterativeParsingState src, InputStream& is) {
1816 if (HasParseError()) {
1817 // Error flag has been set.
1818 return;
1819 }
1820
1821 switch (src) {
1822 case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
1823 case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
1824 case IterativeParsingObjectInitialState:
1825 case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
1826 case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
1827 case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
1828 case IterativeParsingKeyValueDelimiterState:
1829 case IterativeParsingArrayInitialState:
1830 case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return;
1831 default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
1832 }
1833 }
1834
1835 template <unsigned parseFlags, typename InputStream, typename Handler>
1836 ParseResult IterativeParse(InputStream& is, Handler& handler) {
1837 parseResult_.Clear();
1838 ClearStackOnExit scope(*this);
1839 IterativeParsingState state = IterativeParsingStartState;
1840
1841 SkipWhitespaceAndComments<parseFlags>(is);
1842 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
1843 while (is.Peek() != '\0') {
1844 Token t = Tokenize(is.Peek());
1845 IterativeParsingState n = Predict(state, t);
1846 IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
1847
1848 if (d == IterativeParsingErrorState) {
1849 HandleError(state, is);
1850 break;
1851 }
1852
1853 state = d;
1854
1855 // Do not further consume streams if a root JSON has been parsed.
1856 if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
1857 break;
1858
1859 SkipWhitespaceAndComments<parseFlags>(is);
1860 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
1861 }
1862
1863 // Handle the end of file.
1864 if (state != IterativeParsingFinishState)
1865 HandleError(state, is);
1866
1867 return parseResult_;
1868 }
1869
1870 static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string.
1871 internal::Stack<StackAllocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing.
1872 ParseResult parseResult_;
1873}; // class GenericReader
1874
1875//! Reader with UTF8 encoding and default allocator.
1876typedef GenericReader<UTF8<>, UTF8<> > Reader;
1877
1878RAPIDJSON_NAMESPACE_END
1879
1880#ifdef __clang__
1881RAPIDJSON_DIAG_POP
1882#endif
1883
1884
1885#ifdef __GNUC__
1886RAPIDJSON_DIAG_POP
1887#endif
1888
1889#ifdef _MSC_VER
1890RAPIDJSON_DIAG_POP
1891#endif
1892
1893#endif // RAPIDJSON_READER_H_
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition reader.h:467
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
Definition reader.h:535
SourceEncoding::Ch Ch
SourceEncoding character type
Definition reader.h:469
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text (with kParseDefaultFlags)
Definition reader.h:527
GenericReader(StackAllocator *stackAllocator=0, size_t stackCapacity=kDefaultStackCapacity)
Constructor.
Definition reader.h:475
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition reader.h:538
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition reader.h:532
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition reader.h:486
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
Concept for reading and writing characters.
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition rapidjson.h:455
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition rapidjson.h:468
#define RAPIDJSON_PARSE_DEFAULT_FLAGS
User-defined kParseDefaultFlags definition.
Definition reader.h:140
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:402
ParseErrorCode
Error code of parsing.
Definition error.h:64
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)
Macro to indicate a parse error.
Definition reader.h:100
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition reader.h:119
@ kParseErrorDocumentEmpty
The document is empty.
Definition error.h:67
@ kParseErrorDocumentRootNotSingular
The document root must not follow by other values.
Definition error.h:68
@ kParseErrorStringInvalidEncoding
Invalid encoding in string.
Definition error.h:82
Result of parsing (wraps ParseErrorCode)
Definition error.h:106
GenericStringStream< UTF8< char > > StringStream
String stream with UTF8 encoding.
Definition fwd.h:49
unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition rapidjson.h:380
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition reader.h:265
ParseFlag
Combination of parseFlags
Definition reader.h:146
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition reader.h:148
@ kParseNumbersAsStringsFlag
Parse all numbers (ints/doubles) as strings.
Definition reader.h:154
@ kParseValidateEncodingFlag
Validate encoding of JSON strings.
Definition reader.h:149
@ kParseDefaultFlags
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
Definition reader.h:157
@ kParseIterativeFlag
Iterative(constant complexity in terms of function call stack size) parsing.
Definition reader.h:150
@ kParseNanAndInfFlag
Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
Definition reader.h:156
@ kParseCommentsFlag
Allow one-line (//) and multi-line (/‍**/) comments.
Definition reader.h:153
@ kParseFullPrecisionFlag
Parse number in full precision (but slower).
Definition reader.h:152
@ kParseNoFlags
No flags are set.
Definition reader.h:147
@ kParseStopWhenDoneFlag
After parsing a complete JSON root from stream, stop further processing the rest of stream....
Definition reader.h:151
@ kParseTrailingCommasFlag
Allow trailing commas at the end of objects and arrays.
Definition reader.h:155
GenericReader< UTF8< char >, UTF8< char >, CrtAllocator > Reader
Reader with UTF8 encoding and default allocator.
Definition fwd.h:90
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition rapidjson.h:289
Default implementation of Handler.
Definition reader.h:197
bool RawNumber(const Ch *str, SizeType len, bool copy)
enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
Definition reader.h:211
A read-write string stream.
Definition stream.h:144
Read-only string stream.
Definition stream.h:110
const Ch * src_
Current read position.
Definition stream.h:124