1 #ifndef RAPIDJSON_READER_H_
2 #define RAPIDJSON_READER_H_
3 
4 // Copyright (c) 2011 Milo Yip (miloyip@gmail.com)
5 // Version 0.1
6 
7 #include "rapidjson.h"
8 #include "internal/pow10.h"
9 #include "internal/stack.h"
10 #include <csetjmp>
11 
12 #ifdef RAPIDJSON_SSE42
13 #include <nmmintrin.h>
14 #elif defined(RAPIDJSON_SSE2)
15 #include <emmintrin.h>
16 #endif
17 
18 #ifdef _MSC_VER
19 #pragma warning(push)
20 #pragma warning(disable : 4127) // conditional expression is constant
21 #endif
22 
23 #ifndef RAPIDJSON_PARSE_ERROR
24 #define RAPIDJSON_PARSE_ERROR(msg, offset) \
25 	RAPIDJSON_MULTILINEMACRO_BEGIN \
26 	parseError_ = msg; \
27 	errorOffset_ = offset; \
28 	longjmp(jmpbuf_, 1); \
29 	RAPIDJSON_MULTILINEMACRO_END
30 #endif
31 
32 namespace rapidjson {
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 // ParseFlag
36 
37 //! Combination of parseFlags
38 enum ParseFlag {
39 	kParseDefaultFlags = 0,			//!< Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer.
40 	kParseInsituFlag = 1			//!< In-situ(destructive) parsing.
41 };
42 
43 ///////////////////////////////////////////////////////////////////////////////
44 // Handler
45 
46 /*!	\class rapidjson::Handler
47 	\brief Concept for receiving events from GenericReader upon parsing.
48 \code
49 concept Handler {
50 	typename Ch;
51 
52 	void Null();
53 	void Bool(bool b);
54 	void Int(int i);
55 	void Uint(unsigned i);
56 	void Int64(int64_t i);
57 	void Uint64(uint64_t i);
58 	void Double(double d);
59 	void String(const Ch* str, SizeType length, bool copy);
60 	void StartObject();
61 	void EndObject(SizeType memberCount);
62 	void StartArray();
63 	void EndArray(SizeType elementCount);
64 };
65 \endcode
66 */
67 ///////////////////////////////////////////////////////////////////////////////
68 // BaseReaderHandler
69 
70 //! Default implementation of Handler.
71 /*! This can be used as base class of any reader handler.
72 	\implements Handler
73 */
74 template<typename Encoding = UTF8<> >
75 struct BaseReaderHandler {
76 	typedef typename Encoding::Ch Ch;
77 
DefaultBaseReaderHandler78 	void Default() {}
NullBaseReaderHandler79 	void Null() { Default(); }
BoolBaseReaderHandler80 	void Bool(bool) { Default(); }
IntBaseReaderHandler81 	void Int(int) { Default(); }
UintBaseReaderHandler82 	void Uint(unsigned) { Default(); }
Int64BaseReaderHandler83 	void Int64(int64_t) { Default(); }
Uint64BaseReaderHandler84 	void Uint64(uint64_t) { Default(); }
DoubleBaseReaderHandler85 	void Double(double) { Default(); }
StringBaseReaderHandler86 	void String(const Ch*, SizeType, bool) { Default(); }
StartObjectBaseReaderHandler87 	void StartObject() { Default(); }
EndObjectBaseReaderHandler88 	void EndObject(SizeType) { Default(); }
StartArrayBaseReaderHandler89 	void StartArray() { Default(); }
EndArrayBaseReaderHandler90 	void EndArray(SizeType) { Default(); }
91 };
92 
93 ///////////////////////////////////////////////////////////////////////////////
94 // SkipWhitespace
95 
96 //! Skip the JSON white spaces in a stream.
97 /*! \param stream A input stream for skipping white spaces.
98 	\note This function has SSE2/SSE4.2 specialization.
99 */
100 template<typename Stream>
SkipWhitespace(Stream & stream)101 void SkipWhitespace(Stream& stream) {
102 	Stream s = stream;	// Use a local copy for optimization
103 	while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t')
104 		s.Take();
105 	stream = s;
106 }
107 
108 #ifdef RAPIDJSON_SSE42
109 //! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.
SkipWhitespace_SIMD(const char * p)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]);
113 
114 	for (;;) {
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));
117 		if (r == 0)	// all 16 characters are whitespace
118 			p += 16;
119 		else {		// some of characters may be non-whitespace
120 #ifdef _MSC_VER		// Find the index of first non-whitespace
121 			unsigned long offset;
122 			if (_BitScanForward(&offset, r))
123 				return p + offset;
124 #else
125 			if (r != 0)
126 				return p + __builtin_ffs(r) - 1;
127 #endif
128 		}
129 	}
130 }
131 
132 #elif defined(RAPIDJSON_SSE2)
133 
134 //! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
SkipWhitespace_SIMD(const char * p)135 inline const char *SkipWhitespace_SIMD(const char* p) {
136 	static const char whitespaces[4][17] = {
137 		"                ",
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"};
141 
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]);
146 
147 	for (;;) {
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);
154 		if (r == 0)	// all 16 characters are whitespace
155 			p += 16;
156 		else {		// some of characters may be non-whitespace
157 #ifdef _MSC_VER		// Find the index of first non-whitespace
158 			unsigned long offset;
159 			if (_BitScanForward(&offset, r))
160 				return p + offset;
161 #else
162 			if (r != 0)
163 				return p + __builtin_ffs(r) - 1;
164 #endif
165 		}
166 	}
167 }
168 
169 #endif // RAPIDJSON_SSE2
170 
171 #ifdef RAPIDJSON_SIMD
172 //! Template function specialization for InsituStringStream
SkipWhitespace(InsituStringStream & stream)173 template<> inline void SkipWhitespace(InsituStringStream& stream) {
174 	stream.src_ = const_cast<char*>(SkipWhitespace_SIMD(stream.src_));
175 }
176 
177 //! Template function specialization for StringStream
SkipWhitespace(StringStream & stream)178 template<> inline void SkipWhitespace(StringStream& stream) {
179 	stream.src_ = SkipWhitespace_SIMD(stream.src_);
180 }
181 #endif // RAPIDJSON_SIMD
182 
183 ///////////////////////////////////////////////////////////////////////////////
184 // GenericReader
185 
186 //! SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
187 /*! GenericReader parses JSON text from a stream, and send events synchronously to an
188     object implementing Handler concept.
189 
190     It needs to allocate a stack for storing a single decoded string during
191     non-destructive parsing.
192 
193     For in-situ parsing, the decoded string is directly written to the source
194     text string, no temporary buffer is required.
195 
196     A GenericReader object can be reused for parsing multiple JSON text.
197 
198     \tparam Encoding Encoding of both the stream and the parse output.
199     \tparam Allocator Allocator type for stack.
200 */
201 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
202 class GenericReader {
203 public:
204 	typedef typename Encoding::Ch Ch;
205 
206 	//! Constructor.
207 	/*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
208 		\param stackCapacity stack capacity in bytes for storing a single decoded string.  (Only use for non-destructive parsing)
209 	*/
stack_(allocator,stackCapacity)210 	GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {}
211 
212 	//! Parse JSON text.
213 	/*! \tparam parseFlags Combination of ParseFlag.
214 		 \tparam Stream Type of input stream.
215 		 \tparam Handler Type of handler which must implement Handler concept.
216 		 \param stream Input stream to be parsed.
217 		 \param handler The handler to receive events.
218 		 \return Whether the parsing is successful.
219 	*/
220 	template <unsigned parseFlags, typename Stream, typename Handler>
Parse(Stream & stream,Handler & handler)221 	bool Parse(Stream& stream, Handler& handler) {
222 		parseError_ = 0;
223 		errorOffset_ = 0;
224 
225 #ifdef _MSC_VER
226 #pragma warning(push)
227 #pragma warning(disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
228 #endif
229 		if (setjmp(jmpbuf_)) {
230 #ifdef _MSC_VER
231 #pragma warning(pop)
232 #endif
233 			stack_.Clear();
234 			return false;
235 		}
236 
237 		SkipWhitespace(stream);
238 
239 		if (stream.Peek() == '\0')
240 			RAPIDJSON_PARSE_ERROR("Text only contains white space(s)", stream.Tell());
241 		else {
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());
246 			}
247 			SkipWhitespace(stream);
248 
249 			if (stream.Peek() != '\0')
250 				RAPIDJSON_PARSE_ERROR("Nothing should follow the root object or array.", stream.Tell());
251 		}
252 
253 		return true;
254 	}
255 
HasParseError()256 	bool HasParseError() const { return parseError_ != 0; }
GetParseError()257 	const char* GetParseError() const { return parseError_; }
GetErrorOffset()258 	size_t GetErrorOffset() const { return errorOffset_; }
259 
260 private:
261 	// Parse object: { string : value, ... }
262 	template<unsigned parseFlags, typename Stream, typename Handler>
ParseObject(Stream & stream,Handler & handler)263 	void ParseObject(Stream& stream, Handler& handler) {
264 		RAPIDJSON_ASSERT(stream.Peek() == '{');
265 		stream.Take();	// Skip '{'
266 		handler.StartObject();
267 		SkipWhitespace(stream);
268 
269 		if (stream.Peek() == '}') {
270 			stream.Take();
271 			handler.EndObject(0);	// empty object
272 			return;
273 		}
274 
275 		for (SizeType memberCount = 0;;) {
276 			if (stream.Peek() != '"') {
277 				RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", stream.Tell());
278 				break;
279 			}
280 
281 			ParseString<parseFlags>(stream, handler);
282 			SkipWhitespace(stream);
283 
284 			if (stream.Take() != ':') {
285 				RAPIDJSON_PARSE_ERROR("There must be a colon after the name of object member", stream.Tell());
286 				break;
287 			}
288 			SkipWhitespace(stream);
289 
290 			ParseValue<parseFlags>(stream, handler);
291 			SkipWhitespace(stream);
292 
293 			++memberCount;
294 
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());
299 			}
300 		}
301 	}
302 
303 	// Parse array: [ value, ... ]
304 	template<unsigned parseFlags, typename Stream, typename Handler>
ParseArray(Stream & stream,Handler & handler)305 	void ParseArray(Stream& stream, Handler& handler) {
306 		RAPIDJSON_ASSERT(stream.Peek() == '[');
307 		stream.Take();	// Skip '['
308 		handler.StartArray();
309 		SkipWhitespace(stream);
310 
311 		if (stream.Peek() == ']') {
312 			stream.Take();
313 			handler.EndArray(0); // empty array
314 			return;
315 		}
316 
317 		for (SizeType elementCount = 0;;) {
318 			ParseValue<parseFlags>(stream, handler);
319 			++elementCount;
320 			SkipWhitespace(stream);
321 
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());
326 			}
327 		}
328 	}
329 
330 	template<unsigned parseFlags, typename Stream, typename Handler>
ParseNull(Stream & stream,Handler & handler)331 	void ParseNull(Stream& stream, Handler& handler) {
332 		RAPIDJSON_ASSERT(stream.Peek() == 'n');
333 		stream.Take();
334 
335 		if (stream.Take() == 'u' && stream.Take() == 'l' && stream.Take() == 'l')
336 			handler.Null();
337 		else
338 			RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1);
339 	}
340 
341 	template<unsigned parseFlags, typename Stream, typename Handler>
ParseTrue(Stream & stream,Handler & handler)342 	void ParseTrue(Stream& stream, Handler& handler) {
343 		RAPIDJSON_ASSERT(stream.Peek() == 't');
344 		stream.Take();
345 
346 		if (stream.Take() == 'r' && stream.Take() == 'u' && stream.Take() == 'e')
347 			handler.Bool(true);
348 		else
349 			RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell());
350 	}
351 
352 	template<unsigned parseFlags, typename Stream, typename Handler>
ParseFalse(Stream & stream,Handler & handler)353 	void ParseFalse(Stream& stream, Handler& handler) {
354 		RAPIDJSON_ASSERT(stream.Peek() == 'f');
355 		stream.Take();
356 
357 		if (stream.Take() == 'a' && stream.Take() == 'l' && stream.Take() == 's' && stream.Take() == 'e')
358 			handler.Bool(false);
359 		else
360 			RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1);
361 	}
362 
363 	// Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
364 	template<typename Stream>
ParseHex4(Stream & stream)365 	unsigned ParseHex4(Stream& stream) {
366 		Stream s = stream;	// Use a local copy for optimization
367 		unsigned codepoint = 0;
368 		for (int i = 0; i < 4; i++) {
369 			Ch c = s.Take();
370 			codepoint <<= 4;
371 			codepoint += c;
372 			if (c >= '0' && c <= '9')
373 				codepoint -= '0';
374 			else if (c >= 'A' && c <= 'F')
375 				codepoint -= 'A' - 10;
376 			else if (c >= 'a' && c <= 'f')
377 				codepoint -= 'a' - 10;
378 			else
379 				RAPIDJSON_PARSE_ERROR("Incorrect hex digit after \\u escape", s.Tell() - 1);
380 		}
381 		stream = s; // Restore stream
382 		return codepoint;
383 	}
384 
385 	// Parse string, handling the prefix and suffix double quotes and escaping.
386 	template<unsigned parseFlags, typename Stream, typename Handler>
ParseString(Stream & stream,Handler & 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
395 		};
396 #undef Z16
397 
398 		Stream s = stream;	// Use a local copy for optimization
399 		RAPIDJSON_ASSERT(s.Peek() == '\"');
400 		s.Take();	// Skip '\"'
401 		Ch *head;
402 		SizeType len;
403 		if (parseFlags & kParseInsituFlag)
404 			head = s.PutBegin();
405 		else
406 			len = 0;
407 
408 #define RAPIDJSON_PUT(x) \
409 	do { \
410 		if (parseFlags & kParseInsituFlag) \
411 			s.Put(x); \
412 		else { \
413 			*stack_.template Push<Ch>() = x; \
414 			++len; \
415 		} \
416 	} while(false)
417 
418 		for (;;) {
419 			Ch c = s.Take();
420 			if (c == '\\') {	// Escape
421 				Ch e = s.Take();
422 				if ((sizeof(Ch) == 1) && escape[(unsigned char)e])
423 					RAPIDJSON_PUT(escape[(unsigned char)e]);
424 				else if (e == 'u') {	// Unicode
425 					unsigned codepoint = ParseHex4(s);
426 					if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { // Handle UTF-16 surrogate pair
427 						if (s.Take() != '\\' || s.Take() != 'u') {
428 							RAPIDJSON_PARSE_ERROR("Missing the second \\u in surrogate pair", s.Tell() - 2);
429 							return;
430 						}
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);
434 							return;
435 						}
436 						codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
437 					}
438 
439 					Ch buffer[4];
440 					SizeType count = SizeType(Encoding::Encode(buffer, codepoint) - &buffer[0]);
441 
442 					if (parseFlags & kParseInsituFlag)
443 						for (SizeType i = 0; i < count; i++)
444 							s.Put(buffer[i]);
445 					else {
446 						memcpy(stack_.template Push<Ch>(count), buffer, count * sizeof(Ch));
447 						len += count;
448 					}
449 				}
450 				else {
451 					RAPIDJSON_PARSE_ERROR("Unknown escape character", stream.Tell() - 1);
452 					return;
453 				}
454 			}
455 			else if (c == '"') {	// Closing double quote
456 				if (parseFlags & kParseInsituFlag) {
457 					size_t length = s.PutEnd(head);
458 					RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
459 					RAPIDJSON_PUT('\0');	// null-terminate the string
460 					handler.String(head, SizeType(length), false);
461 				}
462 				else {
463 					RAPIDJSON_PUT('\0');
464 					handler.String(stack_.template Pop<Ch>(len), len - 1, true);
465 				}
466 				stream = s;	// restore stream
467 				return;
468 			}
469 			else if (c == '\0') {
470 				RAPIDJSON_PARSE_ERROR("lacks ending quotation before the end of string", stream.Tell() - 1);
471 				return;
472 			}
473 			else if ((unsigned)c < 0x20) {	// RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
474 				RAPIDJSON_PARSE_ERROR("Incorrect unescaped character in string", stream.Tell() - 1);
475 				return;
476 			}
477 			else
478 				RAPIDJSON_PUT(c);	// Normal character, just copy
479 		}
480 #undef RAPIDJSON_PUT
481 	}
482 
483 	template<unsigned parseFlags, typename Stream, typename Handler>
ParseNumber(Stream & stream,Handler & handler)484 	void ParseNumber(Stream& stream, Handler& handler) {
485 		Stream s = stream; // Local copy for optimization
486 		// Parse minus
487 		bool minus = false;
488 		if (s.Peek() == '-') {
489 			minus = true;
490 			s.Take();
491 		}
492 
493 		// Parse int: zero / ( digit1-9 *DIGIT )
494 		unsigned i;
495 		bool try64bit = false;
496 		if (s.Peek() == '0') {
497 			i = 0;
498 			s.Take();
499 		}
500 		else if (s.Peek() >= '1' && s.Peek() <= '9') {
501 			i = s.Take() - '0';
502 
503 			if (minus)
504 				while (s.Peek() >= '0' && s.Peek() <= '9') {
505 					if (i >= 214748364) { // 2^31 = 2147483648
506 						if (i != 214748364 || s.Peek() > '8') {
507 							try64bit = true;
508 							break;
509 						}
510 					}
511 					i = i * 10 + (s.Take() - '0');
512 				}
513 			else
514 				while (s.Peek() >= '0' && s.Peek() <= '9') {
515 					if (i >= 429496729) { // 2^32 - 1 = 4294967295
516 						if (i != 429496729 || s.Peek() > '5') {
517 							try64bit = true;
518 							break;
519 						}
520 					}
521 					i = i * 10 + (s.Take() - '0');
522 				}
523 		}
524 		else {
525 			RAPIDJSON_PARSE_ERROR("Expect a value here.", stream.Tell());
526 			return;
527 		}
528 
529 		// Parse 64bit int
530 		uint64_t i64 = 0;
531 		bool useDouble = false;
532 		if (try64bit) {
533 			i64 = i;
534 			if (minus)
535 				while (s.Peek() >= '0' && s.Peek() <= '9') {
536 					if (i64 >= 922337203685477580uLL) // 2^63 = 9223372036854775808
537 						if (i64 != 922337203685477580uLL || s.Peek() > '8') {
538 							useDouble = true;
539 							break;
540 						}
541 					i64 = i64 * 10 + (s.Take() - '0');
542 				}
543 			else
544 				while (s.Peek() >= '0' && s.Peek() <= '9') {
545 					if (i64 >= 1844674407370955161uLL) // 2^64 - 1 = 18446744073709551615
546 						if (i64 != 1844674407370955161uLL || s.Peek() > '5') {
547 							useDouble = true;
548 							break;
549 						}
550 					i64 = i64 * 10 + (s.Take() - '0');
551 				}
552 		}
553 
554 		// Force double for big integer
555 		double d = 0.0;
556 		if (useDouble) {
557 			d = (double)i64;
558 			while (s.Peek() >= '0' && s.Peek() <= '9') {
559 				if (d >= 1E307) {
560 					RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell());
561 					return;
562 				}
563 				d = d * 10 + (s.Take() - '0');
564 			}
565 		}
566 
567 		// Parse frac = decimal-point 1*DIGIT
568 		int expFrac = 0;
569 		if (s.Peek() == '.') {
570 			if (!useDouble) {
571 				d = try64bit ? (double)i64 : (double)i;
572 				useDouble = true;
573 			}
574 			s.Take();
575 
576 			if (s.Peek() >= '0' && s.Peek() <= '9') {
577 				d = d * 10 + (s.Take() - '0');
578 				--expFrac;
579 			}
580 			else {
581 				RAPIDJSON_PARSE_ERROR("At least one digit in fraction part", stream.Tell());
582 				return;
583 			}
584 
585 			while (s.Peek() >= '0' && s.Peek() <= '9') {
586 				if (expFrac > -16) {
587 					d = d * 10 + (s.Peek() - '0');
588 					--expFrac;
589 				}
590 				s.Take();
591 			}
592 		}
593 
594 		// Parse exp = e [ minus / plus ] 1*DIGIT
595 		int exp = 0;
596 		if (s.Peek() == 'e' || s.Peek() == 'E') {
597 			if (!useDouble) {
598 				d = try64bit ? (double)i64 : (double)i;
599 				useDouble = true;
600 			}
601 			s.Take();
602 
603 			bool expMinus = false;
604 			if (s.Peek() == '+')
605 				s.Take();
606 			else if (s.Peek() == '-') {
607 				s.Take();
608 				expMinus = true;
609 			}
610 
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');
615 					if (exp > 308) {
616 						RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell());
617 						return;
618 					}
619 				}
620 			}
621 			else {
622 				RAPIDJSON_PARSE_ERROR("At least one digit in exponent", s.Tell());
623 				return;
624 			}
625 
626 			if (expMinus)
627 				exp = -exp;
628 		}
629 
630 		// Finish parsing, call event according to the type of number.
631 		if (useDouble) {
632 			d *= internal::Pow10(exp + expFrac);
633 			handler.Double(minus ? -d : d);
634 		}
635 		else {
636 			if (try64bit) {
637 				if (minus)
638 					handler.Int64(-(int64_t)i64);
639 				else
640 					handler.Uint64(i64);
641 			}
642 			else {
643 				if (minus)
644 					handler.Int(-(int)i);
645 				else
646 					handler.Uint(i);
647 			}
648 		}
649 
650 		stream = s; // restore stream
651 	}
652 
653 	// Parse any JSON value
654 	template<unsigned parseFlags, typename Stream, typename Handler>
ParseValue(Stream & stream,Handler & 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);
664 		}
665 	}
666 
667 	static const size_t kDefaultStackCapacity = 256;	//!< Default stack capacity in bytes for storing a single decoded string.
668 	internal::Stack<Allocator> stack_;	//!< A stack for storing decoded string temporarily during non-destructive parsing.
669 	jmp_buf jmpbuf_;					//!< setjmp buffer for fast exit from nested parsing function calls.
670 	const char* parseError_;
671 	size_t errorOffset_;
672 }; // class GenericReader
673 
674 //! Reader with UTF8 encoding and default allocator.
675 typedef GenericReader<UTF8<> > Reader;
676 
677 } // namespace rapidjson
678 
679 #ifdef _MSC_VER
680 #pragma warning(pop)
681 #endif
682 
683 #endif // RAPIDJSON_READER_H_
684