1 #ifndef RAPIDJSON_READER_H_
2 #define RAPIDJSON_READER_H_
8 #include "internal/pow10.h"
9 #include "internal/stack.h"
12 #ifdef RAPIDJSON_SSE42
13 #include <nmmintrin.h>
14 #elif defined(RAPIDJSON_SSE2)
15 #include <emmintrin.h>
20 #pragma warning(disable : 4127) // conditional expression is constant
23 #ifndef RAPIDJSON_PARSE_ERROR
24 #define RAPIDJSON_PARSE_ERROR(msg, offset) \
25 RAPIDJSON_MULTILINEMACRO_BEGIN \
27 errorOffset_ = offset; \
28 longjmp(jmpbuf_, 1); \
29 RAPIDJSON_MULTILINEMACRO_END
39 kParseDefaultFlags = 0,
74 template<
typename Encoding = UTF8<> >
76 typedef typename Encoding::Ch Ch;
79 void Null() { Default(); }
80 void Bool(
bool) { Default(); }
81 void Int(
int) { Default(); }
82 void Uint(
unsigned) { Default(); }
83 void Int64(int64_t) { Default(); }
84 void Uint64(uint64_t) { Default(); }
85 void Double(
double) { Default(); }
86 void String(
const Ch*, SizeType,
bool) { Default(); }
87 void StartObject() { Default(); }
88 void EndObject(SizeType) { Default(); }
89 void StartArray() { Default(); }
90 void EndArray(SizeType) { Default(); }
100 template<
typename Stream>
101 void SkipWhitespace(
Stream& stream) {
103 while (s.Peek() ==
' ' || s.Peek() ==
'\n' || s.Peek() ==
'\r' || s.Peek() ==
'\t')
108 #ifdef RAPIDJSON_SSE42
110 inline const char *SkipWhitespace_SIMD(
const char* p) {
111 static const char whitespace[16] =
" \n\r\t";
112 __m128i w = _mm_loadu_si128((
const __m128i *)&whitespace[0]);
115 __m128i s = _mm_loadu_si128((
const __m128i *)p);
116 unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
120 #ifdef _MSC_VER // Find the index of first non-whitespace
121 unsigned long offset;
122 if (_BitScanForward(&offset, r))
126 return p + __builtin_ffs(r) - 1;
132 #elif defined(RAPIDJSON_SSE2)
135 inline const char *SkipWhitespace_SIMD(
const char* p) {
136 static const char whitespaces[4][17] = {
138 "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
139 "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",
140 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};
142 __m128i w0 = _mm_loadu_si128((
const __m128i *)&whitespaces[0][0]);
143 __m128i w1 = _mm_loadu_si128((
const __m128i *)&whitespaces[1][0]);
144 __m128i w2 = _mm_loadu_si128((
const __m128i *)&whitespaces[2][0]);
145 __m128i w3 = _mm_loadu_si128((
const __m128i *)&whitespaces[3][0]);
148 __m128i s = _mm_loadu_si128((
const __m128i *)p);
149 __m128i x = _mm_cmpeq_epi8(s, w0);
150 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
151 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
152 x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
153 unsigned short r = ~_mm_movemask_epi8(x);
157 #ifdef _MSC_VER // Find the index of first non-whitespace
158 unsigned long offset;
159 if (_BitScanForward(&offset, r))
163 return p + __builtin_ffs(r) - 1;
169 #endif // RAPIDJSON_SSE2
171 #ifdef RAPIDJSON_SIMD
173 template<>
inline void SkipWhitespace(InsituStringStream& stream) {
174 stream.src_ =
const_cast<char*
>(SkipWhitespace_SIMD(stream.src_));
178 template<>
inline void SkipWhitespace(StringStream& stream) {
179 stream.src_ = SkipWhitespace_SIMD(stream.src_);
181 #endif // RAPIDJSON_SIMD
201 template <
typename Encoding,
typename Allocator = MemoryPoolAllocator<> >
204 typedef typename Encoding::Ch Ch;
210 GenericReader(
Allocator* allocator = 0,
size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {}
220 template <
unsigned parseFlags,
typename Stream,
typename Handler>
226 #pragma warning(push)
227 #pragma warning(disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
229 if (setjmp(jmpbuf_)) {
237 SkipWhitespace(stream);
239 if (stream.Peek() ==
'\0')
240 RAPIDJSON_PARSE_ERROR(
"Text only contains white space(s)", stream.Tell());
242 switch (stream.Peek()) {
243 case '{': ParseObject<parseFlags>(stream, handler);
break;
244 case '[': ParseArray<parseFlags>(stream, handler);
break;
245 default: RAPIDJSON_PARSE_ERROR(
"Expect either an object or array at root", stream.Tell());
247 SkipWhitespace(stream);
249 if (stream.Peek() !=
'\0')
250 RAPIDJSON_PARSE_ERROR(
"Nothing should follow the root object or array.", stream.Tell());
256 bool HasParseError()
const {
return parseError_ != 0; }
257 const char* GetParseError()
const {
return parseError_; }
258 size_t GetErrorOffset()
const {
return errorOffset_; }
262 template<
unsigned parseFlags,
typename Stream,
typename Handler>
263 void ParseObject(Stream& stream, Handler& handler) {
264 RAPIDJSON_ASSERT(stream.Peek() ==
'{');
266 handler.StartObject();
267 SkipWhitespace(stream);
269 if (stream.Peek() ==
'}') {
271 handler.EndObject(0);
275 for (SizeType memberCount = 0;;) {
276 if (stream.Peek() !=
'"') {
277 RAPIDJSON_PARSE_ERROR(
"Name of an object member must be a string", stream.Tell());
281 ParseString<parseFlags>(stream, handler);
282 SkipWhitespace(stream);
284 if (stream.Take() !=
':') {
285 RAPIDJSON_PARSE_ERROR(
"There must be a colon after the name of object member", stream.Tell());
288 SkipWhitespace(stream);
290 ParseValue<parseFlags>(stream, handler);
291 SkipWhitespace(stream);
295 switch(stream.Take()) {
296 case ',': SkipWhitespace(stream);
break;
297 case '}': handler.EndObject(memberCount);
return;
298 default: RAPIDJSON_PARSE_ERROR(
"Must be a comma or '}' after an object member", stream.Tell());
304 template<
unsigned parseFlags,
typename Stream,
typename Handler>
305 void ParseArray(Stream& stream, Handler& handler) {
306 RAPIDJSON_ASSERT(stream.Peek() ==
'[');
308 handler.StartArray();
309 SkipWhitespace(stream);
311 if (stream.Peek() ==
']') {
317 for (SizeType elementCount = 0;;) {
318 ParseValue<parseFlags>(stream, handler);
320 SkipWhitespace(stream);
322 switch (stream.Take()) {
323 case ',': SkipWhitespace(stream);
break;
324 case ']': handler.EndArray(elementCount);
return;
325 default: RAPIDJSON_PARSE_ERROR(
"Must be a comma or ']' after an array element.", stream.Tell());
330 template<
unsigned parseFlags,
typename Stream,
typename Handler>
331 void ParseNull(Stream& stream, Handler& handler) {
332 RAPIDJSON_ASSERT(stream.Peek() ==
'n');
335 if (stream.Take() ==
'u' && stream.Take() ==
'l' && stream.Take() ==
'l')
338 RAPIDJSON_PARSE_ERROR(
"Invalid value", stream.Tell() - 1);
341 template<
unsigned parseFlags,
typename Stream,
typename Handler>
342 void ParseTrue(Stream& stream, Handler& handler) {
343 RAPIDJSON_ASSERT(stream.Peek() ==
't');
346 if (stream.Take() ==
'r' && stream.Take() ==
'u' && stream.Take() ==
'e')
349 RAPIDJSON_PARSE_ERROR(
"Invalid value", stream.Tell());
352 template<
unsigned parseFlags,
typename Stream,
typename Handler>
353 void ParseFalse(Stream& stream, Handler& handler) {
354 RAPIDJSON_ASSERT(stream.Peek() ==
'f');
357 if (stream.Take() ==
'a' && stream.Take() ==
'l' && stream.Take() ==
's' && stream.Take() ==
'e')
360 RAPIDJSON_PARSE_ERROR(
"Invalid value", stream.Tell() - 1);
364 template<
typename Stream>
365 unsigned ParseHex4(Stream& stream) {
367 unsigned codepoint = 0;
368 for (
int i = 0; i < 4; i++) {
372 if (c >=
'0' && c <=
'9')
374 else if (c >=
'A' && c <=
'F')
375 codepoint -=
'A' - 10;
376 else if (c >=
'a' && c <=
'f')
377 codepoint -=
'a' - 10;
379 RAPIDJSON_PARSE_ERROR(
"Incorrect hex digit after \\u escape", s.Tell() - 1);
386 template<
unsigned parseFlags,
typename Stream,
typename Handler>
387 void ParseString(Stream& stream, Handler& handler) {
388 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
389 static const Ch escape[256] = {
390 Z16, Z16, 0, 0,
'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'/',
391 Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
'\\', 0, 0, 0,
392 0, 0,
'\b', 0, 0, 0,
'\f', 0, 0, 0, 0, 0, 0, 0,
'\n', 0,
393 0, 0,
'\r', 0,
'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
394 Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
399 RAPIDJSON_ASSERT(s.Peek() ==
'\"');
403 if (parseFlags & kParseInsituFlag)
408 #define RAPIDJSON_PUT(x) \
410 if (parseFlags & kParseInsituFlag) \
413 *stack_.template Push<Ch>() = x; \
422 if ((
sizeof(Ch) == 1 || e < 256) && escape[(
unsigned char)e])
423 RAPIDJSON_PUT(escape[(
unsigned char)e]);
425 unsigned codepoint = ParseHex4(s);
426 if (codepoint >= 0xD800 && codepoint <= 0xDBFF) {
427 if (s.Take() !=
'\\' || s.Take() !=
'u') {
428 RAPIDJSON_PARSE_ERROR(
"Missing the second \\u in surrogate pair", s.Tell() - 2);
431 unsigned codepoint2 = ParseHex4(s);
432 if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) {
433 RAPIDJSON_PARSE_ERROR(
"The second \\u in surrogate pair is invalid", s.Tell() - 2);
436 codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
440 SizeType count = SizeType(Encoding::Encode(buffer, codepoint) - &buffer[0]);
442 if (parseFlags & kParseInsituFlag)
443 for (SizeType i = 0; i < count; i++)
446 memcpy(stack_.template Push<Ch>(count), buffer, count *
sizeof(Ch));
451 RAPIDJSON_PARSE_ERROR(
"Unknown escape character", stream.Tell() - 1);
456 if (parseFlags & kParseInsituFlag) {
457 size_t length = s.PutEnd(head);
458 RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
460 handler.String(head, SizeType(length),
false);
464 handler.String(stack_.template Pop<Ch>(len), len - 1,
true);
469 else if (c ==
'\0') {
470 RAPIDJSON_PARSE_ERROR(
"lacks ending quotation before the end of string", stream.Tell() - 1);
473 else if ((
unsigned)c < 0x20) {
474 RAPIDJSON_PARSE_ERROR(
"Incorrect unescaped character in string", stream.Tell() - 1);
483 template<
unsigned parseFlags,
typename Stream,
typename Handler>
484 void ParseNumber(Stream& stream, Handler& handler) {
488 if (s.Peek() ==
'-') {
495 bool try64bit =
false;
496 if (s.Peek() ==
'0') {
500 else if (s.Peek() >=
'1' && s.Peek() <=
'9') {
504 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
505 if (i >= 214748364) {
506 if (i != 214748364 || s.Peek() >
'8') {
511 i = i * 10 + (s.Take() -
'0');
514 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
515 if (i >= 429496729) {
516 if (i != 429496729 || s.Peek() >
'5') {
521 i = i * 10 + (s.Take() -
'0');
525 RAPIDJSON_PARSE_ERROR(
"Expect a value here.", stream.Tell());
531 bool useDouble =
false;
535 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
536 if (i64 >= 922337203685477580uLL)
537 if (i64 != 922337203685477580uLL || s.Peek() >
'8') {
541 i64 = i64 * 10 + (s.Take() -
'0');
544 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
545 if (i64 >= 1844674407370955161uLL)
546 if (i64 != 1844674407370955161uLL || s.Peek() >
'5') {
550 i64 = i64 * 10 + (s.Take() -
'0');
558 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
560 RAPIDJSON_PARSE_ERROR(
"Number too big to store in double", stream.Tell());
563 d = d * 10 + (s.Take() -
'0');
569 if (s.Peek() ==
'.') {
571 d = try64bit ? (double)i64 : (
double)i;
576 if (s.Peek() >= '0' && s.Peek() <= '9') {
577 d = d * 10 + (s.Take() -
'0');
581 RAPIDJSON_PARSE_ERROR(
"At least one digit in fraction part", stream.Tell());
585 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
587 d = d * 10 + (s.Peek() -
'0');
596 if (s.Peek() ==
'e' || s.Peek() ==
'E') {
598 d = try64bit ? (double)i64 : (
double)i;
603 bool expMinus = false;
606 else if (s.Peek() == '-') {
611 if (s.Peek() >=
'0' && s.Peek() <=
'9') {
612 exp = s.Take() -
'0';
613 while (s.Peek() >=
'0' && s.Peek() <=
'9') {
614 exp = exp * 10 + (s.Take() -
'0');
616 RAPIDJSON_PARSE_ERROR(
"Number too big to store in double", stream.Tell());
622 RAPIDJSON_PARSE_ERROR(
"At least one digit in exponent", s.Tell());
632 d *= internal::Pow10(exp + expFrac);
633 handler.Double(minus ? -d : d);
638 handler.Int64(-(int64_t)i64);
644 handler.Int(-(
int)i);
654 template<
unsigned parseFlags,
typename Stream,
typename Handler>
655 void ParseValue(Stream& stream, Handler& handler) {
656 switch (stream.Peek()) {
657 case 'n': ParseNull <parseFlags>(stream, handler);
break;
658 case 't': ParseTrue <parseFlags>(stream, handler);
break;
659 case 'f': ParseFalse <parseFlags>(stream, handler);
break;
660 case '"': ParseString<parseFlags>(stream, handler);
break;
661 case '{': ParseObject<parseFlags>(stream, handler);
break;
662 case '[': ParseArray <parseFlags>(stream, handler);
break;
663 default : ParseNumber<parseFlags>(stream, handler);
667 static const size_t kDefaultStackCapacity = 256;
668 internal::Stack<Allocator> stack_;
670 const char* parseError_;
675 typedef GenericReader<UTF8<> > Reader;
683 #endif // RAPIDJSON_READER_H_