15 #ifndef RAPIDJSON_READER_H_ 16 #define RAPIDJSON_READER_H_ 20 #include "allocators.h" 22 #include "encodedstream.h" 23 #include "internal/meta.h" 24 #include "internal/stack.h" 25 #include "internal/strtod.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> 40 RAPIDJSON_DIAG_OFF(4127)
41 RAPIDJSON_DIAG_OFF(4702)
46 RAPIDJSON_DIAG_OFF(old-style-cast)
47 RAPIDJSON_DIAG_OFF(padded)
48 RAPIDJSON_DIAG_OFF(switch-enum)
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 125 #include "error/error.h" 138 #ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS 139 #define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags 195 template<
typename Encoding = UTF8<>,
typename Derived =
void>
197 typedef typename Encoding::Ch Ch;
199 typedef typename internal::SelectIf<internal::IsSame<Derived, void>,
BaseReaderHandler, Derived>
::Type Override;
201 bool Default() {
return true; }
202 bool Null() {
return static_cast<Override&
>(*this).Default(); }
203 bool Bool(
bool) {
return static_cast<Override&
>(*this).Default(); }
204 bool Int(
int) {
return static_cast<Override&
>(*this).Default(); }
205 bool Uint(
unsigned) {
return static_cast<Override&
>(*this).Default(); }
206 bool Int64(int64_t) {
return static_cast<Override&
>(*this).Default(); }
207 bool Uint64(uint64_t) {
return static_cast<Override&
>(*this).Default(); }
208 bool Double(
double) {
return static_cast<Override&
>(*this).Default(); }
210 bool RawNumber(
const Ch* str,
SizeType len,
bool copy) {
return static_cast<Override&
>(*this).String(str, len, copy); }
211 bool String(
const Ch*,
SizeType,
bool) {
return static_cast<Override&
>(*this).Default(); }
212 bool StartObject() {
return static_cast<Override&
>(*this).Default(); }
213 bool Key(
const Ch* str,
SizeType len,
bool copy) {
return static_cast<Override&
>(*this).String(str, len, copy); }
214 bool EndObject(
SizeType) {
return static_cast<Override&
>(*this).Default(); }
215 bool StartArray() {
return static_cast<Override&
>(*this).Default(); }
216 bool EndArray(
SizeType) {
return static_cast<Override&
>(*this).Default(); }
224 template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
228 template<
typename Stream>
231 StreamLocalCopy(Stream& original) : s(original), original_(original) {}
243 template<
typename Stream>
263 template<
typename InputStream>
266 InputStream& s(copy.s);
268 typename InputStream::Ch c;
269 while ((c = s.Peek()) ==
' ' || c ==
'\n' || c ==
'\r' || c ==
'\t')
273 inline const char*
SkipWhitespace(
const char* p,
const char* end) {
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 #endif // RAPIDJSON_SSE2 416 #ifdef RAPIDJSON_SIMD 419 is.src_ =
const_cast<char*
>(SkipWhitespace_SIMD(is.src_));
424 is.
src_ = SkipWhitespace_SIMD(is.
src_);
428 is.is_.
src_ = SkipWhitespace_SIMD(is.is_.
src_, is.is_.end_);
430 #endif // RAPIDJSON_SIMD 451 template <
typename SourceEncoding,
typename TargetEncoding,
typename StackAllocator = CrtAllocator>
454 typedef typename SourceEncoding::Ch
Ch;
460 GenericReader(StackAllocator* stackAllocator = 0,
size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {}
470 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
473 return IterativeParse<parseFlags>(is, handler);
475 parseResult_.
Clear();
477 ClearStackOnExit scope(*
this);
479 SkipWhitespaceAndComments<parseFlags>(is);
480 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
484 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
487 ParseValue<parseFlags>(is, handler);
488 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
491 SkipWhitespaceAndComments<parseFlags>(is);
492 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
496 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
511 template <
typename InputStream,
typename Handler>
513 return Parse<kParseDefaultFlags>(is, handler);
526 void SetParseError(
ParseErrorCode code,
size_t offset) { parseResult_.Set(code, offset); }
533 void ClearStack() { stack_.Clear(); }
536 struct ClearStackOnExit {
538 ~ClearStackOnExit() { r_.ClearStack(); }
541 ClearStackOnExit(
const ClearStackOnExit&);
542 ClearStackOnExit& operator=(
const ClearStackOnExit&);
545 template<
unsigned parseFlags,
typename InputStream>
546 void SkipWhitespaceAndComments(InputStream& is) {
551 if (Consume(is,
'*')) {
555 else if (Consume(is,
'*')) {
556 if (Consume(is,
'/'))
564 while (is.Peek() !=
'\0' && is.Take() !=
'\n') {}
574 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
575 void ParseObject(InputStream& is, Handler& handler) {
582 SkipWhitespaceAndComments<parseFlags>(is);
583 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
585 if (Consume(is,
'}')) {
595 ParseString<parseFlags>(is, handler,
true);
596 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
598 SkipWhitespaceAndComments<parseFlags>(is);
599 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
604 SkipWhitespaceAndComments<parseFlags>(is);
605 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
607 ParseValue<parseFlags>(is, handler);
608 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
610 SkipWhitespaceAndComments<parseFlags>(is);
611 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
618 SkipWhitespaceAndComments<parseFlags>(is);
619 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
631 if (is.Peek() ==
'}') {
642 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
643 void ParseArray(InputStream& is, Handler& handler) {
650 SkipWhitespaceAndComments<parseFlags>(is);
651 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
653 if (Consume(is,
']')) {
660 ParseValue<parseFlags>(is, handler);
661 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
664 SkipWhitespaceAndComments<parseFlags>(is);
665 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
667 if (Consume(is,
',')) {
668 SkipWhitespaceAndComments<parseFlags>(is);
669 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
671 else if (Consume(is,
']')) {
680 if (is.Peek() ==
']') {
690 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
691 void ParseNull(InputStream& is, Handler& handler) {
695 if (
RAPIDJSON_LIKELY(Consume(is,
'u') && Consume(is,
'l') && Consume(is,
'l'))) {
703 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
704 void ParseTrue(InputStream& is, Handler& handler) {
708 if (
RAPIDJSON_LIKELY(Consume(is,
'r') && Consume(is,
'u') && Consume(is,
'e'))) {
716 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
717 void ParseFalse(InputStream& is, Handler& handler) {
721 if (
RAPIDJSON_LIKELY(Consume(is,
'a') && Consume(is,
'l') && Consume(is,
's') && Consume(is,
'e'))) {
729 template<
typename InputStream>
730 RAPIDJSON_FORCEINLINE
static bool Consume(InputStream& is,
typename InputStream::Ch expect) {
740 template<
typename InputStream>
741 unsigned ParseHex4(InputStream& is,
size_t escapeOffset) {
742 unsigned codepoint = 0;
743 for (
int i = 0; i < 4; i++) {
746 codepoint +=
static_cast<unsigned>(c);
747 if (c >=
'0' && c <=
'9')
749 else if (c >=
'A' && c <=
'F')
750 codepoint -=
'A' - 10;
751 else if (c >=
'a' && c <=
'f')
752 codepoint -=
'a' - 10;
755 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
762 template <
typename CharType>
768 RAPIDJSON_FORCEINLINE
void Put(Ch c) {
769 *stack_.template Push<Ch>() = c;
773 RAPIDJSON_FORCEINLINE
void* Push(
SizeType count) {
775 return stack_.template Push<Ch>(count);
778 size_t Length()
const {
return length_; }
781 return stack_.template Pop<Ch>(length_);
785 StackStream(
const StackStream&);
786 StackStream& operator=(
const StackStream&);
793 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
794 void ParseString(InputStream& is, Handler& handler,
bool isKey =
false) {
796 InputStream& s(copy.s);
801 bool success =
false;
803 typename InputStream::Ch *head = s.PutBegin();
804 ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
805 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
806 size_t length = s.PutEnd(head) - 1;
808 const typename TargetEncoding::Ch*
const str =
reinterpret_cast<typename TargetEncoding::Ch*
>(head);
809 success = (isKey ? handler.Key(str,
SizeType(length),
false) : handler.String(str,
SizeType(length),
false));
812 StackStream<typename TargetEncoding::Ch> stackStream(stack_);
813 ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
814 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
816 const typename TargetEncoding::Ch*
const str = stackStream.Pop();
817 success = (isKey ? handler.Key(str, length,
true) : handler.String(str, length,
true));
825 template<
unsigned parseFlags,
typename SEncoding,
typename TEncoding,
typename InputStream,
typename OutputStream>
826 RAPIDJSON_FORCEINLINE
void ParseStringToStream(InputStream& is, OutputStream& os) {
828 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 829 static const char escape[256] = {
830 Z16, Z16, 0, 0,
'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'/',
831 Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
832 0, 0,
'\b', 0, 0, 0,
'\f', 0, 0, 0, 0, 0, 0, 0,
'\n', 0,
833 0, 0,
'\r', 0,
'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
834 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
842 ScanCopyUnescapedString(is, os);
846 size_t escapeOffset = is.Tell();
849 if ((
sizeof(Ch) == 1 ||
unsigned(e) < 256) &&
RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
851 os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
855 unsigned codepoint = ParseHex4(is, escapeOffset);
856 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
861 unsigned codepoint2 = ParseHex4(is, escapeOffset);
862 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
865 codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
867 TEncoding::Encode(os, codepoint);
884 size_t offset = is.Tell();
893 template<
typename InputStream,
typename OutputStream>
894 static RAPIDJSON_FORCEINLINE
void ScanCopyUnescapedString(InputStream&, OutputStream&) {
898 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) 900 static RAPIDJSON_FORCEINLINE
void ScanCopyUnescapedString(
StringStream& is, StackStream<char>& os) {
901 const char* p = is.
src_;
904 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
905 while (p != nextAligned)
914 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
915 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
916 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
917 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
918 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
919 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
922 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
923 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
924 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
925 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp);
926 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
927 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
930 #ifdef _MSC_VER // Find the index of first escaped 931 unsigned long offset;
932 _BitScanForward(&offset, r);
935 length =
static_cast<SizeType>(__builtin_ffs(r) - 1);
937 char* q =
reinterpret_cast<char*
>(os.Push(length));
938 for (
size_t i = 0; i < length; i++)
944 _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);
955 if (is.src_ == is.dst_) {
956 SkipUnescapedString(is);
964 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
965 while (p != nextAligned)
975 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
976 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
977 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
978 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
979 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
980 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
982 for (;; p += 16, q += 16) {
983 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
984 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
985 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
986 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp);
987 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
988 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
991 #ifdef _MSC_VER // Find the index of first escaped 992 unsigned long offset;
993 _BitScanForward(&offset, r);
996 length =
static_cast<size_t>(__builtin_ffs(r) - 1);
998 for (
const char* pend = p + length; p != pend; )
1002 _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);
1015 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(p) + 15) &
static_cast<size_t>(~15));
1016 for (; p != nextAligned; p++)
1018 is.src_ = is.dst_ = p;
1023 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
1024 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
1025 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
1026 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1027 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1028 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1031 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1032 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1033 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1034 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp);
1035 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1036 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
1039 #ifdef _MSC_VER // Find the index of first escaped 1040 unsigned long offset;
1041 _BitScanForward(&offset, r);
1044 length =
static_cast<size_t>(__builtin_ffs(r) - 1);
1051 is.src_ = is.dst_ = p;
1055 template<
typename InputStream,
bool backup,
bool pushOnTake>
1058 template<
typename InputStream>
1059 class NumberStream<InputStream, false, false> {
1061 typedef typename InputStream::Ch Ch;
1063 NumberStream(
GenericReader& reader, InputStream& s) : is(s) { (void)reader; }
1065 RAPIDJSON_FORCEINLINE Ch Peek()
const {
return is.Peek(); }
1066 RAPIDJSON_FORCEINLINE Ch TakePush() {
return is.Take(); }
1067 RAPIDJSON_FORCEINLINE Ch Take() {
return is.Take(); }
1068 RAPIDJSON_FORCEINLINE
void Push(
char) {}
1070 size_t Tell() {
return is.Tell(); }
1071 size_t Length() {
return 0; }
1072 const char* Pop() {
return 0; }
1075 NumberStream& operator=(
const NumberStream&);
1080 template<
typename InputStream>
1081 class NumberStream<InputStream, true, false> :
public NumberStream<InputStream, false, false> {
1082 typedef NumberStream<InputStream, false, false> Base;
1084 NumberStream(
GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
1086 RAPIDJSON_FORCEINLINE Ch TakePush() {
1087 stackStream.Put(static_cast<char>(Base::is.Peek()));
1088 return Base::is.Take();
1091 RAPIDJSON_FORCEINLINE
void Push(
char c) {
1095 size_t Length() {
return stackStream.Length(); }
1098 stackStream.Put(
'\0');
1099 return stackStream.Pop();
1103 StackStream<char> stackStream;
1106 template<
typename InputStream>
1107 class NumberStream<InputStream, true, true> :
public NumberStream<InputStream, true, false> {
1108 typedef NumberStream<InputStream, true, false> Base;
1110 NumberStream(
GenericReader& reader, InputStream& is) : Base(reader, is) {}
1112 RAPIDJSON_FORCEINLINE Ch Take() {
return Base::TakePush(); }
1115 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
1116 void ParseNumber(InputStream& is, Handler& handler) {
1118 NumberStream<InputStream,
1125 size_t startOffset = s.Tell();
1127 bool useNanOrInf =
false;
1130 bool minus = Consume(s,
'-');
1135 bool use64bit =
false;
1136 int significandDigit = 0;
1142 i =
static_cast<unsigned>(s.TakePush() -
'0');
1153 i = i * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1165 i = i * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1172 if (
RAPIDJSON_LIKELY(Consume(s,
'N') && Consume(s,
'a') && Consume(s,
'N'))) {
1173 d = std::numeric_limits<double>::quiet_NaN();
1175 else if (
RAPIDJSON_LIKELY(Consume(s,
'I') && Consume(s,
'n') && Consume(s,
'f'))) {
1176 d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
1178 && Consume(s,
'i') && Consume(s,
't') && Consume(s,
'y'))))
1188 bool useDouble =
false;
1194 d =
static_cast<double>(i64);
1198 i64 = i64 * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1205 d =
static_cast<double>(i64);
1209 i64 = i64 * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1219 d = d * 10 + (s.TakePush() -
'0');
1225 size_t decimalPosition;
1226 if (Consume(s,
'.')) {
1227 decimalPosition = s.Length();
1242 i64 = i64 * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1249 d =
static_cast<double>(i64);
1252 d =
static_cast<double>(use64bit ? i64 : i);
1258 if (significandDigit < 17) {
1259 d = d * 10.0 + (s.TakePush() -
'0');
1269 decimalPosition = s.Length();
1273 if (Consume(s,
'e') || Consume(s,
'E')) {
1275 d =
static_cast<double>(use64bit ? i64 : i);
1279 bool expMinus =
false;
1280 if (Consume(s,
'+'))
1282 else if (Consume(s,
'-'))
1286 exp =
static_cast<int>(s.Take() -
'0');
1289 exp = exp * 10 +
static_cast<int>(s.Take() -
'0');
1290 if (exp >= 214748364) {
1297 int maxExp = 308 - expFrac;
1299 exp = exp * 10 +
static_cast<int>(s.Take() -
'0');
1316 if (parseFlags & kParseInsituFlag) {
1318 typename InputStream::Ch* head = is.PutBegin();
1319 const size_t length = s.Tell() - startOffset;
1322 const typename TargetEncoding::Ch*
const str =
reinterpret_cast<typename TargetEncoding::Ch*
>(head);
1323 cont = handler.RawNumber(str,
SizeType(length),
false);
1328 StackStream<typename TargetEncoding::Ch> dstStream(stack_);
1329 while (numCharsToCopy--) {
1332 dstStream.Put(
'\0');
1333 const typename TargetEncoding::Ch* str = dstStream.Pop();
1335 cont = handler.RawNumber(str,
SizeType(length),
true);
1339 size_t length = s.Length();
1340 const char* decimal = s.Pop();
1343 int p = exp + expFrac;
1345 d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
1347 d = internal::StrtodNormalPrecision(d, p);
1349 cont = handler.Double(minus ? -d : d);
1351 else if (useNanOrInf) {
1352 cont = handler.Double(d);
1357 cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
1359 cont = handler.Uint64(i64);
1363 cont = handler.Int(static_cast<int32_t>(~i + 1));
1365 cont = handler.Uint(i);
1374 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
1375 void ParseValue(InputStream& is, Handler& handler) {
1376 switch (is.Peek()) {
1377 case 'n': ParseNull <parseFlags>(is, handler);
break;
1378 case 't': ParseTrue <parseFlags>(is, handler);
break;
1379 case 'f': ParseFalse <parseFlags>(is, handler);
break;
1380 case '"': ParseString<parseFlags>(is, handler);
break;
1381 case '{': ParseObject<parseFlags>(is, handler);
break;
1382 case '[': ParseArray <parseFlags>(is, handler);
break;
1384 ParseNumber<parseFlags>(is, handler);
1393 enum IterativeParsingState {
1394 IterativeParsingStartState = 0,
1395 IterativeParsingFinishState,
1396 IterativeParsingErrorState,
1399 IterativeParsingObjectInitialState,
1400 IterativeParsingMemberKeyState,
1401 IterativeParsingKeyValueDelimiterState,
1402 IterativeParsingMemberValueState,
1403 IterativeParsingMemberDelimiterState,
1404 IterativeParsingObjectFinishState,
1407 IterativeParsingArrayInitialState,
1408 IterativeParsingElementState,
1409 IterativeParsingElementDelimiterState,
1410 IterativeParsingArrayFinishState,
1413 IterativeParsingValueState
1416 enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 };
1420 LeftBracketToken = 0,
1423 LeftCurlyBracketToken,
1424 RightCurlyBracketToken,
1438 RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
1441 #define N NumberToken 1442 #define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N 1444 static const unsigned char tokenMap[256] = {
1447 N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N,
1448 N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N,
1450 N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N,
1451 N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N,
1452 N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N,
1453 N16, N16, N16, N16, N16, N16, N16, N16
1459 if (
sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
1460 return static_cast<Token
>(tokenMap[
static_cast<unsigned char>(c)]);
1465 RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {
1467 static const char G[cIterativeParsingStateCount][kTokenCount] = {
1470 IterativeParsingArrayInitialState,
1471 IterativeParsingErrorState,
1472 IterativeParsingObjectInitialState,
1473 IterativeParsingErrorState,
1474 IterativeParsingErrorState,
1475 IterativeParsingErrorState,
1476 IterativeParsingValueState,
1477 IterativeParsingValueState,
1478 IterativeParsingValueState,
1479 IterativeParsingValueState,
1480 IterativeParsingValueState
1484 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1485 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1486 IterativeParsingErrorState
1490 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1491 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1492 IterativeParsingErrorState
1496 IterativeParsingErrorState,
1497 IterativeParsingErrorState,
1498 IterativeParsingErrorState,
1499 IterativeParsingObjectFinishState,
1500 IterativeParsingErrorState,
1501 IterativeParsingErrorState,
1502 IterativeParsingMemberKeyState,
1503 IterativeParsingErrorState,
1504 IterativeParsingErrorState,
1505 IterativeParsingErrorState,
1506 IterativeParsingErrorState
1510 IterativeParsingErrorState,
1511 IterativeParsingErrorState,
1512 IterativeParsingErrorState,
1513 IterativeParsingErrorState,
1514 IterativeParsingErrorState,
1515 IterativeParsingKeyValueDelimiterState,
1516 IterativeParsingErrorState,
1517 IterativeParsingErrorState,
1518 IterativeParsingErrorState,
1519 IterativeParsingErrorState,
1520 IterativeParsingErrorState
1524 IterativeParsingArrayInitialState,
1525 IterativeParsingErrorState,
1526 IterativeParsingObjectInitialState,
1527 IterativeParsingErrorState,
1528 IterativeParsingErrorState,
1529 IterativeParsingErrorState,
1530 IterativeParsingMemberValueState,
1531 IterativeParsingMemberValueState,
1532 IterativeParsingMemberValueState,
1533 IterativeParsingMemberValueState,
1534 IterativeParsingMemberValueState
1538 IterativeParsingErrorState,
1539 IterativeParsingErrorState,
1540 IterativeParsingErrorState,
1541 IterativeParsingObjectFinishState,
1542 IterativeParsingMemberDelimiterState,
1543 IterativeParsingErrorState,
1544 IterativeParsingErrorState,
1545 IterativeParsingErrorState,
1546 IterativeParsingErrorState,
1547 IterativeParsingErrorState,
1548 IterativeParsingErrorState
1552 IterativeParsingErrorState,
1553 IterativeParsingErrorState,
1554 IterativeParsingErrorState,
1555 IterativeParsingObjectFinishState,
1556 IterativeParsingErrorState,
1557 IterativeParsingErrorState,
1558 IterativeParsingMemberKeyState,
1559 IterativeParsingErrorState,
1560 IterativeParsingErrorState,
1561 IterativeParsingErrorState,
1562 IterativeParsingErrorState
1566 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1567 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1568 IterativeParsingErrorState
1572 IterativeParsingArrayInitialState,
1573 IterativeParsingArrayFinishState,
1574 IterativeParsingObjectInitialState,
1575 IterativeParsingErrorState,
1576 IterativeParsingErrorState,
1577 IterativeParsingErrorState,
1578 IterativeParsingElementState,
1579 IterativeParsingElementState,
1580 IterativeParsingElementState,
1581 IterativeParsingElementState,
1582 IterativeParsingElementState
1586 IterativeParsingErrorState,
1587 IterativeParsingArrayFinishState,
1588 IterativeParsingErrorState,
1589 IterativeParsingErrorState,
1590 IterativeParsingElementDelimiterState,
1591 IterativeParsingErrorState,
1592 IterativeParsingErrorState,
1593 IterativeParsingErrorState,
1594 IterativeParsingErrorState,
1595 IterativeParsingErrorState,
1596 IterativeParsingErrorState
1600 IterativeParsingArrayInitialState,
1601 IterativeParsingArrayFinishState,
1602 IterativeParsingObjectInitialState,
1603 IterativeParsingErrorState,
1604 IterativeParsingErrorState,
1605 IterativeParsingErrorState,
1606 IterativeParsingElementState,
1607 IterativeParsingElementState,
1608 IterativeParsingElementState,
1609 IterativeParsingElementState,
1610 IterativeParsingElementState
1614 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1615 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1616 IterativeParsingErrorState
1620 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1621 IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1622 IterativeParsingErrorState
1626 return static_cast<IterativeParsingState
>(G[state][token]);
1631 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
1632 RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
1636 case IterativeParsingErrorState:
1639 case IterativeParsingObjectInitialState:
1640 case IterativeParsingArrayInitialState:
1644 IterativeParsingState n = src;
1645 if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
1646 n = IterativeParsingElementState;
1647 else if (src == IterativeParsingKeyValueDelimiterState)
1648 n = IterativeParsingMemberValueState;
1650 *stack_.template Push<SizeType>(1) = n;
1652 *stack_.template Push<SizeType>(1) = 0;
1654 bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
1658 return IterativeParsingErrorState;
1666 case IterativeParsingMemberKeyState:
1667 ParseString<parseFlags>(is, handler,
true);
1668 if (HasParseError())
1669 return IterativeParsingErrorState;
1673 case IterativeParsingKeyValueDelimiterState:
1678 case IterativeParsingMemberValueState:
1680 ParseValue<parseFlags>(is, handler);
1681 if (HasParseError()) {
1682 return IterativeParsingErrorState;
1686 case IterativeParsingElementState:
1688 ParseValue<parseFlags>(is, handler);
1689 if (HasParseError()) {
1690 return IterativeParsingErrorState;
1694 case IterativeParsingMemberDelimiterState:
1695 case IterativeParsingElementDelimiterState:
1698 *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
1701 case IterativeParsingObjectFinishState:
1706 return IterativeParsingErrorState;
1709 SizeType c = *stack_.template Pop<SizeType>(1);
1711 if (src == IterativeParsingMemberValueState)
1714 IterativeParsingState n =
static_cast<IterativeParsingState
>(*stack_.template Pop<SizeType>(1));
1716 if (n == IterativeParsingStartState)
1717 n = IterativeParsingFinishState;
1719 bool hr = handler.EndObject(c);
1723 return IterativeParsingErrorState;
1731 case IterativeParsingArrayFinishState:
1736 return IterativeParsingErrorState;
1739 SizeType c = *stack_.template Pop<SizeType>(1);
1741 if (src == IterativeParsingElementState)
1744 IterativeParsingState n =
static_cast<IterativeParsingState
>(*stack_.template Pop<SizeType>(1));
1746 if (n == IterativeParsingStartState)
1747 n = IterativeParsingFinishState;
1749 bool hr = handler.EndArray(c);
1753 return IterativeParsingErrorState;
1775 ParseValue<parseFlags>(is, handler);
1776 if (HasParseError()) {
1777 return IterativeParsingErrorState;
1779 return IterativeParsingFinishState;
1783 template <
typename InputStream>
1784 void HandleError(IterativeParsingState src, InputStream& is) {
1785 if (HasParseError()) {
1793 case IterativeParsingObjectInitialState:
1797 case IterativeParsingKeyValueDelimiterState:
1798 case IterativeParsingArrayInitialState:
1804 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
1805 ParseResult IterativeParse(InputStream& is, Handler& handler) {
1806 parseResult_.
Clear();
1807 ClearStackOnExit scope(*
this);
1808 IterativeParsingState state = IterativeParsingStartState;
1810 SkipWhitespaceAndComments<parseFlags>(is);
1811 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
1812 while (is.Peek() !=
'\0') {
1813 Token t = Tokenize(is.Peek());
1814 IterativeParsingState n = Predict(state, t);
1815 IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
1817 if (d == IterativeParsingErrorState) {
1818 HandleError(state, is);
1828 SkipWhitespaceAndComments<parseFlags>(is);
1829 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
1833 if (state != IterativeParsingFinishState)
1834 HandleError(state, is);
1836 return parseResult_;
1839 static const size_t kDefaultStackCapacity = 256;
1862 #endif // RAPIDJSON_READER_H_ bool RawNumber(const Ch *str, SizeType len, bool copy)
enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) ...
Definition: reader.h:210
Encoding conversion.
Definition: encodings.h:658
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition: reader.h:471
Invalid value.
Definition: error.h:70
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:380
Iterative(constant complexity in terms of function call stack size) parsing.
Definition: reader.h:149
Represents an in-memory input byte stream.
Definition: memorystream.h:40
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:402
Parsing was terminated.
Definition: error.h:88
Missing a comma or '}' after an object member.
Definition: error.h:74
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:289
Default implementation of Handler.
Definition: fwd.h:85
Read-only string stream.
Definition: fwd.h:47
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:119
GenericReader< UTF8<>, UTF8<> > Reader
Reader with UTF8 encoding and default allocator.
Definition: reader.h:1845
The document is empty.
Definition: error.h:67
Missing a comma or ']' after an array element.
Definition: error.h:76
const Ch * src_
Current read position.
Definition: stream.h:124
No flags are set.
Definition: reader.h:146
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text (with kParseDefaultFlags)
Definition: reader.h:512
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: reader.h:517
Missing a name for object member.
Definition: error.h:72
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
Allow trailing commas at the end of objects and arrays.
Definition: reader.h:154
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:116
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)
Macro to indicate a parse error.
Definition: reader.h:99
Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
Definition: reader.h:155
A read-write string stream.
Definition: fwd.h:52
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:454
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
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: fwd.h:88
ParseFlag
Combination of parseFlags.
Definition: reader.h:145
ParseErrorCode
Error code of parsing.
Definition: error.h:64
Miss exponent in number.
Definition: error.h:86
Invalid escape character in string.
Definition: error.h:80
Invalid encoding in string.
Definition: error.h:82
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:455
Definition: document.h:399
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition: reader.h:264
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: reader.h:523
Validate encoding of JSON strings.
Definition: reader.h:148
Miss fraction part in number.
Definition: error.h:85
Incorrect hex digit after \u escape in string.
Definition: error.h:78
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:118
void Clear()
Reset error code.
Definition: error.h:128
Unspecific syntax error.
Definition: error.h:89
The surrogate pair in string is invalid.
Definition: error.h:79
Missing a colon after a name of object member.
Definition: error.h:73
Type
Type of JSON value.
Definition: rapidjson.h:603
GenericReader(StackAllocator *stackAllocator=0, size_t stackCapacity=kDefaultStackCapacity)
Constructor.
Definition: reader.h:460
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:468
Missing a closing quotation mark in string.
Definition: error.h:81
The document root must not follow by other values.
Definition: error.h:68
In-situ(destructive) parsing.
Definition: reader.h:147
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
Definition: reader.h:520
Allow one-line (//) and multi-line (/**/) comments.
Definition: reader.h:152