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