15#ifndef RAPIDJSON_READER_H_
16#define RAPIDJSON_READER_H_
20#include "allocators.h"
22#include "encodedstream.h"
23#include "internal/clzll.h"
24#include "internal/meta.h"
25#include "internal/stack.h"
26#include "internal/strtod.h"
29#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
31#pragma intrinsic(_BitScanForward)
35#elif defined(RAPIDJSON_SSE2)
37#elif defined(RAPIDJSON_NEON)
43RAPIDJSON_DIAG_OFF(old-style-cast)
44RAPIDJSON_DIAG_OFF(padded)
45RAPIDJSON_DIAG_OFF(
switch-
enum)
46#elif defined(_MSC_VER)
48RAPIDJSON_DIAG_OFF(4127)
49RAPIDJSON_DIAG_OFF(4702)
54RAPIDJSON_DIAG_OFF(effc++)
58#define RAPIDJSON_NOTHING
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
65#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
66 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
99#ifndef RAPIDJSON_PARSE_ERROR_NORETURN
100#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
101 RAPIDJSON_MULTILINEMACRO_BEGIN \
102 RAPIDJSON_ASSERT(!HasParseError()); \
103 SetParseError(parseErrorCode, offset); \
104 RAPIDJSON_MULTILINEMACRO_END
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
139#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS
140#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags
197template<
typename Encoding = UTF8<>,
typename Derived =
void>
199 typedef typename Encoding::Ch Ch;
201 typedef typename internal::SelectIf<internal::IsSame<Derived, void>,
BaseReaderHandler, Derived>
::Type Override;
203 bool Default() {
return true; }
204 bool Null() {
return static_cast<Override&
>(*this).Default(); }
205 bool Bool(
bool) {
return static_cast<Override&
>(*this).Default(); }
206 bool Int(
int) {
return static_cast<Override&
>(*this).Default(); }
207 bool Uint(
unsigned) {
return static_cast<Override&
>(*this).Default(); }
208 bool Int64(int64_t) {
return static_cast<Override&
>(*this).Default(); }
209 bool Uint64(uint64_t) {
return static_cast<Override&
>(*this).Default(); }
210 bool Double(
double) {
return static_cast<Override&
>(*this).Default(); }
212 bool RawNumber(
const Ch* str,
SizeType len,
bool copy) {
return static_cast<Override&
>(*this).String(str, len, copy); }
213 bool String(
const Ch*,
SizeType,
bool) {
return static_cast<Override&
>(*this).Default(); }
214 bool StartObject() {
return static_cast<Override&
>(*this).Default(); }
215 bool Key(
const Ch* str,
SizeType len,
bool copy) {
return static_cast<Override&
>(*this).String(str, len, copy); }
216 bool EndObject(
SizeType) {
return static_cast<Override&
>(*this).Default(); }
217 bool StartArray() {
return static_cast<Override&
>(*this).Default(); }
218 bool EndArray(
SizeType) {
return static_cast<Override&
>(*this).Default(); }
226template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
230template<
typename Stream>
245template<
typename Stream>
265template<
typename InputStream>
268 InputStream& s(copy.s);
270 typename InputStream::Ch c;
271 while ((c = s.Peek()) ==
' ' || c ==
'\n' || c ==
'\r' || c ==
'\t')
275inline const char*
SkipWhitespace(
const char* p,
const char* end) {
276 while (p != end && (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t'))
281#ifdef RAPIDJSON_SSE42
283inline const char *SkipWhitespace_SIMD(
const char* p) {
285 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
291 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
292 while (p != nextAligned)
293 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
299 static const char whitespace[16] =
" \n\r\t";
300 const __m128i w = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(whitespace.data()));
303 const __m128i s = _mm_load_si128(
reinterpret_cast<const __m128i *
>(p));
304 const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
310inline const char *SkipWhitespace_SIMD(
const char* p,
const char* end) {
312 if (p != end && (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t'))
318 static const char whitespace[16] =
" \n\r\t";
319 const __m128i w = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(whitespace.data()));
321 for (; p <= end - 16; p += 16) {
322 const __m128i s = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(p));
323 const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
331#elif defined(RAPIDJSON_SSE2)
334inline const char *SkipWhitespace_SIMD(
const char* p) {
336 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
342 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
343 while (p != nextAligned)
344 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
350 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
351 static const char whitespaces[4][16] = { C16(
' '), C16(
'\n'), C16(
'\r'), C16(
'\t') };
354 const __m128i w0 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(whitespaces[0].data()));
355 const __m128i w1 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(whitespaces[1].data()));
356 const __m128i w2 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(whitespaces[2].data()));
357 const __m128i w3 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(whitespaces[3].data()));
360 const __m128i s = _mm_load_si128(
reinterpret_cast<const __m128i *
>(p));
361 __m128i x = _mm_cmpeq_epi8(s, w0);
362 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
363 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
364 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
365 unsigned short r =
static_cast<unsigned short>(~_mm_movemask_epi8(x));
368 unsigned long offset;
369 _BitScanForward(&offset, r);
372 return p + __builtin_ffs(r) - 1;
378inline const char *SkipWhitespace_SIMD(
const char* p,
const char* end) {
380 if (p != end && (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t'))
386 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
387 static const char whitespaces[4][16] = { C16(
' '), C16(
'\n'), C16(
'\r'), C16(
'\t') };
390 const __m128i w0 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(whitespaces[0].data()));
391 const __m128i w1 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(whitespaces[1].data()));
392 const __m128i w2 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(whitespaces[2].data()));
393 const __m128i w3 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(whitespaces[3].data()));
395 for (; p <= end - 16; p += 16) {
396 const __m128i s = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(p));
397 __m128i x = _mm_cmpeq_epi8(s, w0);
398 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
399 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
400 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
401 unsigned short r =
static_cast<unsigned short>(~_mm_movemask_epi8(x));
404 unsigned long offset;
405 _BitScanForward(&offset, r);
408 return p + __builtin_ffs(r) - 1;
416#elif defined(RAPIDJSON_NEON)
419inline const char *SkipWhitespace_SIMD(
const char* p) {
421 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
427 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
428 while (p != nextAligned)
429 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
434 const uint8x16_t w0 = vmovq_n_u8(
' ');
435 const uint8x16_t w1 = vmovq_n_u8(
'\n');
436 const uint8x16_t w2 = vmovq_n_u8(
'\r');
437 const uint8x16_t w3 = vmovq_n_u8(
'\t');
440 const uint8x16_t s = vld1q_u8(
reinterpret_cast<const uint8_t *
>(p));
441 uint8x16_t x = vceqq_u8(s, w0);
442 x = vorrq_u8(x, vceqq_u8(s, w1));
443 x = vorrq_u8(x, vceqq_u8(s, w2));
444 x = vorrq_u8(x, vceqq_u8(s, w3));
448 uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);
449 uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);
453 uint32_t lz = internal::clzll(high);
454 return p + 8 + (lz >> 3);
457 uint32_t lz = internal::clzll(low);
458 return p + (lz >> 3);
463inline const char *SkipWhitespace_SIMD(
const char* p,
const char* end) {
465 if (p != end && (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t'))
470 const uint8x16_t w0 = vmovq_n_u8(
' ');
471 const uint8x16_t w1 = vmovq_n_u8(
'\n');
472 const uint8x16_t w2 = vmovq_n_u8(
'\r');
473 const uint8x16_t w3 = vmovq_n_u8(
'\t');
475 for (; p <= end - 16; p += 16) {
476 const uint8x16_t s = vld1q_u8(
reinterpret_cast<const uint8_t *
>(p));
477 uint8x16_t x = vceqq_u8(s, w0);
478 x = vorrq_u8(x, vceqq_u8(s, w1));
479 x = vorrq_u8(x, vceqq_u8(s, w2));
480 x = vorrq_u8(x, vceqq_u8(s, w3));
484 uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);
485 uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);
489 uint32_t lz = internal::clzll(high);
490 return p + 8 + (lz >> 3);
493 uint32_t lz = internal::clzll(low);
494 return p + (lz >> 3);
506 is.src_ =
const_cast<char*
>(SkipWhitespace_SIMD(is.src_));
511 is.
src_ = SkipWhitespace_SIMD(is.
src_);
515 is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
538template <
typename SourceEncoding,
typename TargetEncoding,
typename StackAllocator = CrtAllocator>
541 typedef typename SourceEncoding::Ch
Ch;
547 GenericReader(StackAllocator* stackAllocator = 0,
size_t stackCapacity = kDefaultStackCapacity) :
548 stack_(stackAllocator, stackCapacity), parseResult_(), state_(IterativeParsingStartState) {}
558 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
561 return IterativeParse<parseFlags>(is, handler);
563 parseResult_.
Clear();
565 ClearStackOnExit scope(*
this);
567 SkipWhitespaceAndComments<parseFlags>(is);
568 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
572 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
575 ParseValue<parseFlags>(is, handler);
576 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
579 SkipWhitespaceAndComments<parseFlags>(is);
580 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
584 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
599 template <
typename InputStream,
typename Handler>
601 return Parse<kParseDefaultFlags>(is, handler);
608 parseResult_.
Clear();
609 state_ = IterativeParsingStartState;
619 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
622 SkipWhitespaceAndComments<parseFlags>(is);
624 Token t = Tokenize(is.Peek());
625 IterativeParsingState n = Predict(state_, t);
626 IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
631 if (d == IterativeParsingErrorState) {
632 HandleError(state_, is);
643 SkipWhitespaceAndComments<parseFlags>(is);
644 if (is.Peek() !=
'\0') {
646 HandleError(state_, is);
659 if (!IsIterativeParsingDelimiterState(n))
666 if (state_ != IterativeParsingFinishState) {
667 HandleError(state_, is);
678 return IsIterativeParsingCompleteState(state_);
691 void SetParseError(
ParseErrorCode code,
size_t offset) { parseResult_.
Set(code, offset); }
698 void ClearStack() { stack_.Clear(); }
701 struct ClearStackOnExit {
703 ~ClearStackOnExit() { r_.ClearStack(); }
706 ClearStackOnExit(
const ClearStackOnExit&);
707 ClearStackOnExit& operator=(
const ClearStackOnExit&);
710 template<
unsigned parseFlags,
typename InputStream>
711 void SkipWhitespaceAndComments(InputStream& is) {
716 if (Consume(is,
'*')) {
720 else if (Consume(is,
'*')) {
721 if (Consume(is,
'/'))
729 while (is.Peek() !=
'\0' && is.Take() !=
'\n') {}
739 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
740 void ParseObject(InputStream& is,
Handler& handler) {
747 SkipWhitespaceAndComments<parseFlags>(is);
748 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
750 if (Consume(is,
'}')) {
760 ParseString<parseFlags>(is, handler,
true);
761 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
763 SkipWhitespaceAndComments<parseFlags>(is);
764 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
769 SkipWhitespaceAndComments<parseFlags>(is);
770 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
772 ParseValue<parseFlags>(is, handler);
773 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
775 SkipWhitespaceAndComments<parseFlags>(is);
776 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
783 SkipWhitespaceAndComments<parseFlags>(is);
784 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
796 if (is.Peek() ==
'}') {
807 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
808 void ParseArray(InputStream& is,
Handler& handler) {
815 SkipWhitespaceAndComments<parseFlags>(is);
816 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
818 if (Consume(is,
']')) {
825 ParseValue<parseFlags>(is, handler);
826 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
829 SkipWhitespaceAndComments<parseFlags>(is);
830 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
832 if (Consume(is,
',')) {
833 SkipWhitespaceAndComments<parseFlags>(is);
834 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
836 else if (Consume(is,
']')) {
845 if (is.Peek() ==
']') {
855 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
856 void ParseNull(InputStream& is,
Handler& handler) {
860 if (
RAPIDJSON_LIKELY(Consume(is,
'u') && Consume(is,
'l') && Consume(is,
'l'))) {
868 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
869 void ParseTrue(InputStream& is,
Handler& handler) {
873 if (
RAPIDJSON_LIKELY(Consume(is,
'r') && Consume(is,
'u') && Consume(is,
'e'))) {
881 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
882 void ParseFalse(InputStream& is,
Handler& handler) {
886 if (
RAPIDJSON_LIKELY(Consume(is,
'a') && Consume(is,
'l') && Consume(is,
's') && Consume(is,
'e'))) {
894 template<
typename InputStream>
895 RAPIDJSON_FORCEINLINE
static bool Consume(InputStream& is,
typename InputStream::Ch expect) {
905 template<
typename InputStream>
906 unsigned ParseHex4(InputStream& is,
size_t escapeOffset) {
907 unsigned codepoint = 0;
908 for (
int i = 0; i < 4; i++) {
911 codepoint +=
static_cast<unsigned>(c);
912 if (c >=
'0' && c <=
'9')
914 else if (c >=
'A' && c <=
'F')
915 codepoint -=
'A' - 10;
916 else if (c >=
'a' && c <=
'f')
917 codepoint -=
'a' - 10;
920 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
927 template <
typename CharType>
933 RAPIDJSON_FORCEINLINE
void Put(Ch c) {
934 *stack_.template Push<Ch>() = c;
938 RAPIDJSON_FORCEINLINE
void* Push(
SizeType count) {
940 return stack_.template Push<Ch>(count);
943 size_t Length()
const {
return length_; }
946 return stack_.template Pop<Ch>(length_);
950 StackStream(
const StackStream&);
951 StackStream& operator=(
const StackStream&);
958 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
959 void ParseString(InputStream& is,
Handler& handler,
bool isKey =
false) {
961 InputStream& s(copy.s);
966 bool success =
false;
968 typename InputStream::Ch *head = s.PutBegin();
969 ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
970 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
971 size_t length = s.PutEnd(head) - 1;
973 const typename TargetEncoding::Ch*
const str =
reinterpret_cast<typename TargetEncoding::Ch*
>(head);
974 success = (isKey ? handler.Key(str,
SizeType(length),
false) : handler.String(str,
SizeType(length),
false));
977 StackStream<typename TargetEncoding::Ch> stackStream(stack_);
978 ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
979 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
981 const typename TargetEncoding::Ch*
const str = stackStream.Pop();
982 success = (isKey ? handler.Key(str, length,
true) : handler.String(str, length,
true));
990 template<
unsigned parseFlags,
typename SEncoding,
typename TEncoding,
typename InputStream,
typename OutputStream>
991 RAPIDJSON_FORCEINLINE
void ParseStringToStream(InputStream& is, OutputStream& os) {
993#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
994 static const char escape[256] = {
995 Z16, Z16, 0, 0,
'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'/',
996 Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
997 0, 0,
'\b', 0, 0, 0,
'\f', 0, 0, 0, 0, 0, 0, 0,
'\n', 0,
998 0, 0,
'\r', 0,
'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
999 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
1007 ScanCopyUnescapedString(is, os);
1011 size_t escapeOffset = is.Tell();
1014 if ((
sizeof(
Ch) == 1 ||
unsigned(e) < 256) &&
RAPIDJSON_LIKELY(escape[
static_cast<unsigned char>(e)])) {
1016 os.Put(
static_cast<typename TEncoding::Ch
>(escape[
static_cast<unsigned char>(e)]));
1024 unsigned codepoint = ParseHex4(is, escapeOffset);
1025 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
1030 unsigned codepoint2 = ParseHex4(is, escapeOffset);
1031 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
1034 codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
1036 TEncoding::Encode(os, codepoint);
1053 size_t offset = is.Tell();
1062 template<
typename InputStream,
typename OutputStream>
1063 static RAPIDJSON_FORCEINLINE
void ScanCopyUnescapedString(InputStream&, OutputStream&) {
1067#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
1069 static RAPIDJSON_FORCEINLINE
void ScanCopyUnescapedString(
StringStream& is, StackStream<char>& os) {
1070 const char* p = is.
src_;
1073 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
1074 while (p != nextAligned)
1083 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
1084 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
1085 static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1086 const __m128i dq = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(dquote.data()));
1087 const __m128i bs = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(bslash.data()));
1088 const __m128i sp = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(space.data()));
1091 const __m128i s = _mm_load_si128(
reinterpret_cast<const __m128i *
>(p));
1092 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1093 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1094 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp);
1095 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1096 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
1100 unsigned long offset;
1101 _BitScanForward(&offset, r);
1104 length =
static_cast<SizeType>(__builtin_ffs(r) - 1);
1107 char* q =
reinterpret_cast<char*
>(os.Push(length));
1108 for (
size_t i = 0; i < length; i++)
1115 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(os.Push(16)), s);
1126 if (is.src_ == is.dst_) {
1127 SkipUnescapedString(is);
1135 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
1136 while (p != nextAligned)
1146 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
1147 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
1148 static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1149 const __m128i dq = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(dquote.data()));
1150 const __m128i bs = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(bslash.data()));
1151 const __m128i sp = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(space.data()));
1153 for (;; p += 16, q += 16) {
1154 const __m128i s = _mm_load_si128(
reinterpret_cast<const __m128i *
>(p));
1155 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1156 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1157 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp);
1158 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1159 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
1163 unsigned long offset;
1164 _BitScanForward(&offset, r);
1167 length =
static_cast<size_t>(__builtin_ffs(r) - 1);
1169 for (
const char* pend = p + length; p != pend; )
1173 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(q), s);
1186 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
1187 for (; p != nextAligned; p++)
1189 is.src_ = is.dst_ = p;
1194 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
1195 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
1196 static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1197 const __m128i dq = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(dquote.data()));
1198 const __m128i bs = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(bslash.data()));
1199 const __m128i sp = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(space.data()));
1202 const __m128i s = _mm_load_si128(
reinterpret_cast<const __m128i *
>(p));
1203 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1204 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1205 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp);
1206 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1207 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
1211 unsigned long offset;
1212 _BitScanForward(&offset, r);
1215 length =
static_cast<size_t>(__builtin_ffs(r) - 1);
1222 is.src_ = is.dst_ = p;
1224#elif defined(RAPIDJSON_NEON)
1226 static RAPIDJSON_FORCEINLINE
void ScanCopyUnescapedString(
StringStream& is, StackStream<char>& os) {
1227 const char* p = is.
src_;
1230 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
1231 while (p != nextAligned)
1240 const uint8x16_t s0 = vmovq_n_u8(
'"');
1241 const uint8x16_t s1 = vmovq_n_u8(
'\\');
1242 const uint8x16_t s2 = vmovq_n_u8(
'\b');
1243 const uint8x16_t s3 = vmovq_n_u8(32);
1246 const uint8x16_t s = vld1q_u8(
reinterpret_cast<const uint8_t *
>(p));
1247 uint8x16_t x = vceqq_u8(s, s0);
1248 x = vorrq_u8(x, vceqq_u8(s, s1));
1249 x = vorrq_u8(x, vceqq_u8(s, s2));
1250 x = vorrq_u8(x, vcltq_u8(s, s3));
1253 uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);
1254 uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);
1257 bool escaped =
false;
1260 uint32_t lz = internal::clzll(high);
1261 length = 8 + (lz >> 3);
1265 uint32_t lz = internal::clzll(low);
1271 char* q =
reinterpret_cast<char*
>(os.Push(length));
1272 for (
size_t i = 0; i < length; i++)
1279 vst1q_u8(
reinterpret_cast<uint8_t *
>(os.Push(16)), s);
1290 if (is.src_ == is.dst_) {
1291 SkipUnescapedString(is);
1299 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
1300 while (p != nextAligned)
1310 const uint8x16_t s0 = vmovq_n_u8(
'"');
1311 const uint8x16_t s1 = vmovq_n_u8(
'\\');
1312 const uint8x16_t s2 = vmovq_n_u8(
'\b');
1313 const uint8x16_t s3 = vmovq_n_u8(32);
1315 for (;; p += 16, q += 16) {
1316 const uint8x16_t s = vld1q_u8(
reinterpret_cast<uint8_t *
>(p));
1317 uint8x16_t x = vceqq_u8(s, s0);
1318 x = vorrq_u8(x, vceqq_u8(s, s1));
1319 x = vorrq_u8(x, vceqq_u8(s, s2));
1320 x = vorrq_u8(x, vcltq_u8(s, s3));
1323 uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);
1324 uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);
1327 bool escaped =
false;
1330 uint32_t lz = internal::clzll(high);
1331 length = 8 + (lz >> 3);
1335 uint32_t lz = internal::clzll(low);
1340 for (
const char* pend = p + length; p != pend; ) {
1345 vst1q_u8(
reinterpret_cast<uint8_t *
>(q), s);
1358 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
1359 for (; p != nextAligned; p++)
1361 is.src_ = is.dst_ = p;
1366 const uint8x16_t s0 = vmovq_n_u8(
'"');
1367 const uint8x16_t s1 = vmovq_n_u8(
'\\');
1368 const uint8x16_t s2 = vmovq_n_u8(
'\b');
1369 const uint8x16_t s3 = vmovq_n_u8(32);
1372 const uint8x16_t s = vld1q_u8(
reinterpret_cast<uint8_t *
>(p));
1373 uint8x16_t x = vceqq_u8(s, s0);
1374 x = vorrq_u8(x, vceqq_u8(s, s1));
1375 x = vorrq_u8(x, vceqq_u8(s, s2));
1376 x = vorrq_u8(x, vcltq_u8(s, s3));
1379 uint64_t low = vgetq_lane_u64(vreinterpretq_u64_u8(x), 0);
1380 uint64_t high = vgetq_lane_u64(vreinterpretq_u64_u8(x), 1);
1384 uint32_t lz = internal::clzll(high);
1389 uint32_t lz = internal::clzll(low);
1395 is.src_ = is.dst_ = p;
1399 template<
typename InputStream,
bool backup,
bool pushOnTake>
1402 template<
typename InputStream>
1403 class NumberStream<InputStream, false, false> {
1405 typedef typename InputStream::Ch
Ch;
1407 NumberStream(
GenericReader& reader, InputStream& s) : is(s) { (void)reader; }
1409 RAPIDJSON_FORCEINLINE
Ch Peek()
const {
return is.Peek(); }
1410 RAPIDJSON_FORCEINLINE
Ch TakePush() {
return is.Take(); }
1411 RAPIDJSON_FORCEINLINE
Ch Take() {
return is.Take(); }
1412 RAPIDJSON_FORCEINLINE
void Push(
char) {}
1414 size_t Tell() {
return is.Tell(); }
1415 size_t Length() {
return 0; }
1416 const char* Pop() {
return 0; }
1419 NumberStream& operator=(
const NumberStream&);
1424 template<
typename InputStream>
1425 class NumberStream<InputStream, true, false> :
public NumberStream<InputStream, false, false> {
1426 typedef NumberStream<InputStream, false, false> Base;
1428 NumberStream(
GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
1430 RAPIDJSON_FORCEINLINE
Ch TakePush() {
1431 stackStream.Put(
static_cast<char>(Base::is.Peek()));
1432 return Base::is.Take();
1435 RAPIDJSON_FORCEINLINE
void Push(
char c) {
1439 size_t Length() {
return stackStream.Length(); }
1442 stackStream.Put(
'\0');
1443 return stackStream.Pop();
1447 StackStream<char> stackStream;
1450 template<
typename InputStream>
1451 class NumberStream<InputStream, true, true> :
public NumberStream<InputStream, true, false> {
1452 typedef NumberStream<InputStream, true, false> Base;
1454 NumberStream(
GenericReader& reader, InputStream& is) : Base(reader, is) {}
1456 RAPIDJSON_FORCEINLINE
Ch Take() {
return Base::TakePush(); }
1459 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
1460 void ParseNumber(InputStream& is,
Handler& handler) {
1462 NumberStream<InputStream,
1469 size_t startOffset = s.Tell();
1471 bool useNanOrInf =
false;
1474 bool minus = Consume(s,
'-');
1479 bool use64bit =
false;
1480 int significandDigit = 0;
1486 i =
static_cast<unsigned>(s.TakePush() -
'0');
1497 i = i * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1509 i = i * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1515 if (Consume(s,
'N')) {
1516 if (Consume(s,
'a') && Consume(s,
'N')) {
1517 d = std::numeric_limits<double>::quiet_NaN();
1522 if (Consume(s,
'n') && Consume(s,
'f')) {
1523 d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
1527 && Consume(s,
'i') && Consume(s,
't') && Consume(s,
'y')))) {
1541 bool useDouble =
false;
1547 d =
static_cast<double>(i64);
1551 i64 = i64 * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1558 d =
static_cast<double>(i64);
1562 i64 = i64 * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1570 d = d * 10 + (s.TakePush() -
'0');
1576 size_t decimalPosition;
1577 if (Consume(s,
'.')) {
1578 decimalPosition = s.Length();
1593 i64 = i64 * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1600 d =
static_cast<double>(i64);
1603 d =
static_cast<double>(use64bit ? i64 : i);
1609 if (significandDigit < 17) {
1610 d = d * 10.0 + (s.TakePush() -
'0');
1620 decimalPosition = s.Length();
1624 if (Consume(s,
'e') || Consume(s,
'E')) {
1626 d =
static_cast<double>(use64bit ? i64 : i);
1630 bool expMinus =
false;
1631 if (Consume(s,
'+'))
1633 else if (Consume(s,
'-'))
1637 exp =
static_cast<int>(s.Take() -
'0');
1646 int maxExp = (expFrac + 2147483639) / 10;
1649 exp = exp * 10 +
static_cast<int>(s.Take() -
'0');
1657 int maxExp = 308 - expFrac;
1659 exp = exp * 10 +
static_cast<int>(s.Take() -
'0');
1678 typename InputStream::Ch* head = is.PutBegin();
1679 const size_t length = s.Tell() - startOffset;
1682 const typename TargetEncoding::Ch*
const str =
reinterpret_cast<typename TargetEncoding::Ch*
>(head);
1683 cont = handler.RawNumber(str,
SizeType(length),
false);
1688 StackStream<typename TargetEncoding::Ch> dstStream(stack_);
1689 while (numCharsToCopy--) {
1692 dstStream.Put(
'\0');
1693 const typename TargetEncoding::Ch* str = dstStream.Pop();
1695 cont = handler.RawNumber(str,
SizeType(length),
true);
1699 size_t length = s.Length();
1700 const char* decimal = s.Pop();
1703 int p = exp + expFrac;
1705 d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
1707 d = internal::StrtodNormalPrecision(d, p);
1710 if (d > (std::numeric_limits<double>::max)()) {
1716 cont = handler.Double(minus ? -d : d);
1718 else if (useNanOrInf) {
1719 cont = handler.Double(d);
1724 cont = handler.Int64(
static_cast<int64_t
>(~i64 + 1));
1726 cont = handler.Uint64(i64);
1730 cont = handler.Int(
static_cast<int32_t
>(~i + 1));
1732 cont = handler.Uint(i);
1741 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
1742 void ParseValue(InputStream& is,
Handler& handler) {
1743 switch (is.Peek()) {
1744 case 'n': ParseNull <parseFlags>(is, handler);
break;
1745 case 't': ParseTrue <parseFlags>(is, handler);
break;
1746 case 'f': ParseFalse <parseFlags>(is, handler);
break;
1747 case '"': ParseString<parseFlags>(is, handler);
break;
1748 case '{': ParseObject<parseFlags>(is, handler);
break;
1749 case '[': ParseArray <parseFlags>(is, handler);
break;
1751 ParseNumber<parseFlags>(is, handler);
1760 enum IterativeParsingState {
1761 IterativeParsingFinishState = 0,
1762 IterativeParsingErrorState,
1763 IterativeParsingStartState,
1766 IterativeParsingObjectInitialState,
1767 IterativeParsingMemberKeyState,
1768 IterativeParsingMemberValueState,
1769 IterativeParsingObjectFinishState,
1772 IterativeParsingArrayInitialState,
1773 IterativeParsingElementState,
1774 IterativeParsingArrayFinishState,
1777 IterativeParsingValueState,
1780 IterativeParsingElementDelimiterState,
1781 IterativeParsingMemberDelimiterState,
1782 IterativeParsingKeyValueDelimiterState,
1784 cIterativeParsingStateCount
1789 LeftBracketToken = 0,
1792 LeftCurlyBracketToken,
1793 RightCurlyBracketToken,
1807 RAPIDJSON_FORCEINLINE Token Tokenize(
Ch c)
const {
1810#define N NumberToken
1811#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1813 static const unsigned char tokenMap[256] = {
1816 N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N,
1817 N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N,
1819 N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N,
1820 N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N,
1821 N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N,
1822 N16, N16, N16, N16, N16, N16, N16, N16
1828 if (
sizeof(
Ch) == 1 ||
static_cast<unsigned>(c) < 256)
1829 return static_cast<Token
>(tokenMap[
static_cast<unsigned char>(c)]);
1834 RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token)
const {
1836 static const char G[cIterativeParsingStateCount][kTokenCount] = {
1839 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1840 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1841 IterativeParsingErrorState
1845 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1846 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1847 IterativeParsingErrorState
1851 IterativeParsingArrayInitialState,
1852 IterativeParsingErrorState,
1853 IterativeParsingObjectInitialState,
1854 IterativeParsingErrorState,
1855 IterativeParsingErrorState,
1856 IterativeParsingErrorState,
1857 IterativeParsingValueState,
1858 IterativeParsingValueState,
1859 IterativeParsingValueState,
1860 IterativeParsingValueState,
1861 IterativeParsingValueState
1865 IterativeParsingErrorState,
1866 IterativeParsingErrorState,
1867 IterativeParsingErrorState,
1868 IterativeParsingObjectFinishState,
1869 IterativeParsingErrorState,
1870 IterativeParsingErrorState,
1871 IterativeParsingMemberKeyState,
1872 IterativeParsingErrorState,
1873 IterativeParsingErrorState,
1874 IterativeParsingErrorState,
1875 IterativeParsingErrorState
1879 IterativeParsingErrorState,
1880 IterativeParsingErrorState,
1881 IterativeParsingErrorState,
1882 IterativeParsingErrorState,
1883 IterativeParsingErrorState,
1884 IterativeParsingKeyValueDelimiterState,
1885 IterativeParsingErrorState,
1886 IterativeParsingErrorState,
1887 IterativeParsingErrorState,
1888 IterativeParsingErrorState,
1889 IterativeParsingErrorState
1893 IterativeParsingErrorState,
1894 IterativeParsingErrorState,
1895 IterativeParsingErrorState,
1896 IterativeParsingObjectFinishState,
1897 IterativeParsingMemberDelimiterState,
1898 IterativeParsingErrorState,
1899 IterativeParsingErrorState,
1900 IterativeParsingErrorState,
1901 IterativeParsingErrorState,
1902 IterativeParsingErrorState,
1903 IterativeParsingErrorState
1907 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1908 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1909 IterativeParsingErrorState
1913 IterativeParsingArrayInitialState,
1914 IterativeParsingArrayFinishState,
1915 IterativeParsingObjectInitialState,
1916 IterativeParsingErrorState,
1917 IterativeParsingErrorState,
1918 IterativeParsingErrorState,
1919 IterativeParsingElementState,
1920 IterativeParsingElementState,
1921 IterativeParsingElementState,
1922 IterativeParsingElementState,
1923 IterativeParsingElementState
1927 IterativeParsingErrorState,
1928 IterativeParsingArrayFinishState,
1929 IterativeParsingErrorState,
1930 IterativeParsingErrorState,
1931 IterativeParsingElementDelimiterState,
1932 IterativeParsingErrorState,
1933 IterativeParsingErrorState,
1934 IterativeParsingErrorState,
1935 IterativeParsingErrorState,
1936 IterativeParsingErrorState,
1937 IterativeParsingErrorState
1941 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1942 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1943 IterativeParsingErrorState
1947 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1948 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1949 IterativeParsingErrorState
1953 IterativeParsingArrayInitialState,
1954 IterativeParsingArrayFinishState,
1955 IterativeParsingObjectInitialState,
1956 IterativeParsingErrorState,
1957 IterativeParsingErrorState,
1958 IterativeParsingErrorState,
1959 IterativeParsingElementState,
1960 IterativeParsingElementState,
1961 IterativeParsingElementState,
1962 IterativeParsingElementState,
1963 IterativeParsingElementState
1967 IterativeParsingErrorState,
1968 IterativeParsingErrorState,
1969 IterativeParsingErrorState,
1970 IterativeParsingObjectFinishState,
1971 IterativeParsingErrorState,
1972 IterativeParsingErrorState,
1973 IterativeParsingMemberKeyState,
1974 IterativeParsingErrorState,
1975 IterativeParsingErrorState,
1976 IterativeParsingErrorState,
1977 IterativeParsingErrorState
1981 IterativeParsingArrayInitialState,
1982 IterativeParsingErrorState,
1983 IterativeParsingObjectInitialState,
1984 IterativeParsingErrorState,
1985 IterativeParsingErrorState,
1986 IterativeParsingErrorState,
1987 IterativeParsingMemberValueState,
1988 IterativeParsingMemberValueState,
1989 IterativeParsingMemberValueState,
1990 IterativeParsingMemberValueState,
1991 IterativeParsingMemberValueState
1995 return static_cast<IterativeParsingState
>(G[state][token]);
2000 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
2001 RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is,
Handler& handler) {
2005 case IterativeParsingErrorState:
2008 case IterativeParsingObjectInitialState:
2009 case IterativeParsingArrayInitialState:
2013 IterativeParsingState n = src;
2014 if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
2015 n = IterativeParsingElementState;
2016 else if (src == IterativeParsingKeyValueDelimiterState)
2017 n = IterativeParsingMemberValueState;
2019 *stack_.template Push<SizeType>(1) = n;
2021 *stack_.template Push<SizeType>(1) = 0;
2023 bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
2027 return IterativeParsingErrorState;
2035 case IterativeParsingMemberKeyState:
2036 ParseString<parseFlags>(is, handler,
true);
2038 return IterativeParsingErrorState;
2042 case IterativeParsingKeyValueDelimiterState:
2047 case IterativeParsingMemberValueState:
2049 ParseValue<parseFlags>(is, handler);
2051 return IterativeParsingErrorState;
2055 case IterativeParsingElementState:
2057 ParseValue<parseFlags>(is, handler);
2059 return IterativeParsingErrorState;
2063 case IterativeParsingMemberDelimiterState:
2064 case IterativeParsingElementDelimiterState:
2067 *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
2070 case IterativeParsingObjectFinishState:
2075 return IterativeParsingErrorState;
2078 SizeType c = *stack_.template Pop<SizeType>(1);
2080 if (src == IterativeParsingMemberValueState)
2083 IterativeParsingState n =
static_cast<IterativeParsingState
>(*stack_.template Pop<SizeType>(1));
2085 if (n == IterativeParsingStartState)
2086 n = IterativeParsingFinishState;
2088 bool hr = handler.EndObject(c);
2092 return IterativeParsingErrorState;
2100 case IterativeParsingArrayFinishState:
2105 return IterativeParsingErrorState;
2108 SizeType c = *stack_.template Pop<SizeType>(1);
2110 if (src == IterativeParsingElementState)
2113 IterativeParsingState n =
static_cast<IterativeParsingState
>(*stack_.template Pop<SizeType>(1));
2115 if (n == IterativeParsingStartState)
2116 n = IterativeParsingFinishState;
2118 bool hr = handler.EndArray(c);
2122 return IterativeParsingErrorState;
2144 ParseValue<parseFlags>(is, handler);
2146 return IterativeParsingErrorState;
2148 return IterativeParsingFinishState;
2152 template <
typename InputStream>
2153 void HandleError(IterativeParsingState src, InputStream& is) {
2162 case IterativeParsingObjectInitialState:
2166 case IterativeParsingKeyValueDelimiterState:
2167 case IterativeParsingArrayInitialState:
2173 RAPIDJSON_FORCEINLINE
bool IsIterativeParsingDelimiterState(IterativeParsingState s)
const {
2174 return s >= IterativeParsingElementDelimiterState;
2177 RAPIDJSON_FORCEINLINE
bool IsIterativeParsingCompleteState(IterativeParsingState s)
const {
2178 return s <= IterativeParsingErrorState;
2181 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
2183 parseResult_.
Clear();
2184 ClearStackOnExit scope(*
this);
2185 IterativeParsingState state = IterativeParsingStartState;
2187 SkipWhitespaceAndComments<parseFlags>(is);
2188 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
2189 while (is.Peek() !=
'\0') {
2190 Token t = Tokenize(is.Peek());
2191 IterativeParsingState n = Predict(state, t);
2192 IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
2194 if (d == IterativeParsingErrorState) {
2195 HandleError(state, is);
2205 SkipWhitespaceAndComments<parseFlags>(is);
2206 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
2210 if (state != IterativeParsingFinishState)
2211 HandleError(state, is);
2213 return parseResult_;
2216 static const size_t kDefaultStackCapacity = 256;
2219 IterativeParsingState state_;
2227#if defined(__clang__) || defined(_MSC_VER)
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
bool IterativeParseNext(InputStream &is, Handler &handler)
Parse one token from JSON text.
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text (with kParseDefaultFlags)
void IterativeParseInit()
Initialize JSON text token-by-token parsing.
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const
Check if token-by-token parsing JSON text is complete.
GenericReader(StackAllocator *stackAllocator=0, size_t stackCapacity=kDefaultStackCapacity)
Constructor.
SourceEncoding::Ch Ch
SourceEncoding character type.
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
A type-unsafe stack for storing different types of data.
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.
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
#define RAPIDJSON_ASSERT(x)
Assertion.
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)
Macro to indicate a parse error.
ParseErrorCode
Error code of parsing.
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
@ kParseErrorDocumentEmpty
The document is empty.
@ kParseErrorNumberMissFraction
Miss fraction part in number.
@ kParseErrorStringInvalidEncoding
Invalid encoding in string.
@ kParseErrorValueInvalid
Invalid value.
@ kParseErrorDocumentRootNotSingular
The document root must not follow by other values.
@ kParseErrorUnspecificSyntaxError
Unspecific syntax error.
@ kParseErrorObjectMissCommaOrCurlyBracket
Missing a comma or '}' after an object member.
@ kParseErrorObjectMissColon
Missing a colon after a name of object member.
@ kParseErrorStringMissQuotationMark
Missing a closing quotation mark in string.
@ kParseErrorTermination
Parsing was terminated.
@ kParseErrorNumberMissExponent
Miss exponent in number.
@ kParseErrorStringEscapeInvalid
Invalid escape character in string.
@ kParseErrorArrayMissCommaOrSquareBracket
Missing a comma or ']' after an array element.
@ kParseErrorStringUnicodeSurrogateInvalid
The surrogate pair in string is invalid.
@ kParseErrorObjectMissName
Missing a name for object member.
@ kParseErrorNumberTooBig
Number too big to be stored in double.
@ kParseErrorStringUnicodeEscapeInvalidHex
Incorrect hex digit after \u escape in string.
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
GenericReader< UTF8<>, UTF8<> > Reader
Reader with UTF8 encoding and default allocator.
ParseFlag
Combination of parseFlags.
@ kParseFullPrecisionFlag
Parse number in full precision (but slower).
@ kParseInsituFlag
In-situ(destructive) parsing.
@ kParseNoFlags
No flags are set.
@ kParseCommentsFlag
Allow one-line (//) and multi-line (/**/) comments.
@ kParseEscapedApostropheFlag
Allow escaped apostrophe in strings.
@ kParseDefaultFlags
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS.
@ kParseTrailingCommasFlag
Allow trailing commas at the end of objects and arrays.
@ kParseNanAndInfFlag
Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
@ kParseValidateEncodingFlag
Validate encoding of JSON strings.
@ kParseNumbersAsStringsFlag
Parse all numbers (ints/doubles) as strings.
@ kParseIterativeFlag
Iterative(constant complexity in terms of function call stack size) parsing.
@ kParseStopWhenDoneFlag
After parsing a complete JSON root from stream, stop further processing the rest of stream....
Default implementation of Handler.
bool RawNumber(const Ch *str, SizeType len, bool copy)
enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
A read-write string stream.
const Ch * src_
Current read position.
Represents an in-memory input byte stream.
Result of parsing (wraps ParseErrorCode)
ParseErrorCode Code() const
Get the error code.
void Clear()
Reset error code.
void Set(ParseErrorCode code, size_t offset=0)
Update error code and offset.
bool IsError() const
Whether the result is an error.
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.