15 #ifndef RAPIDJSON_READER_H_ 16 #define RAPIDJSON_READER_H_ 28 #if defined(RAPIDJSON_SIMD) && defined(_MSC_VER) 30 #pragma intrinsic(_BitScanForward) 32 #ifdef RAPIDJSON_SSE42 33 #include <nmmintrin.h> 34 #elif defined(RAPIDJSON_SSE2) 35 #include <emmintrin.h> 36 #elif defined(RAPIDJSON_NEON) 42 RAPIDJSON_DIAG_OFF(old-style-cast)
43 RAPIDJSON_DIAG_OFF(padded)
44 RAPIDJSON_DIAG_OFF(
switch-
enum)
45 #elif defined(_MSC_VER) 47 RAPIDJSON_DIAG_OFF(4127)
48 RAPIDJSON_DIAG_OFF(4702)
53 RAPIDJSON_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 195 template<
typename Encoding = UTF8<>,
typename Derived =
void>
205 bool Uint(
unsigned) {
return static_cast<Override&
>(*this).Default(); }
224 template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
228 template<
typename Stream>
243 template<
typename Stream>
263 template<
typename InputStream>
266 InputStream&
s(
copy.s);
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 280 inline 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);
308 inline 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) 332 inline 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));
365 #ifdef _MSC_VER // Find the index of first non-whitespace 366 unsigned long offset;
367 _BitScanForward(&offset,
r);
370 return p + __builtin_ffs(
r) - 1;
376 inline 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));
401 #ifdef _MSC_VER // Find the index of first non-whitespace 402 unsigned long offset;
403 _BitScanForward(&offset,
r);
406 return p + __builtin_ffs(
r) - 1;
414 #elif defined(RAPIDJSON_NEON) 417 inline 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);
461 inline 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);
499 #endif // RAPIDJSON_NEON 501 #ifdef RAPIDJSON_SIMD 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_);
515 #endif // RAPIDJSON_SIMD 536 template <
typename SourceEncoding,
typename TargetEncoding,
typename StackAllocator = CrtAllocator>
556 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
559 return IterativeParse<parseFlags>(is, handler);
563 ClearStackOnExit scope(*
this);
565 SkipWhitespaceAndComments<parseFlags>(is);
573 ParseValue<parseFlags>(is, handler);
577 SkipWhitespaceAndComments<parseFlags>(is);
597 template <
typename InputStream,
typename Handler>
599 return Parse<kParseDefaultFlags>(is, handler);
617 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
620 SkipWhitespaceAndComments<parseFlags>(is);
641 SkipWhitespaceAndComments<parseFlags>(is);
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>
745 SkipWhitespaceAndComments<parseFlags>(is);
746 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
758 ParseString<parseFlags>(is, handler,
true);
759 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
761 SkipWhitespaceAndComments<parseFlags>(is);
762 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
767 SkipWhitespaceAndComments<parseFlags>(is);
768 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
770 ParseValue<parseFlags>(is, handler);
771 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
773 SkipWhitespaceAndComments<parseFlags>(is);
774 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
781 SkipWhitespaceAndComments<parseFlags>(is);
782 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
794 if (is.Peek() ==
'}') {
805 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
813 SkipWhitespaceAndComments<parseFlags>(is);
814 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
823 ParseValue<parseFlags>(is, handler);
824 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
827 SkipWhitespaceAndComments<parseFlags>(is);
828 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
831 SkipWhitespaceAndComments<parseFlags>(is);
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>
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>
932 *
stack_.template Push<Ch>() =
c;
956 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
957 void ParseString(InputStream& is, Handler& handler,
bool isKey =
false) {
959 InputStream&
s(
copy.s);
967 ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(
s,
s);
968 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
969 size_t length =
s.PutEnd(head) - 1;
975 StackStream<typename TargetEncoding::Ch> stackStream(
stack_);
976 ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(
s, stackStream);
977 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
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));
1093 #ifdef _MSC_VER // Find the index of first escaped 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));
1156 #ifdef _MSC_VER // Find the index of first escaped 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));
1204 #ifdef _MSC_VER // Find the index of first escaped 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);
1391 #endif // RAPIDJSON_NEON 1393 template<
typename InputStream,
bool backup,
bool pushOnTake>
1396 template<
typename InputStream>
1406 RAPIDJSON_FORCEINLINE
void Push(
char) {}
1410 const char*
Pop() {
return 0; }
1418 template<
typename InputStream>
1425 stackStream.Put(static_cast<char>(Base::is.Peek()));
1426 return Base::is.Take();
1429 RAPIDJSON_FORCEINLINE
void Push(
char c) {
1433 size_t Length() {
return stackStream.Length(); }
1436 stackStream.Put(
'\0');
1437 return stackStream.Pop();
1444 template<
typename InputStream>
1450 RAPIDJSON_FORCEINLINE
Ch Take() {
return Base::TakePush(); }
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');
1673 const size_t length =
s.Tell() - startOffset;
1677 cont = handler.RawNumber(
str,
SizeType(length),
false);
1682 StackStream<typename TargetEncoding::Ch> dstStream(
stack_);
1683 while (numCharsToCopy--) {
1686 dstStream.Put(
'\0');
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()) {
1738 case 'n': ParseNull <parseFlags>(is, handler);
break;
1739 case 't': ParseTrue <parseFlags>(is, handler);
break;
1740 case 'f': ParseFalse <parseFlags>(is, handler);
break;
1741 case '"': ParseString<parseFlags>(is, handler);
break;
1742 case '{': ParseObject<parseFlags>(is, handler);
break;
1743 case '[': ParseArray <parseFlags>(is, handler);
break;
1745 ParseNumber<parseFlags>(is, handler);
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;
2030 ParseString<parseFlags>(is, handler,
true);
2043 ParseValue<parseFlags>(is, handler);
2051 ParseValue<parseFlags>(is, handler);
2061 *
stack_.template Top<SizeType>() = *
stack_.template Top<SizeType>() + 1;
2082 bool hr = handler.EndObject(
c);
2112 bool hr = handler.EndArray(
c);
2138 ParseValue<parseFlags>(is, handler);
2146 template <
typename InputStream>
2175 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
2178 ClearStackOnExit scope(*
this);
2181 SkipWhitespaceAndComments<parseFlags>(is);
2183 while (is.Peek() !=
'\0') {
2199 SkipWhitespaceAndComments<parseFlags>(is);
2221 #if defined(__clang__) || defined(_MSC_VER) 2230 #endif // RAPIDJSON_READER_H_ bool Default()
Definition: reader.h:201
bool RawNumber(const Ch *str, SizeType len, bool copy)
enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) ...
Definition: reader.h:210
RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream &is, OutputStream &os)
Definition: reader.h:989
StreamLocalCopy(Stream &original)
Definition: reader.h:231
bool StartArray()
Definition: reader.h:215
SizeType length_
Definition: reader.h:952
Ch Take()
Definition: stream.h:195
Definition: reader.h:1790
Encoding conversion.
Definition: encodings.h:658
void HandleError(IterativeParsingState src, InputStream &is)
Definition: reader.h:2147
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition: reader.h:557
Definition: reader.h:1767
void ClearStack()
Definition: reader.h:696
Invalid value.
Definition: error.h:70
Encoding::Ch Ch
Definition: reader.h:197
Definition: reader.h:1787
RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) const
Definition: reader.h:2167
double StrtodFullPrecision(double d, int p, const char *decimals, size_t length, size_t decimalPosition, int exp)
Definition: strtod.h:226
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
Iterative(constant complexity in terms of function call stack size) parsing.
Definition: reader.h:149
~StreamLocalCopy()
Definition: reader.h:232
Represents an in-memory input byte stream.
Definition: memorystream.h:40
int * count
Definition: gmock_stress_test.cc:176
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:411
Ch Peek()
Definition: stream.h:194
RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) const
Definition: reader.h:1828
Parsing was terminated.
Definition: error.h:88
Missing a comma or '}' after an object member.
Definition: error.h:74
ParseResult parseResult_
Definition: reader.h:2212
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:294
bool Int64(int64_t)
Definition: reader.h:206
int i
Definition: pymoduletest.py:23
Default implementation of Handler.
Definition: fwd.h:85
Definition: reader.h:1761
RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream &is, Handler &handler)
Definition: reader.h:1995
Read-only string stream.
Definition: fwd.h:47
StackStream(internal::Stack< StackAllocator > &stack)
Definition: reader.h:930
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
GenericReader< UTF8<>, UTF8<> > Reader
Reader with UTF8 encoding and default allocator.
Definition: reader.h:2217
The document is empty.
Definition: error.h:67
Missing a comma or ']' after an array element.
Definition: error.h:76
#define Ch(x, y, z)
Definition: sha512-blocks.c:34
t
Definition: console.py:33
Definition: reader.h:1760
bool Uint64(uint64_t)
Definition: reader.h:207
bool EndObject(SizeType)
Definition: reader.h:214
bool Uint(unsigned)
Definition: reader.h:205
bool String(const Ch *, SizeType, bool)
Definition: reader.h:211
const Ch * src_
Current read position.
Definition: stream.h:168
No flags are set.
Definition: reader.h:146
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text (with kParseDefaultFlags)
Definition: reader.h:598
bool EndArray(SizeType)
Definition: reader.h:216
bool StartObject()
Definition: reader.h:212
Definition: reader.h:1786
const char * s
Definition: minissdp.c:596
RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) const
Definition: reader.h:1801
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition: reader.h:680
void SetParseError(ParseErrorCode code, size_t offset)
Definition: reader.h:689
Definition: reader.h:1783
void ParseString(InputStream &is, Handler &handler, bool isKey=false)
Definition: reader.h:957
#define G(r, i, a, b, c, d)
RAPIDJSON_FORCEINLINE void Put(Ch c)
Definition: reader.h:931
ParseErrorCode Code() const
Get the error code.
Definition: error.h:116
GenericReader & operator=(const GenericReader &)
#define w0(p)
Definition: aesb.c:106
Definition: reader.h:1775
Missing a name for object member.
Definition: error.h:72
StackStream & operator=(const StackStream &)
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
Allow trailing commas at the end of objects and arrays.
Definition: reader.h:154
Definition: reader.h:1798
void ParseValue(InputStream &is, Handler &handler)
Definition: reader.h:1736
void ParseArray(InputStream &is, Handler &handler)
Definition: reader.h:806
void Clear()
Definition: stack.h:98
RAPIDJSON_FORCEINLINE bool IterativeParseComplete() const
Check if token-by-token parsing JSON text is complete.
Definition: reader.h:675
void copy(key &AA, const key &A)
Definition: rctOps.h:79
Definition: reader.h:1789
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
bool Int(int)
Definition: reader.h:204
Definition: reader.h:1763
Definition: reader.h:1796
internal::SelectIf< internal::IsSame< Derived, void >, BaseReaderHandler, Derived >::Type Override
Definition: reader.h:199
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)
Macro to indicate a parse error.
Definition: reader.h:99
CharType Ch
Definition: reader.h:928
Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
Definition: reader.h:155
Stream s
Definition: reader.h:234
Ch * dst_
Definition: stream.h:209
internal::Stack< StackAllocator > & stack_
Definition: reader.h:951
Number too big to be stored in double.
Definition: error.h:84
Parse all numbers (ints/doubles) as strings.
Definition: reader.h:153
After parsing a complete JSON root from stream, stop further processing the rest of stream...
Definition: reader.h:150
SourceEncoding::Ch Ch
SourceEncoding character type.
Definition: reader.h:539
unsigned ParseHex4(InputStream &is, size_t escapeOffset)
Definition: reader.h:904
e
Definition: pymoduletest.py:79
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS. ...
Definition: reader.h:156
Parse number in full precision (but slower).
Definition: reader.h:151
UTF-8 encoding.
Definition: encodings.h:96
Definition: reader.h:1794
Ch * src_
Definition: stream.h:208
void ParseTrue(InputStream &is, Handler &handler)
Definition: reader.h:867
void Set(ParseErrorCode code, size_t offset=0)
Update error code and offset.
Definition: error.h:136
default
Definition: pymoduletest.py:17
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: fwd.h:88
double StrtodNormalPrecision(double d, int p)
Definition: strtod.h:37
const portMappingElt code
Definition: portlistingparse.c:22
size_t Tell()
Definition: stream.h:196
bool Key(const Ch *str, SizeType len, bool copy)
Definition: reader.h:213
RAPIDJSON_FORCEINLINE void * Push(SizeType count)
Definition: reader.h:936
ParseFlag
Combination of parseFlags.
Definition: reader.h:145
ClearStackOnExit & operator=(const ClearStackOnExit &)
ParseErrorCode
Error code of parsing.
Definition: error.h:64
void SkipWhitespaceAndComments(InputStream &is)
Definition: reader.h:709
static const size_t kDefaultStackCapacity
Default stack capacity in bytes for storing a single decoded string.
Definition: reader.h:2210
IterativeParsingState
Definition: reader.h:1754
t3
Definition: pow225521.h:103
Definition: reader.h:1792
Token
Definition: reader.h:1782
#define RAPIDJSON_PARSE_DEFAULT_FLAGS
Definition: reader.h:139
unsigned __int64 uint64_t
Definition: stdint.h:136
IterativeParsingState state_
Definition: reader.h:2213
bool IterativeParseNext(InputStream &is, Handler &handler)
Parse one token from JSON text.
Definition: reader.h:618
#define w3(p)
Definition: aesb.c:109
Definition: reader.h:1762
Miss exponent in number.
Definition: error.h:86
#define false
Definition: stdbool.h:37
void ParseFalse(InputStream &is, Handler &handler)
Definition: reader.h:880
Invalid escape character in string.
Definition: error.h:80
Invalid encoding in string.
Definition: error.h:82
void ParseNumber(InputStream &is, Handler &handler)
Definition: reader.h:1454
Definition: reader.h:1756
bool success
Definition: cold-transaction.cpp:57
GenericReader & r_
Definition: reader.h:703
bool Bool(bool)
Definition: reader.h:203
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:468
r
Definition: testupnpigd.py:61
t2
Definition: pow22523.h:103
Definition: reader.h:1793
const char *const str
Definition: portlistingparse.c:23
Stream & original_
Definition: reader.h:239
Definition: document.h:406
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition: reader.h:264
void ParseObject(InputStream &is, Handler &handler)
Definition: reader.h:738
Stream & s
Definition: reader.h:248
Definition: reader.h:1766
Definition: blake256.h:36
RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) const
Definition: reader.h:2171
bool Double(double)
Definition: reader.h:208
#define w2(p)
Definition: aesb.c:108
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: reader.h:686
Definition: reader.h:1755
bool IsError() const
Whether the result is an error.
Definition: error.h:123
Validate encoding of JSON strings.
Definition: reader.h:148
Definition: reader.h:1776
signed __int64 int64_t
Definition: stdint.h:135
Miss fraction part in number.
Definition: error.h:85
t1
Definition: pow22523.h:58
d
Definition: pymoduletest.py:79
Incorrect hex digit after \u escape in string.
Definition: error.h:78
internal::Stack< StackAllocator > stack_
A stack for storing decoded string temporarily during non-destructive parsing.
Definition: reader.h:2211
Definition: reader.h:1778
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:118
p
Definition: pymoduletest.py:75
void Clear()
Reset error code.
Definition: error.h:134
static RAPIDJSON_FORCEINLINE bool Consume(InputStream &is, typename InputStream::Ch expect)
Definition: reader.h:893
Unspecific syntax error.
Definition: error.h:89
Ch * Pop()
Definition: reader.h:943
void IterativeParseInit()
Initialize JSON text token-by-token parsing.
Definition: reader.h:605
Definition: reader.h:1768
The surrogate pair in string is invalid.
Definition: error.h:79
void ParseNull(InputStream &is, Handler &handler)
Definition: reader.h:854
bool Null()
Definition: reader.h:202
Missing a colon after a name of object member.
Definition: error.h:73
ParseResult IterativeParse(InputStream &is, Handler &handler)
Definition: reader.h:2176
size_t Length() const
Definition: reader.h:941
Definition: reader.h:1784
Type
Type of JSON value.
Definition: rapidjson.h:623
Definition: reader.h:1394
StreamLocalCopy(Stream &original)
Definition: reader.h:246
GenericReader(StackAllocator *stackAllocator=0, size_t stackCapacity=kDefaultStackCapacity)
Constructor.
Definition: reader.h:545
ClearStackOnExit(GenericReader &r)
Definition: reader.h:700
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:481
Missing a closing quotation mark in string.
Definition: error.h:81
static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream &, OutputStream &)
Definition: reader.h:1057
Definition: reader.h:1795
#define true
Definition: stdbool.h:36
Definition: reader.h:1757
The document root must not follow by other values.
Definition: error.h:68
c
Definition: pymoduletest.py:79
In-situ(destructive) parsing.
Definition: reader.h:147
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
Definition: reader.h:683
Definition: reader.h:1771
~ClearStackOnExit()
Definition: reader.h:701
#define w1(p)
Definition: aesb.c:107
Allow one-line (//) and multi-line (/**/) comments.
Definition: reader.h:152
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition: error.h:118
Definition: reader.h:1774