reader.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #ifndef RAPIDJSON_READER_H_
16 #define RAPIDJSON_READER_H_
17 
18 /*! \file reader.h */
19 
20 #include "allocators.h"
21 #include "stream.h"
22 #include "encodedstream.h"
23 #include "internal/meta.h"
24 #include "internal/stack.h"
25 #include "internal/strtod.h"
26 #include <limits>
27 #include <cmath>
28 
29 #if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
30 #include <intrin.h>
31 #pragma intrinsic(_BitScanForward)
32 #endif
33 #ifdef RAPIDJSON_SSE42
34 #include <nmmintrin.h>
35 #elif defined(RAPIDJSON_SSE2)
36 #include <emmintrin.h>
37 #endif
38 
39 #ifdef _MSC_VER
40 RAPIDJSON_DIAG_PUSH
41 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
42 RAPIDJSON_DIAG_OFF(4702) // unreachable code
43 #endif
44 
45 #ifdef __clang__
46 RAPIDJSON_DIAG_PUSH
47 RAPIDJSON_DIAG_OFF(old-style-cast)
48 RAPIDJSON_DIAG_OFF(padded)
49 RAPIDJSON_DIAG_OFF(switch-enum)
50 #endif
51 
52 #ifdef __GNUC__
53 RAPIDJSON_DIAG_PUSH
54 RAPIDJSON_DIAG_OFF(effc++)
55 #endif
56 
57 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
58 #define RAPIDJSON_NOTHING /* deliberately empty */
59 #ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
60 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
61  RAPIDJSON_MULTILINEMACRO_BEGIN \
62  if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
63  RAPIDJSON_MULTILINEMACRO_END
64 #endif
65 #define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
66  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
67 //!@endcond
68 
69 /*! \def RAPIDJSON_PARSE_ERROR_NORETURN
70  \ingroup RAPIDJSON_ERRORS
71  \brief Macro to indicate a parse error.
72  \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
73  \param offset position of the error in JSON input (\c size_t)
74 
75  This macros can be used as a customization point for the internal
76  error handling mechanism of RapidJSON.
77 
78  A common usage model is to throw an exception instead of requiring the
79  caller to explicitly check the \ref rapidjson::GenericReader::Parse's
80  return value:
81 
82  \code
83  #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \
84  throw ParseException(parseErrorCode, #parseErrorCode, offset)
85 
86  #include <stdexcept> // std::runtime_error
87  #include "rapidjson/error/error.h" // rapidjson::ParseResult
88 
89  struct ParseException : std::runtime_error, rapidjson::ParseResult {
90  ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset)
91  : std::runtime_error(msg), ParseResult(code, offset) {}
92  };
93 
94  #include "rapidjson/reader.h"
95  \endcode
96 
97  \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse
98  */
99 #ifndef RAPIDJSON_PARSE_ERROR_NORETURN
100 #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
101  RAPIDJSON_MULTILINEMACRO_BEGIN \
102  RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
103  SetParseError(parseErrorCode, offset); \
104  RAPIDJSON_MULTILINEMACRO_END
105 #endif
106 
107 /*! \def RAPIDJSON_PARSE_ERROR
108  \ingroup RAPIDJSON_ERRORS
109  \brief (Internal) macro to indicate and handle a parse error.
110  \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
111  \param offset position of the error in JSON input (\c size_t)
112 
113  Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing.
114 
115  \see RAPIDJSON_PARSE_ERROR_NORETURN
116  \hideinitializer
117  */
118 #ifndef RAPIDJSON_PARSE_ERROR
119 #define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \
120  RAPIDJSON_MULTILINEMACRO_BEGIN \
121  RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
122  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
123  RAPIDJSON_MULTILINEMACRO_END
124 #endif
125 
126 #include "error/error.h" // ParseErrorCode, ParseResult
127 
128 RAPIDJSON_NAMESPACE_BEGIN
129 
130 ///////////////////////////////////////////////////////////////////////////////
131 // ParseFlag
132 
133 /*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS
134  \ingroup RAPIDJSON_CONFIG
135  \brief User-defined kParseDefaultFlags definition.
136 
137  User can define this as any \c ParseFlag combinations.
138 */
139 #ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS
140 #define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags
141 #endif
142 
143 //! Combination of parseFlags
144 /*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream
145  */
146 enum ParseFlag {
147  kParseNoFlags = 0, //!< No flags are set.
148  kParseInsituFlag = 1, //!< In-situ(destructive) parsing.
149  kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings.
150  kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing.
151  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.
152  kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower).
153  kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments.
154  kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings.
155  kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.
156  kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
157  kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
158 };
159 
160 ///////////////////////////////////////////////////////////////////////////////
161 // Handler
162 
163 /*! \class rapidjson::Handler
164  \brief Concept for receiving events from GenericReader upon parsing.
165  The functions return true if no error occurs. If they return false,
166  the event publisher should terminate the process.
167 \code
168 concept Handler {
169  typename Ch;
170 
171  bool Null();
172  bool Bool(bool b);
173  bool Int(int i);
174  bool Uint(unsigned i);
175  bool Int64(int64_t i);
176  bool Uint64(uint64_t i);
177  bool Double(double d);
178  /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
179  bool RawNumber(const Ch* str, SizeType length, bool copy);
180  bool String(const Ch* str, SizeType length, bool copy);
181  bool StartObject();
182  bool Key(const Ch* str, SizeType length, bool copy);
183  bool EndObject(SizeType memberCount);
184  bool StartArray();
185  bool EndArray(SizeType elementCount);
186 };
187 \endcode
188 */
189 ///////////////////////////////////////////////////////////////////////////////
190 // BaseReaderHandler
191 
192 //! Default implementation of Handler.
193 /*! This can be used as base class of any reader handler.
194  \note implements Handler concept
195 */
196 template<typename Encoding = UTF8<>, typename Derived = void>
197 struct BaseReaderHandler {
198  typedef typename Encoding::Ch Ch;
199 
200  typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override;
201 
202  bool Default() { return true; }
203  bool Null() { return static_cast<Override&>(*this).Default(); }
204  bool Bool(bool) { return static_cast<Override&>(*this).Default(); }
205  bool Int(int) { return static_cast<Override&>(*this).Default(); }
206  bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); }
207  bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); }
208  bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); }
209  bool Double(double) { return static_cast<Override&>(*this).Default(); }
210  /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
211  bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
212  bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); }
213  bool StartObject() { return static_cast<Override&>(*this).Default(); }
214  bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
215  bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }
216  bool StartArray() { return static_cast<Override&>(*this).Default(); }
217  bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }
218 };
219 
220 ///////////////////////////////////////////////////////////////////////////////
221 // StreamLocalCopy
222 
223 namespace internal {
224 
225 template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
226 class StreamLocalCopy;
227 
228 //! Do copy optimization.
229 template<typename Stream>
230 class StreamLocalCopy<Stream, 1> {
231 public:
232  StreamLocalCopy(Stream& original) : s(original), original_(original) {}
233  ~StreamLocalCopy() { original_ = s; }
234 
235  Stream s;
236 
237 private:
238  StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
239 
240  Stream& original_;
241 };
242 
243 //! Keep reference.
244 template<typename Stream>
245 class StreamLocalCopy<Stream, 0> {
246 public:
247  StreamLocalCopy(Stream& original) : s(original) {}
248 
249  Stream& s;
250 
251 private:
252  StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
253 };
254 
255 } // namespace internal
256 
257 ///////////////////////////////////////////////////////////////////////////////
258 // SkipWhitespace
259 
260 //! Skip the JSON white spaces in a stream.
261 /*! \param is A input stream for skipping white spaces.
262  \note This function has SSE2/SSE4.2 specialization.
263 */
264 template<typename InputStream>
265 void SkipWhitespace(InputStream& is) {
266  internal::StreamLocalCopy<InputStream> copy(is);
267  InputStream& s(copy.s);
268 
269  typename InputStream::Ch c;
270  while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t')
271  s.Take();
272 }
273 
274 inline const char* SkipWhitespace(const char* p, const char* end) {
275  while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
276  ++p;
277  return p;
278 }
279 
280 #ifdef RAPIDJSON_SSE42
281 //! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.
282 inline const char *SkipWhitespace_SIMD(const char* p) {
283  // Fast return for single non-whitespace
284  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
285  ++p;
286  else
287  return p;
288 
289  // 16-byte align to the next boundary
290  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
291  while (p != nextAligned)
292  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
293  ++p;
294  else
295  return p;
296 
297  // The rest of string using SIMD
298  static const char whitespace[16] = " \n\r\t";
299  const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
300 
301  for (;; p += 16) {
302  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
303  const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
304  if (r != 0) { // some of characters is non-whitespace
305 #ifdef _MSC_VER // Find the index of first non-whitespace
306  unsigned long offset;
307  _BitScanForward(&offset, r);
308  return p + offset;
309 #else
310  return p + __builtin_ffs(r) - 1;
311 #endif
312  }
313  }
314 }
315 
316 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
317  // Fast return for single non-whitespace
318  if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
319  ++p;
320  else
321  return p;
322 
323  // The middle of string using SIMD
324  static const char whitespace[16] = " \n\r\t";
325  const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
326 
327  for (; p <= end - 16; p += 16) {
328  const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
329  const int r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
330  if (r != 0) { // some of characters is non-whitespace
331 #ifdef _MSC_VER // Find the index of first non-whitespace
332  unsigned long offset;
333  _BitScanForward(&offset, r);
334  return p + offset;
335 #else
336  return p + __builtin_ffs(r) - 1;
337 #endif
338  }
339  }
340 
341  return SkipWhitespace(p, end);
342 }
343 
344 #elif defined(RAPIDJSON_SSE2)
345 
346 //! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
347 inline const char *SkipWhitespace_SIMD(const char* p) {
348  // Fast return for single non-whitespace
349  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
350  ++p;
351  else
352  return p;
353 
354  // 16-byte align to the next boundary
355  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
356  while (p != nextAligned)
357  if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
358  ++p;
359  else
360  return p;
361 
362  // The rest of string
363  #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
364  static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
365  #undef C16
366 
367  const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
368  const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
369  const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
370  const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
371 
372  for (;; p += 16) {
373  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
374  __m128i x = _mm_cmpeq_epi8(s, w0);
375  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
376  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
377  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
378  unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
379  if (r != 0) { // some of characters may be non-whitespace
380 #ifdef _MSC_VER // Find the index of first non-whitespace
381  unsigned long offset;
382  _BitScanForward(&offset, r);
383  return p + offset;
384 #else
385  return p + __builtin_ffs(r) - 1;
386 #endif
387  }
388  }
389 }
390 
391 inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
392  // Fast return for single non-whitespace
393  if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
394  ++p;
395  else
396  return p;
397 
398  // The rest of string
399  #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
400  static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
401  #undef C16
402 
403  const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
404  const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
405  const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
406  const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
407 
408  for (; p <= end - 16; p += 16) {
409  const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
410  __m128i x = _mm_cmpeq_epi8(s, w0);
411  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
412  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
413  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
414  unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
415  if (r != 0) { // some of characters may be non-whitespace
416 #ifdef _MSC_VER // Find the index of first non-whitespace
417  unsigned long offset;
418  _BitScanForward(&offset, r);
419  return p + offset;
420 #else
421  return p + __builtin_ffs(r) - 1;
422 #endif
423  }
424  }
425 
426  return SkipWhitespace(p, end);
427 }
428 
429 #endif // RAPIDJSON_SSE2
430 
431 #ifdef RAPIDJSON_SIMD
432 //! Template function specialization for InsituStringStream
433 template<> inline void SkipWhitespace(InsituStringStream& is) {
434  is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
435 }
436 
437 //! Template function specialization for StringStream
438 template<> inline void SkipWhitespace(StringStream& is) {
439  is.src_ = SkipWhitespace_SIMD(is.src_);
440 }
441 
442 template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {
443  is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
444 }
445 #endif // RAPIDJSON_SIMD
446 
447 ///////////////////////////////////////////////////////////////////////////////
448 // GenericReader
449 
450 //! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator.
451 /*! GenericReader parses JSON text from a stream, and send events synchronously to an
452  object implementing Handler concept.
453 
454  It needs to allocate a stack for storing a single decoded string during
455  non-destructive parsing.
456 
457  For in-situ parsing, the decoded string is directly written to the source
458  text string, no temporary buffer is required.
459 
460  A GenericReader object can be reused for parsing multiple JSON text.
461 
462  \tparam SourceEncoding Encoding of the input stream.
463  \tparam TargetEncoding Encoding of the parse output.
464  \tparam StackAllocator Allocator type for stack.
465 */
466 template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
467 class GenericReader {
468 public:
469  typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type
470 
471  //! Constructor.
472  /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
473  \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
474  */
475  GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {}
476 
477  //! Parse JSON text.
478  /*! \tparam parseFlags Combination of \ref ParseFlag.
479  \tparam InputStream Type of input stream, implementing Stream concept.
480  \tparam Handler Type of handler, implementing Handler concept.
481  \param is Input stream to be parsed.
482  \param handler The handler to receive events.
483  \return Whether the parsing is successful.
484  */
485  template <unsigned parseFlags, typename InputStream, typename Handler>
486  ParseResult Parse(InputStream& is, Handler& handler) {
487  if (parseFlags & kParseIterativeFlag)
488  return IterativeParse<parseFlags>(is, handler);
489 
490  parseResult_.Clear();
491 
492  ClearStackOnExit scope(*this);
493 
494  SkipWhitespaceAndComments<parseFlags>(is);
495  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
496 
497  if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) {
499  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
500  }
501  else {
502  ParseValue<parseFlags>(is, handler);
503  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
504 
505  if (!(parseFlags & kParseStopWhenDoneFlag)) {
506  SkipWhitespaceAndComments<parseFlags>(is);
507  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
508 
509  if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) {
511  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
512  }
513  }
514  }
515 
516  return parseResult_;
517  }
518 
519  //! Parse JSON text (with \ref kParseDefaultFlags)
520  /*! \tparam InputStream Type of input stream, implementing Stream concept
521  \tparam Handler Type of handler, implementing Handler concept.
522  \param is Input stream to be parsed.
523  \param handler The handler to receive events.
524  \return Whether the parsing is successful.
525  */
526  template <typename InputStream, typename Handler>
527  ParseResult Parse(InputStream& is, Handler& handler) {
528  return Parse<kParseDefaultFlags>(is, handler);
529  }
530 
531  //! Whether a parse error has occured in the last parsing.
532  bool HasParseError() const { return parseResult_.IsError(); }
533 
534  //! Get the \ref ParseErrorCode of last parsing.
535  ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }
536 
537  //! Get the position of last parsing error in input, 0 otherwise.
538  size_t GetErrorOffset() const { return parseResult_.Offset(); }
539 
540 protected:
541  void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
542 
543 private:
544  // Prohibit copy constructor & assignment operator.
546  GenericReader& operator=(const GenericReader&);
547 
548  void ClearStack() { stack_.Clear(); }
549 
550  // clear stack on any exit from ParseStream, e.g. due to exception
551  struct ClearStackOnExit {
552  explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
553  ~ClearStackOnExit() { r_.ClearStack(); }
554  private:
555  GenericReader& r_;
556  ClearStackOnExit(const ClearStackOnExit&);
557  ClearStackOnExit& operator=(const ClearStackOnExit&);
558  };
559 
560  template<unsigned parseFlags, typename InputStream>
561  void SkipWhitespaceAndComments(InputStream& is) {
562  SkipWhitespace(is);
563 
564  if (parseFlags & kParseCommentsFlag) {
565  while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) {
566  if (Consume(is, '*')) {
567  while (true) {
568  if (RAPIDJSON_UNLIKELY(is.Peek() == '\0'))
570  else if (Consume(is, '*')) {
571  if (Consume(is, '/'))
572  break;
573  }
574  else
575  is.Take();
576  }
577  }
578  else if (RAPIDJSON_LIKELY(Consume(is, '/')))
579  while (is.Peek() != '\0' && is.Take() != '\n');
580  else
582 
583  SkipWhitespace(is);
584  }
585  }
586  }
587 
588  // Parse object: { string : value, ... }
589  template<unsigned parseFlags, typename InputStream, typename Handler>
590  void ParseObject(InputStream& is, Handler& handler) {
591  RAPIDJSON_ASSERT(is.Peek() == '{');
592  is.Take(); // Skip '{'
593 
594  if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
596 
597  SkipWhitespaceAndComments<parseFlags>(is);
598  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
599 
600  if (Consume(is, '}')) {
601  if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object
603  return;
604  }
605 
606  for (SizeType memberCount = 0;;) {
607  if (RAPIDJSON_UNLIKELY(is.Peek() != '"'))
609 
610  ParseString<parseFlags>(is, handler, true);
611  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
612 
613  SkipWhitespaceAndComments<parseFlags>(is);
614  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
615 
616  if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))
618 
619  SkipWhitespaceAndComments<parseFlags>(is);
620  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
621 
622  ParseValue<parseFlags>(is, handler);
623  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
624 
625  SkipWhitespaceAndComments<parseFlags>(is);
626  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
627 
628  ++memberCount;
629 
630  switch (is.Peek()) {
631  case ',':
632  is.Take();
633  SkipWhitespaceAndComments<parseFlags>(is);
634  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
635  break;
636  case '}':
637  is.Take();
638  if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
640  return;
641  default:
642  RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy
643  }
644 
645  if (parseFlags & kParseTrailingCommasFlag) {
646  if (is.Peek() == '}') {
647  if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
649  is.Take();
650  return;
651  }
652  }
653  }
654  }
655 
656  // Parse array: [ value, ... ]
657  template<unsigned parseFlags, typename InputStream, typename Handler>
658  void ParseArray(InputStream& is, Handler& handler) {
659  RAPIDJSON_ASSERT(is.Peek() == '[');
660  is.Take(); // Skip '['
661 
662  if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
664 
665  SkipWhitespaceAndComments<parseFlags>(is);
666  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
667 
668  if (Consume(is, ']')) {
669  if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array
671  return;
672  }
673 
674  for (SizeType elementCount = 0;;) {
675  ParseValue<parseFlags>(is, handler);
676  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
677 
678  ++elementCount;
679  SkipWhitespaceAndComments<parseFlags>(is);
680  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
681 
682  if (Consume(is, ',')) {
683  SkipWhitespaceAndComments<parseFlags>(is);
684  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
685  }
686  else if (Consume(is, ']')) {
687  if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
689  return;
690  }
691  else
693 
694  if (parseFlags & kParseTrailingCommasFlag) {
695  if (is.Peek() == ']') {
696  if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
698  is.Take();
699  return;
700  }
701  }
702  }
703  }
704 
705  template<unsigned parseFlags, typename InputStream, typename Handler>
706  void ParseNull(InputStream& is, Handler& handler) {
707  RAPIDJSON_ASSERT(is.Peek() == 'n');
708  is.Take();
709 
710  if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {
711  if (RAPIDJSON_UNLIKELY(!handler.Null()))
713  }
714  else
716  }
717 
718  template<unsigned parseFlags, typename InputStream, typename Handler>
719  void ParseTrue(InputStream& is, Handler& handler) {
720  RAPIDJSON_ASSERT(is.Peek() == 't');
721  is.Take();
722 
723  if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {
724  if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))
726  }
727  else
729  }
730 
731  template<unsigned parseFlags, typename InputStream, typename Handler>
732  void ParseFalse(InputStream& is, Handler& handler) {
733  RAPIDJSON_ASSERT(is.Peek() == 'f');
734  is.Take();
735 
736  if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {
737  if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))
739  }
740  else
742  }
743 
744  template<typename InputStream>
745  RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
746  if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
747  is.Take();
748  return true;
749  }
750  else
751  return false;
752  }
753 
754  // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
755  template<typename InputStream>
756  unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
757  unsigned codepoint = 0;
758  for (int i = 0; i < 4; i++) {
759  Ch c = is.Peek();
760  codepoint <<= 4;
761  codepoint += static_cast<unsigned>(c);
762  if (c >= '0' && c <= '9')
763  codepoint -= '0';
764  else if (c >= 'A' && c <= 'F')
765  codepoint -= 'A' - 10;
766  else if (c >= 'a' && c <= 'f')
767  codepoint -= 'a' - 10;
768  else {
770  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
771  }
772  is.Take();
773  }
774  return codepoint;
775  }
776 
777  template <typename CharType>
778  class StackStream {
779  public:
780  typedef CharType Ch;
781 
782  StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {}
783  RAPIDJSON_FORCEINLINE void Put(Ch c) {
784  *stack_.template Push<Ch>() = c;
785  ++length_;
786  }
787 
788  RAPIDJSON_FORCEINLINE void* Push(SizeType count) {
789  length_ += count;
790  return stack_.template Push<Ch>(count);
791  }
792 
793  size_t Length() const { return length_; }
794 
795  Ch* Pop() {
796  return stack_.template Pop<Ch>(length_);
797  }
798 
799  private:
800  StackStream(const StackStream&);
801  StackStream& operator=(const StackStream&);
802 
803  internal::Stack<StackAllocator>& stack_;
804  SizeType length_;
805  };
806 
807  // Parse string and generate String event. Different code paths for kParseInsituFlag.
808  template<unsigned parseFlags, typename InputStream, typename Handler>
809  void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
810  internal::StreamLocalCopy<InputStream> copy(is);
811  InputStream& s(copy.s);
812 
813  RAPIDJSON_ASSERT(s.Peek() == '\"');
814  s.Take(); // Skip '\"'
815 
816  bool success = false;
817  if (parseFlags & kParseInsituFlag) {
818  typename InputStream::Ch *head = s.PutBegin();
819  ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
820  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
821  size_t length = s.PutEnd(head) - 1;
822  RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
823  const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
824  success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
825  }
826  else {
827  StackStream<typename TargetEncoding::Ch> stackStream(stack_);
828  ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
829  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
830  SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;
831  const typename TargetEncoding::Ch* const str = stackStream.Pop();
832  success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
833  }
834  if (RAPIDJSON_UNLIKELY(!success))
836  }
837 
838  // Parse string to an output is
839  // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
840  template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
841  RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
842 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
843 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
844  static const char escape[256] = {
845  Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
846  Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
847  0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
848  0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
849  Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
850  };
851 #undef Z16
852 //!@endcond
853 
854  for (;;) {
855  // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
856  if (!(parseFlags & kParseValidateEncodingFlag))
857  ScanCopyUnescapedString(is, os);
858 
859  Ch c = is.Peek();
860  if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape
861  size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset
862  is.Take();
863  Ch e = is.Peek();
864  if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
865  is.Take();
866  os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
867  }
868  else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
869  is.Take();
870  unsigned codepoint = ParseHex4(is, escapeOffset);
871  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
872  if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
873  // Handle UTF-16 surrogate pair
874  if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
876  unsigned codepoint2 = ParseHex4(is, escapeOffset);
877  RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
878  if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
880  codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
881  }
882  TEncoding::Encode(os, codepoint);
883  }
884  else
886  }
887  else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote
888  is.Take();
889  os.Put('\0'); // null-terminate the string
890  return;
891  }
892  else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
893  if (c == '\0')
895  else
897  }
898  else {
899  size_t offset = is.Tell();
900  if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
904  }
905  }
906  }
907 
908  template<typename InputStream, typename OutputStream>
909  static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {
910  // Do nothing for generic version
911  }
912 
913 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
914  // StringStream -> StackStream<char>
915  static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
916  const char* p = is.src_;
917 
918  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
919  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
920  while (p != nextAligned)
921  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
922  is.src_ = p;
923  return;
924  }
925  else
926  os.Put(*p++);
927 
928  // The rest of string using SIMD
929  static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
930  static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
931  static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
932  const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
933  const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
934  const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
935 
936  for (;; p += 16) {
937  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
938  const __m128i t1 = _mm_cmpeq_epi8(s, dq);
939  const __m128i t2 = _mm_cmpeq_epi8(s, bs);
940  const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
941  const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
942  unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
943  if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
944  SizeType length;
945  #ifdef _MSC_VER // Find the index of first escaped
946  unsigned long offset;
947  _BitScanForward(&offset, r);
948  length = offset;
949  #else
950  length = static_cast<SizeType>(__builtin_ffs(r) - 1);
951  #endif
952  char* q = reinterpret_cast<char*>(os.Push(length));
953  for (size_t i = 0; i < length; i++)
954  q[i] = p[i];
955 
956  p += length;
957  break;
958  }
959  _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);
960  }
961 
962  is.src_ = p;
963  }
964 
965  // InsituStringStream -> InsituStringStream
966  static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
967  RAPIDJSON_ASSERT(&is == &os);
968  (void)os;
969 
970  if (is.src_ == is.dst_) {
971  SkipUnescapedString(is);
972  return;
973  }
974 
975  char* p = is.src_;
976  char *q = is.dst_;
977 
978  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
979  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
980  while (p != nextAligned)
981  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
982  is.src_ = p;
983  is.dst_ = q;
984  return;
985  }
986  else
987  *q++ = *p++;
988 
989  // The rest of string using SIMD
990  static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
991  static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
992  static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
993  const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
994  const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
995  const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
996 
997  for (;; p += 16, q += 16) {
998  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
999  const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1000  const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1001  const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
1002  const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1003  unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1004  if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1005  size_t length;
1006 #ifdef _MSC_VER // Find the index of first escaped
1007  unsigned long offset;
1008  _BitScanForward(&offset, r);
1009  length = offset;
1010 #else
1011  length = static_cast<size_t>(__builtin_ffs(r) - 1);
1012 #endif
1013  for (const char* pend = p + length; p != pend; )
1014  *q++ = *p++;
1015  break;
1016  }
1017  _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);
1018  }
1019 
1020  is.src_ = p;
1021  is.dst_ = q;
1022  }
1023 
1024  // When read/write pointers are the same for insitu stream, just skip unescaped characters
1025  static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
1026  RAPIDJSON_ASSERT(is.src_ == is.dst_);
1027  char* p = is.src_;
1028 
1029  // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
1030  const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
1031  for (; p != nextAligned; p++)
1032  if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
1033  is.src_ = is.dst_ = p;
1034  return;
1035  }
1036 
1037  // The rest of string using SIMD
1038  static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
1039  static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
1040  static const char space[16] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
1041  const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
1042  const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
1043  const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
1044 
1045  for (;; p += 16) {
1046  const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
1047  const __m128i t1 = _mm_cmpeq_epi8(s, dq);
1048  const __m128i t2 = _mm_cmpeq_epi8(s, bs);
1049  const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x19) == 0x19
1050  const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
1051  unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
1052  if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
1053  size_t length;
1054 #ifdef _MSC_VER // Find the index of first escaped
1055  unsigned long offset;
1056  _BitScanForward(&offset, r);
1057  length = offset;
1058 #else
1059  length = static_cast<size_t>(__builtin_ffs(r) - 1);
1060 #endif
1061  p += length;
1062  break;
1063  }
1064  }
1065 
1066  is.src_ = is.dst_ = p;
1067  }
1068 #endif
1069 
1070  template<typename InputStream, bool backup, bool pushOnTake>
1071  class NumberStream;
1072 
1073  template<typename InputStream>
1074  class NumberStream<InputStream, false, false> {
1075  public:
1076  typedef typename InputStream::Ch Ch;
1077 
1078  NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; }
1079  ~NumberStream() {}
1080 
1081  RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
1082  RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
1083  RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
1084  RAPIDJSON_FORCEINLINE void Push(char) {}
1085 
1086  size_t Tell() { return is.Tell(); }
1087  size_t Length() { return 0; }
1088  const char* Pop() { return 0; }
1089 
1090  protected:
1091  NumberStream& operator=(const NumberStream&);
1092 
1093  InputStream& is;
1094  };
1095 
1096  template<typename InputStream>
1097  class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
1098  typedef NumberStream<InputStream, false, false> Base;
1099  public:
1100  NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
1101  ~NumberStream() {}
1102 
1103  RAPIDJSON_FORCEINLINE Ch TakePush() {
1104  stackStream.Put(static_cast<char>(Base::is.Peek()));
1105  return Base::is.Take();
1106  }
1107 
1108  RAPIDJSON_FORCEINLINE void Push(char c) {
1109  stackStream.Put(c);
1110  }
1111 
1112  size_t Length() { return stackStream.Length(); }
1113 
1114  const char* Pop() {
1115  stackStream.Put('\0');
1116  return stackStream.Pop();
1117  }
1118 
1119  private:
1120  StackStream<char> stackStream;
1121  };
1122 
1123  template<typename InputStream>
1124  class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
1125  typedef NumberStream<InputStream, true, false> Base;
1126  public:
1127  NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
1128  ~NumberStream() {}
1129 
1130  RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
1131  };
1132 
1133  template<unsigned parseFlags, typename InputStream, typename Handler>
1134  void ParseNumber(InputStream& is, Handler& handler) {
1135  internal::StreamLocalCopy<InputStream> copy(is);
1136  NumberStream<InputStream,
1137  ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
1138  ((parseFlags & kParseInsituFlag) == 0) :
1139  ((parseFlags & kParseFullPrecisionFlag) != 0),
1140  (parseFlags & kParseNumbersAsStringsFlag) != 0 &&
1141  (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);
1142 
1143  size_t startOffset = s.Tell();
1144  double d = 0.0;
1145  bool useNanOrInf = false;
1146 
1147  // Parse minus
1148  bool minus = Consume(s, '-');
1149 
1150  // Parse int: zero / ( digit1-9 *DIGIT )
1151  unsigned i = 0;
1152  uint64_t i64 = 0;
1153  bool use64bit = false;
1154  int significandDigit = 0;
1155  if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {
1156  i = 0;
1157  s.TakePush();
1158  }
1159  else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {
1160  i = static_cast<unsigned>(s.TakePush() - '0');
1161 
1162  if (minus)
1163  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1164  if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648
1165  if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {
1166  i64 = i;
1167  use64bit = true;
1168  break;
1169  }
1170  }
1171  i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1172  significandDigit++;
1173  }
1174  else
1175  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1176  if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295
1177  if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {
1178  i64 = i;
1179  use64bit = true;
1180  break;
1181  }
1182  }
1183  i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
1184  significandDigit++;
1185  }
1186  }
1187  // Parse NaN or Infinity here
1188  else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {
1189  useNanOrInf = true;
1190  if (RAPIDJSON_LIKELY(Consume(s, 'N') && Consume(s, 'a') && Consume(s, 'N'))) {
1191  d = std::numeric_limits<double>::quiet_NaN();
1192  }
1193  else if (RAPIDJSON_LIKELY(Consume(s, 'I') && Consume(s, 'n') && Consume(s, 'f'))) {
1194  d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
1195  if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
1196  && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y'))))
1198  }
1199  else
1201  }
1202  else
1204 
1205  // Parse 64bit int
1206  bool useDouble = false;
1207  if (use64bit) {
1208  if (minus)
1209  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1210  if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808
1211  if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {
1212  d = static_cast<double>(i64);
1213  useDouble = true;
1214  break;
1215  }
1216  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1217  significandDigit++;
1218  }
1219  else
1220  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1221  if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615
1222  if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {
1223  d = static_cast<double>(i64);
1224  useDouble = true;
1225  break;
1226  }
1227  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1228  significandDigit++;
1229  }
1230  }
1231 
1232  // Force double for big integer
1233  if (useDouble) {
1234  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1235  d = d * 10 + (s.TakePush() - '0');
1236  }
1237  }
1238 
1239  // Parse frac = decimal-point 1*DIGIT
1240  int expFrac = 0;
1241  size_t decimalPosition;
1242  if (Consume(s, '.')) {
1243  decimalPosition = s.Length();
1244 
1245  if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
1247 
1248  if (!useDouble) {
1249 #if RAPIDJSON_64BIT
1250  // Use i64 to store significand in 64-bit architecture
1251  if (!use64bit)
1252  i64 = i;
1253 
1254  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1255  if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
1256  break;
1257  else {
1258  i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
1259  --expFrac;
1260  if (i64 != 0)
1261  significandDigit++;
1262  }
1263  }
1264 
1265  d = static_cast<double>(i64);
1266 #else
1267  // Use double to store significand in 32-bit architecture
1268  d = static_cast<double>(use64bit ? i64 : i);
1269 #endif
1270  useDouble = true;
1271  }
1272 
1273  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1274  if (significandDigit < 17) {
1275  d = d * 10.0 + (s.TakePush() - '0');
1276  --expFrac;
1277  if (RAPIDJSON_LIKELY(d > 0.0))
1278  significandDigit++;
1279  }
1280  else
1281  s.TakePush();
1282  }
1283  }
1284  else
1285  decimalPosition = s.Length(); // decimal position at the end of integer.
1286 
1287  // Parse exp = e [ minus / plus ] 1*DIGIT
1288  int exp = 0;
1289  if (Consume(s, 'e') || Consume(s, 'E')) {
1290  if (!useDouble) {
1291  d = static_cast<double>(use64bit ? i64 : i);
1292  useDouble = true;
1293  }
1294 
1295  bool expMinus = false;
1296  if (Consume(s, '+'))
1297  ;
1298  else if (Consume(s, '-'))
1299  expMinus = true;
1300 
1301  if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1302  exp = static_cast<int>(s.Take() - '0');
1303  if (expMinus) {
1304  // (exp + expFrac) must not underflow int => we're detecting when -exp gets
1305  // dangerously close to INT_MIN (a pessimistic next digit 9 would push it into
1306  // underflow territory):
1307  //
1308  // -(exp * 10 + 9) + expFrac >= INT_MIN
1309  // <=> exp <= (expFrac - INT_MIN - 9) / 10
1310  RAPIDJSON_ASSERT(expFrac <= 0);
1311  int maxExp = (expFrac + 2147483639) / 10;
1312 
1313  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1314  exp = exp * 10 + static_cast<int>(s.Take() - '0');
1315  if (RAPIDJSON_UNLIKELY(exp > maxExp)) {
1316  while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent
1317  s.Take();
1318  }
1319  }
1320  }
1321  else { // positive exp
1322  int maxExp = 308 - expFrac;
1323  while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
1324  exp = exp * 10 + static_cast<int>(s.Take() - '0');
1325  if (RAPIDJSON_UNLIKELY(exp > maxExp))
1327  }
1328  }
1329  }
1330  else
1332 
1333  if (expMinus)
1334  exp = -exp;
1335  }
1336 
1337  // Finish parsing, call event according to the type of number.
1338  bool cont = true;
1339 
1340  if (parseFlags & kParseNumbersAsStringsFlag) {
1341  if (parseFlags & kParseInsituFlag) {
1342  s.Pop(); // Pop stack no matter if it will be used or not.
1343  typename InputStream::Ch* head = is.PutBegin();
1344  const size_t length = s.Tell() - startOffset;
1345  RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
1346  // unable to insert the \0 character here, it will erase the comma after this number
1347  const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
1348  cont = handler.RawNumber(str, SizeType(length), false);
1349  }
1350  else {
1351  SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
1352  StringStream srcStream(s.Pop());
1353  StackStream<typename TargetEncoding::Ch> dstStream(stack_);
1354  while (numCharsToCopy--) {
1355  Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);
1356  }
1357  dstStream.Put('\0');
1358  const typename TargetEncoding::Ch* str = dstStream.Pop();
1359  const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1;
1360  cont = handler.RawNumber(str, SizeType(length), true);
1361  }
1362  }
1363  else {
1364  size_t length = s.Length();
1365  const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not.
1366 
1367  if (useDouble) {
1368  int p = exp + expFrac;
1369  if (parseFlags & kParseFullPrecisionFlag)
1370  d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
1371  else
1372  d = internal::StrtodNormalPrecision(d, p);
1373 
1374  if (std::isinf(d)) {
1375  // Overflow
1376  // TODO: internal::StrtodX should report overflow (or underflow)
1378  }
1379 
1380  cont = handler.Double(minus ? -d : d);
1381  }
1382  else if (useNanOrInf) {
1383  cont = handler.Double(d);
1384  }
1385  else {
1386  if (use64bit) {
1387  if (minus)
1388  cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
1389  else
1390  cont = handler.Uint64(i64);
1391  }
1392  else {
1393  if (minus)
1394  cont = handler.Int(static_cast<int32_t>(~i + 1));
1395  else
1396  cont = handler.Uint(i);
1397  }
1398  }
1399  }
1400  if (RAPIDJSON_UNLIKELY(!cont))
1402  }
1403 
1404  // Parse any JSON value
1405  template<unsigned parseFlags, typename InputStream, typename Handler>
1406  void ParseValue(InputStream& is, Handler& handler) {
1407  switch (is.Peek()) {
1408  case 'n': ParseNull <parseFlags>(is, handler); break;
1409  case 't': ParseTrue <parseFlags>(is, handler); break;
1410  case 'f': ParseFalse <parseFlags>(is, handler); break;
1411  case '"': ParseString<parseFlags>(is, handler); break;
1412  case '{': ParseObject<parseFlags>(is, handler); break;
1413  case '[': ParseArray <parseFlags>(is, handler); break;
1414  default :
1415  ParseNumber<parseFlags>(is, handler);
1416  break;
1417 
1418  }
1419  }
1420 
1421  // Iterative Parsing
1422 
1423  // States
1424  enum IterativeParsingState {
1425  IterativeParsingStartState = 0,
1426  IterativeParsingFinishState,
1427  IterativeParsingErrorState,
1428 
1429  // Object states
1430  IterativeParsingObjectInitialState,
1431  IterativeParsingMemberKeyState,
1432  IterativeParsingKeyValueDelimiterState,
1433  IterativeParsingMemberValueState,
1434  IterativeParsingMemberDelimiterState,
1435  IterativeParsingObjectFinishState,
1436 
1437  // Array states
1438  IterativeParsingArrayInitialState,
1439  IterativeParsingElementState,
1440  IterativeParsingElementDelimiterState,
1441  IterativeParsingArrayFinishState,
1442 
1443  // Single value state
1444  IterativeParsingValueState
1445  };
1446 
1447  enum { cIterativeParsingStateCount = IterativeParsingValueState + 1 };
1448 
1449  // Tokens
1450  enum Token {
1451  LeftBracketToken = 0,
1452  RightBracketToken,
1453 
1454  LeftCurlyBracketToken,
1455  RightCurlyBracketToken,
1456 
1457  CommaToken,
1458  ColonToken,
1459 
1460  StringToken,
1461  FalseToken,
1462  TrueToken,
1463  NullToken,
1464  NumberToken,
1465 
1466  kTokenCount
1467  };
1468 
1469  RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
1470 
1471 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
1472 #define N NumberToken
1473 #define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
1474  // Maps from ASCII to Token
1475  static const unsigned char tokenMap[256] = {
1476  N16, // 00~0F
1477  N16, // 10~1F
1478  N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F
1479  N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F
1480  N16, // 40~4F
1481  N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F
1482  N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F
1483  N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F
1484  N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF
1485  };
1486 #undef N
1487 #undef N16
1488 //!@endcond
1489 
1490  if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
1491  return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);
1492  else
1493  return NumberToken;
1494  }
1495 
1496  RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {
1497  // current state x one lookahead token -> new state
1498  static const char G[cIterativeParsingStateCount][kTokenCount] = {
1499  // Start
1500  {
1501  IterativeParsingArrayInitialState, // Left bracket
1502  IterativeParsingErrorState, // Right bracket
1503  IterativeParsingObjectInitialState, // Left curly bracket
1504  IterativeParsingErrorState, // Right curly bracket
1505  IterativeParsingErrorState, // Comma
1506  IterativeParsingErrorState, // Colon
1507  IterativeParsingValueState, // String
1508  IterativeParsingValueState, // False
1509  IterativeParsingValueState, // True
1510  IterativeParsingValueState, // Null
1511  IterativeParsingValueState // Number
1512  },
1513  // Finish(sink state)
1514  {
1515  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1516  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1517  IterativeParsingErrorState
1518  },
1519  // Error(sink state)
1520  {
1521  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1522  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1523  IterativeParsingErrorState
1524  },
1525  // ObjectInitial
1526  {
1527  IterativeParsingErrorState, // Left bracket
1528  IterativeParsingErrorState, // Right bracket
1529  IterativeParsingErrorState, // Left curly bracket
1530  IterativeParsingObjectFinishState, // Right curly bracket
1531  IterativeParsingErrorState, // Comma
1532  IterativeParsingErrorState, // Colon
1533  IterativeParsingMemberKeyState, // String
1534  IterativeParsingErrorState, // False
1535  IterativeParsingErrorState, // True
1536  IterativeParsingErrorState, // Null
1537  IterativeParsingErrorState // Number
1538  },
1539  // MemberKey
1540  {
1541  IterativeParsingErrorState, // Left bracket
1542  IterativeParsingErrorState, // Right bracket
1543  IterativeParsingErrorState, // Left curly bracket
1544  IterativeParsingErrorState, // Right curly bracket
1545  IterativeParsingErrorState, // Comma
1546  IterativeParsingKeyValueDelimiterState, // Colon
1547  IterativeParsingErrorState, // String
1548  IterativeParsingErrorState, // False
1549  IterativeParsingErrorState, // True
1550  IterativeParsingErrorState, // Null
1551  IterativeParsingErrorState // Number
1552  },
1553  // KeyValueDelimiter
1554  {
1555  IterativeParsingArrayInitialState, // Left bracket(push MemberValue state)
1556  IterativeParsingErrorState, // Right bracket
1557  IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state)
1558  IterativeParsingErrorState, // Right curly bracket
1559  IterativeParsingErrorState, // Comma
1560  IterativeParsingErrorState, // Colon
1561  IterativeParsingMemberValueState, // String
1562  IterativeParsingMemberValueState, // False
1563  IterativeParsingMemberValueState, // True
1564  IterativeParsingMemberValueState, // Null
1565  IterativeParsingMemberValueState // Number
1566  },
1567  // MemberValue
1568  {
1569  IterativeParsingErrorState, // Left bracket
1570  IterativeParsingErrorState, // Right bracket
1571  IterativeParsingErrorState, // Left curly bracket
1572  IterativeParsingObjectFinishState, // Right curly bracket
1573  IterativeParsingMemberDelimiterState, // Comma
1574  IterativeParsingErrorState, // Colon
1575  IterativeParsingErrorState, // String
1576  IterativeParsingErrorState, // False
1577  IterativeParsingErrorState, // True
1578  IterativeParsingErrorState, // Null
1579  IterativeParsingErrorState // Number
1580  },
1581  // MemberDelimiter
1582  {
1583  IterativeParsingErrorState, // Left bracket
1584  IterativeParsingErrorState, // Right bracket
1585  IterativeParsingErrorState, // Left curly bracket
1586  IterativeParsingObjectFinishState, // Right curly bracket
1587  IterativeParsingErrorState, // Comma
1588  IterativeParsingErrorState, // Colon
1589  IterativeParsingMemberKeyState, // String
1590  IterativeParsingErrorState, // False
1591  IterativeParsingErrorState, // True
1592  IterativeParsingErrorState, // Null
1593  IterativeParsingErrorState // Number
1594  },
1595  // ObjectFinish(sink state)
1596  {
1597  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1598  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1599  IterativeParsingErrorState
1600  },
1601  // ArrayInitial
1602  {
1603  IterativeParsingArrayInitialState, // Left bracket(push Element state)
1604  IterativeParsingArrayFinishState, // Right bracket
1605  IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1606  IterativeParsingErrorState, // Right curly bracket
1607  IterativeParsingErrorState, // Comma
1608  IterativeParsingErrorState, // Colon
1609  IterativeParsingElementState, // String
1610  IterativeParsingElementState, // False
1611  IterativeParsingElementState, // True
1612  IterativeParsingElementState, // Null
1613  IterativeParsingElementState // Number
1614  },
1615  // Element
1616  {
1617  IterativeParsingErrorState, // Left bracket
1618  IterativeParsingArrayFinishState, // Right bracket
1619  IterativeParsingErrorState, // Left curly bracket
1620  IterativeParsingErrorState, // Right curly bracket
1621  IterativeParsingElementDelimiterState, // Comma
1622  IterativeParsingErrorState, // Colon
1623  IterativeParsingErrorState, // String
1624  IterativeParsingErrorState, // False
1625  IterativeParsingErrorState, // True
1626  IterativeParsingErrorState, // Null
1627  IterativeParsingErrorState // Number
1628  },
1629  // ElementDelimiter
1630  {
1631  IterativeParsingArrayInitialState, // Left bracket(push Element state)
1632  IterativeParsingArrayFinishState, // Right bracket
1633  IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
1634  IterativeParsingErrorState, // Right curly bracket
1635  IterativeParsingErrorState, // Comma
1636  IterativeParsingErrorState, // Colon
1637  IterativeParsingElementState, // String
1638  IterativeParsingElementState, // False
1639  IterativeParsingElementState, // True
1640  IterativeParsingElementState, // Null
1641  IterativeParsingElementState // Number
1642  },
1643  // ArrayFinish(sink state)
1644  {
1645  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1646  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1647  IterativeParsingErrorState
1648  },
1649  // Single Value (sink state)
1650  {
1651  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1652  IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
1653  IterativeParsingErrorState
1654  }
1655  }; // End of G
1656 
1657  return static_cast<IterativeParsingState>(G[state][token]);
1658  }
1659 
1660  // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
1661  // May return a new state on state pop.
1662  template <unsigned parseFlags, typename InputStream, typename Handler>
1663  RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
1664  (void)token;
1665 
1666  switch (dst) {
1667  case IterativeParsingErrorState:
1668  return dst;
1669 
1670  case IterativeParsingObjectInitialState:
1671  case IterativeParsingArrayInitialState:
1672  {
1673  // Push the state(Element or MemeberValue) if we are nested in another array or value of member.
1674  // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
1675  IterativeParsingState n = src;
1676  if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
1677  n = IterativeParsingElementState;
1678  else if (src == IterativeParsingKeyValueDelimiterState)
1679  n = IterativeParsingMemberValueState;
1680  // Push current state.
1681  *stack_.template Push<SizeType>(1) = n;
1682  // Initialize and push the member/element count.
1683  *stack_.template Push<SizeType>(1) = 0;
1684  // Call handler
1685  bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
1686  // On handler short circuits the parsing.
1687  if (!hr) {
1689  return IterativeParsingErrorState;
1690  }
1691  else {
1692  is.Take();
1693  return dst;
1694  }
1695  }
1696 
1697  case IterativeParsingMemberKeyState:
1698  ParseString<parseFlags>(is, handler, true);
1699  if (HasParseError())
1700  return IterativeParsingErrorState;
1701  else
1702  return dst;
1703 
1704  case IterativeParsingKeyValueDelimiterState:
1705  RAPIDJSON_ASSERT(token == ColonToken);
1706  is.Take();
1707  return dst;
1708 
1709  case IterativeParsingMemberValueState:
1710  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1711  ParseValue<parseFlags>(is, handler);
1712  if (HasParseError()) {
1713  return IterativeParsingErrorState;
1714  }
1715  return dst;
1716 
1717  case IterativeParsingElementState:
1718  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1719  ParseValue<parseFlags>(is, handler);
1720  if (HasParseError()) {
1721  return IterativeParsingErrorState;
1722  }
1723  return dst;
1724 
1725  case IterativeParsingMemberDelimiterState:
1726  case IterativeParsingElementDelimiterState:
1727  is.Take();
1728  // Update member/element count.
1729  *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
1730  return dst;
1731 
1732  case IterativeParsingObjectFinishState:
1733  {
1734  // Transit from delimiter is only allowed when trailing commas are enabled
1735  if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {
1737  return IterativeParsingErrorState;
1738  }
1739  // Get member count.
1740  SizeType c = *stack_.template Pop<SizeType>(1);
1741  // If the object is not empty, count the last member.
1742  if (src == IterativeParsingMemberValueState)
1743  ++c;
1744  // Restore the state.
1745  IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1746  // Transit to Finish state if this is the topmost scope.
1747  if (n == IterativeParsingStartState)
1748  n = IterativeParsingFinishState;
1749  // Call handler
1750  bool hr = handler.EndObject(c);
1751  // On handler short circuits the parsing.
1752  if (!hr) {
1754  return IterativeParsingErrorState;
1755  }
1756  else {
1757  is.Take();
1758  return n;
1759  }
1760  }
1761 
1762  case IterativeParsingArrayFinishState:
1763  {
1764  // Transit from delimiter is only allowed when trailing commas are enabled
1765  if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {
1767  return IterativeParsingErrorState;
1768  }
1769  // Get element count.
1770  SizeType c = *stack_.template Pop<SizeType>(1);
1771  // If the array is not empty, count the last element.
1772  if (src == IterativeParsingElementState)
1773  ++c;
1774  // Restore the state.
1775  IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
1776  // Transit to Finish state if this is the topmost scope.
1777  if (n == IterativeParsingStartState)
1778  n = IterativeParsingFinishState;
1779  // Call handler
1780  bool hr = handler.EndArray(c);
1781  // On handler short circuits the parsing.
1782  if (!hr) {
1784  return IterativeParsingErrorState;
1785  }
1786  else {
1787  is.Take();
1788  return n;
1789  }
1790  }
1791 
1792  default:
1793  // This branch is for IterativeParsingValueState actually.
1794  // Use `default:` rather than
1795  // `case IterativeParsingValueState:` is for code coverage.
1796 
1797  // The IterativeParsingStartState is not enumerated in this switch-case.
1798  // It is impossible for that case. And it can be caught by following assertion.
1799 
1800  // The IterativeParsingFinishState is not enumerated in this switch-case either.
1801  // It is a "derivative" state which cannot triggered from Predict() directly.
1802  // Therefore it cannot happen here. And it can be caught by following assertion.
1803  RAPIDJSON_ASSERT(dst == IterativeParsingValueState);
1804 
1805  // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
1806  ParseValue<parseFlags>(is, handler);
1807  if (HasParseError()) {
1808  return IterativeParsingErrorState;
1809  }
1810  return IterativeParsingFinishState;
1811  }
1812  }
1813 
1814  template <typename InputStream>
1815  void HandleError(IterativeParsingState src, InputStream& is) {
1816  if (HasParseError()) {
1817  // Error flag has been set.
1818  return;
1819  }
1820 
1821  switch (src) {
1822  case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
1823  case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
1824  case IterativeParsingObjectInitialState:
1825  case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
1826  case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
1827  case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
1828  case IterativeParsingKeyValueDelimiterState:
1829  case IterativeParsingArrayInitialState:
1830  case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return;
1831  default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
1832  }
1833  }
1834 
1835  template <unsigned parseFlags, typename InputStream, typename Handler>
1836  ParseResult IterativeParse(InputStream& is, Handler& handler) {
1837  parseResult_.Clear();
1838  ClearStackOnExit scope(*this);
1839  IterativeParsingState state = IterativeParsingStartState;
1840 
1841  SkipWhitespaceAndComments<parseFlags>(is);
1842  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
1843  while (is.Peek() != '\0') {
1844  Token t = Tokenize(is.Peek());
1845  IterativeParsingState n = Predict(state, t);
1846  IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
1847 
1848  if (d == IterativeParsingErrorState) {
1849  HandleError(state, is);
1850  break;
1851  }
1852 
1853  state = d;
1854 
1855  // Do not further consume streams if a root JSON has been parsed.
1856  if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
1857  break;
1858 
1859  SkipWhitespaceAndComments<parseFlags>(is);
1860  RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
1861  }
1862 
1863  // Handle the end of file.
1864  if (state != IterativeParsingFinishState)
1865  HandleError(state, is);
1866 
1867  return parseResult_;
1868  }
1869 
1870  static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string.
1871  internal::Stack<StackAllocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing.
1872  ParseResult parseResult_;
1873 }; // class GenericReader
1874 
1875 //! Reader with UTF8 encoding and default allocator.
1877 
1878 RAPIDJSON_NAMESPACE_END
1879 
1880 #ifdef __clang__
1881 RAPIDJSON_DIAG_POP
1882 #endif
1883 
1884 
1885 #ifdef __GNUC__
1886 RAPIDJSON_DIAG_POP
1887 #endif
1888 
1889 #ifdef _MSC_VER
1890 RAPIDJSON_DIAG_POP
1891 #endif
1892 
1893 #endif // RAPIDJSON_READER_H_
Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
Definition: reader.h:156
Read-only string stream.
Definition: fwd.h:47
Iterative(constant complexity in terms of function call stack size) parsing.
Definition: reader.h:150
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
Parse all numbers (ints/doubles) as strings.
Definition: reader.h:154
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition: reader.h:486
Validate encoding of JSON strings.
Definition: reader.h:149
Invalid value.
Definition: error.h:70
The surrogate pair in string is invalid.
Definition: error.h:79
#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset)
(Internal) macro to indicate and handle a parse error.
Definition: reader.h:119
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:289
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: fwd.h:88
Encoding conversion.
Definition: encodings.h:658
Missing a colon after a name of object member.
Definition: error.h:73
Incorrect hex digit after \u escape in string.
Definition: error.h:78
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
Definition: reader.h:535
Miss fraction part in number.
Definition: error.h:85
unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:380
bool RawNumber(const Ch *str, SizeType len, bool copy)
enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length) ...
Definition: reader.h:211
ParseErrorCode
Error code of parsing.
Definition: error.h:64
GenericReader(StackAllocator *stackAllocator=0, size_t stackCapacity=kDefaultStackCapacity)
Constructor.
Definition: reader.h:475
void Clear()
Reset error code.
Definition: error.h:128
Represents an in-memory input byte stream.
Definition: memorystream.h:40
Missing a comma or &#39;]&#39; after an array element.
Definition: error.h:76
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: reader.h:532
SourceEncoding::Ch Ch
SourceEncoding character type.
Definition: reader.h:469
The document root must not follow by other values.
Definition: error.h:68
const Ch * src_
Current read position.
Definition: stream.h:124
#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset)
Macro to indicate a parse error.
Definition: reader.h:100
Allow trailing commas at the end of objects and arrays.
Definition: reader.h:155
No flags are set.
Definition: reader.h:147
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:455
Unspecific syntax error.
Definition: error.h:89
Parse number in full precision (but slower).
Definition: reader.h:152
Missing a closing quotation mark in string.
Definition: error.h:81
Invalid escape character in string.
Definition: error.h:80
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
Missing a name for object member.
Definition: error.h:72
Type
Type of JSON value.
Definition: rapidjson.h:603
After parsing a complete JSON root from stream, stop further processing the rest of stream...
Definition: reader.h:151
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition: reader.h:265
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:468
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: reader.h:538
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS. ...
Definition: reader.h:157
ParseFlag
Combination of parseFlags.
Definition: reader.h:146
Allow one-line (//) and multi-line (/**/) comments.
Definition: reader.h:153
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:39
Parsing was terminated.
Definition: error.h:88
Number too big to be stored in double.
Definition: error.h:84
Default implementation of Handler.
Definition: fwd.h:85
Miss exponent in number.
Definition: error.h:86
In-situ(destructive) parsing.
Definition: reader.h:148
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text (with kParseDefaultFlags)
Definition: reader.h:527
UTF-8 encoding.
Definition: encodings.h:96
The document is empty.
Definition: error.h:67
Missing a comma or &#39;}&#39; after an object member.
Definition: error.h:74
Invalid encoding in string.
Definition: error.h:82
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:402
#define RAPIDJSON_PARSE_DEFAULT_FLAGS
User-defined kParseDefaultFlags definition.
Definition: reader.h:140
A read-write string stream.
Definition: fwd.h:52