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