NCBI C++ ToolKit
reader.h
Go to the documentation of this file.

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