26 #ifndef RAPIDJSON_READER_H_
27 #define RAPIDJSON_READER_H_
42 #ifdef RAPIDJSON_SSE42
43 #include <nmmintrin.h>
44 #elif defined(RAPIDJSON_SSE2)
45 #include <emmintrin.h>
50 #pragma warning(disable : 4127)
53 #ifndef RAPIDJSON_PARSE_ERROR
54 #define RAPIDJSON_PARSE_ERROR(msg, offset) \
55 RAPIDJSON_MULTILINEMACRO_BEGIN \
57 errorOffset_ = offset; \
58 longjmp(jmpbuf_, 1); \
59 RAPIDJSON_MULTILINEMACRO_END
103 template<
typename Encoding = UTF8<> >
105 typedef typename Encoding::Ch
Ch;
129 template<
typename Stream>
132 while (s.Peek() ==
' ' || s.Peek() ==
'\n' || s.Peek() ==
'\r' || s.Peek() ==
'\t')
137 #ifdef RAPIDJSON_SSE42
139 inline const char *SkipWhitespace_SIMD(
const char* p) {
140 static const char whitespace[16] =
" \n\r\t";
141 __m128i w = _mm_loadu_si128((
const __m128i *)&whitespace[0]);
144 __m128i s = _mm_loadu_si128((
const __m128i *)p);
145 unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
150 unsigned long offset;
151 if (_BitScanForward(&offset, r))
155 return p + __builtin_ffs(r) - 1;
161 #elif defined(RAPIDJSON_SSE2)
164 inline const char *SkipWhitespace_SIMD(
const char* p) {
165 static const char whitespaces[4][17] = {
167 "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
168 "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",
169 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};
171 __m128i w0 = _mm_loadu_si128((
const __m128i *)&whitespaces[0][0]);
172 __m128i w1 = _mm_loadu_si128((
const __m128i *)&whitespaces[1][0]);
173 __m128i w2 = _mm_loadu_si128((
const __m128i *)&whitespaces[2][0]);
174 __m128i w3 = _mm_loadu_si128((
const __m128i *)&whitespaces[3][0]);
177 __m128i s = _mm_loadu_si128((
const __m128i *)p);
178 __m128i x = _mm_cmpeq_epi8(s, w0);
179 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
180 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
181 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
182 unsigned short r = ~_mm_movemask_epi8(x);
187 unsigned long offset;
188 if (_BitScanForward(&offset, r))
192 return p + __builtin_ffs(r) - 1;
200 #ifdef RAPIDJSON_SIMD
203 stream.src_ =
const_cast<char*
>(SkipWhitespace_SIMD(stream.src_));
208 stream.src_ = SkipWhitespace_SIMD(stream.src_);
230 template <
typename Encoding,
typename Allocator = MemoryPoolAllocator<> >
233 typedef typename Encoding::Ch
Ch;
249 template <
unsigned parseFlags,
typename Stream,
typename Handler>
255 #pragma warning(push)
256 #pragma warning(disable : 4611)
268 if (stream.Peek() ==
'\0')
271 switch (stream.Peek()) {
272 case '{': ParseObject<parseFlags>(stream, handler);
break;
273 case '[': ParseArray<parseFlags>(stream, handler);
break;
278 if (stream.Peek() !=
'\0' && stream.Peek() !=
static_cast<Ch>(std::char_traits<Ch>::eof()))
291 template<
unsigned parseFlags,
typename Stream,
typename Handler>
295 handler.StartObject();
298 if (stream.Peek() ==
'}') {
300 handler.EndObject(0);
305 if (stream.Peek() !=
'"') {
310 ParseString<parseFlags>(stream, handler);
313 if (stream.Take() !=
':') {
319 ParseValue<parseFlags>(stream, handler);
324 switch(stream.Take()) {
326 case '}': handler.EndObject(memberCount);
return;
333 template<
unsigned parseFlags,
typename Stream,
typename Handler>
337 handler.StartArray();
340 if (stream.Peek() ==
']') {
347 ParseValue<parseFlags>(stream, handler);
351 switch (stream.Take()) {
353 case ']': handler.EndArray(elementCount);
return;
360 template<
unsigned parseFlags,
typename Stream,
typename Handler>
365 if( stream.Peek() ==
'a' && stream.Take() ==
'a' && stream.Take() ==
'n' )
366 handler.Double( std::numeric_limits<double>::quiet_NaN() );
367 else if (stream.Take() ==
'u' && stream.Take() ==
'l' && stream.Take() ==
'l')
374 template<
unsigned parseFlags,
typename Stream,
typename Handler>
379 if (stream.Take() ==
'n' && stream.Take() ==
'f')
380 handler.Double( std::numeric_limits<double>::infinity() );
385 template<
unsigned parseFlags,
typename Stream,
typename Handler>
390 if (stream.Take() ==
'r' && stream.Take() ==
'u' && stream.Take() ==
'e')
396 template<
unsigned parseFlags,
typename Stream,
typename Handler>
401 if (stream.Take() ==
'a' && stream.Take() ==
'l' && stream.Take() ==
's' && stream.Take() ==
'e')
402 handler.Bool_(
false);
408 template<
typename Stream>
411 unsigned codepoint = 0;
412 for (
int i = 0;
i < 4;
i++) {
416 if (c >=
'0' && c <=
'9')
418 else if (c >=
'A' && c <=
'F')
419 codepoint -=
'A' - 10;
420 else if (c >=
'a' && c <=
'f')
421 codepoint -=
'a' - 10;
438 bool characterOk<char>(
Ch )
446 static constexpr
int to_int( T t ){
return t; }
449 typename std::enable_if <
to_int(std::numeric_limits<Ch>::max()) <
to_int(256),
bool>::type
456 typename std::enable_if<
to_int(std::numeric_limits<Ch>::max()) >=
to_int(256),
bool>::type
462 template<
unsigned parseFlags,
typename Stream,
typename Handler>
464 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
465 static const Ch escape[256] = {
466 Z16,
Z16, 0, 0,
'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'/',
467 Z16,
Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
468 0, 0,
'\b', 0, 0, 0,
'\f', 0, 0, 0, 0, 0, 0, 0,
'\n', 0,
469 0, 0,
'\r', 0,
'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
484 #define RAPIDJSON_PUT(x) \
486 if (parseFlags & kParseInsituFlag) \
489 *stack_.template Push<Ch>() = x; \
498 if ((
sizeof(
Ch) == 1 ||
characterOk(e)) && escape[(
unsigned char)e])
502 if (codepoint >= 0xD800 && codepoint <= 0xDBFF) {
503 if (s.Take() !=
'\\' || s.Take() !=
'u') {
508 if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) {
512 codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
516 SizeType count =
SizeType(Encoding::Encode(buffer, codepoint) - &buffer[0]);
522 memcpy(
stack_.template Push<Ch>(count), buffer, count *
sizeof(
Ch));
533 size_t length = s.PutEnd(head);
536 handler.String(head,
SizeType(length),
false);
540 handler.String(
stack_.template Pop<Ch>(len), len - 1,
true);
545 else if (c ==
'\0') {
549 else if ((
unsigned)c < 0x20) {
559 template<
unsigned parseFlags,
typename Stream,
typename Handler>
565 if (s.Peek() ==
'-') {
572 bool try64bit =
false;
573 if (s.Peek() ==
'0') {
577 else if (s.Peek() >=
'1' && s.Peek() <=
'9') {
581 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
582 if (
i >= 214748364) {
583 if (
i != 214748364 || s.Peek() >
'8') {
588 i =
i * 10 + (s.Take() -
'0');
591 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
592 if (
i >= 429496729) {
593 if (
i != 429496729 || s.Peek() >
'5') {
598 i =
i * 10 + (s.Take() -
'0');
608 bool useDouble =
false;
612 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
613 if (i64 >= 922337203685477580uLL)
614 if (i64 != 922337203685477580uLL || s.Peek() >
'8') {
618 i64 = i64 * 10 + (s.Take() -
'0');
621 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
622 if (i64 >= 1844674407370955161uLL)
623 if (i64 != 1844674407370955161uLL || s.Peek() >
'5') {
627 i64 = i64 * 10 + (s.Take() -
'0');
635 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
640 d = d * 10 + (s.Take() -
'0');
646 if (s.Peek() ==
'.') {
648 d = try64bit ? (
double)i64 : (
double)
i;
653 if (s.Peek() >=
'0' && s.Peek() <=
'9') {
654 d = d * 10 + (s.Take() -
'0');
662 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
664 d = d * 10 + (s.Peek() -
'0');
673 if (s.Peek() ==
'e' || s.Peek() ==
'E') {
675 d = try64bit ? (
double)i64 : (
double)
i;
680 bool expMinus =
false;
683 else if (s.Peek() ==
'-') {
688 if (s.Peek() >=
'0' && s.Peek() <=
'9') {
689 exp = s.Take() -
'0';
690 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
691 exp =
exp * 10 + (s.Take() -
'0');
694 std::stringstream ss;
695 ss.precision( std::numeric_limits<double>::max_digits10 );
701 if( std::fpclassify( dd ) == FP_SUBNORMAL )
702 handler.Double( dd );
722 handler.Double(minus ? -d : d);
727 handler.Int64(-(int64_t)i64);
733 handler.Int(-(
int)
i);
743 template<
unsigned parseFlags,
typename Stream,
typename Handler>
745 switch (stream.Peek()) {
746 case 'n': ParseNaNNull_ <parseFlags>(stream, handler);
break;
747 case 'i': ParseInfinity <parseFlags>(stream, handler);
break;
748 case 't': ParseTrue <parseFlags>(stream, handler);
break;
749 case 'f': ParseFalse <parseFlags>(stream, handler);
break;
750 case '"': ParseString <parseFlags>(stream, handler);
break;
751 case '{': ParseObject <parseFlags>(stream, handler);
break;
752 case '[': ParseArray <parseFlags>(stream, handler);
break;
753 default : ParseNumber <parseFlags>(stream, handler);
Concept for allocating, resizing and freeing memory block.
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: reader.h:231
void ParseValue(Stream &stream, Handler &handler)
Definition: reader.h:744
void ParseObject(Stream &stream, Handler &handler)
Definition: reader.h:292
void ParseNumber(Stream &stream, Handler &handler)
Definition: reader.h:560
jmp_buf jmpbuf_
setjmp buffer for fast exit from nested parsing function calls.
Definition: reader.h:759
void ParseInfinity(Stream &stream, Handler &handler)
Definition: reader.h:375
bool Parse(Stream &stream, Handler &handler)
Parse JSON text.
Definition: reader.h:250
unsigned ParseHex4(Stream &stream)
Definition: reader.h:409
internal::Stack< Allocator > stack_
A stack for storing decoded string temporarily during non-destructive parsing.
Definition: reader.h:758
void ParseArray(Stream &stream, Handler &handler)
Definition: reader.h:334
Encoding::Ch Ch
Definition: reader.h:233
const char * parseError_
Definition: reader.h:760
void ParseString(Stream &stream, Handler &handler)
Definition: reader.h:463
void ParseTrue(Stream &stream, Handler &handler)
Definition: reader.h:386
void ParseNaNNull_(Stream &stream, Handler &handler)
Definition: reader.h:361
const char * GetParseError() const
Definition: reader.h:286
std::enable_if< to_int(std::numeric_limits< Ch >::max())< to_int(256), bool >::type characterOk(Ch) { return true;} template< class Ch > typename std::enable_if< to_int(std::numeric_limits< Ch >::max()) >=to_int(256), bool >::type characterOk(Ch c)
Definition: reader.h:457
static constexpr int to_int(T t)
Definition: reader.h:446
size_t errorOffset_
Definition: reader.h:761
void ParseFalse(Stream &stream, Handler &handler)
Definition: reader.h:397
GenericReader(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity)
Constructor.
Definition: reader.h:239
bool HasParseError() const
Definition: reader.h:285
static const size_t kDefaultStackCapacity
Default stack capacity in bytes for storing a single decoded string.
Definition: reader.h:757
size_t GetErrorOffset() const
Definition: reader.h:287
Concept for receiving events from GenericReader upon parsing.
Concept for reading and writing characters.
A type-unsafe stack for storing different types of data.
Definition: stack.h:39
const std::complex< Mdouble > i
Definition: ExtendedMath.h:51
Mdouble exp(Mdouble Exponent)
Definition: ExtendedMath.cc:84
double Pow10(int n)
Computes integer powers of 10 in double (10.0^n).
Definition: pow10.h:37
Definition: document.h:38
unsigned SizeType
Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
Definition: rapidjson.h:92
GenericInsituStringStream< UTF8<> > InsituStringStream
Definition: rapidjson.h:532
void SkipWhitespace(Stream &stream)
Skip the JSON white spaces in a stream.
Definition: reader.h:130
GenericReader< UTF8<> > Reader
Reader with UTF8 encoding and default allocator.
Definition: reader.h:765
ParseFlag
Combination of parseFlags.
Definition: reader.h:67
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition: reader.h:69
@ kParseDefaultFlags
Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer.
Definition: reader.h:68
GenericStringStream< UTF8<> > StringStream
Definition: rapidjson.h:502
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:105
#define RAPIDJSON_PARSE_ERROR(msg, offset)
Definition: reader.h:54
Default implementation of Handler.
Definition: reader.h:104
void Default()
Definition: reader.h:107
void Int(int)
Definition: reader.h:110
void StartObject()
Definition: reader.h:116
void Null_()
Definition: reader.h:108
void Bool_(bool)
Definition: reader.h:109
void EndObject(SizeType)
Definition: reader.h:117
void StartArray()
Definition: reader.h:118
void Double(double)
Definition: reader.h:114
void Uint(unsigned)
Definition: reader.h:111
void Int64(int64_t)
Definition: reader.h:112
void Uint64(uint64_t)
Definition: reader.h:113
void EndArray(SizeType)
Definition: reader.h:119
void String(const Ch *, SizeType, bool)
Definition: reader.h:115
Encoding::Ch Ch
Definition: reader.h:105