All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
reader.h
1 // Copyright (C) 2011 Milo Yip
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 
21 #ifndef RAPIDJSON_READER_H_
22 #define RAPIDJSON_READER_H_
23 
24 // Copyright (c) 2011 Milo Yip (miloyip@gmail.com)
25 // Version 0.1
26 
27 #include "rapidjson.h"
28 #include "encodings.h"
29 #include "internal/meta.h"
30 #include "internal/pow10.h"
31 #include "internal/stack.h"
32 
33 #if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
34 #include <intrin.h>
35 #pragma intrinsic(_BitScanForward)
36 #endif
37 #ifdef RAPIDJSON_SSE42
38 #include <nmmintrin.h>
39 #elif defined(RAPIDJSON_SSE2)
40 #include <emmintrin.h>
41 #endif
42 
43 #ifdef _MSC_VER
44 RAPIDJSON_DIAG_PUSH
45 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
46 RAPIDJSON_DIAG_OFF(4702) // unreachable code
47 #endif
48 
49 #define RAPIDJSON_NOTHING /* deliberately empty */
50 #ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
51 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
52  RAPIDJSON_MULTILINEMACRO_BEGIN \
53  if (HasParseError()) { return value; } \
54  RAPIDJSON_MULTILINEMACRO_END
55 #endif
56 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
57  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
58 
59 #ifndef RAPIDJSON_PARSE_ERROR_NORETURN
60 #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
61  RAPIDJSON_MULTILINEMACRO_BEGIN \
62  RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
63  parseResult_.Set(parseErrorCode,offset); \
64  RAPIDJSON_MULTILINEMACRO_END
65 #endif
66 
67 #ifndef RAPIDJSON_PARSE_ERROR
68 #define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \
69  RAPIDJSON_MULTILINEMACRO_BEGIN \
70  RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
71  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
72  RAPIDJSON_MULTILINEMACRO_END
73 #endif
74 
75 #include "error/error.h" // ParseErrorCode, ParseResult
76 
77 namespace rapidjson {
78 
79 ///////////////////////////////////////////////////////////////////////////////
80 // ParseFlag
81 
82 //! Combination of parseFlags
83 /*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream
84  */
85 enum ParseFlag {
86  kParseDefaultFlags = 0, //!< Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer.
87  kParseInsituFlag = 1, //!< In-situ(destructive) parsing.
88  kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings.
89  kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing.
90  kParseStopWhenDoneFlag = 8 //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error.
91 };
92 
93 ///////////////////////////////////////////////////////////////////////////////
94 // Handler
95 
96 /*! \class rapidjson::Handler
97  \brief Concept for receiving events from GenericReader upon parsing.
98  The functions return true if no error occurs. If they return false,
99  the event publisher should terminate the process.
100 \code
101 concept Handler {
102  typename Ch;
103 
104  bool Null();
105  bool Bool(bool b);
106  bool Int(int i);
107  bool Uint(unsigned i);
108  bool Int64(int64_t i);
109  bool Uint64(uint64_t i);
110  bool Double(double d);
111  bool String(const Ch* str, SizeType length, bool copy);
112  bool StartObject();
113  bool EndObject(SizeType memberCount);
114  bool StartArray();
115  bool EndArray(SizeType elementCount);
116 };
117 \endcode
118 */
119 ///////////////////////////////////////////////////////////////////////////////
120 // BaseReaderHandler
121 
122 //! Default implementation of Handler.
123 /*! This can be used as base class of any reader handler.
124  \note implements Handler concept
125 */
126 template<typename Encoding = UTF8<>, typename Derived = void>
128  typedef typename Encoding::Ch Ch;
129 
130  typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override;
131 
132  bool Default() { return true; }
133  bool Null() { return static_cast<Override&>(*this).Default(); }
134  bool Bool(bool) { return static_cast<Override&>(*this).Default(); }
135  bool Int(int) { return static_cast<Override&>(*this).Default(); }
136  bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); }
137  bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); }
138  bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); }
139  bool Double(double) { return static_cast<Override&>(*this).Default(); }
140  bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); }
141  bool StartObject() { return static_cast<Override&>(*this).Default(); }
142  bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }
143  bool StartArray() { return static_cast<Override&>(*this).Default(); }
144  bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }
145 };
146 
147 ///////////////////////////////////////////////////////////////////////////////
148 // StreamLocalCopy
149 
150 namespace internal {
151 
152 template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
153 class StreamLocalCopy;
154 
155 //! Do copy optimization.
156 template<typename Stream>
157 class StreamLocalCopy<Stream, 1> {
158 public:
159  StreamLocalCopy(Stream& original) : s(original), original_(original) {}
160  ~StreamLocalCopy() { original_ = s; }
161 
162  Stream s;
163 
164 private:
165  StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
166 
167  Stream& original_;
168 };
169 
170 //! Keep reference.
171 template<typename Stream>
172 class StreamLocalCopy<Stream, 0> {
173 public:
174  StreamLocalCopy(Stream& original) : s(original) {}
175 
176  Stream& s;
177 
178 private:
179  StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
180 };
181 
182 } // namespace internal
183 
184 ///////////////////////////////////////////////////////////////////////////////
185 // SkipWhitespace
186 
187 //! Skip the JSON white spaces in a stream.
188 /*! \param is A input stream for skipping white spaces.
189  \note This function has SSE2/SSE4.2 specialization.
190 */
191 template<typename InputStream>
192 void SkipWhitespace(InputStream& is) {
193  internal::StreamLocalCopy<InputStream> copy(is);
194  InputStream& s(copy.s);
195 
196  while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t')
197  s.Take();
198 }
199 
200 #ifdef RAPIDJSON_SSE42
201 //! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.
202 inline const char *SkipWhitespace_SIMD(const char* p) {
203  static const char whitespace[16] = " \n\r\t";
204  static const char whitespaces[4][17] = {
205  " ",
206  "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
207  "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",
208  "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};
209 
210  // 16-byte align to the lower boundary
211  const char* ap = reinterpret_cast<const char*>(reinterpret_cast<size_t>(p) & ~15);
212 
213  // Test first unaligned characters
214  // Cannot make use of _mm_cmpistrm() because it stops when encounters '\0' before p
215  if (ap != p) {
216  const __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]);
217  const __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]);
218  const __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]);
219  const __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]);
220 
221  unsigned char shift = reinterpret_cast<size_t>(p) & 15;
222  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i*>(ap));
223  __m128i x = _mm_cmpeq_epi8(s, w0);
224  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
225  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
226  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
227  unsigned short r = (unsigned short)~_mm_movemask_epi8(x);
228  r = r >> shift << shift; // Clear results before p
229  if (r != 0) {
230 #ifdef _MSC_VER // Find the index of first non-whitespace
231  unsigned long offset;
232  _BitScanForward(&offset, r);
233  return ap + offset;
234 #else
235  return ap + __builtin_ffs(r) - 1;
236 #endif
237  }
238  ap += 16;
239  }
240 
241  const __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]);
242 
243  // The rest of string
244  for (;; ap += 16) {
245  const __m128i s = _mm_load_si128((const __m128i *)ap);
246  const unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
247  if (r != 0) { // some of characters is non-whitespace
248 #ifdef _MSC_VER // Find the index of first non-whitespace
249  unsigned long offset;
250  _BitScanForward(&offset, r);
251  return ap + offset;
252 #else
253  return ap + __builtin_ffs(r) - 1;
254 #endif
255  }
256  }
257 }
258 
259 #elif defined(RAPIDJSON_SSE2)
260 
261 //! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
262 inline const char *SkipWhitespace_SIMD(const char* p) {
263  static const char whitespaces[4][17] = {
264  " ",
265  "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
266  "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",
267  "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};
268 
269  const __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]);
270  const __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]);
271  const __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]);
272  const __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]);
273 
274  // 16-byte align to the lower boundary
275  const char* ap = reinterpret_cast<const char*>(reinterpret_cast<size_t>(p) & ~15);
276 
277  // Test first unaligned characters
278  if (ap != p) {
279  unsigned char shift = reinterpret_cast<size_t>(p) & 15;
280  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i*>(ap));
281  __m128i x = _mm_cmpeq_epi8(s, w0);
282  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
283  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
284  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
285  unsigned short r = (unsigned short)~_mm_movemask_epi8(x);
286  r = r >> shift << shift; // Clear results before p
287  if (r != 0) {
288 #ifdef _MSC_VER // Find the index of first non-whitespace
289  unsigned long offset;
290  _BitScanForward(&offset, r);
291  return ap + offset;
292 #else
293  return ap + __builtin_ffs(r) - 1;
294 #endif
295  }
296  ap += 16;
297  }
298 
299  // The rest of string
300  for (;; ap += 16) {
301  const __m128i s = _mm_load_si128((const __m128i *)ap);
302  __m128i x = _mm_cmpeq_epi8(s, w0);
303  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
304  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
305  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
306  unsigned short r = (unsigned short)~_mm_movemask_epi8(x);
307  if (r != 0) { // some of characters may be non-whitespace
308 #ifdef _MSC_VER // Find the index of first non-whitespace
309  unsigned long offset;
310  _BitScanForward(&offset, r);
311  return ap + offset;
312 #else
313  return ap + __builtin_ffs(r) - 1;
314 #endif
315  }
316  }
317 }
318 
319 #endif // RAPIDJSON_SSE2
320 
321 #ifdef RAPIDJSON_SIMD
322 //! Template function specialization for InsituStringStream
323 template<> inline void SkipWhitespace(InsituStringStream& is) {
324  is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
325 }
326 
327 //! Template function specialization for StringStream
328 template<> inline void SkipWhitespace(StringStream& is) {
329  is.src_ = SkipWhitespace_SIMD(is.src_);
330 }
331 #endif // RAPIDJSON_SIMD
332 
333 ///////////////////////////////////////////////////////////////////////////////
334 // GenericReader
335 
336 //! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator.
337 /*! GenericReader parses JSON text from a stream, and send events synchronously to an
338  object implementing Handler concept.
339 
340  It needs to allocate a stack for storing a single decoded string during
341  non-destructive parsing.
342 
343  For in-situ parsing, the decoded string is directly written to the source
344  text string, no temporary buffer is required.
345 
346  A GenericReader object can be reused for parsing multiple JSON text.
347 
348  \tparam SourceEncoding Encoding of the input stream.
349  \tparam TargetEncoding Encoding of the parse output.
350  \tparam Allocator Allocator type for stack.
351 */
352 template <typename SourceEncoding, typename TargetEncoding, typename Allocator = MemoryPoolAllocator<> >
354 public:
355  typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type
356 
357  //! Constructor.
358  /*! \param allocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
359  \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
360  */
361  GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseResult_() {}
362 
363  //! Parse JSON text.
364  /*! \tparam parseFlags Combination of \ref ParseFlag.
365  \tparam InputStream Type of input stream, implementing Stream concept.
366  \tparam Handler Type of handler, implementing Handler concept.
367  \param is Input stream to be parsed.
368  \param handler The handler to receive events.
369  \return Whether the parsing is successful.
370  */
371  template <unsigned parseFlags, typename InputStream, typename Handler>
372  ParseResult Parse(InputStream& is, Handler& handler) {
373  if (parseFlags & kParseIterativeFlag)
374  return IterativeParse<parseFlags>(is, handler);
375 
376  parseResult_.Clear();
377 
378  ClearStackOnExit scope(*this);
379 
380  SkipWhitespace(is);
381 
382  if (is.Peek() == '\0') {
383  RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
384  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
385  }
386  else {
387  ParseValue<parseFlags>(is, handler);
388  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
389 
390  if (!(parseFlags & kParseStopWhenDoneFlag)) {
391  SkipWhitespace(is);
392 
393  if (is.Peek() != '\0') {
394  RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
395  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
396  }
397  }
398  }
399 
400  return parseResult_;
401  }
402 
403  //! Parse JSON text (with \ref kParseDefaultFlags)
404  /*! \tparam InputStream Type of input stream, implementing Stream concept
405  \tparam Handler Type of handler, implementing Handler concept.
406  \param is Input stream to be parsed.
407  \param handler The handler to receive events.
408  \return Whether the parsing is successful.
409  */
410  template <typename InputStream, typename Handler>
411  ParseResult Parse(InputStream& is, Handler& handler) {
412  return Parse<kParseDefaultFlags>(is, handler);
413  }
414 
415  //! Whether a parse error has occured in the last parsing.
416  bool HasParseError() const { return parseResult_.IsError(); }
417 
418  //! Get the \ref ParseErrorCode of last parsing.
419  ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }
420 
421  //! Get the position of last parsing error in input, 0 otherwise.
422  size_t GetErrorOffset() const { return parseResult_.Offset(); }
423 
424 private:
425  // Prohibit copy constructor & assignment operator.
427  GenericReader& operator=(const GenericReader&);
428 
429  void ClearStack() { stack_.Clear(); }
430 
431  // clear stack on any exit from ParseStream, e.g. due to exception
432  struct ClearStackOnExit {
433  explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
434  ~ClearStackOnExit() { r_.ClearStack(); }
435  private:
436  GenericReader& r_;
437  ClearStackOnExit(const ClearStackOnExit&);
438  ClearStackOnExit& operator=(const ClearStackOnExit&);
439  };
440 
441  // Parse object: { string : value, ... }
442  template<unsigned parseFlags, typename InputStream, typename Handler>
443  void ParseObject(InputStream& is, Handler& handler) {
444  RAPIDJSON_ASSERT(is.Peek() == '{');
445  is.Take(); // Skip '{'
446 
447  if (!handler.StartObject())
448  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
449 
450  SkipWhitespace(is);
451 
452  if (is.Peek() == '}') {
453  is.Take();
454  if (!handler.EndObject(0)) // empty object
455  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
456  return;
457  }
458 
459  for (SizeType memberCount = 0;;) {
460  if (is.Peek() != '"')
461  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
462 
463  ParseString<parseFlags>(is, handler);
464  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
465 
466  SkipWhitespace(is);
467 
468  if (is.Take() != ':')
469  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
470 
471  SkipWhitespace(is);
472 
473  ParseValue<parseFlags>(is, handler);
474  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
475 
476  SkipWhitespace(is);
477 
478  ++memberCount;
479 
480  switch (is.Take()) {
481  case ',': SkipWhitespace(is); break;
482  case '}':
483  if (!handler.EndObject(memberCount))
484  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
485  else
486  return;
487  default: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
488  }
489  }
490  }
491 
492  // Parse array: [ value, ... ]
493  template<unsigned parseFlags, typename InputStream, typename Handler>
494  void ParseArray(InputStream& is, Handler& handler) {
495  RAPIDJSON_ASSERT(is.Peek() == '[');
496  is.Take(); // Skip '['
497 
498  if (!handler.StartArray())
499  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
500 
501  SkipWhitespace(is);
502 
503  if (is.Peek() == ']') {
504  is.Take();
505  if (!handler.EndArray(0)) // empty array
506  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
507  return;
508  }
509 
510  for (SizeType elementCount = 0;;) {
511  ParseValue<parseFlags>(is, handler);
512  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
513 
514  ++elementCount;
515  SkipWhitespace(is);
516 
517  switch (is.Take()) {
518  case ',': SkipWhitespace(is); break;
519  case ']':
520  if (!handler.EndArray(elementCount))
521  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
522  else
523  return;
524  default: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
525  }
526  }
527  }
528 
529  template<unsigned parseFlags, typename InputStream, typename Handler>
530  void ParseNull(InputStream& is, Handler& handler) {
531  RAPIDJSON_ASSERT(is.Peek() == 'n');
532  is.Take();
533 
534  if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l') {
535  if (!handler.Null())
536  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
537  }
538  else
539  RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1);
540  }
541 
542  template<unsigned parseFlags, typename InputStream, typename Handler>
543  void ParseTrue(InputStream& is, Handler& handler) {
544  RAPIDJSON_ASSERT(is.Peek() == 't');
545  is.Take();
546 
547  if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e') {
548  if (!handler.Bool(true))
549  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
550  }
551  else
552  RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1);
553  }
554 
555  template<unsigned parseFlags, typename InputStream, typename Handler>
556  void ParseFalse(InputStream& is, Handler& handler) {
557  RAPIDJSON_ASSERT(is.Peek() == 'f');
558  is.Take();
559 
560  if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e') {
561  if (!handler.Bool(false))
562  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
563  }
564  else
565  RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1);
566  }
567 
568  // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
569  template<typename InputStream>
570  unsigned ParseHex4(InputStream& is) {
571  unsigned codepoint = 0;
572  for (int i = 0; i < 4; i++) {
573  Ch c = is.Take();
574  codepoint <<= 4;
575  codepoint += static_cast<unsigned>(c);
576  if (c >= '0' && c <= '9')
577  codepoint -= '0';
578  else if (c >= 'A' && c <= 'F')
579  codepoint -= 'A' - 10;
580  else if (c >= 'a' && c <= 'f')
581  codepoint -= 'a' - 10;
582  else {
583  RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, is.Tell() - 1);
584  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
585  }
586  }
587  return codepoint;
588  }
589 
590  class StackStream {
591  public:
592  typedef typename TargetEncoding::Ch Ch;
593 
594  StackStream(internal::Stack<Allocator>& stack) : stack_(stack), length_(0) {}
595  RAPIDJSON_FORCEINLINE void Put(Ch c) {
596  *stack_.template Push<Ch>() = c;
597  ++length_;
598  }
599  internal::Stack<Allocator>& stack_;
600  SizeType length_;
601 
602  private:
603  StackStream(const StackStream&);
604  StackStream& operator=(const StackStream&);
605  };
606 
607  // Parse string and generate String event. Different code paths for kParseInsituFlag.
608  template<unsigned parseFlags, typename InputStream, typename Handler>
609  void ParseString(InputStream& is, Handler& handler) {
610  internal::StreamLocalCopy<InputStream> copy(is);
611  InputStream& s(copy.s);
612 
613  if (parseFlags & kParseInsituFlag) {
614  typename InputStream::Ch *head = s.PutBegin();
615  ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
616  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
617  size_t length = s.PutEnd(head) - 1;
618  RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
619  if (!handler.String((typename TargetEncoding::Ch*)head, SizeType(length), false))
620  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
621  }
622  else {
623  StackStream stackStream(stack_);
624  ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
625  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
626  if (!handler.String(stack_.template Pop<typename TargetEncoding::Ch>(stackStream.length_), stackStream.length_ - 1, true))
627  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
628  }
629  }
630 
631  // Parse string to an output is
632  // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
633  template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
634  RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
635 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
636  static const char escape[256] = {
637  Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
638  Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
639  0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
640  0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
641  Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
642  };
643 #undef Z16
644 
645  RAPIDJSON_ASSERT(is.Peek() == '\"');
646  is.Take(); // Skip '\"'
647 
648  for (;;) {
649  Ch c = is.Peek();
650  if (c == '\\') { // Escape
651  is.Take();
652  Ch e = is.Take();
653  if ((sizeof(Ch) == 1 || unsigned(e) < 256) && escape[(unsigned char)e]) {
654  os.Put(escape[(unsigned char)e]);
655  }
656  else if (e == 'u') { // Unicode
657  unsigned codepoint = ParseHex4(is);
658  if (codepoint >= 0xD800 && codepoint <= 0xDBFF) {
659  // Handle UTF-16 surrogate pair
660  if (is.Take() != '\\' || is.Take() != 'u')
661  RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2);
662  unsigned codepoint2 = ParseHex4(is);
663  if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF)
664  RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, is.Tell() - 2);
665  codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
666  }
667  TEncoding::Encode(os, codepoint);
668  }
669  else
670  RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1);
671  }
672  else if (c == '"') { // Closing double quote
673  is.Take();
674  os.Put('\0'); // null-terminate the string
675  return;
676  }
677  else if (c == '\0')
678  RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell() - 1);
679  else if ((unsigned)c < 0x20) // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
680  RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, is.Tell() - 1);
681  else {
682  if (parseFlags & kParseValidateEncodingFlag ?
683  !Transcoder<SEncoding, TEncoding>::Validate(is, os) :
685  RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell());
686  }
687  }
688  }
689 
690  inline double StrtodFastPath(double significand, int exp) {
691  // Fast path only works on limited range of values.
692  // But for simplicity and performance, currently only implement this.
693  // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
694  if (exp < -308)
695  return 0.0;
696  else if (exp >= 0)
697  return significand * internal::Pow10(exp);
698  else
699  return significand / internal::Pow10(-exp);
700  }
701 
702  template<unsigned parseFlags, typename InputStream, typename Handler>
703  void ParseNumber(InputStream& is, Handler& handler) {
704  internal::StreamLocalCopy<InputStream> copy(is);
705  InputStream& s(copy.s);
706 
707  // Parse minus
708  bool minus = false;
709  if (s.Peek() == '-') {
710  minus = true;
711  s.Take();
712  }
713 
714  // Parse int: zero / ( digit1-9 *DIGIT )
715  unsigned i = 0;
716  bool try64bit = false;
717  if (s.Peek() == '0') {
718  i = 0;
719  s.Take();
720  }
721  else if (s.Peek() >= '1' && s.Peek() <= '9') {
722  i = static_cast<unsigned>(s.Take() - '0');
723 
724  if (minus)
725  while (s.Peek() >= '0' && s.Peek() <= '9') {
726  if (i >= 214748364) { // 2^31 = 2147483648
727  if (i != 214748364 || s.Peek() > '8') {
728  try64bit = true;
729  break;
730  }
731  }
732  i = i * 10 + static_cast<unsigned>(s.Take() - '0');
733  }
734  else
735  while (s.Peek() >= '0' && s.Peek() <= '9') {
736  if (i >= 429496729) { // 2^32 - 1 = 4294967295
737  if (i != 429496729 || s.Peek() > '5') {
738  try64bit = true;
739  break;
740  }
741  }
742  i = i * 10 + static_cast<unsigned>(s.Take() - '0');
743  }
744  }
745  else
746  RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
747 
748  // Parse 64bit int
749  uint64_t i64 = 0;
750  bool useDouble = false;
751  if (try64bit) {
752  i64 = i;
753  if (minus)
754  while (s.Peek() >= '0' && s.Peek() <= '9') {
755  if (i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC)) // 2^63 = 9223372036854775808
756  if (i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8') {
757  useDouble = true;
758  break;
759  }
760  i64 = i64 * 10 + static_cast<unsigned>(s.Take() - '0');
761  }
762  else
763  while (s.Peek() >= '0' && s.Peek() <= '9') {
764  if (i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999)) // 2^64 - 1 = 18446744073709551615
765  if (i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5') {
766  useDouble = true;
767  break;
768  }
769  i64 = i64 * 10 + static_cast<unsigned>(s.Take() - '0');
770  }
771  }
772 
773  // Force double for big integer
774  double d = 0.0;
775  if (useDouble) {
776  d = (double)i64;
777  while (s.Peek() >= '0' && s.Peek() <= '9') {
778  if (d >= 1.7976931348623157e307) // DBL_MAX / 10.0
779  RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell());
780  d = d * 10 + (s.Take() - '0');
781  }
782  }
783 
784  // Parse frac = decimal-point 1*DIGIT
785  int expFrac = 0;
786  if (s.Peek() == '.') {
787  if (!useDouble) {
788  d = try64bit ? (double)i64 : (double)i;
789  useDouble = true;
790  }
791  s.Take();
792 
793  if (s.Peek() >= '0' && s.Peek() <= '9') {
794  d = d * 10 + (s.Take() - '0');
795  --expFrac;
796  }
797  else
798  RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
799 
800  while (s.Peek() >= '0' && s.Peek() <= '9') {
801  if (expFrac > -16) {
802  d = d * 10 + (s.Peek() - '0');
803  --expFrac;
804  }
805  s.Take();
806  }
807  }
808 
809  // Parse exp = e [ minus / plus ] 1*DIGIT
810  int exp = 0;
811  if (s.Peek() == 'e' || s.Peek() == 'E') {
812  if (!useDouble) {
813  d = try64bit ? (double)i64 : (double)i;
814  useDouble = true;
815  }
816  s.Take();
817 
818  bool expMinus = false;
819  if (s.Peek() == '+')
820  s.Take();
821  else if (s.Peek() == '-') {
822  s.Take();
823  expMinus = true;
824  }
825 
826  if (s.Peek() >= '0' && s.Peek() <= '9') {
827  exp = s.Take() - '0';
828  while (s.Peek() >= '0' && s.Peek() <= '9') {
829  exp = exp * 10 + (s.Take() - '0');
830  if (exp > 308 && !expMinus) // exp > 308 should be rare, so it should be checked first.
831  RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, s.Tell());
832  }
833  }
834  else
835  RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());
836 
837  if (expMinus)
838  exp = -exp;
839  }
840 
841  // Finish parsing, call event according to the type of number.
842  bool cont = true;
843  if (useDouble) {
844  int expSum = exp + expFrac;
845  if (expSum < -308) {
846  // Prevent expSum < -308, making Pow10(expSum) = 0
847  d = StrtodFastPath(d, exp);
848  d = StrtodFastPath(d, expFrac);
849  }
850  else
851  d = StrtodFastPath(d, expSum);
852 
853  cont = handler.Double(minus ? -d : d);
854  }
855  else {
856  if (try64bit) {
857  if (minus)
858  cont = handler.Int64(-(int64_t)i64);
859  else
860  cont = handler.Uint64(i64);
861  }
862  else {
863  if (minus)
864  cont = handler.Int(-(int)i);
865  else
866  cont = handler.Uint(i);
867  }
868  }
869  if (!cont)
870  RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
871  }
872 
873  // Parse any JSON value
874  template<unsigned parseFlags, typename InputStream, typename Handler>
875  void ParseValue(InputStream& is, Handler& handler) {
876  switch (is.Peek()) {
877  case 'n': ParseNull <parseFlags>(is, handler); break;
878  case 't': ParseTrue <parseFlags>(is, handler); break;
879  case 'f': ParseFalse <parseFlags>(is, handler); break;
880  case '"': ParseString<parseFlags>(is, handler); break;
881  case '{': ParseObject<parseFlags>(is, handler); break;
882  case '[': ParseArray <parseFlags>(is, handler); break;
883  default : ParseNumber<parseFlags>(is, handler);
884  }
885  }
886 
887  // Iterative Parsing
888 
889  // States
890  enum IterativeParsingState {
891  IterativeParsingStartState = 0,
892  IterativeParsingFinishState,
893  IterativeParsingErrorState,
894 
895  // Object states
896  IterativeParsingObjectInitialState,
897  IterativeParsingMemberKeyState,
898  IterativeParsingKeyValueDelimiterState,
899  IterativeParsingMemberValueState,
900  IterativeParsingMemberDelimiterState,
901  IterativeParsingObjectFinishState,
902 
903  // Array states
904  IterativeParsingArrayInitialState,
905  IterativeParsingElementState,
906  IterativeParsingElementDelimiterState,
907  IterativeParsingArrayFinishState,
908 
909  // Single value state
910  IterativeParsingValueState,
911 
912  cIterativeParsingStateCount
913  };
914 
915  // Tokens
916  enum Token {
917  LeftBracketToken = 0,
918  RightBracketToken,
919 
920  LeftCurlyBracketToken,
921  RightCurlyBracketToken,
922 
923  CommaToken,
924  ColonToken,
925 
926  StringToken,
927  FalseToken,
928  TrueToken,
929  NullToken,
930  NumberToken,
931 
932  kTokenCount
933  };
934 
935  RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
936 #define N NumberToken
937 #define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
938  // Maps from ASCII to Token
939  static const unsigned char tokenMap[256] = {
940  N16, // 00~0F
941  N16, // 10~1F
942  N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F
943  N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F
944  N16, // 40~4F
945  N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F
946  N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F
947  N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F
948  N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF
949  };
950 #undef N
951 #undef N16
952 
953  if (sizeof(Ch) == 1 || unsigned(c) < 256)
954  return (Token)tokenMap[(unsigned char)c];
955  else
956  return NumberToken;
957  }
958 
959  RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {
960  // current state x one lookahead token -> new state
961  static const char G[cIterativeParsingStateCount][kTokenCount] = {
962  // Start
963  {
964  IterativeParsingArrayInitialState, // Left bracket
965  IterativeParsingErrorState, // Right bracket
966  IterativeParsingObjectInitialState, // Left curly bracket
967  IterativeParsingErrorState, // Right curly bracket
968  IterativeParsingErrorState, // Comma
969  IterativeParsingErrorState, // Colon
970  IterativeParsingValueState, // String
971  IterativeParsingValueState, // False
972  IterativeParsingValueState, // True
973  IterativeParsingValueState, // Null
974  IterativeParsingValueState // Number
975  },
976  // Finish(sink state)
977  {
978  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
979  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
980  IterativeParsingErrorState
981  },
982  // Error(sink state)
983  {
984  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
985  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
986  IterativeParsingErrorState
987  },
988  // ObjectInitial
989  {
990  IterativeParsingErrorState, // Left bracket
991  IterativeParsingErrorState, // Right bracket
992  IterativeParsingErrorState, // Left curly bracket
993  IterativeParsingObjectFinishState, // Right curly bracket
994  IterativeParsingErrorState, // Comma
995  IterativeParsingErrorState, // Colon
996  IterativeParsingMemberKeyState, // String
997  IterativeParsingErrorState, // False
998  IterativeParsingErrorState, // True
999  IterativeParsingErrorState, // Null
1000  IterativeParsingErrorState // Number
1001  },
1002  // MemberKey
1003  {
1004  IterativeParsingErrorState, // Left bracket
1005  IterativeParsingErrorState, // Right bracket
1006  IterativeParsingErrorState, // Left curly bracket
1007  IterativeParsingErrorState, // Right curly bracket
1008  IterativeParsingErrorState, // Comma
1009  IterativeParsingKeyValueDelimiterState, // Colon
1010  IterativeParsingErrorState, // String
1011  IterativeParsingErrorState, // False
1012  IterativeParsingErrorState, // True
1013  IterativeParsingErrorState, // Null
1014  IterativeParsingErrorState // Number
1015  },
1016  // KeyValueDelimiter
1017  {
1018  IterativeParsingArrayInitialState, // Left bracket(push MemberValue state)
1019  IterativeParsingErrorState, // Right bracket
1020  IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state)
1021  IterativeParsingErrorState, // Right curly bracket
1022  IterativeParsingErrorState, // Comma
1023  IterativeParsingErrorState, // Colon
1024  IterativeParsingMemberValueState, // String
1025  IterativeParsingMemberValueState, // False
1026  IterativeParsingMemberValueState, // True
1027  IterativeParsingMemberValueState, // Null
1028  IterativeParsingMemberValueState // Number
1029  },
1030  // MemberValue
1031  {
1032  IterativeParsingErrorState, // Left bracket
1033  IterativeParsingErrorState, // Right bracket
1034  IterativeParsingErrorState, // Left curly bracket
1035  IterativeParsingObjectFinishState, // Right curly bracket
1036  IterativeParsingMemberDelimiterState, // Comma
1037  IterativeParsingErrorState, // Colon
1038  IterativeParsingErrorState, // String
1039  IterativeParsingErrorState, // False
1040  IterativeParsingErrorState, // True
1041  IterativeParsingErrorState, // Null
1042  IterativeParsingErrorState // Number
1043  },
1044  // MemberDelimiter
1045  {
1046  IterativeParsingErrorState, // Left bracket
1047  IterativeParsingErrorState, // Right bracket
1048  IterativeParsingErrorState, // Left curly bracket
1049  IterativeParsingErrorState, // Right curly bracket
1050  IterativeParsingErrorState, // Comma
1051  IterativeParsingErrorState, // Colon
1052  IterativeParsingMemberKeyState, // String
1053  IterativeParsingErrorState, // False
1054  IterativeParsingErrorState, // True
1055  IterativeParsingErrorState, // Null
1056  IterativeParsingErrorState // Number
1057  },
1058  // ObjectFinish(sink state)
1059  {
1060  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1061  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1062  IterativeParsingErrorState
1063  },
1064  // ArrayInitial
1065  {
1066  IterativeParsingArrayInitialState, // Left bracket(push Element state)
1067  IterativeParsingArrayFinishState, // Right bracket
1068  IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1069  IterativeParsingErrorState, // Right curly bracket
1070  IterativeParsingErrorState, // Comma
1071  IterativeParsingErrorState, // Colon
1072  IterativeParsingElementState, // String
1073  IterativeParsingElementState, // False
1074  IterativeParsingElementState, // True
1075  IterativeParsingElementState, // Null
1076  IterativeParsingElementState // Number
1077  },
1078  // Element
1079  {
1080  IterativeParsingErrorState, // Left bracket
1081  IterativeParsingArrayFinishState, // Right bracket
1082  IterativeParsingErrorState, // Left curly bracket
1083  IterativeParsingErrorState, // Right curly bracket
1084  IterativeParsingElementDelimiterState, // Comma
1085  IterativeParsingErrorState, // Colon
1086  IterativeParsingErrorState, // String
1087  IterativeParsingErrorState, // False
1088  IterativeParsingErrorState, // True
1089  IterativeParsingErrorState, // Null
1090  IterativeParsingErrorState // Number
1091  },
1092  // ElementDelimiter
1093  {
1094  IterativeParsingArrayInitialState, // Left bracket(push Element state)
1095  IterativeParsingErrorState, // Right bracket
1096  IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1097  IterativeParsingErrorState, // Right curly bracket
1098  IterativeParsingErrorState, // Comma
1099  IterativeParsingErrorState, // Colon
1100  IterativeParsingElementState, // String
1101  IterativeParsingElementState, // False
1102  IterativeParsingElementState, // True
1103  IterativeParsingElementState, // Null
1104  IterativeParsingElementState // Number
1105  },
1106  // ArrayFinish(sink state)
1107  {
1108  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1109  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1110  IterativeParsingErrorState
1111  },
1112  // Single Value (sink state)
1113  {
1114  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1115  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1116  IterativeParsingErrorState
1117  }
1118  }; // End of G
1119 
1120  return (IterativeParsingState)G[state][token];
1121  }
1122 
1123  // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
1124  // May return a new state on state pop.
1125  template <unsigned parseFlags, typename InputStream, typename Handler>
1126  RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
1127  switch (dst) {
1128  case IterativeParsingStartState:
1129  RAPIDJSON_ASSERT(false);
1130  return IterativeParsingErrorState;
1131 
1132  case IterativeParsingFinishState:
1133  return dst;
1134 
1135  case IterativeParsingErrorState:
1136  return dst;
1137 
1138  case IterativeParsingObjectInitialState:
1139  case IterativeParsingArrayInitialState:
1140  {
1141  // Push the state(Element or MemeberValue) if we are nested in another array or value of member.
1142  // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
1143  IterativeParsingState n = src;
1144  if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
1145  n = IterativeParsingElementState;
1146  else if (src == IterativeParsingKeyValueDelimiterState)
1147  n = IterativeParsingMemberValueState;
1148  // Push current state.
1149  *stack_.template Push<SizeType>(1) = n;
1150  // Initialize and push the member/element count.
1151  *stack_.template Push<SizeType>(1) = 0;
1152  // Call handler
1153  bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
1154  // On handler short circuits the parsing.
1155  if (!hr) {
1156  RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1157  return IterativeParsingErrorState;
1158  }
1159  else {
1160  is.Take();
1161  return dst;
1162  }
1163  }
1164 
1165  case IterativeParsingMemberKeyState:
1166  ParseString<parseFlags>(is, handler);
1167  if (HasParseError())
1168  return IterativeParsingErrorState;
1169  else
1170  return dst;
1171 
1172  case IterativeParsingKeyValueDelimiterState:
1173  if (token == ColonToken) {
1174  is.Take();
1175  return dst;
1176  }
1177  else
1178  return IterativeParsingErrorState;
1179 
1180  case IterativeParsingMemberValueState:
1181  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1182  ParseValue<parseFlags>(is, handler);
1183  if (HasParseError()) {
1184  return IterativeParsingErrorState;
1185  }
1186  return dst;
1187 
1188  case IterativeParsingElementState:
1189  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1190  ParseValue<parseFlags>(is, handler);
1191  if (HasParseError()) {
1192  return IterativeParsingErrorState;
1193  }
1194  return dst;
1195 
1196  case IterativeParsingMemberDelimiterState:
1197  case IterativeParsingElementDelimiterState:
1198  is.Take();
1199  // Update member/element count.
1200  *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
1201  return dst;
1202 
1203  case IterativeParsingObjectFinishState:
1204  {
1205  // Get member count.
1206  SizeType c = *stack_.template Pop<SizeType>(1);
1207  // If the object is not empty, count the last member.
1208  if (src == IterativeParsingMemberValueState)
1209  ++c;
1210  // Restore the state.
1211  IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1212  // Transit to Finish state if this is the topmost scope.
1213  if (n == IterativeParsingStartState)
1214  n = IterativeParsingFinishState;
1215  // Call handler
1216  bool hr = handler.EndObject(c);
1217  // On handler short circuits the parsing.
1218  if (!hr) {
1219  RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1220  return IterativeParsingErrorState;
1221  }
1222  else {
1223  is.Take();
1224  return n;
1225  }
1226  }
1227 
1228  case IterativeParsingArrayFinishState:
1229  {
1230  // Get element count.
1231  SizeType c = *stack_.template Pop<SizeType>(1);
1232  // If the array is not empty, count the last element.
1233  if (src == IterativeParsingElementState)
1234  ++c;
1235  // Restore the state.
1236  IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1237  // Transit to Finish state if this is the topmost scope.
1238  if (n == IterativeParsingStartState)
1239  n = IterativeParsingFinishState;
1240  // Call handler
1241  bool hr = handler.EndArray(c);
1242  // On handler short circuits the parsing.
1243  if (!hr) {
1244  RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
1245  return IterativeParsingErrorState;
1246  }
1247  else {
1248  is.Take();
1249  return n;
1250  }
1251  }
1252 
1253  case IterativeParsingValueState:
1254  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1255  ParseValue<parseFlags>(is, handler);
1256  if (HasParseError()) {
1257  return IterativeParsingErrorState;
1258  }
1259  return IterativeParsingFinishState;
1260 
1261  default:
1262  RAPIDJSON_ASSERT(false);
1263  return IterativeParsingErrorState;
1264  }
1265  }
1266 
1267  template <typename InputStream>
1268  void HandleError(IterativeParsingState src, InputStream& is) {
1269  if (HasParseError()) {
1270  // Error flag has been set.
1271  return;
1272  }
1273 
1274  switch (src) {
1275  case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell());
1276  case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell());
1277  case IterativeParsingObjectInitialState:
1278  case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
1279  case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
1280  case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
1281  case IterativeParsingElementState: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
1282  default: RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
1283  }
1284  }
1285 
1286  template <unsigned parseFlags, typename InputStream, typename Handler>
1287  ParseResult IterativeParse(InputStream& is, Handler& handler) {
1288  parseResult_.Clear();
1289  ClearStackOnExit scope(*this);
1290  IterativeParsingState state = IterativeParsingStartState;
1291 
1292  SkipWhitespace(is);
1293  while (is.Peek() != '\0') {
1294  Token t = Tokenize(is.Peek());
1295  IterativeParsingState n = Predict(state, t);
1296  IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
1297 
1298  if (d == IterativeParsingErrorState) {
1299  HandleError(state, is);
1300  break;
1301  }
1302 
1303  state = d;
1304 
1305  // Do not further consume streams if a root JSON has been parsed.
1306  if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
1307  break;
1308 
1309  SkipWhitespace(is);
1310  }
1311 
1312  // Handle the end of file.
1313  if (state != IterativeParsingFinishState)
1314  HandleError(state, is);
1315 
1316  return parseResult_;
1317  }
1318 
1319  static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string.
1320  internal::Stack<Allocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing.
1321  ParseResult parseResult_;
1322 }; // class GenericReader
1323 
1324 //! Reader with UTF8 encoding and default allocator.
1326 
1327 } // namespace rapidjson
1328 
1329 #ifdef _MSC_VER
1330 RAPIDJSON_DIAG_POP
1331 #endif
1332 
1333 #endif // RAPIDJSON_READER_H_
Result of parsing (wraps ParseErrorCode)
Definition: error.h:97
The document root must not follow by other values.
Definition: error.h:60
Iterative(constant complexity in terms of function call stack size) parsing.
Definition: reader.h:89
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
Validate encoding of JSON strings.
Definition: reader.h:88
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:138
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: reader.h:353
SourceEncoding::Ch Ch
SourceEncoding character type.
Definition: reader.h:355
unsigned SizeType
Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
Definition: rapidjson.h:162
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: reader.h:422
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
Definition: reader.h:419
Invalid value.
Definition: error.h:62
Miss fraction part in number.
Definition: error.h:77
The document is empty.
Definition: error.h:59
The surrogate pair in string is invalid.
Definition: error.h:71
GenericInsituStringStream< UTF8<> > InsituStringStream
Insitu string stream with UTF8 encoding.
Definition: rapidjson.h:414
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text (with kParseDefaultFlags)
Definition: reader.h:411
Missing a colon after a name of object member.
Definition: error.h:65
Missing a closing quotation mark in string.
Definition: error.h:73
Invalid escape character in string.
Definition: error.h:72
Missing a name for object member.
Definition: error.h:64
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:175
Number too big to be stored in double.
Definition: error.h:76
Type
Type of JSON value.
Definition: rapidjson.h:420
After parsing a complete JSON root from stream, stop further processing the rest of stream...
Definition: reader.h:90
GenericReader(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity)
Constructor.
Definition: reader.h:361
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition: reader.h:192
GenericStringStream< UTF8<> > StringStream
String stream with UTF8 encoding.
Definition: rapidjson.h:373
Invalid encoding in string.
Definition: error.h:74
bool IsError() const
Whether the result is an error.
Definition: error.h:112
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: reader.h:416
Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer...
Definition: reader.h:86
ParseFlag
Combination of parseFlags.
Definition: reader.h:85
Concept for reading and writing characters.
ParseErrorCode Code() const
Get the error code.
Definition: error.h:105
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition: reader.h:372
Missing a comma or '}' after an object member.
Definition: error.h:66
Default implementation of Handler.
Definition: reader.h:127
common definitions and configuration
In-situ(destructive) parsing.
Definition: reader.h:87
ParseErrorCode
Error code of parsing.
Definition: error.h:56
UTF-8 encoding.
Definition: encodings.h:101
Unspecific syntax error.
Definition: error.h:81
Concept for allocating, resizing and freeing memory block.
Parsing was terminated.
Definition: error.h:80
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition: error.h:107
GenericReader< UTF8<>, UTF8<> > Reader
Reader with UTF8 encoding and default allocator.
Definition: reader.h:1325
static RAPIDJSON_FORCEINLINE bool Transcode(InputStream &is, OutputStream &os)
Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the outp...
Definition: encodings.h:594
Incorrect hex digit after \u escape in string.
Definition: error.h:70
Miss exponent in number.
Definition: error.h:78
Missing a comma or ']' after an array element.
Definition: error.h:68
void Clear()
Reset error code.
Definition: error.h:119