reader.h
Go to the documentation of this file.
1 #ifndef RAPIDJSON_READER_H_
2 #define RAPIDJSON_READER_H_
3 
4 // Copyright (c) 2011-2023Milo Yip (miloyip@gmail.com)
5 // Version 0.1
6 
7 #include "rapidjson.h"
8 #include "internal/pow10.h"
9 #include "internal/stack.h"
10 #include <csetjmp>
11 
12 // All part of denormalized parsing
13 #include <limits> // for numeric_limits
14 #include <cmath> // for fpclassify
15 #include <sstream>
16 
17 #ifdef RAPIDJSON_SSE42
18 #include <nmmintrin.h>
19 #elif defined(RAPIDJSON_SSE2)
20 #include <emmintrin.h>
21 #endif
22 
23 #ifdef _MSC_VER
24 #pragma warning(push)
25 #pragma warning(disable : 4127) // conditional expression is constant
26 #endif
27 
28 #ifndef RAPIDJSON_PARSE_ERROR
29 #define RAPIDJSON_PARSE_ERROR(msg, offset) \
30  RAPIDJSON_MULTILINEMACRO_BEGIN \
31  parseError_ = msg; \
32  errorOffset_ = offset; \
33  longjmp(jmpbuf_, 1); \
34  RAPIDJSON_MULTILINEMACRO_END
35 #endif
36 namespace rapidjson {
37 
39 // ParseFlag
40 
42  enum ParseFlag {
44  kParseInsituFlag = 1
45  };
46 
48 // Handler
49 
72 // BaseReaderHandler
73 
75 
78  template<typename Encoding = UTF8<> >
80  typedef typename Encoding::Ch Ch;
81 
82  void Default() {}
83  void Null_() { Default(); }
84  void Bool_(bool) { Default(); }
85  void Int(int) { Default(); }
86  void Uint(unsigned) { Default(); }
87  void Int64(int64_t) { Default(); }
88  void Uint64(uint64_t) { Default(); }
89  void Double(double) { Default(); }
90  void String(const Ch*, SizeType, bool) { Default(); }
91  void StartObject() { Default(); }
92  void EndObject(SizeType) { Default(); }
93  void StartArray() { Default(); }
94  void EndArray(SizeType) { Default(); }
95  };
96 
98 // SkipWhitespace
99 
101 
104  template<typename Stream>
105  void SkipWhitespace(Stream& stream) {
106  Stream s = stream; // Use a local copy for optimization
107  while (s.Peek() == ' ' || s.Peek() == '\n' || s.Peek() == '\r' || s.Peek() == '\t')
108  s.Take();
109  stream = s;
110  }
111 
112 #ifdef RAPIDJSON_SSE42
114 inline const char *SkipWhitespace_SIMD(const char* p) {
115  static const char whitespace[16] = " \n\r\t";
116  __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]);
117 
118  for (;;) {
119  __m128i s = _mm_loadu_si128((const __m128i *)p);
120  unsigned r = _mm_cvtsi128_si32(_mm_cmpistrm(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK | _SIDD_NEGATIVE_POLARITY));
121  if (r == 0) // all 16 characters are whitespace
122  p += 16;
123  else { // some of characters may be non-whitespace
124 #ifdef _MSC_VER // Find the index of first non-whitespace
125  unsigned long offset;
126  if (_BitScanForward(&offset, r))
127  return p + offset;
128 #else
129  if (r != 0)
130  return p + __builtin_ffs(r) - 1;
131 #endif
132  }
133  }
134 }
135 
136 #elif defined(RAPIDJSON_SSE2)
137 
139 inline const char *SkipWhitespace_SIMD(const char* p) {
140  static const char whitespaces[4][17] = {
141  " ",
142  "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
143  "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r",
144  "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"};
145 
146  __m128i w0 = _mm_loadu_si128((const __m128i *)&whitespaces[0][0]);
147  __m128i w1 = _mm_loadu_si128((const __m128i *)&whitespaces[1][0]);
148  __m128i w2 = _mm_loadu_si128((const __m128i *)&whitespaces[2][0]);
149  __m128i w3 = _mm_loadu_si128((const __m128i *)&whitespaces[3][0]);
150 
151  for (;;) {
152  __m128i s = _mm_loadu_si128((const __m128i *)p);
153  __m128i x = _mm_cmpeq_epi8(s, w0);
154  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
155  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
156  x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
157  unsigned short r = ~_mm_movemask_epi8(x);
158  if (r == 0) // all 16 characters are whitespace
159  p += 16;
160  else { // some of characters may be non-whitespace
161 #ifdef _MSC_VER // Find the index of first non-whitespace
162  unsigned long offset;
163  if (_BitScanForward(&offset, r))
164  return p + offset;
165 #else
166  if (r != 0)
167  return p + __builtin_ffs(r) - 1;
168 #endif
169  }
170  }
171 }
172 
173 #endif // RAPIDJSON_SSE2
174 
175 #ifdef RAPIDJSON_SIMD
177 template<> inline void SkipWhitespace(InsituStringStream& stream) {
178  stream.src_ = const_cast<char*>(SkipWhitespace_SIMD(stream.src_));
179 }
180 
182 template<> inline void SkipWhitespace(StringStream& stream) {
183  stream.src_ = SkipWhitespace_SIMD(stream.src_);
184 }
185 #endif // RAPIDJSON_SIMD
186 
188 // GenericReader
189 
191 
205  template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
207  public:
208  typedef typename Encoding::Ch Ch;
209 
211 
214  GenericReader(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(allocator, stackCapacity), parseError_(0), errorOffset_(0) {}
215 
217 
224  template <unsigned parseFlags, typename Stream, typename Handler>
225  bool Parse(Stream& stream, Handler& handler) {
226  parseError_ = 0;
227  errorOffset_ = 0;
228 
229 #ifdef _MSC_VER
230  #pragma warning(push)
231 #pragma warning(disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
232 #endif
233  if (setjmp(jmpbuf_)) {
234 #ifdef _MSC_VER
235 #pragma warning(pop)
236 #endif
237  stack_.Clear();
238  return false;
239  }
240 
241  SkipWhitespace(stream);
242 
243  if (stream.Peek() == '\0')
244  RAPIDJSON_PARSE_ERROR("Text only contains white space(s)", stream.Tell());
245  else {
246  switch (stream.Peek()) {
247  case '{': ParseObject<parseFlags>(stream, handler); break;
248  case '[': ParseArray<parseFlags>(stream, handler); break;
249  default: RAPIDJSON_PARSE_ERROR("Expect either an object or array at root", stream.Tell());
250  }
251  SkipWhitespace(stream);
252 
253  if (stream.Peek() != '\0' && stream.Peek() != static_cast<Ch>(std::char_traits<Ch>::eof()))
254  RAPIDJSON_PARSE_ERROR("Nothing should follow the root object or array.", stream.Tell());
255  }
256 
257  return true;
258  }
259 
260  bool HasParseError() const { return parseError_ != 0; }
261  const char* GetParseError() const { return parseError_; }
262  size_t GetErrorOffset() const { return errorOffset_; }
263 
264  private:
265  // Parse object: { string : value, ... }
266  template<unsigned parseFlags, typename Stream, typename Handler>
267  void ParseObject(Stream& stream, Handler& handler) {
268  RAPIDJSON_ASSERT(stream.Peek() == '{');
269  stream.Take(); // Skip '{'
270  handler.StartObject();
271  SkipWhitespace(stream);
272 
273  if (stream.Peek() == '}') {
274  stream.Take();
275  handler.EndObject(0); // empty object
276  return;
277  }
278 
279  for (SizeType memberCount = 0;;) {
280  if (stream.Peek() != '"') {
281  RAPIDJSON_PARSE_ERROR("Name of an object member must be a string", stream.Tell());
282  break;
283  }
284 
285  ParseString<parseFlags>(stream, handler);
286  SkipWhitespace(stream);
287 
288  if (stream.Take() != ':') {
289  RAPIDJSON_PARSE_ERROR("There must be a colon after the name of object member", stream.Tell());
290  break;
291  }
292  SkipWhitespace(stream);
293 
294  ParseValue<parseFlags>(stream, handler);
295  SkipWhitespace(stream);
296 
297  ++memberCount;
298 
299  switch(stream.Take()) {
300  case ',': SkipWhitespace(stream); break;
301  case '}': handler.EndObject(memberCount); return;
302  default: RAPIDJSON_PARSE_ERROR("Must be a comma or '}' after an object member", stream.Tell());
303  }
304  }
305  }
306 
307  // Parse array: [ value, ... ]
308  template<unsigned parseFlags, typename Stream, typename Handler>
309  void ParseArray(Stream& stream, Handler& handler) {
310  RAPIDJSON_ASSERT(stream.Peek() == '[');
311  stream.Take(); // Skip '['
312  handler.StartArray();
313  SkipWhitespace(stream);
314 
315  if (stream.Peek() == ']') {
316  stream.Take();
317  handler.EndArray(0); // empty array
318  return;
319  }
320 
321  for (SizeType elementCount = 0;;) {
322  ParseValue<parseFlags>(stream, handler);
323  ++elementCount;
324  SkipWhitespace(stream);
325 
326  switch (stream.Take()) {
327  case ',': SkipWhitespace(stream); break;
328  case ']': handler.EndArray(elementCount); return;
329  default: RAPIDJSON_PARSE_ERROR("Must be a comma or ']' after an array element.", stream.Tell());
330  }
331  }
332  }
333 
334  // Parses for null or NaN
335  template<unsigned parseFlags, typename Stream, typename Handler>
336  void ParseNaNNull_(Stream& stream, Handler& handler) {
337  RAPIDJSON_ASSERT(stream.Peek() == 'n');
338  stream.Take();
339 
340  if( stream.Peek() == 'a' && stream.Take() == 'a' && stream.Take() == 'n' )
341  handler.Double( std::numeric_limits<double>::quiet_NaN() );
342  else if (stream.Take() == 'u' && stream.Take() == 'l' && stream.Take() == 'l')
343  handler.Null_();
344  else
345  RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1);
346  }
347 
348  // Parses for infinity
349  template<unsigned parseFlags, typename Stream, typename Handler>
350  void ParseInfinity(Stream& stream, Handler& handler) {
351  RAPIDJSON_ASSERT(stream.Peek() == 'i');
352  stream.Take();
353 
354  if (stream.Take() == 'n' && stream.Take() == 'f')
355  handler.Double( std::numeric_limits<double>::infinity() );
356  else
357  RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1);
358  }
359 
360  template<unsigned parseFlags, typename Stream, typename Handler>
361  void ParseTrue(Stream& stream, Handler& handler) {
362  RAPIDJSON_ASSERT(stream.Peek() == 't');
363  stream.Take();
364 
365  if (stream.Take() == 'r' && stream.Take() == 'u' && stream.Take() == 'e')
366  handler.Bool_(true);
367  else
368  RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell());
369  }
370 
371  template<unsigned parseFlags, typename Stream, typename Handler>
372  void ParseFalse(Stream& stream, Handler& handler) {
373  RAPIDJSON_ASSERT(stream.Peek() == 'f');
374  stream.Take();
375 
376  if (stream.Take() == 'a' && stream.Take() == 'l' && stream.Take() == 's' && stream.Take() == 'e')
377  handler.Bool_(false);
378  else
379  RAPIDJSON_PARSE_ERROR("Invalid value", stream.Tell() - 1);
380  }
381 
382  // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
383  template<typename Stream>
384  unsigned ParseHex4(Stream& stream) {
385  Stream s = stream; // Use a local copy for optimization
386  unsigned codepoint = 0;
387  for (int i = 0; i < 4; i++) {
388  Ch c = s.Take();
389  codepoint <<= 4;
390  codepoint += c;
391  if (c >= '0' && c <= '9')
392  codepoint -= '0';
393  else if (c >= 'A' && c <= 'F')
394  codepoint -= 'A' - 10;
395  else if (c >= 'a' && c <= 'f')
396  codepoint -= 'a' - 10;
397  else
398  RAPIDJSON_PARSE_ERROR("Incorrect hex digit after \\u escape", s.Tell() - 1);
399  }
400  stream = s; // Restore stream
401  return codepoint;
402  }
403 
404  // cereal Temporary until constexpr support is added in RTM
405 #ifdef _MSC_VER
406  template <class Ch>
407  bool characterOk( Ch c )
408  {
409  return c < 256;
410  }
411 
412  template <>
413  bool characterOk<char>( Ch )
414  {
415  return true;
416  }
417 
418 #else
419  // As part of a fix for GCC 4.7
420  template <class T>
421  static constexpr int to_int( T t ){ return t; }
422 
423  template<class Ch>
424  typename std::enable_if < to_int(std::numeric_limits<Ch>::max()) < to_int(256), bool>::type
425  characterOk( Ch )
426  {
427  return true;
428  }
429 
430  template<class Ch>
431  typename std::enable_if< to_int(std::numeric_limits<Ch>::max()) >= to_int(256), bool>::type
433  { return c < 256; }
434 #endif
435 
436  // Parse string, handling the prefix and suffix double quotes and escaping.
437  template<unsigned parseFlags, typename Stream, typename Handler>
438  void ParseString(Stream& stream, Handler& handler) {
439 #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
440  static const Ch escape[256] = {
441  Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
442  Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
443  0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
444  0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
445  Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
446  };
447 #undef Z16
448 
449  Stream s = stream; // Use a local copy for optimization
450  RAPIDJSON_ASSERT(s.Peek() == '\"');
451  s.Take(); // Skip '\"'
452  Ch *head;
453  SizeType len;
454  if (parseFlags & kParseInsituFlag)
455  head = s.PutBegin();
456  else
457  len = 0;
458 
459 #define RAPIDJSON_PUT(x) \
460  do { \
461  if (parseFlags & kParseInsituFlag) \
462  s.Put(x); \
463  else { \
464  *stack_.template Push<Ch>() = x; \
465  ++len; \
466  } \
467  } while(false)
468 
469  for (;;) {
470  Ch c = s.Take();
471  if (c == '\\') { // Escape
472  Ch e = s.Take();
473  if ((sizeof(Ch) == 1 || characterOk(e)) && escape[(unsigned char)e])
474  RAPIDJSON_PUT(escape[(unsigned char)e]);
475  else if (e == 'u') { // Unicode
476  unsigned codepoint = ParseHex4(s);
477  if (codepoint >= 0xD800 && codepoint <= 0xDBFF) { // Handle UTF-16 surrogate pair
478  if (s.Take() != '\\' || s.Take() != 'u') {
479  RAPIDJSON_PARSE_ERROR("Missing the second \\u in surrogate pair", s.Tell() - 2);
480  return;
481  }
482  unsigned codepoint2 = ParseHex4(s);
483  if (codepoint2 < 0xDC00 || codepoint2 > 0xDFFF) {
484  RAPIDJSON_PARSE_ERROR("The second \\u in surrogate pair is invalid", s.Tell() - 2);
485  return;
486  }
487  codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
488  }
489 
490  Ch buffer[4];
491  SizeType count = SizeType(Encoding::Encode(buffer, codepoint) - &buffer[0]);
492 
493  if (parseFlags & kParseInsituFlag)
494  for (SizeType i = 0; i < count; i++)
495  s.Put(buffer[i]);
496  else {
497  memcpy(stack_.template Push<Ch>(count), buffer, count * sizeof(Ch));
498  len += count;
499  }
500  }
501  else {
502  RAPIDJSON_PARSE_ERROR("Unknown escape character", stream.Tell() - 1);
503  return;
504  }
505  }
506  else if (c == '"') { // Closing double quote
507  if (parseFlags & kParseInsituFlag) {
508  size_t length = s.PutEnd(head);
509  RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
510  RAPIDJSON_PUT('\0'); // null-terminate the string
511  handler.String(head, SizeType(length), false);
512  }
513  else {
514  RAPIDJSON_PUT('\0');
515  handler.String(stack_.template Pop<Ch>(len), len - 1, true);
516  }
517  stream = s; // restore stream
518  return;
519  }
520  else if (c == '\0') {
521  RAPIDJSON_PARSE_ERROR("lacks ending quotation before the end of string", stream.Tell() - 1);
522  return;
523  }
524  else if ((unsigned)c < 0x20) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
525  RAPIDJSON_PARSE_ERROR("Incorrect unescaped character in string", stream.Tell() - 1);
526  return;
527  }
528  else
529  RAPIDJSON_PUT(c); // Normal character, just copy
530  }
531 #undef RAPIDJSON_PUT
532  }
533 
534  template<unsigned parseFlags, typename Stream, typename Handler>
535  void ParseNumber(Stream& stream, Handler& handler) {
536  Stream s = stream; // Local copy for optimization
537 
538  // Parse minus
539  bool minus = false;
540  if (s.Peek() == '-') {
541  minus = true;
542  s.Take();
543  }
544 
545  // Parse int: zero / ( digit1-9 *DIGIT )
546  unsigned i;
547  bool try64bit = false;
548  if (s.Peek() == '0') {
549  i = 0;
550  s.Take();
551  }
552  else if (s.Peek() >= '1' && s.Peek() <= '9') {
553  i = s.Take() - '0';
554 
555  if (minus)
556  while (s.Peek() >= '0' && s.Peek() <= '9') {
557  if (i >= 214748364) { // 2^31 = 2147483648
558  if (i != 214748364 || s.Peek() > '8') {
559  try64bit = true;
560  break;
561  }
562  }
563  i = i * 10 + (s.Take() - '0');
564  }
565  else
566  while (s.Peek() >= '0' && s.Peek() <= '9') {
567  if (i >= 429496729) { // 2^32 - 1 = 4294967295
568  if (i != 429496729 || s.Peek() > '5') {
569  try64bit = true;
570  break;
571  }
572  }
573  i = i * 10 + (s.Take() - '0');
574  }
575  }
576  else {
577  RAPIDJSON_PARSE_ERROR("Expect a value here.", stream.Tell());
578  return;
579  }
580 
581  // Parse 64bit int
582  uint64_t i64 = 0;
583  bool useDouble = false;
584  if (try64bit) {
585  i64 = i;
586  if (minus)
587  while (s.Peek() >= '0' && s.Peek() <= '9') {
588  if (i64 >= 922337203685477580uLL) // 2^63 = 9223372036854775808
589  if (i64 != 922337203685477580uLL || s.Peek() > '8') {
590  useDouble = true;
591  break;
592  }
593  i64 = i64 * 10 + (s.Take() - '0');
594  }
595  else
596  while (s.Peek() >= '0' && s.Peek() <= '9') {
597  if (i64 >= 1844674407370955161uLL) // 2^64 - 1 = 18446744073709551615
598  if (i64 != 1844674407370955161uLL || s.Peek() > '5') {
599  useDouble = true;
600  break;
601  }
602  i64 = i64 * 10 + (s.Take() - '0');
603  }
604  }
605 
606  // Force double for big integer
607  double d = 0.0;
608  if (useDouble) {
609  d = (double)i64;
610  while (s.Peek() >= '0' && s.Peek() <= '9') {
611  if (d >= 1E307) {
612  RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell());
613  return;
614  }
615  d = d * 10 + (s.Take() - '0');
616  }
617  }
618 
619  // Parse frac = decimal-point 1*DIGIT
620  int expFrac = 0;
621  if (s.Peek() == '.') {
622  if (!useDouble) {
623  d = try64bit ? (double)i64 : (double)i;
624  useDouble = true;
625  }
626  s.Take();
627 
628  if (s.Peek() >= '0' && s.Peek() <= '9') {
629  d = d * 10 + (s.Take() - '0');
630  --expFrac;
631  }
632  else {
633  RAPIDJSON_PARSE_ERROR("At least one digit in fraction part", stream.Tell());
634  return;
635  }
636 
637  while (s.Peek() >= '0' && s.Peek() <= '9') {
638  if (expFrac > -20) {
639  d = d * 10 + (s.Peek() - '0');
640  --expFrac;
641  }
642  s.Take();
643  }
644  }
645 
646  // Parse exp = e [ minus / plus ] 1*DIGIT
647  int exp = 0;
648  if (s.Peek() == 'e' || s.Peek() == 'E') {
649  if (!useDouble) {
650  d = try64bit ? (double)i64 : (double)i;
651  useDouble = true;
652  }
653  s.Take();
654 
655  bool expMinus = false;
656  if (s.Peek() == '+')
657  s.Take();
658  else if (s.Peek() == '-') {
659  s.Take();
660  expMinus = true;
661  }
662 
663  if (s.Peek() >= '0' && s.Peek() <= '9') {
664  exp = s.Take() - '0';
665  while (s.Peek() >= '0' && s.Peek() <= '9') {
666  exp = exp * 10 + (s.Take() - '0');
667  if (exp > 308) {
668  // Attempt denormalized construction
669  std::stringstream ss;
670  ss.precision( std::numeric_limits<double>::max_digits10 );
671  ss << d * internal::Pow10(expFrac) << 'e' << (expMinus ? '-' : '+') << exp;
672 
673  double dd;
674  ss >> dd;
675 
676  if( std::fpclassify( dd ) == FP_SUBNORMAL )
677  handler.Double( dd );
678  else
679  RAPIDJSON_PARSE_ERROR("Number too big to store in double", stream.Tell());
680 
681  return;
682  }
683  }
684  }
685  else {
686  RAPIDJSON_PARSE_ERROR("At least one digit in exponent", s.Tell());
687  return;
688  }
689 
690  if (expMinus)
691  exp = -exp;
692  }
693 
694  // Finish parsing, call event according to the type of number.
695  if (useDouble) {
696  d *= internal::Pow10(exp + expFrac);
697  handler.Double(minus ? -d : d);
698  }
699  else {
700  if (try64bit) {
701  if (minus)
702  handler.Int64(-(int64_t)i64);
703  else
704  handler.Uint64(i64);
705  }
706  else {
707  if (minus)
708  handler.Int(-(int)i);
709  else
710  handler.Uint(i);
711  }
712  }
713 
714  stream = s; // restore stream
715  }
716 
717  // Parse any JSON value
718  template<unsigned parseFlags, typename Stream, typename Handler>
719  void ParseValue(Stream& stream, Handler& handler) {
720  switch (stream.Peek()) {
721  case 'n': ParseNaNNull_ <parseFlags>(stream, handler); break;
722  case 'i': ParseInfinity <parseFlags>(stream, handler); break;
723  case 't': ParseTrue <parseFlags>(stream, handler); break;
724  case 'f': ParseFalse <parseFlags>(stream, handler); break;
725  case '"': ParseString <parseFlags>(stream, handler); break;
726  case '{': ParseObject <parseFlags>(stream, handler); break;
727  case '[': ParseArray <parseFlags>(stream, handler); break;
728  default : ParseNumber <parseFlags>(stream, handler);
729  }
730  }
731 
732  static const size_t kDefaultStackCapacity = 256;
734  jmp_buf jmpbuf_;
735  const char* parseError_;
736  size_t errorOffset_;
737  }; // class GenericReader
738 
741 
742 } // namespace rapidjson
743 
744 #ifdef _MSC_VER
745 #pragma warning(pop)
746 #endif
747 
748 #endif // RAPIDJSON_READER_H_
static void escape(void *p)
Definition: BenchTimer.h:30
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
RowVector3d w
Definition: Matrix_resize_int.cpp:3
float * p
Definition: Tutorial_Map_using.cpp:9
Concept for allocating, resizing and freeing memory block.
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: reader.h:206
void ParseValue(Stream &stream, Handler &handler)
Definition: reader.h:719
void ParseObject(Stream &stream, Handler &handler)
Definition: reader.h:267
void ParseNumber(Stream &stream, Handler &handler)
Definition: reader.h:535
jmp_buf jmpbuf_
setjmp buffer for fast exit from nested parsing function calls.
Definition: reader.h:734
void ParseInfinity(Stream &stream, Handler &handler)
Definition: reader.h:350
bool Parse(Stream &stream, Handler &handler)
Parse JSON text.
Definition: reader.h:225
unsigned ParseHex4(Stream &stream)
Definition: reader.h:384
internal::Stack< Allocator > stack_
A stack for storing decoded string temporarily during non-destructive parsing.
Definition: reader.h:733
void ParseArray(Stream &stream, Handler &handler)
Definition: reader.h:309
Encoding::Ch Ch
Definition: reader.h:208
const char * parseError_
Definition: reader.h:735
void ParseString(Stream &stream, Handler &handler)
Definition: reader.h:438
void ParseTrue(Stream &stream, Handler &handler)
Definition: reader.h:361
void ParseNaNNull_(Stream &stream, Handler &handler)
Definition: reader.h:336
const char * GetParseError() const
Definition: reader.h:261
std::enable_if< to_int(std::numeric_limits< Ch >::max())< to_int(256), bool >::type characterOk(Ch) { return true;} template< class Ch > typename std::enable_if< to_int(std::numeric_limits< Ch >::max()) >=to_int(256), bool >::type characterOk(Ch c)
Definition: reader.h:432
static constexpr int to_int(T t)
Definition: reader.h:421
size_t errorOffset_
Definition: reader.h:736
void ParseFalse(Stream &stream, Handler &handler)
Definition: reader.h:372
GenericReader(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity)
Constructor.
Definition: reader.h:214
bool HasParseError() const
Definition: reader.h:260
static const size_t kDefaultStackCapacity
Default stack capacity in bytes for storing a single decoded string.
Definition: reader.h:732
size_t GetErrorOffset() const
Definition: reader.h:262
Concept for receiving events from GenericReader upon parsing.
Concept for reading and writing characters.
A type-unsafe stack for storing different types of data.
Definition: stack.h:14
#define max(a, b)
Definition: datatypes.h:23
RealScalar s
Definition: level1_cplx_impl.h:130
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 exp(const bfloat16 &a)
Definition: BFloat16.h:615
std::int64_t int64_t
Definition: Meta.h:43
std::uint64_t uint64_t
Definition: Meta.h:42
r
Definition: UniformPSDSelfTest.py:20
int c
Definition: calibrate.py:100
default
Definition: calibrate.py:45
type
Definition: compute_granudrum_aor.py:141
list x
Definition: plotDoE.py:28
t
Definition: plotPSD.py:36
double Pow10(int n)
Computes integer powers of 10 in double (10.0^n).
Definition: pow10.h:12
Definition: document.h:13
unsigned SizeType
Use 32-bit array/string indices even for 64-bit platform, instead of using size_t.
Definition: rapidjson.h:67
GenericInsituStringStream< UTF8<> > InsituStringStream
Definition: rapidjson.h:507
void SkipWhitespace(Stream &stream)
Skip the JSON white spaces in a stream.
Definition: reader.h:105
GenericReader< UTF8<> > Reader
Reader with UTF8 encoding and default allocator.
Definition: reader.h:740
ParseFlag
Combination of parseFlags.
Definition: reader.h:42
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition: reader.h:44
@ kParseDefaultFlags
Default parse flags. Non-destructive parsing. Text strings are decoded into allocated buffer.
Definition: reader.h:43
GenericStringStream< UTF8<> > StringStream
Definition: rapidjson.h:477
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:80
#define RAPIDJSON_PUT(x)
#define RAPIDJSON_PARSE_ERROR(msg, offset)
Definition: reader.h:29
#define Z16
Default implementation of Handler.
Definition: reader.h:79
void Default()
Definition: reader.h:82
void Int(int)
Definition: reader.h:85
void StartObject()
Definition: reader.h:91
void Null_()
Definition: reader.h:83
void Bool_(bool)
Definition: reader.h:84
void EndObject(SizeType)
Definition: reader.h:92
void StartArray()
Definition: reader.h:93
void Double(double)
Definition: reader.h:89
void Uint(unsigned)
Definition: reader.h:86
void Int64(int64_t)
Definition: reader.h:87
void Uint64(uint64_t)
Definition: reader.h:88
void EndArray(SizeType)
Definition: reader.h:94
void String(const Ch *, SizeType, bool)
Definition: reader.h:90
Encoding::Ch Ch
Definition: reader.h:80