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>
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
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;
205 bool Uint(
unsigned) {
return static_cast<Override&
>(*this).Default(); }
224 template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
225 class StreamLocalCopy;
228 template<
typename Stream>
229 class StreamLocalCopy<Stream, 1> {
237 StreamLocalCopy& operator=(
const StreamLocalCopy&) ;
243 template<
typename Stream>
244 class StreamLocalCopy<Stream, 0> {
251 StreamLocalCopy& operator=(
const StreamLocalCopy&) ;
263 template<
typename InputStream>
265 internal::StreamLocalCopy<InputStream> copy(is);
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
281 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_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
304 #ifdef _MSC_VER // Find the index of first non-whitespace
306 _BitScanForward(&offset, r);
309 return p + __builtin_ffs(r) - 1;
315 inline const char *SkipWhitespace_SIMD(
const char* p,
const char*
end) {
317 if (p != end && (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t'))
323 static const char whitespace[16] =
" \n\r\t";
324 const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
326 for (; p <= end - 16; p += 16) {
327 const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
328 const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
330 #ifdef _MSC_VER // Find the index of first non-whitespace
332 _BitScanForward(&offset, r);
335 return p + __builtin_ffs(r) - 1;
343 #elif defined(RAPIDJSON_SSE2)
346 inline const char *SkipWhitespace_SIMD(
const char* p) {
348 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
354 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(
p) + 15) &
static_cast<size_t>(~15));
355 while (p != nextAligned)
356 if (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t')
362 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
363 static const char whitespaces[4][16] = { C16(
' '), C16(
'\n'), C16(
'\r'), C16(
'\t') };
366 const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
367 const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
368 const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
369 const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
372 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
373 __m128i
x = _mm_cmpeq_epi8(s, w0);
374 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
375 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
376 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
377 unsigned short r =
static_cast<unsigned short>(~_mm_movemask_epi8(x));
379 #ifdef _MSC_VER // Find the index of first non-whitespace
381 _BitScanForward(&offset, r);
384 return p + __builtin_ffs(r) - 1;
390 inline const char *SkipWhitespace_SIMD(
const char* p,
const char* end) {
392 if (p != end && (*p ==
' ' || *p ==
'\n' || *p ==
'\r' || *p ==
'\t'))
398 #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
399 static const char whitespaces[4][16] = { C16(
' '), C16(
'\n'), C16(
'\r'), C16(
'\t') };
402 const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
403 const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
404 const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
405 const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
407 for (; p <= end - 16; p += 16) {
408 const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
409 __m128i x = _mm_cmpeq_epi8(s, w0);
410 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
411 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
412 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
413 unsigned short r =
static_cast<unsigned short>(~_mm_movemask_epi8(x));
415 #ifdef _MSC_VER // Find the index of first non-whitespace
417 _BitScanForward(&offset, r);
420 return p + __builtin_ffs(r) - 1;
428 #endif // RAPIDJSON_SSE2
430 #ifdef RAPIDJSON_SIMD
433 is.
src_ =
const_cast<char*
>(SkipWhitespace_SIMD(is.
src_));
438 is.
src_ = SkipWhitespace_SIMD(is.
src_);
442 is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
444 #endif // RAPIDJSON_SIMD
465 template <
typename SourceEncoding,
typename TargetEncoding,
typename StackAllocator = CrtAllocator>
468 typedef typename SourceEncoding::Ch
Ch;
484 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
487 return IterativeParse<parseFlags>(is, handler);
493 SkipWhitespaceAndComments<parseFlags>(is);
501 ParseValue<parseFlags>(is, handler);
505 SkipWhitespaceAndComments<parseFlags>(is);
525 template <
typename InputStream,
typename Handler>
527 return Parse<kParseDefaultFlags>(is, handler);
559 template<
unsigned parseFlags,
typename InputStream>
578 while (is.Peek() !=
'\0' && is.Take() !=
'\n');
588 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
596 SkipWhitespaceAndComments<parseFlags>(is);
597 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
609 ParseString<parseFlags>(is, handler,
true);
610 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
612 SkipWhitespaceAndComments<parseFlags>(is);
613 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
618 SkipWhitespaceAndComments<parseFlags>(is);
619 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
621 ParseValue<parseFlags>(is, handler);
622 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
624 SkipWhitespaceAndComments<parseFlags>(is);
625 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
632 SkipWhitespaceAndComments<parseFlags>(is);
633 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
645 if (is.Peek() ==
'}') {
656 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
664 SkipWhitespaceAndComments<parseFlags>(is);
665 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
674 ParseValue<parseFlags>(is, handler);
675 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
678 SkipWhitespaceAndComments<parseFlags>(is);
679 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
682 SkipWhitespaceAndComments<parseFlags>(is);
683 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
694 if (is.Peek() ==
']') {
704 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
717 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
730 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
743 template<
typename InputStream>
744 RAPIDJSON_FORCEINLINE
static bool Consume(InputStream& is,
typename InputStream::Ch expect) {
754 template<
typename InputStream>
755 unsigned ParseHex4(InputStream& is,
size_t escapeOffset) {
756 unsigned codepoint = 0;
757 for (
int i = 0; i < 4; i++) {
760 codepoint +=
static_cast<unsigned>(
c);
761 if (c >=
'0' && c <=
'9')
763 else if (c >=
'A' && c <=
'F')
764 codepoint -=
'A' - 10;
765 else if (c >=
'a' && c <=
'f')
766 codepoint -=
'a' - 10;
769 RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
776 template <
typename CharType>
783 *
stack_.template Push<Ch>() = c;
807 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
808 void ParseString(InputStream& is, Handler& handler,
bool isKey =
false) {
809 internal::StreamLocalCopy<InputStream> copy(is);
810 InputStream&
s(copy.s);
815 bool success =
false;
817 typename InputStream::Ch *head = s.PutBegin();
818 ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(
s,
s);
819 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
820 size_t length = s.PutEnd(head) - 1;
822 const typename TargetEncoding::Ch*
const str =
reinterpret_cast<typename TargetEncoding::Ch*
>(head);
823 success = (isKey ? handler.Key(str,
SizeType(length),
false) : handler.String(str,
SizeType(length),
false));
827 ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(
s, stackStream);
828 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
830 const typename TargetEncoding::Ch*
const str = stackStream.
Pop();
831 success = (isKey ? handler.Key(str, length,
true) : handler.String(str, length,
true));
839 template<
unsigned parseFlags,
typename SEncoding,
typename TEncoding,
typename InputStream,
typename OutputStream>
842 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
843 static const char escape[256] = {
844 Z16,
Z16, 0, 0,
'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'/',
845 Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
846 0, 0,
'\b', 0, 0, 0,
'\f', 0, 0, 0, 0, 0, 0, 0,
'\n', 0,
847 0, 0,
'\r', 0,
'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
848 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
860 size_t escapeOffset = is.Tell();
863 if ((
sizeof(
Ch) == 1 ||
unsigned(e) < 256) &&
RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
865 os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
869 unsigned codepoint =
ParseHex4(is, escapeOffset);
870 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
875 unsigned codepoint2 =
ParseHex4(is, escapeOffset);
876 RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
879 codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
881 TEncoding::Encode(os, codepoint);
898 size_t offset = is.Tell();
907 template<
typename InputStream,
typename OutputStream>
912 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
915 const char* p = is.
src_;
918 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(
p) + 15) &
static_cast<size_t>(~15));
919 while (p != nextAligned)
928 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
929 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
930 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
931 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
932 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
933 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
936 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
937 const __m128i
t1 = _mm_cmpeq_epi8(s, dq);
938 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
939 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp);
940 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
941 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
944 #ifdef _MSC_VER // Find the index of first escaped
946 _BitScanForward(&offset, r);
949 length =
static_cast<SizeType>(__builtin_ffs(r) - 1);
951 char*
q =
reinterpret_cast<char*
>(os.Push(length));
952 for (
size_t i = 0; i <
length; i++)
958 _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);
970 SkipUnescapedString(is);
978 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(
p) + 15) &
static_cast<size_t>(~15));
979 while (p != nextAligned)
989 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
990 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
991 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
992 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
993 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
994 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
996 for (;; p += 16, q += 16) {
997 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
998 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
999 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1000 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp);
1001 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1002 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
1005 #ifdef _MSC_VER // Find the index of first escaped
1007 _BitScanForward(&offset, r);
1010 length =
static_cast<size_t>(__builtin_ffs(r) - 1);
1012 for (
const char* pend = p + length; p != pend; )
1016 _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);
1029 const char* nextAligned =
reinterpret_cast<const char*
>((
reinterpret_cast<size_t>(
p) + 15) &
static_cast<size_t>(~15));
1030 for (; p != nextAligned; p++)
1037 static const char dquote[16] = {
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"',
'\"' };
1038 static const char bslash[16] = {
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\',
'\\' };
1039 static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
1040 const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1041 const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1042 const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1045 const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1046 const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1047 const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1048 const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp);
1049 const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1050 unsigned short r =
static_cast<unsigned short>(_mm_movemask_epi8(x));
1053 #ifdef _MSC_VER // Find the index of first escaped
1055 _BitScanForward(&offset, r);
1058 length =
static_cast<size_t>(__builtin_ffs(r) - 1);
1069 template<
typename InputStream,
bool backup,
bool pushOnTake>
1072 template<
typename InputStream>
1073 class NumberStream<InputStream, false, false> {
1075 typedef typename InputStream::Ch
Ch;
1083 RAPIDJSON_FORCEINLINE
void Push(
char) {}
1087 const char*
Pop() {
return 0; }
1090 NumberStream&
operator=(
const NumberStream&);
1095 template<
typename InputStream>
1096 class NumberStream<InputStream, true, false> :
public NumberStream<InputStream, false, false> {
1103 stackStream.Put(static_cast<char>(Base::is.Peek()));
1104 return Base::is.Take();
1107 RAPIDJSON_FORCEINLINE
void Push(
char c) {
1111 size_t Length() {
return stackStream.Length(); }
1114 stackStream.Put(
'\0');
1115 return stackStream.Pop();
1122 template<
typename InputStream>
1123 class NumberStream<InputStream, true, true> :
public NumberStream<InputStream, true, false> {
1129 RAPIDJSON_FORCEINLINE
Ch Take() {
return Base::TakePush(); }
1132 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
1134 internal::StreamLocalCopy<InputStream> copy(is);
1135 NumberStream<InputStream,
1142 size_t startOffset = s.Tell();
1144 bool useNanOrInf =
false;
1152 bool use64bit =
false;
1153 int significandDigit = 0;
1159 i =
static_cast<unsigned>(s.TakePush() -
'0');
1170 i = i * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1182 i = i * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1190 d = std::numeric_limits<double>::quiet_NaN();
1193 d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
1205 bool useDouble =
false;
1211 d =
static_cast<double>(i64);
1215 i64 = i64 * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1222 d =
static_cast<double>(i64);
1226 i64 = i64 * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1236 d = d * 10 + (s.TakePush() -
'0');
1242 size_t decimalPosition;
1244 decimalPosition = s.Length();
1259 i64 = i64 * 10 +
static_cast<unsigned>(s.TakePush() -
'0');
1266 d =
static_cast<double>(i64);
1269 d =
static_cast<double>(use64bit ? i64 : i);
1275 if (significandDigit < 17) {
1276 d = d * 10.0 + (s.TakePush() -
'0');
1286 decimalPosition = s.Length();
1292 d =
static_cast<double>(use64bit ? i64 : i);
1296 bool expMinus =
false;
1303 exp =
static_cast<int>(s.Take() -
'0');
1306 exp = exp * 10 +
static_cast<int>(s.Take() -
'0');
1307 if (exp >= 214748364) {
1314 int maxExp = 308 - expFrac;
1316 exp = exp * 10 +
static_cast<int>(s.Take() -
'0');
1333 if (parseFlags & kParseInsituFlag) {
1335 typename InputStream::Ch* head = is.PutBegin();
1336 const size_t length = s.Tell() - startOffset;
1339 const typename TargetEncoding::Ch*
const str =
reinterpret_cast<typename TargetEncoding::Ch*
>(head);
1340 cont = handler.RawNumber(str,
SizeType(length),
false);
1346 while (numCharsToCopy--) {
1349 dstStream.Put(
'\0');
1350 const typename TargetEncoding::Ch* str = dstStream.Pop();
1352 cont = handler.RawNumber(str,
SizeType(length),
true);
1356 size_t length = s.Length();
1357 const char* decimal = s.Pop();
1360 int p = exp + expFrac;
1366 cont = handler.Double(minus ? -d : d);
1368 else if (useNanOrInf) {
1369 cont = handler.Double(d);
1374 cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
1376 cont = handler.Uint64(i64);
1380 cont = handler.Int(static_cast<int32_t>(~i + 1));
1382 cont = handler.Uint(i);
1391 template<
unsigned parseFlags,
typename InputStream,
typename Handler>
1393 switch (is.Peek()) {
1394 case 'n': ParseNull <parseFlags>(is, handler);
break;
1395 case 't': ParseTrue <parseFlags>(is, handler);
break;
1396 case 'f': ParseFalse <parseFlags>(is, handler);
break;
1397 case '"': ParseString<parseFlags>(is, handler);
break;
1398 case '{': ParseObject<parseFlags>(is, handler);
break;
1399 case '[': ParseArray <parseFlags>(is, handler);
break;
1401 ParseNumber<parseFlags>(is, handler);
1458 #define N NumberToken
1459 #define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1461 static const unsigned char tokenMap[256] = {
1464 N, N,
StringToken, N, N, N, N, N, N, N, N, N,
CommaToken, N, N, N,
1465 N, N, N, N, N, N, N, N, N, N,
ColonToken, N, N, N, N, N,
1467 N, N, N, N, N, N, N, N, N, N, N,
LeftBracketToken, N,
RightBracketToken, N, N,
1468 N, N, N, N, N, N,
FalseToken, N, N, N, N, N, N, N,
NullToken, N,
1469 N, N, N, N,
TrueToken, N, N, N, N, N, N,
LeftCurlyBracketToken, N,
RightCurlyBracketToken, N, N,
1470 N16, N16, N16, N16, N16, N16, N16, N16
1476 if (
sizeof(
Ch) == 1 || static_cast<unsigned>(c) < 256)
1477 return static_cast<Token>(tokenMap[
static_cast<unsigned char>(
c)]);
1497 IterativeParsingValueState
1503 IterativeParsingErrorState
1509 IterativeParsingErrorState
1523 IterativeParsingErrorState
1537 IterativeParsingErrorState
1551 IterativeParsingMemberValueState
1565 IterativeParsingErrorState
1579 IterativeParsingErrorState
1585 IterativeParsingErrorState
1599 IterativeParsingElementState
1613 IterativeParsingErrorState
1627 IterativeParsingElementState
1633 IterativeParsingErrorState
1639 IterativeParsingErrorState
1648 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
1667 *
stack_.template Push<SizeType>(1) = n;
1669 *
stack_.template Push<SizeType>(1) = 0;
1684 ParseString<parseFlags>(is, handler,
true);
1697 ParseValue<parseFlags>(is, handler);
1705 ParseValue<parseFlags>(is, handler);
1715 *
stack_.template Top<SizeType>() = *
stack_.template Top<SizeType>() + 1;
1736 bool hr = handler.EndObject(c);
1766 bool hr = handler.EndArray(c);
1792 ParseValue<parseFlags>(is, handler);
1800 template <
typename InputStream>
1821 template <
unsigned parseFlags,
typename InputStream,
typename Handler>
1827 SkipWhitespaceAndComments<parseFlags>(is);
1829 while (is.Peek() !=
'\0') {
1845 SkipWhitespaceAndComments<parseFlags>(is);
1879 #endif // RAPIDJSON_READER_H_