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