15#ifndef RAPIDJSON_READER_H_
16#define RAPIDJSON_READER_H_
28#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
30#pragma intrinsic(_BitScanForward)
34#elif defined(RAPIDJSON_SSE2)
36#elif defined(RAPIDJSON_NEON)
42RAPIDJSON_DIAG_OFF(old-style-cast)
43RAPIDJSON_DIAG_OFF(padded)
44RAPIDJSON_DIAG_OFF(
switch-
enum)
45#elif defined(_MSC_VER)
47RAPIDJSON_DIAG_OFF(4127)
48RAPIDJSON_DIAG_OFF(4702)
53RAPIDJSON_DIAG_OFF(effc++)
57#define RAPIDJSON_NOTHING
58#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
59#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
60 RAPIDJSON_MULTILINEMACRO_BEGIN \
61 if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
62 RAPIDJSON_MULTILINEMACRO_END
64#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
65 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
98#ifndef RAPIDJSON_PARSE_ERROR_NORETURN
99#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
100 RAPIDJSON_MULTILINEMACRO_BEGIN \
101 RAPIDJSON_ASSERT(!HasParseError()); \
102 SetParseError(parseErrorCode, offset); \
103 RAPIDJSON_MULTILINEMACRO_END
117#ifndef RAPIDJSON_PARSE_ERROR
118#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \
119 RAPIDJSON_MULTILINEMACRO_BEGIN \
120 RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
121 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
122 RAPIDJSON_MULTILINEMACRO_END
138#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS
139#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags
178 bool RawNumber(const Ch* str, SizeType length, bool copy);
179 bool String(const Ch* str, SizeType length, bool copy);
181 bool Key(const Ch* str, SizeType length, bool copy);
182 bool EndObject(SizeType memberCount);
184 bool EndArray(SizeType elementCount);
195template<
typename Encoding = UTF8<>,
typename Derived =
void>
197 typedef typename Encoding::Ch
Ch;
205 bool Uint(
unsigned) {
return static_cast<Override&
>(*this).Default(); }
224template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
228template<
typename Stream>
243template<
typename Stream>
263template<
typename InputStream>
266 InputStream&
s(copy.s);
268 typename InputStream::Ch c;
269 while ((c =
s.Peek()) ==
' ' || c ==
'\n' || c ==
'\r' || c ==
'\t')
274 while (p != end && (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t'))
279#ifdef RAPIDJSON_SSE42
281inline const char *SkipWhitespace_SIMD(
const char* p) {
283 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
289 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
290 while (p != nextAligned)
291 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
297 static const char whitespace[16] =
" \n\r\t";
298 const __m128i w = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&whitespace[0]));
301 const __m128i
s = _mm_load_si128(
reinterpret_cast<const __m128i *
>(p));
302 const int r = _mm_cmpistri(w,
s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
308inline const char *SkipWhitespace_SIMD(
const char* p,
const char* end) {
310 if (p != end && (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t'))
316 static const char whitespace[16] =
" \n\r\t";
317 const __m128i w = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&whitespace[0]));
319 for (; p <= end - 16; p += 16) {
320 const __m128i
s = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(p));
321 const int r = _mm_cmpistri(w,
s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
329#elif defined(RAPIDJSON_SSE2)
332inline const char *SkipWhitespace_SIMD(
const char* p) {
334 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
340 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
341 while (p != nextAligned)
342 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
348 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
349 static const char whitespaces[4][16] = { C16(
' '), C16(
'\n'), C16(
'\r'), C16(
'\t') };
352 const __m128i
w0 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&whitespaces[0][0]));
353 const __m128i
w1 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&whitespaces[1][0]));
354 const __m128i
w2 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&whitespaces[2][0]));
355 const __m128i
w3 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&whitespaces[3][0]));
358 const __m128i
s = _mm_load_si128(
reinterpret_cast<const __m128i *
>(p));
359 __m128i x = _mm_cmpeq_epi8(
s,
w0);
360 x = _mm_or_si128(x, _mm_cmpeq_epi8(
s,
w1));
361 x = _mm_or_si128(x, _mm_cmpeq_epi8(
s,
w2));
362 x = _mm_or_si128(x, _mm_cmpeq_epi8(
s,
w3));
363 unsigned short r =
static_cast<unsigned short>(~_mm_movemask_epi8(x));
366 unsigned long offset;
367 _BitScanForward(&offset, r);
370 return p + __builtin_ffs(r) - 1;
376inline const char *SkipWhitespace_SIMD(
const char* p,
const char* end) {
378 if (p != end && (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t'))
384 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
385 static const char whitespaces[4][16] = { C16(
' '), C16(
'\n'), C16(
'\r'), C16(
'\t') };
388 const __m128i
w0 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&whitespaces[0][0]));
389 const __m128i
w1 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&whitespaces[1][0]));
390 const __m128i
w2 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&whitespaces[2][0]));
391 const __m128i
w3 = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&whitespaces[3][0]));
393 for (; p <= end - 16; p += 16) {
394 const __m128i
s = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(p));
395 __m128i x = _mm_cmpeq_epi8(
s,
w0);
396 x = _mm_or_si128(x, _mm_cmpeq_epi8(
s,
w1));
397 x = _mm_or_si128(x, _mm_cmpeq_epi8(
s,
w2));
398 x = _mm_or_si128(x, _mm_cmpeq_epi8(
s,
w3));
399 unsigned short r =
static_cast<unsigned short>(~_mm_movemask_epi8(x));
402 unsigned long offset;
403 _BitScanForward(&offset, r);
406 return p + __builtin_ffs(r) - 1;
414#elif defined(RAPIDJSON_NEON)
417inline const char *SkipWhitespace_SIMD(
const char* p) {
419 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
425 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
426 while (p != nextAligned)
427 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
432 const uint8x16_t
w0 = vmovq_n_u8(
' ');
433 const uint8x16_t
w1 = vmovq_n_u8(
'\n');
434 const uint8x16_t
w2 = vmovq_n_u8(
'\r');
435 const uint8x16_t
w3 = vmovq_n_u8(
'\t');
438 const uint8x16_t
s = vld1q_u8(
reinterpret_cast<const uint8_t *
>(p));
439 uint8x16_t x = vceqq_u8(
s,
w0);
440 x = vorrq_u8(x, vceqq_u8(
s,
w1));
441 x = vorrq_u8(x, vceqq_u8(
s,
w2));
442 x = vorrq_u8(x, vceqq_u8(
s,
w3));
446 uint64_t low = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 0);
447 uint64_t high = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 1);
451 int lz =__builtin_clzll(high);;
452 return p + 8 + (lz >> 3);
455 int lz = __builtin_clzll(low);;
456 return p + (lz >> 3);
461inline const char *SkipWhitespace_SIMD(
const char* p,
const char* end) {
463 if (p != end && (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t'))
468 const uint8x16_t
w0 = vmovq_n_u8(
' ');
469 const uint8x16_t
w1 = vmovq_n_u8(
'\n');
470 const uint8x16_t
w2 = vmovq_n_u8(
'\r');
471 const uint8x16_t
w3 = vmovq_n_u8(
'\t');
473 for (; p <= end - 16; p += 16) {
474 const uint8x16_t
s = vld1q_u8(
reinterpret_cast<const uint8_t *
>(p));
475 uint8x16_t x = vceqq_u8(
s,
w0);
476 x = vorrq_u8(x, vceqq_u8(
s,
w1));
477 x = vorrq_u8(x, vceqq_u8(
s,
w2));
478 x = vorrq_u8(x, vceqq_u8(
s,
w3));
482 uint64_t low = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 0);
483 uint64_t high = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 1);
487 int lz = __builtin_clzll(high);
488 return p + 8 + (lz >> 3);
491 int lz = __builtin_clzll(low);
492 return p + (lz >> 3);
504 is.
src_ =
const_cast<char*
>(SkipWhitespace_SIMD(is.
src_));
509 is.
src_ = SkipWhitespace_SIMD(is.
src_);
513 is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
536template <
typename SourceEncoding,
typename TargetEncoding,
typename StackAllocator = CrtAllocator>
539 typedef typename SourceEncoding::Ch
Ch;
556 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
563 ClearStackOnExit scope(*
this);
597 template <
typename InputStream,
typename Handler>
617 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
642 if (is.Peek() !=
'\0') {
708 template<
unsigned parseFlags,
typename InputStream>
727 while (is.Peek() !=
'\0' && is.Take() !=
'\n') {}
737 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
746 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
759 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
762 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
768 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
771 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
774 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
782 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
794 if (is.Peek() ==
'}') {
805 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
814 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
824 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
828 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
832 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
843 if (is.Peek() ==
']') {
853 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
866 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
879 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
892 template<
typename InputStream>
893 RAPIDJSON_FORCEINLINE
static bool Consume(InputStream& is,
typename InputStream::Ch
expect) {
903 template<
typename InputStream>
904 unsigned ParseHex4(InputStream& is,
size_t escapeOffset) {
905 unsigned codepoint = 0;
906 for (
int i = 0; i < 4; i++) {
909 codepoint +=
static_cast<unsigned>(c);
910 if (c >=
'0' && c <=
'9')
912 else if (c >=
'A' && c <=
'F')
913 codepoint -=
'A' - 10;
914 else if (c >=
'a' && c <=
'f')
915 codepoint -=
'a' - 10;
918 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
925 template <
typename CharType>
931 RAPIDJSON_FORCEINLINE
void Put(
Ch c) {
956 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
959 InputStream&
s(copy.s);
966 typename InputStream::Ch *head =
s.PutBegin();
968 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
969 size_t length =
s.PutEnd(head) - 1;
971 const typename TargetEncoding::Ch*
const str =
reinterpret_cast<typename TargetEncoding::Ch*
>(head);
975 StackStream<typename TargetEncoding::Ch> stackStream(
stack_);
977 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
979 const typename TargetEncoding::Ch*
const str = stackStream.Pop();
980 success = (isKey ? handler.Key(
str, length,
true) : handler.String(
str, length,
true));
988 template<
unsigned parseFlags,
typename SEncoding,
typename TEncoding,
typename InputStream,
typename OutputStream>
991#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
992 static const char escape[256] = {
993 Z16,
Z16, 0, 0,
'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'/',
994 Z16,
Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
995 0, 0,
'\b', 0, 0, 0,
'\f', 0, 0, 0, 0, 0, 0, 0,
'\n', 0,
996 0, 0,
'\r', 0,
'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1009 size_t escapeOffset = is.Tell();
1012 if ((
sizeof(
Ch) == 1 ||
unsigned(e) < 256) &&
RAPIDJSON_LIKELY(escape[
static_cast<unsigned char>(e)])) {
1014 os.Put(
static_cast<typename TEncoding::Ch
>(escape[
static_cast<unsigned char>(e)]));
1018 unsigned codepoint =
ParseHex4(is, escapeOffset);
1019 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
1024 unsigned codepoint2 =
ParseHex4(is, escapeOffset);
1025 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
1028 codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
1030 TEncoding::Encode(os, codepoint);
1047 size_t offset = is.Tell();
1056 template<
typename InputStream,
typename OutputStream>
1061#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
1064 const char* p = is.
src_;
1067 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
1068 while (p != nextAligned)
1077 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
1078 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
1079 static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1080 const __m128i dq = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&dquote[0]));
1081 const __m128i bs = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&bslash[0]));
1082 const __m128i sp = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&space[0]));
1085 const __m128i
s = _mm_load_si128(
reinterpret_cast<const __m128i *
>(p));
1086 const __m128i
t1 = _mm_cmpeq_epi8(
s, dq);
1087 const __m128i
t2 = _mm_cmpeq_epi8(
s, bs);
1088 const __m128i
t3 = _mm_cmpeq_epi8(_mm_max_epu8(
s, sp), sp);
1089 const __m128i x = _mm_or_si128(_mm_or_si128(
t1,
t2),
t3);
1090 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
1094 unsigned long offset;
1095 _BitScanForward(&offset, r);
1098 length =
static_cast<SizeType>(__builtin_ffs(r) - 1);
1101 char*
q =
reinterpret_cast<char*
>(os.Push(length));
1102 for (
size_t i = 0;
i < length;
i++)
1109 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(os.Push(16)),
s);
1121 SkipUnescapedString(is);
1129 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(
p) + 15) &
static_cast<size_t>(~15));
1130 while (p != nextAligned)
1140 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
1141 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
1142 static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1143 const __m128i dq = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&dquote[0]));
1144 const __m128i bs = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&bslash[0]));
1145 const __m128i sp = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&space[0]));
1147 for (;;
p += 16,
q += 16) {
1148 const __m128i
s = _mm_load_si128(
reinterpret_cast<const __m128i *
>(p));
1149 const __m128i
t1 = _mm_cmpeq_epi8(
s, dq);
1150 const __m128i
t2 = _mm_cmpeq_epi8(
s, bs);
1151 const __m128i
t3 = _mm_cmpeq_epi8(_mm_max_epu8(
s, sp), sp);
1152 const __m128i x = _mm_or_si128(_mm_or_si128(
t1,
t2),
t3);
1153 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
1157 unsigned long offset;
1158 _BitScanForward(&offset, r);
1161 length =
static_cast<size_t>(__builtin_ffs(r) - 1);
1163 for (
const char* pend = p + length;
p != pend; )
1167 _mm_storeu_si128(
reinterpret_cast<__m128i *
>(q),
s);
1180 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(
p) + 15) &
static_cast<size_t>(~15));
1181 for (;
p != nextAligned;
p++)
1188 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
1189 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
1190 static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
1191 const __m128i dq = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&dquote[0]));
1192 const __m128i bs = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&bslash[0]));
1193 const __m128i sp = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(&space[0]));
1196 const __m128i
s = _mm_load_si128(
reinterpret_cast<const __m128i *
>(p));
1197 const __m128i
t1 = _mm_cmpeq_epi8(
s, dq);
1198 const __m128i
t2 = _mm_cmpeq_epi8(
s, bs);
1199 const __m128i
t3 = _mm_cmpeq_epi8(_mm_max_epu8(
s, sp), sp);
1200 const __m128i x = _mm_or_si128(_mm_or_si128(
t1,
t2),
t3);
1201 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
1205 unsigned long offset;
1206 _BitScanForward(&offset, r);
1209 length =
static_cast<size_t>(__builtin_ffs(r) - 1);
1218#elif defined(RAPIDJSON_NEON)
1221 const char*
p = is.
src_;
1224 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(
p) + 15) &
static_cast<size_t>(~15));
1225 while (p != nextAligned)
1234 const uint8x16_t s0 = vmovq_n_u8(
'"');
1235 const uint8x16_t s1 = vmovq_n_u8(
'\\');
1236 const uint8x16_t s2 = vmovq_n_u8(
'\b');
1237 const uint8x16_t s3 = vmovq_n_u8(32);
1240 const uint8x16_t
s = vld1q_u8(
reinterpret_cast<const uint8_t *
>(p));
1241 uint8x16_t x = vceqq_u8(
s, s0);
1242 x = vorrq_u8(x, vceqq_u8(
s, s1));
1243 x = vorrq_u8(x, vceqq_u8(
s, s2));
1244 x = vorrq_u8(x, vcltq_u8(
s, s3));
1247 uint64_t low = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 0);
1248 uint64_t high = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 1);
1251 bool escaped =
false;
1254 unsigned lz = (unsigned)__builtin_clzll(high);;
1255 length = 8 + (lz >> 3);
1259 unsigned lz = (unsigned)__builtin_clzll(low);;
1265 char*
q =
reinterpret_cast<char*
>(os.Push(length));
1266 for (
size_t i = 0;
i < length;
i++)
1273 vst1q_u8(
reinterpret_cast<uint8_t *
>(os.Push(16)),
s);
1285 SkipUnescapedString(is);
1293 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(
p) + 15) &
static_cast<size_t>(~15));
1294 while (p != nextAligned)
1304 const uint8x16_t s0 = vmovq_n_u8(
'"');
1305 const uint8x16_t s1 = vmovq_n_u8(
'\\');
1306 const uint8x16_t s2 = vmovq_n_u8(
'\b');
1307 const uint8x16_t s3 = vmovq_n_u8(32);
1309 for (;;
p += 16,
q += 16) {
1310 const uint8x16_t
s = vld1q_u8(
reinterpret_cast<uint8_t *
>(p));
1311 uint8x16_t x = vceqq_u8(
s, s0);
1312 x = vorrq_u8(x, vceqq_u8(
s, s1));
1313 x = vorrq_u8(x, vceqq_u8(
s, s2));
1314 x = vorrq_u8(x, vcltq_u8(
s, s3));
1317 uint64_t low = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 0);
1318 uint64_t high = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 1);
1321 bool escaped =
false;
1324 unsigned lz = (unsigned)__builtin_clzll(high);
1325 length = 8 + (lz >> 3);
1329 unsigned lz = (unsigned)__builtin_clzll(low);
1334 for (
const char* pend = p + length;
p != pend; ) {
1339 vst1q_u8(
reinterpret_cast<uint8_t *
>(q),
s);
1352 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(
p) + 15) &
static_cast<size_t>(~15));
1353 for (;
p != nextAligned;
p++)
1360 const uint8x16_t s0 = vmovq_n_u8(
'"');
1361 const uint8x16_t s1 = vmovq_n_u8(
'\\');
1362 const uint8x16_t s2 = vmovq_n_u8(
'\b');
1363 const uint8x16_t s3 = vmovq_n_u8(32);
1366 const uint8x16_t
s = vld1q_u8(
reinterpret_cast<uint8_t *
>(p));
1367 uint8x16_t x = vceqq_u8(
s, s0);
1368 x = vorrq_u8(x, vceqq_u8(
s, s1));
1369 x = vorrq_u8(x, vceqq_u8(
s, s2));
1370 x = vorrq_u8(x, vcltq_u8(
s, s3));
1373 uint64_t low = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 0);
1374 uint64_t high = vgetq_lane_u64(
reinterpret_cast<uint64x2_t
>(x), 1);
1378 int lz = __builtin_clzll(high);
1383 int lz = __builtin_clzll(low);
1393 template<
typename InputStream,
bool backup,
bool pushOnTake>
1396 template<
typename InputStream>
1399 typedef typename InputStream::Ch
Ch;
1403 RAPIDJSON_FORCEINLINE
Ch Peek()
const {
return is.Peek(); }
1406 RAPIDJSON_FORCEINLINE
void Push(
char) {}
1410 const char*
Pop() {
return 0; }
1418 template<
typename InputStream>
1429 RAPIDJSON_FORCEINLINE
void Push(
char c) {
1444 template<
typename InputStream>
1453 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
1456 NumberStream<InputStream,
1463 size_t startOffset =
s.Tell();
1465 bool useNanOrInf =
false;
1473 bool use64bit =
false;
1474 int significandDigit = 0;
1480 i =
static_cast<unsigned>(
s.TakePush() -
'0');
1491 i = i * 10 +
static_cast<unsigned>(
s.TakePush() -
'0');
1503 i = i * 10 +
static_cast<unsigned>(
s.TakePush() -
'0');
1511 d = std::numeric_limits<double>::quiet_NaN();
1517 d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
1535 bool useDouble =
false;
1541 d =
static_cast<double>(i64);
1545 i64 = i64 * 10 +
static_cast<unsigned>(
s.TakePush() -
'0');
1552 d =
static_cast<double>(i64);
1556 i64 = i64 * 10 +
static_cast<unsigned>(
s.TakePush() -
'0');
1564 d =
d * 10 + (
s.TakePush() -
'0');
1570 size_t decimalPosition;
1572 decimalPosition =
s.Length();
1587 i64 = i64 * 10 +
static_cast<unsigned>(
s.TakePush() -
'0');
1594 d =
static_cast<double>(i64);
1597 d =
static_cast<double>(use64bit ? i64 : i);
1603 if (significandDigit < 17) {
1604 d =
d * 10.0 + (
s.TakePush() -
'0');
1614 decimalPosition =
s.Length();
1620 d =
static_cast<double>(use64bit ? i64 : i);
1624 bool expMinus =
false;
1631 exp =
static_cast<int>(
s.Take() -
'0');
1640 int maxExp = (expFrac + 2147483639) / 10;
1643 exp = exp * 10 +
static_cast<int>(
s.Take() -
'0');
1651 int maxExp = 308 - expFrac;
1653 exp = exp * 10 +
static_cast<int>(
s.Take() -
'0');
1672 typename InputStream::Ch* head = is.PutBegin();
1673 const size_t length =
s.Tell() - startOffset;
1676 const typename TargetEncoding::Ch*
const str =
reinterpret_cast<typename TargetEncoding::Ch*
>(head);
1677 cont = handler.RawNumber(
str,
SizeType(length),
false);
1682 StackStream<typename TargetEncoding::Ch> dstStream(
stack_);
1683 while (numCharsToCopy--) {
1686 dstStream.Put(
'\0');
1687 const typename TargetEncoding::Ch*
str = dstStream.Pop();
1689 cont = handler.RawNumber(
str,
SizeType(length),
true);
1693 size_t length =
s.Length();
1694 const char* decimal =
s.Pop();
1697 int p = exp + expFrac;
1704 if (
d > std::numeric_limits<double>::max()) {
1710 cont = handler.Double(minus ? -
d :
d);
1712 else if (useNanOrInf) {
1713 cont = handler.Double(
d);
1718 cont = handler.Int64(
static_cast<int64_t>(~i64 + 1));
1720 cont = handler.Uint64(i64);
1724 cont = handler.Int(
static_cast<int32_t>(~i + 1));
1726 cont = handler.Uint(i);
1735 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
1737 switch (is.Peek()) {
1804#define N NumberToken
1805#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1807 static const unsigned char tokenMap[256] = {
1810 N, N,
StringToken, N, N, N, N, N, N, N, N, N,
CommaToken, N, N, N,
1811 N, N, N, N, N, N, N, N, N, N,
ColonToken, N, N, N, N, N,
1813 N, N, N, N, N, N, N, N, N, N, N,
LeftBracketToken, N,
RightBracketToken, N, N,
1814 N, N, N, N, N, N,
FalseToken, N, N, N, N, N, N, N,
NullToken, N,
1815 N, N, N, N,
TrueToken, N, N, N, N, N, N,
LeftCurlyBracketToken, N,
RightCurlyBracketToken, N, N,
1816 N16, N16, N16, N16, N16, N16, N16, N16
1822 if (
sizeof(
Ch) == 1 ||
static_cast<unsigned>(c) < 256)
1823 return static_cast<Token>(tokenMap[
static_cast<unsigned char>(c)]);
1994 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
2013 *
stack_.template Push<SizeType>(1) = n;
2015 *
stack_.template Push<SizeType>(1) = 0;
2061 *
stack_.template Top<SizeType>() = *
stack_.template Top<SizeType>() + 1;
2082 bool hr = handler.EndObject(c);
2112 bool hr = handler.EndArray(c);
2146 template <
typename InputStream>
2175 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
2178 ClearStackOnExit scope(*
this);
2183 while (is.Peek() !=
'\0') {
2221#if defined(__clang__) || defined(_MSC_VER)
#define w1(p)
Definition aesb.c:107
#define s(x, c)
Definition aesb.c:47
#define w0(p)
Definition aesb.c:106
#define w3(p)
Definition aesb.c:109
#define w2(p)
Definition aesb.c:108
#define G(r, i, a, b, c, d)
internal::Stack< StackAllocator > & stack_
Definition reader.h:951
StackStream(internal::Stack< StackAllocator > &stack)
Definition reader.h:930
StackStream & operator=(const StackStream &)
size_t Length() const
Definition reader.h:941
StackStream(const StackStream &)
RAPIDJSON_FORCEINLINE void * Push(SizeType count)
Definition reader.h:936
CharType Ch
Definition reader.h:928
SizeType length_
Definition reader.h:952
RAPIDJSON_FORCEINLINE void Put(Ch c)
Definition reader.h:931
Ch * Pop()
Definition reader.h:943
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition reader.h:537
RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) const
Definition reader.h:1801
RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream &is, Handler &handler)
Definition reader.h:1995
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition reader.h:557
RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const
Definition reader.h:2167
ParseResult parseResult_
Definition reader.h:2212
void ClearStack()
Definition reader.h:696
static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream &, OutputStream &)
Definition reader.h:1057
void ParseNumber(InputStream &is, Handler &handler)
Definition reader.h:1454
bool IterativeParseNext(InputStream &is, Handler &handler)
Parse one token from JSON text.
Definition reader.h:618
IterativeParsingState
Definition reader.h:1754
@ IterativeParsingKeyValueDelimiterState
Definition reader.h:1776
@ IterativeParsingObjectFinishState
Definition reader.h:1763
@ IterativeParsingErrorState
Definition reader.h:1756
@ IterativeParsingFinishState
Definition reader.h:1755
@ IterativeParsingElementDelimiterState
Definition reader.h:1774
@ IterativeParsingMemberDelimiterState
Definition reader.h:1775
@ IterativeParsingMemberKeyState
Definition reader.h:1761
@ IterativeParsingObjectInitialState
Definition reader.h:1760
@ IterativeParsingArrayFinishState
Definition reader.h:1768
@ cIterativeParsingStateCount
Definition reader.h:1778
@ IterativeParsingMemberValueState
Definition reader.h:1762
@ IterativeParsingValueState
Definition reader.h:1771
@ IterativeParsingArrayInitialState
Definition reader.h:1766
@ IterativeParsingStartState
Definition reader.h:1757
@ IterativeParsingElementState
Definition reader.h:1767
RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const
Definition reader.h:2171
void HandleError(IterativeParsingState src, InputStream &is)
Definition reader.h:2147
void SkipWhitespaceAndComments(InputStream &is)
Definition reader.h:709
static RAPIDJSON_FORCEINLINE bool Consume(InputStream &is, typename InputStream::Ch expect)
Definition reader.h:893
ParseResult IterativeParse(InputStream &is, Handler &handler)
Definition reader.h:2176
GenericReader & operator=(const GenericReader &)
void ParseTrue(InputStream &is, Handler &handler)
Definition reader.h:867
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text (with kParseDefaultFlags).
Definition reader.h:598
Token
Definition reader.h:1782
@ FalseToken
Definition reader.h:1793
@ TrueToken
Definition reader.h:1794
@ LeftBracketToken
Definition reader.h:1783
@ ColonToken
Definition reader.h:1790
@ RightCurlyBracketToken
Definition reader.h:1787
@ kTokenCount
Definition reader.h:1798
@ StringToken
Definition reader.h:1792
@ RightBracketToken
Definition reader.h:1784
@ LeftCurlyBracketToken
Definition reader.h:1786
@ NullToken
Definition reader.h:1795
@ NumberToken
Definition reader.h:1796
@ CommaToken
Definition reader.h:1789
internal::Stack< CrtAllocator > stack_
Definition reader.h:2211
void IterativeParseInit()
Initialize JSON text token-by-token parsing.
Definition reader.h:605
void ParseValue(InputStream &is, Handler &handler)
Definition reader.h:1736
void ParseArray(InputStream &is, Handler &handler)
Definition reader.h:806
RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream &is, OutputStream &os)
Definition reader.h:989
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
Definition reader.h:683
RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const
Check if token-by-token parsing JSON text is complete.
Definition reader.h:675
GenericReader(StackAllocator *stackAllocator=0, size_t stackCapacity=kDefaultStackCapacity)
Constructor.
Definition reader.h:545
UTF8< char >::Ch Ch
Definition reader.h:539
void ParseString(InputStream &is, Handler &handler, bool isKey=false)
Definition reader.h:957
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition reader.h:680
static const size_t kDefaultStackCapacity
Definition reader.h:2210
GenericReader(const GenericReader &)
RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) const
Definition reader.h:1828
IterativeParsingState state_
Definition reader.h:2213
void SetParseError(ParseErrorCode code, size_t offset)
Definition reader.h:689
void ParseNull(InputStream &is, Handler &handler)
Definition reader.h:854
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition reader.h:686
void ParseFalse(InputStream &is, Handler &handler)
Definition reader.h:880
void ParseObject(InputStream &is, Handler &handler)
Definition reader.h:738
unsigned ParseHex4(InputStream &is, size_t escapeOffset)
Definition reader.h:904
A type-unsafe stack for storing different types of data.
Definition stack.h:36
StreamLocalCopy & operator=(const StreamLocalCopy &)
StreamLocalCopy(Stream &original)
Definition reader.h:246
Stream & s
Definition reader.h:248
Stream s
Definition reader.h:234
Stream & original_
Definition reader.h:239
StreamLocalCopy & operator=(const StreamLocalCopy &)
StreamLocalCopy(Stream &original)
Definition reader.h:231
~StreamLocalCopy()
Definition reader.h:232
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
Concept for reading and writing characters.
bool success
Definition cold-transaction.cpp:57
GenericStringStream< UTF8< char > > StringStream
Definition fwd.h:49
GenericInsituStringStream< UTF8< char > > InsituStringStream
Definition fwd.h:54
GenericReader< UTF8< char >, UTF8< char >, CrtAllocator > Reader
Definition fwd.h:90
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition rapidjson.h:468
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition rapidjson.h:481
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:411
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition rapidjson.h:121
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition rapidjson.h:124
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)
Macro to indicate a parse error.
Definition reader.h:99
ParseErrorCode
Error code of parsing.
Definition error.h:64
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition reader.h:118
@ kParseErrorDocumentEmpty
The document is empty.
Definition error.h:67
@ kParseErrorNumberMissFraction
Miss fraction part in number.
Definition error.h:85
@ kParseErrorStringInvalidEncoding
Invalid encoding in string.
Definition error.h:82
@ kParseErrorValueInvalid
Invalid value.
Definition error.h:70
@ kParseErrorDocumentRootNotSingular
The document root must not follow by other values.
Definition error.h:68
@ kParseErrorUnspecificSyntaxError
Unspecific syntax error.
Definition error.h:89
@ kParseErrorObjectMissCommaOrCurlyBracket
Missing a comma or '}' after an object member.
Definition error.h:74
@ kParseErrorObjectMissColon
Missing a colon after a name of object member.
Definition error.h:73
@ kParseErrorStringMissQuotationMark
Missing a closing quotation mark in string.
Definition error.h:81
@ kParseErrorTermination
Parsing was terminated.
Definition error.h:88
@ kParseErrorNumberMissExponent
Miss exponent in number.
Definition error.h:86
@ kParseErrorStringEscapeInvalid
Invalid escape character in string.
Definition error.h:80
@ kParseErrorArrayMissCommaOrSquareBracket
Missing a comma or ']' after an array element.
Definition error.h:76
@ kParseErrorStringUnicodeSurrogateInvalid
The surrogate pair in string is invalid.
Definition error.h:79
@ kParseErrorObjectMissName
Missing a name for object member.
Definition error.h:72
@ kParseErrorNumberTooBig
Number too big to be stored in double.
Definition error.h:84
@ kParseErrorStringUnicodeEscapeInvalidHex
Incorrect hex digit after \u escape in string.
Definition error.h:78
int q
Definition base.py:2
Definition document.h:406
double StrtodFullPrecision(double d, int p, const char *decimals, size_t length, size_t decimalPosition, int exp)
Definition strtod.h:226
double StrtodNormalPrecision(double d, int p)
Definition strtod.h:37
int i
Definition pymoduletest.py:23
p
Definition pymoduletest.py:75
r
Definition testupnpigd.py:61
const char *const str
Definition portlistingparse.c:23
const portMappingElt code
Definition portlistingparse.c:22
Type
Type of JSON value.
Definition rapidjson.h:623
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.).
Definition rapidjson.h:389
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition rapidjson.h:294
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition reader.h:264
#define RAPIDJSON_PARSE_DEFAULT_FLAGS
Definition reader.h:139
ParseFlag
Combination of parseFlags.
Definition reader.h:145
@ kParseFullPrecisionFlag
Parse number in full precision (but slower).
Definition reader.h:151
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition reader.h:147
@ kParseNoFlags
No flags are set.
Definition reader.h:146
@ kParseCommentsFlag
Allow one-line (//) and multi-line (/**/) comments.
Definition reader.h:152
@ kParseDefaultFlags
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS.
Definition reader.h:156
@ kParseTrailingCommasFlag
Allow trailing commas at the end of objects and arrays.
Definition reader.h:154
@ kParseNanAndInfFlag
Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
Definition reader.h:155
@ kParseValidateEncodingFlag
Validate encoding of JSON strings.
Definition reader.h:148
@ kParseNumbersAsStringsFlag
Parse all numbers (ints/doubles) as strings.
Definition reader.h:153
@ kParseIterativeFlag
Iterative(constant complexity in terms of function call stack size) parsing.
Definition reader.h:149
@ kParseStopWhenDoneFlag
After parsing a complete JSON root from stream, stop further processing the rest of stream....
Definition reader.h:150
t2
Definition pow22523.h:103
t1
Definition pow22523.h:58
t3
Definition pow225521.h:103
signed __int64 int64_t
Definition stdint.h:135
signed int int32_t
Definition stdint.h:123
unsigned char uint8_t
Definition stdint.h:124
unsigned __int64 uint64_t
Definition stdint.h:136
Default implementation of Handler.
Definition reader.h:196
bool Int64(int64_t)
Definition reader.h:206
bool EndObject(SizeType)
Definition reader.h:214
bool Uint(unsigned)
Definition reader.h:205
bool Uint64(uint64_t)
Definition reader.h:207
bool String(const Ch *, SizeType, bool)
Definition reader.h:211
bool Double(double)
Definition reader.h:208
Encoding::Ch Ch
Definition reader.h:197
bool Default()
Definition reader.h:201
bool Int(int)
Definition reader.h:204
internal::SelectIf< internal::IsSame< Derived, void >, BaseReaderHandler, Derived >::Type Override
Definition reader.h:199
bool StartArray()
Definition reader.h:215
bool RawNumber(const Ch *str, SizeType len, bool copy)
enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
Definition reader.h:210
bool Bool(bool)
Definition reader.h:203
bool StartObject()
Definition reader.h:212
bool Key(const Ch *str, SizeType len, bool copy)
Definition reader.h:213
bool Null()
Definition reader.h:202
bool EndArray(SizeType)
Definition reader.h:216
Ch * dst_
Definition stream.h:209
Ch * src_
Definition stream.h:208
GenericReader & r_
Definition reader.h:703
ClearStackOnExit(GenericReader &r)
Definition reader.h:700
ClearStackOnExit(const ClearStackOnExit &)
~ClearStackOnExit()
Definition reader.h:701
ClearStackOnExit & operator=(const ClearStackOnExit &)
const Ch * src_
Current read position.
Definition stream.h:168
Represents an in-memory input byte stream.
Definition memorystream.h:40
Result of parsing (wraps ParseErrorCode).
Definition error.h:106
Encoding conversion.
Definition encodings.h:658
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream &is, OutputStream &os)
Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the outp...
Definition encodings.h:661
static RAPIDJSON_FORCEINLINE bool Validate(InputStream &is, OutputStream &os)
Validate one Unicode codepoint from an encoded stream.
Definition encodings.h:680
UTF-8 encoding.
Definition encodings.h:96