readertest.cpp
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #include "unittest.h"
16 
17 #include "rapidjson/reader.h"
20 #include "rapidjson/memorystream.h"
21 
22 #include <limits>
23 
24 using namespace rapidjson;
25 
26 RAPIDJSON_DIAG_PUSH
27 #ifdef __GNUC__
28 RAPIDJSON_DIAG_OFF(effc++)
29 RAPIDJSON_DIAG_OFF(float-equal)
30 RAPIDJSON_DIAG_OFF(missing-noreturn)
31 #if __GNUC__ >= 7
32 RAPIDJSON_DIAG_OFF(dangling-else)
33 #endif
34 #endif // __GNUC__
35 
36 #ifdef __clang__
37 RAPIDJSON_DIAG_OFF(variadic-macros)
38 RAPIDJSON_DIAG_OFF(c++98-compat-pedantic)
39 #endif
40 
41 template<bool expect>
42 struct ParseBoolHandler : BaseReaderHandler<UTF8<>, ParseBoolHandler<expect> > {
43  ParseBoolHandler() : step_(0) {}
44  bool Default() { ADD_FAILURE(); return false; }
45  // gcc 4.8.x generates warning in EXPECT_EQ(bool, bool) on this gtest version.
46  // Workaround with EXPECT_TRUE().
47  bool Bool(bool b) { /*EXPECT_EQ(expect, b); */EXPECT_TRUE(expect == b); ++step_; return true; }
48 
49  unsigned step_;
50 };
51 
52 TEST(Reader, ParseTrue) {
53  StringStream s("true");
55  Reader reader;
56  reader.Parse(s, h);
57  EXPECT_EQ(1u, h.step_);
58 }
59 
60 TEST(Reader, ParseFalse) {
61  StringStream s("false");
63  Reader reader;
64  reader.Parse(s, h);
65  EXPECT_EQ(1u, h.step_);
66 }
67 
68 struct ParseIntHandler : BaseReaderHandler<UTF8<>, ParseIntHandler> {
69  ParseIntHandler() : step_(0), actual_() {}
70  bool Default() { ADD_FAILURE(); return false; }
71  bool Int(int i) { actual_ = i; step_++; return true; }
72 
73  unsigned step_;
74  int actual_;
75 };
76 
77 struct ParseUintHandler : BaseReaderHandler<UTF8<>, ParseUintHandler> {
78  ParseUintHandler() : step_(0), actual_() {}
79  bool Default() { ADD_FAILURE(); return false; }
80  bool Uint(unsigned i) { actual_ = i; step_++; return true; }
81 
82  unsigned step_;
83  unsigned actual_;
84 };
85 
86 struct ParseInt64Handler : BaseReaderHandler<UTF8<>, ParseInt64Handler> {
87  ParseInt64Handler() : step_(0), actual_() {}
88  bool Default() { ADD_FAILURE(); return false; }
89  bool Int64(int64_t i) { actual_ = i; step_++; return true; }
90 
91  unsigned step_;
93 };
94 
95 struct ParseUint64Handler : BaseReaderHandler<UTF8<>, ParseUint64Handler> {
96  ParseUint64Handler() : step_(0), actual_() {}
97  bool Default() { ADD_FAILURE(); return false; }
98  bool Uint64(uint64_t i) { actual_ = i; step_++; return true; }
99 
100  unsigned step_;
102 };
103 
104 struct ParseDoubleHandler : BaseReaderHandler<UTF8<>, ParseDoubleHandler> {
105  ParseDoubleHandler() : step_(0), actual_() {}
106  bool Default() { ADD_FAILURE(); return false; }
107  bool Double(double d) { actual_ = d; step_++; return true; }
108 
109  unsigned step_;
110  double actual_;
111 };
112 
113 TEST(Reader, ParseNumber_Integer) {
114 #define TEST_INTEGER(Handler, str, x) \
115  { \
116  StringStream s(str); \
117  Handler h; \
118  Reader reader; \
119  reader.Parse(s, h); \
120  EXPECT_EQ(1u, h.step_); \
121  EXPECT_EQ(x, h.actual_); \
122  }
123 
124  TEST_INTEGER(ParseUintHandler, "0", 0u);
125  TEST_INTEGER(ParseUintHandler, "123", 123u);
126  TEST_INTEGER(ParseUintHandler, "2147483648", 2147483648u); // 2^31 - 1 (cannot be stored in int)
127  TEST_INTEGER(ParseUintHandler, "4294967295", 4294967295u);
128 
129  TEST_INTEGER(ParseIntHandler, "-123", -123);
130  TEST_INTEGER(ParseIntHandler, "-2147483648", static_cast<int32_t>(0x80000000)); // -2^31 (min of int)
131 
132  TEST_INTEGER(ParseUint64Handler, "4294967296", RAPIDJSON_UINT64_C2(1, 0)); // 2^32 (max of unsigned + 1, force to use uint64_t)
133  TEST_INTEGER(ParseUint64Handler, "18446744073709551615", RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)); // 2^64 - 1 (max of uint64_t)
134 
135  TEST_INTEGER(ParseInt64Handler, "-2147483649", static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x7FFFFFFF))); // -2^31 -1 (min of int - 1, force to use int64_t)
136  TEST_INTEGER(ParseInt64Handler, "-9223372036854775808", static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))); // -2^63 (min of int64_t)
137 
138  // Random test for uint32_t/int32_t
139  {
140  union {
141  uint32_t u;
142  int32_t i;
143  }u;
144  Random r;
145 
146  for (unsigned i = 0; i < 100000; i++) {
147  u.u = r();
148 
149  char buffer[32];
150  *internal::u32toa(u.u, buffer) = '\0';
151  TEST_INTEGER(ParseUintHandler, buffer, u.u);
152 
153  if (u.i < 0) {
154  *internal::i32toa(u.i, buffer) = '\0';
155  TEST_INTEGER(ParseIntHandler, buffer, u.i);
156  }
157  }
158  }
159 
160  // Random test for uint64_t/int64_t
161  {
162  union {
163  uint64_t u;
164  int64_t i;
165  }u;
166  Random r;
167 
168  for (unsigned i = 0; i < 100000; i++) {
169  u.u = uint64_t(r()) << 32;
170  u.u |= r();
171 
172  char buffer[32];
173  if (u.u > uint64_t(4294967295u)) {
174  *internal::u64toa(u.u, buffer) = '\0';
175  TEST_INTEGER(ParseUint64Handler, buffer, u.u);
176  }
177 
178  if (u.i < -int64_t(2147483648u)) {
179  *internal::i64toa(u.i, buffer) = '\0';
180  TEST_INTEGER(ParseInt64Handler, buffer, u.i);
181  }
182  }
183  }
184 #undef TEST_INTEGER
185 }
186 
187 template<bool fullPrecision>
188 static void TestParseDouble() {
189 #define TEST_DOUBLE(fullPrecision, str, x) \
190  { \
191  StringStream s(str); \
192  ParseDoubleHandler h; \
193  Reader reader; \
194  ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code()); \
195  EXPECT_EQ(1u, h.step_); \
196  internal::Double e(x), a(h.actual_); \
197  if (fullPrecision) { \
198  EXPECT_EQ(e.Uint64Value(), a.Uint64Value()); \
199  if (e.Uint64Value() != a.Uint64Value()) \
200  printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", str, h.actual_, x); \
201  } \
202  else { \
203  EXPECT_EQ(e.Sign(), a.Sign()); /* for 0.0 != -0.0 */ \
204  EXPECT_DOUBLE_EQ(x, h.actual_); \
205  } \
206  }
207 
208  TEST_DOUBLE(fullPrecision, "0.0", 0.0);
209  TEST_DOUBLE(fullPrecision, "-0.0", -0.0); // For checking issue #289
210  TEST_DOUBLE(fullPrecision, "1.0", 1.0);
211  TEST_DOUBLE(fullPrecision, "-1.0", -1.0);
212  TEST_DOUBLE(fullPrecision, "1.5", 1.5);
213  TEST_DOUBLE(fullPrecision, "-1.5", -1.5);
214  TEST_DOUBLE(fullPrecision, "3.1416", 3.1416);
215  TEST_DOUBLE(fullPrecision, "1E10", 1E10);
216  TEST_DOUBLE(fullPrecision, "1e10", 1e10);
217  TEST_DOUBLE(fullPrecision, "1E+10", 1E+10);
218  TEST_DOUBLE(fullPrecision, "1E-10", 1E-10);
219  TEST_DOUBLE(fullPrecision, "-1E10", -1E10);
220  TEST_DOUBLE(fullPrecision, "-1e10", -1e10);
221  TEST_DOUBLE(fullPrecision, "-1E+10", -1E+10);
222  TEST_DOUBLE(fullPrecision, "-1E-10", -1E-10);
223  TEST_DOUBLE(fullPrecision, "1.234E+10", 1.234E+10);
224  TEST_DOUBLE(fullPrecision, "1.234E-10", 1.234E-10);
225  TEST_DOUBLE(fullPrecision, "1.79769e+308", 1.79769e+308);
226  TEST_DOUBLE(fullPrecision, "2.22507e-308", 2.22507e-308);
227  TEST_DOUBLE(fullPrecision, "-1.79769e+308", -1.79769e+308);
228  TEST_DOUBLE(fullPrecision, "-2.22507e-308", -2.22507e-308);
229  TEST_DOUBLE(fullPrecision, "4.9406564584124654e-324", 4.9406564584124654e-324); // minimum denormal
230  TEST_DOUBLE(fullPrecision, "2.2250738585072009e-308", 2.2250738585072009e-308); // Max subnormal double
231  TEST_DOUBLE(fullPrecision, "2.2250738585072014e-308", 2.2250738585072014e-308); // Min normal positive double
232  TEST_DOUBLE(fullPrecision, "1.7976931348623157e+308", 1.7976931348623157e+308); // Max double
233  TEST_DOUBLE(fullPrecision, "1e-10000", 0.0); // must underflow
234  TEST_DOUBLE(fullPrecision, "18446744073709551616", 18446744073709551616.0); // 2^64 (max of uint64_t + 1, force to use double)
235  TEST_DOUBLE(fullPrecision, "-9223372036854775809", -9223372036854775809.0); // -2^63 - 1(min of int64_t + 1, force to use double)
236  TEST_DOUBLE(fullPrecision, "0.9868011474609375", 0.9868011474609375); // https://github.com/miloyip/rapidjson/issues/120
237  TEST_DOUBLE(fullPrecision, "123e34", 123e34); // Fast Path Cases In Disguise
238  TEST_DOUBLE(fullPrecision, "45913141877270640000.0", 45913141877270640000.0);
239  TEST_DOUBLE(fullPrecision, "2.2250738585072011e-308", 2.2250738585072011e-308); // http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
240  TEST_DOUBLE(fullPrecision, "1e-00011111111111", 0.0); // Issue #313
241  TEST_DOUBLE(fullPrecision, "-1e-00011111111111", -0.0);
242  TEST_DOUBLE(fullPrecision, "1e-214748363", 0.0); // Maximum supported negative exponent
243  TEST_DOUBLE(fullPrecision, "1e-214748364", 0.0);
244  TEST_DOUBLE(fullPrecision, "1e-21474836311", 0.0);
245  TEST_DOUBLE(fullPrecision, "0.017976931348623157e+310", 1.7976931348623157e+308); // Max double in another form
246 
247  // Since
248  // abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... x 10^-324
249  // abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... x 10 ^ -324
250  // So 2.2250738585072012e-308 should round to 2^-1022 = 2.2250738585072014e-308
251  TEST_DOUBLE(fullPrecision, "2.2250738585072012e-308", 2.2250738585072014e-308); // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
252 
253  // More closer to normal/subnormal boundary
254  // boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... x 10^-308
255  TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164564e-308", 2.2250738585072009e-308);
256  TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164565e-308", 2.2250738585072014e-308);
257 
258  // 1.0 is in (1.0 - 2^-54, 1.0 + 2^-53)
259  // 1.0 - 2^-54 = 0.999999999999999944488848768742172978818416595458984375
260  TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984375", 1.0); // round to even
261  TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984374", 0.99999999999999989); // previous double
262  TEST_DOUBLE(fullPrecision, "0.999999999999999944488848768742172978818416595458984376", 1.0); // next double
263  // 1.0 + 2^-53 = 1.00000000000000011102230246251565404236316680908203125
264  TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203125", 1.0); // round to even
265  TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203124", 1.0); // previous double
266  TEST_DOUBLE(fullPrecision, "1.00000000000000011102230246251565404236316680908203126", 1.00000000000000022); // next double
267 
268  // Numbers from https://github.com/floitsch/double-conversion/blob/master/test/cctest/test-strtod.cc
269 
270  TEST_DOUBLE(fullPrecision, "72057594037927928.0", 72057594037927928.0);
271  TEST_DOUBLE(fullPrecision, "72057594037927936.0", 72057594037927936.0);
272  TEST_DOUBLE(fullPrecision, "72057594037927932.0", 72057594037927936.0);
273  TEST_DOUBLE(fullPrecision, "7205759403792793199999e-5", 72057594037927928.0);
274  TEST_DOUBLE(fullPrecision, "7205759403792793200001e-5", 72057594037927936.0);
275 
276  TEST_DOUBLE(fullPrecision, "9223372036854774784.0", 9223372036854774784.0);
277  TEST_DOUBLE(fullPrecision, "9223372036854775808.0", 9223372036854775808.0);
278  TEST_DOUBLE(fullPrecision, "9223372036854775296.0", 9223372036854775808.0);
279  TEST_DOUBLE(fullPrecision, "922337203685477529599999e-5", 9223372036854774784.0);
280  TEST_DOUBLE(fullPrecision, "922337203685477529600001e-5", 9223372036854775808.0);
281 
282  TEST_DOUBLE(fullPrecision, "10141204801825834086073718800384", 10141204801825834086073718800384.0);
283  TEST_DOUBLE(fullPrecision, "10141204801825835211973625643008", 10141204801825835211973625643008.0);
284  TEST_DOUBLE(fullPrecision, "10141204801825834649023672221696", 10141204801825835211973625643008.0);
285  TEST_DOUBLE(fullPrecision, "1014120480182583464902367222169599999e-5", 10141204801825834086073718800384.0);
286  TEST_DOUBLE(fullPrecision, "1014120480182583464902367222169600001e-5", 10141204801825835211973625643008.0);
287 
288  TEST_DOUBLE(fullPrecision, "5708990770823838890407843763683279797179383808", 5708990770823838890407843763683279797179383808.0);
289  TEST_DOUBLE(fullPrecision, "5708990770823839524233143877797980545530986496", 5708990770823839524233143877797980545530986496.0);
290  TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185152", 5708990770823839524233143877797980545530986496.0);
291  TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185151999e-3", 5708990770823838890407843763683279797179383808.0);
292  TEST_DOUBLE(fullPrecision, "5708990770823839207320493820740630171355185152001e-3", 5708990770823839524233143877797980545530986496.0);
293 
294  {
295  char n1e308[310]; // '1' followed by 308 '0'
296  n1e308[0] = '1';
297  for (int i = 1; i < 309; i++)
298  n1e308[i] = '0';
299  n1e308[309] = '\0';
300  TEST_DOUBLE(fullPrecision, n1e308, 1E308);
301  }
302 
303  // Cover trimming
304  TEST_DOUBLE(fullPrecision,
305 "2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508"
306 "7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012"
307 "9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306"
308 "6665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505"
309 "1080609940730262937128958950003583799967207254304360284078895771796150945516748243471030702609144621"
310 "5722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844"
311 "2390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042"
312 "7567186443383770486037861622771738545623065874679014086723327636718751234567890123456789012345678901"
313 "e-308",
314  2.2250738585072014e-308);
315 
316  {
317  static const unsigned count = 100; // Tested with 1000000 locally
318  Random r;
319  Reader reader; // Reusing reader to prevent heap allocation
320 
321  // Exhaustively test different exponents with random significant
322  for (uint64_t exp = 0; exp < 2047; exp++) {
323  ;
324  for (unsigned i = 0; i < count; i++) {
325  // Need to call r() in two statements for cross-platform coherent sequence.
326  uint64_t u = (exp << 52) | uint64_t(r() & 0x000FFFFF) << 32;
327  u |= uint64_t(r());
329 
330  char buffer[32];
331  *internal::dtoa(d.Value(), buffer) = '\0';
332 
333  StringStream s(buffer);
335  ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code());
336  EXPECT_EQ(1u, h.step_);
338  if (fullPrecision) {
339  EXPECT_EQ(d.Uint64Value(), a.Uint64Value());
340  if (d.Uint64Value() != a.Uint64Value())
341  printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.actual_, d.Value());
342  }
343  else {
344  EXPECT_EQ(d.Sign(), a.Sign()); // for 0.0 != -0.0
345  EXPECT_DOUBLE_EQ(d.Value(), h.actual_);
346  }
347  }
348  }
349  }
350 
351  // Issue #340
352  TEST_DOUBLE(fullPrecision, "7.450580596923828e-9", 7.450580596923828e-9);
353  {
354  internal::Double d(1.0);
355  for (int i = 0; i < 324; i++) {
356  char buffer[32];
357  *internal::dtoa(d.Value(), buffer) = '\0';
358 
359  StringStream s(buffer);
361  Reader reader;
362  ASSERT_EQ(kParseErrorNone, reader.Parse<fullPrecision ? kParseFullPrecisionFlag : 0>(s, h).Code());
363  EXPECT_EQ(1u, h.step_);
365  if (fullPrecision) {
366  EXPECT_EQ(d.Uint64Value(), a.Uint64Value());
367  if (d.Uint64Value() != a.Uint64Value())
368  printf(" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.actual_, d.Value());
369  }
370  else {
371  EXPECT_EQ(d.Sign(), a.Sign()); // for 0.0 != -0.0
372  EXPECT_DOUBLE_EQ(d.Value(), h.actual_);
373  }
374 
375 
376  d = d.Value() * 0.5;
377  }
378  }
379 #undef TEST_DOUBLE
380 }
381 
382 TEST(Reader, ParseNumber_NormalPrecisionDouble) {
383  TestParseDouble<false>();
384 }
385 
386 TEST(Reader, ParseNumber_FullPrecisionDouble) {
387  TestParseDouble<true>();
388 }
389 
390 TEST(Reader, ParseNumber_NormalPrecisionError) {
391  static unsigned count = 1000000;
392  Random r;
393 
394  double ulpSum = 0.0;
395  double ulpMax = 0.0;
396  for (unsigned i = 0; i < count; i++) {
397  internal::Double e, a;
398  do {
399  // Need to call r() in two statements for cross-platform coherent sequence.
400  uint64_t u = uint64_t(r()) << 32;
401  u |= uint64_t(r());
402  e = u;
403  } while (e.IsNan() || e.IsInf() || !e.IsNormal());
404 
405  char buffer[32];
406  *internal::dtoa(e.Value(), buffer) = '\0';
407 
408  StringStream s(buffer);
410  Reader reader;
411  ASSERT_EQ(kParseErrorNone, reader.Parse(s, h).Code());
412  EXPECT_EQ(1u, h.step_);
413 
414  a = h.actual_;
415  uint64_t bias1 = e.ToBias();
416  uint64_t bias2 = a.ToBias();
417  double ulp = static_cast<double>(bias1 >= bias2 ? bias1 - bias2 : bias2 - bias1);
418  ulpMax = std::max(ulpMax, ulp);
419  ulpSum += ulp;
420  }
421  printf("ULP Average = %g, Max = %g \n", ulpSum / count, ulpMax);
422 }
423 
424 TEST(Reader, ParseNumber_Error) {
425 #define TEST_NUMBER_ERROR(errorCode, str, errorOffset, streamPos) \
426  { \
427  char buffer[1001]; \
428  sprintf(buffer, "%s", str); \
429  InsituStringStream s(buffer); \
430  BaseReaderHandler<> h; \
431  Reader reader; \
432  EXPECT_FALSE(reader.Parse(s, h)); \
433  EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
434  EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
435  EXPECT_EQ(streamPos, s.Tell());\
436  }
437 
438  // Number too big to be stored in double.
439  {
440  char n1e309[311]; // '1' followed by 309 '0'
441  n1e309[0] = '1';
442  for (int i = 1; i < 310; i++)
443  n1e309[i] = '0';
444  n1e309[310] = '\0';
446  }
448 
449  // Miss fraction part in number.
452 
453  // Miss exponent in number.
456 
457 #undef TEST_NUMBER_ERROR
458 }
459 
460 template <typename Encoding>
461 struct ParseStringHandler : BaseReaderHandler<Encoding, ParseStringHandler<Encoding> > {
462  ParseStringHandler() : str_(0), length_(0), copy_() {}
463  ~ParseStringHandler() { EXPECT_TRUE(str_ != 0); if (copy_) free(const_cast<typename Encoding::Ch*>(str_)); }
464 
466  ParseStringHandler& operator=(const ParseStringHandler&);
467 
468  bool Default() { ADD_FAILURE(); return false; }
469  bool String(const typename Encoding::Ch* str, size_t length, bool copy) {
470  EXPECT_EQ(0, str_);
471  if (copy) {
472  str_ = static_cast<typename Encoding::Ch*>(malloc((length + 1) * sizeof(typename Encoding::Ch)));
473  memcpy(const_cast<typename Encoding::Ch*>(str_), str, (length + 1) * sizeof(typename Encoding::Ch));
474  }
475  else
476  str_ = str;
477  length_ = length;
478  copy_ = copy;
479  return true;
480  }
481 
482  const typename Encoding::Ch* str_;
483  size_t length_;
484  bool copy_;
485 };
486 
487 TEST(Reader, ParseString) {
488 #define TEST_STRING(Encoding, e, x) \
489  { \
490  Encoding::Ch* buffer = StrDup(x); \
491  GenericInsituStringStream<Encoding> is(buffer); \
492  ParseStringHandler<Encoding> h; \
493  GenericReader<Encoding, Encoding> reader; \
494  reader.Parse<kParseInsituFlag | kParseValidateEncodingFlag>(is, h); \
495  EXPECT_EQ(0, StrCmp<Encoding::Ch>(e, h.str_)); \
496  EXPECT_EQ(StrLen(e), h.length_); \
497  free(buffer); \
498  GenericStringStream<Encoding> s(x); \
499  ParseStringHandler<Encoding> h2; \
500  GenericReader<Encoding, Encoding> reader2; \
501  reader2.Parse(s, h2); \
502  EXPECT_EQ(0, StrCmp<Encoding::Ch>(e, h2.str_)); \
503  EXPECT_EQ(StrLen(e), h2.length_); \
504  }
505 
506  // String constant L"\xXX" can only specify character code in bytes, which is not endianness-neutral.
507  // And old compiler does not support u"" and U"" string literal. So here specify string literal by array of Ch.
508  // In addition, GCC 4.8 generates -Wnarrowing warnings when character code >= 128 are assigned to signed integer types.
509  // Therefore, utype is added for declaring unsigned array, and then cast it to Encoding::Ch.
510 #define ARRAY(...) { __VA_ARGS__ }
511 #define TEST_STRINGARRAY(Encoding, utype, array, x) \
512  { \
513  static const utype ue[] = array; \
514  static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
515  TEST_STRING(Encoding, e, x); \
516  }
517 
518 #define TEST_STRINGARRAY2(Encoding, utype, earray, xarray) \
519  { \
520  static const utype ue[] = earray; \
521  static const utype xe[] = xarray; \
522  static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
523  static const Encoding::Ch* x = reinterpret_cast<const Encoding::Ch *>(&xe[0]); \
524  TEST_STRING(Encoding, e, x); \
525  }
526 
527  TEST_STRING(UTF8<>, "", "\"\"");
528  TEST_STRING(UTF8<>, "Hello", "\"Hello\"");
529  TEST_STRING(UTF8<>, "Hello\nWorld", "\"Hello\\nWorld\"");
530  TEST_STRING(UTF8<>, "\"\\/\b\f\n\r\t", "\"\\\"\\\\/\\b\\f\\n\\r\\t\"");
531  TEST_STRING(UTF8<>, "\x24", "\"\\u0024\""); // Dollar sign U+0024
532  TEST_STRING(UTF8<>, "\xC2\xA2", "\"\\u00A2\""); // Cents sign U+00A2
533  TEST_STRING(UTF8<>, "\xE2\x82\xAC", "\"\\u20AC\""); // Euro sign U+20AC
534  TEST_STRING(UTF8<>, "\xF0\x9D\x84\x9E", "\"\\uD834\\uDD1E\""); // G clef sign U+1D11E
535 
536  // UTF16
537  TEST_STRING(UTF16<>, L"", L"\"\"");
538  TEST_STRING(UTF16<>, L"Hello", L"\"Hello\"");
539  TEST_STRING(UTF16<>, L"Hello\nWorld", L"\"Hello\\nWorld\"");
540  TEST_STRING(UTF16<>, L"\"\\/\b\f\n\r\t", L"\"\\\"\\\\/\\b\\f\\n\\r\\t\"");
541  TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x0024, 0x0000), L"\"\\u0024\"");
542  TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x00A2, 0x0000), L"\"\\u00A2\""); // Cents sign U+00A2
543  TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0x20AC, 0x0000), L"\"\\u20AC\""); // Euro sign U+20AC
544  TEST_STRINGARRAY(UTF16<>, wchar_t, ARRAY(0xD834, 0xDD1E, 0x0000), L"\"\\uD834\\uDD1E\""); // G clef sign U+1D11E
545 
546  // UTF32
547  TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('\0'), ARRAY('\"', '\"', '\0'));
548  TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('H', 'e', 'l', 'l', 'o', '\0'), ARRAY('\"', 'H', 'e', 'l', 'l', 'o', '\"', '\0'));
549  TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('H', 'e', 'l', 'l', 'o', '\n', 'W', 'o', 'r', 'l', 'd', '\0'), ARRAY('\"', 'H', 'e', 'l', 'l', 'o', '\\', 'n', 'W', 'o', 'r', 'l', 'd', '\"', '\0'));
550  TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY('\"', '\\', '/', '\b', '\f', '\n', '\r', '\t', '\0'), ARRAY('\"', '\\', '\"', '\\', '\\', '/', '\\', 'b', '\\', 'f', '\\', 'n', '\\', 'r', '\\', 't', '\"', '\0'));
551  TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x00024, 0x0000), ARRAY('\"', '\\', 'u', '0', '0', '2', '4', '\"', '\0'));
552  TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x000A2, 0x0000), ARRAY('\"', '\\', 'u', '0', '0', 'A', '2', '\"', '\0')); // Cents sign U+00A2
553  TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x020AC, 0x0000), ARRAY('\"', '\\', 'u', '2', '0', 'A', 'C', '\"', '\0')); // Euro sign U+20AC
554  TEST_STRINGARRAY2(UTF32<>, unsigned, ARRAY(0x1D11E, 0x0000), ARRAY('\"', '\\', 'u', 'D', '8', '3', '4', '\\', 'u', 'D', 'D', '1', 'E', '\"', '\0')); // G clef sign U+1D11E
555 
556 #undef TEST_STRINGARRAY
557 #undef ARRAY
558 #undef TEST_STRING
559 
560  // Support of null character in string
561  {
562  StringStream s("\"Hello\\u0000World\"");
563  const char e[] = "Hello\0World";
565  Reader reader;
566  reader.Parse(s, h);
567  EXPECT_EQ(0, memcmp(e, h.str_, h.length_ + 1));
568  EXPECT_EQ(11u, h.length_);
569  }
570 }
571 
572 TEST(Reader, ParseString_Transcoding) {
573  const char* x = "\"Hello\"";
574  const wchar_t* e = L"Hello";
576  GenericReader<UTF8<>, UTF16<> > reader;
578  reader.Parse(is, h);
579  EXPECT_EQ(0, StrCmp<UTF16<>::Ch>(e, h.str_));
580  EXPECT_EQ(StrLen(e), h.length_);
581 }
582 
583 TEST(Reader, ParseString_TranscodingWithValidation) {
584  const char* x = "\"Hello\"";
585  const wchar_t* e = L"Hello";
587  GenericReader<UTF8<>, UTF16<> > reader;
589  reader.Parse<kParseValidateEncodingFlag>(is, h);
590  EXPECT_EQ(0, StrCmp<UTF16<>::Ch>(e, h.str_));
591  EXPECT_EQ(StrLen(e), h.length_);
592 }
593 
594 TEST(Reader, ParseString_NonDestructive) {
595  StringStream s("\"Hello\\nWorld\"");
597  Reader reader;
598  reader.Parse(s, h);
599  EXPECT_EQ(0, StrCmp("Hello\nWorld", h.str_));
600  EXPECT_EQ(11u, h.length_);
601 }
602 
603 template <typename Encoding>
604 ParseErrorCode TestString(const typename Encoding::Ch* str) {
608  reader.template Parse<kParseValidateEncodingFlag>(s, h);
609  return reader.GetParseErrorCode();
610 }
611 
612 TEST(Reader, ParseString_Error) {
613 #define TEST_STRING_ERROR(errorCode, str, errorOffset, streamPos)\
614 {\
615  GenericStringStream<UTF8<> > s(str);\
616  BaseReaderHandler<UTF8<> > h;\
617  GenericReader<UTF8<> , UTF8<> > reader;\
618  reader.Parse<kParseValidateEncodingFlag>(s, h);\
619  EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
620  EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
621  EXPECT_EQ(streamPos, s.Tell());\
622 }
623 
624 #define ARRAY(...) { __VA_ARGS__ }
625 #define TEST_STRINGENCODING_ERROR(Encoding, TargetEncoding, utype, array) \
626  { \
627  static const utype ue[] = array; \
628  static const Encoding::Ch* e = reinterpret_cast<const Encoding::Ch *>(&ue[0]); \
629  EXPECT_EQ(kParseErrorStringInvalidEncoding, TestString<Encoding>(e));\
630  /* decode error */\
631  GenericStringStream<Encoding> s(e);\
632  BaseReaderHandler<TargetEncoding> h;\
633  GenericReader<Encoding, TargetEncoding> reader;\
634  reader.Parse(s, h);\
635  EXPECT_EQ(kParseErrorStringInvalidEncoding, reader.GetParseErrorCode());\
636  }
637 
638  // Invalid escape character in string.
640 
641  // Incorrect hex digit after \\u escape in string.
643 
644  // Quotation in \\u escape in string (Issue #288)
646  TEST_STRING_ERROR(kParseErrorStringUnicodeEscapeInvalidHex, "[\"\\uD800\\uFFF\"]", 2, 13);
647 
648  // The surrogate pair in string is invalid.
650  TEST_STRING_ERROR(kParseErrorStringUnicodeSurrogateInvalid, "[\"\\uD800\\uFFFF\"]", 2, 14);
651 
652  // Missing a closing quotation mark in string.
654 
655  // http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
656 
657  // 3 Malformed sequences
658 
659  // 3.1 Unexpected continuation bytes
660  {
661  char e[] = { '[', '\"', 0, '\"', ']', '\0' };
662  for (unsigned char c = 0x80u; c <= 0xBFu; c++) {
663  e[2] = static_cast<char>(c);
664  ParseErrorCode error = TestString<UTF8<> >(e);
665  EXPECT_EQ(kParseErrorStringInvalidEncoding, error);
667  std::cout << static_cast<unsigned>(c) << std::endl;
668  }
669  }
670 
671  // 3.2 Lonely start characters, 3.5 Impossible bytes
672  {
673  char e[] = { '[', '\"', 0, ' ', '\"', ']', '\0' };
674  for (unsigned c = 0xC0u; c <= 0xFFu; c++) {
675  e[2] = static_cast<char>(c);
676  int streamPos;
677  if (c <= 0xC1u)
678  streamPos = 3; // 0xC0 - 0xC1
679  else if (c <= 0xDFu)
680  streamPos = 4; // 0xC2 - 0xDF
681  else if (c <= 0xEFu)
682  streamPos = 5; // 0xE0 - 0xEF
683  else if (c <= 0xF4u)
684  streamPos = 6; // 0xF0 - 0xF4
685  else
686  streamPos = 3; // 0xF5 - 0xFF
688  }
689  }
690 
691  // 4 Overlong sequences
692 
693  // 4.1 Examples of an overlong ASCII character
694  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0xAFu, '\"', ']', '\0'));
695  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0xAFu, '\"', ']', '\0'));
696  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0xAFu, '\"', ']', '\0'));
697 
698  // 4.2 Maximum overlong sequences
699  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC1u, 0xBFu, '\"', ']', '\0'));
700  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x9Fu, 0xBFu, '\"', ']', '\0'));
701  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x8Fu, 0xBFu, 0xBFu, '\"', ']', '\0'));
702 
703  // 4.3 Overlong representation of the NUL character
704  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0x80u, '\"', ']', '\0'));
705  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0x80u, '\"', ']', '\0'));
706  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0x80u, '\"', ']', '\0'));
707 
708  // 5 Illegal code positions
709 
710  // 5.1 Single UTF-16 surrogates
711  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xA0u, 0x80u, '\"', ']', '\0'));
712  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xADu, 0xBFu, '\"', ']', '\0'));
713  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xAEu, 0x80u, '\"', ']', '\0'));
714  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xAFu, 0xBFu, '\"', ']', '\0'));
715  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xB0u, 0x80u, '\"', ']', '\0'));
716  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xBEu, 0x80u, '\"', ']', '\0'));
717  TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xEDu, 0xBFu, 0xBFu, '\"', ']', '\0'));
718 
719  // Malform UTF-16 sequences
720  TEST_STRINGENCODING_ERROR(UTF16<>, UTF8<>, wchar_t, ARRAY('[', '\"', 0xDC00, 0xDC00, '\"', ']', '\0'));
721  TEST_STRINGENCODING_ERROR(UTF16<>, UTF8<>, wchar_t, ARRAY('[', '\"', 0xD800, 0xD800, '\"', ']', '\0'));
722 
723  // Malform UTF-32 sequence
724  TEST_STRINGENCODING_ERROR(UTF32<>, UTF8<>, unsigned, ARRAY('[', '\"', 0x110000, '\"', ']', '\0'));
725 
726  // Malform ASCII sequence
727  TEST_STRINGENCODING_ERROR(ASCII<>, UTF8<>, char, ARRAY('[', '\"', char(0x80u), '\"', ']', '\0'));
728  TEST_STRINGENCODING_ERROR(ASCII<>, UTF8<>, char, ARRAY('[', '\"', char(0x01u), '\"', ']', '\0'));
729  TEST_STRINGENCODING_ERROR(ASCII<>, UTF8<>, char, ARRAY('[', '\"', char(0x1Cu), '\"', ']', '\0'));
730 
731 #undef ARRAY
732 #undef TEST_STRINGARRAY_ERROR
733 }
734 
735 template <unsigned count>
736 struct ParseArrayHandler : BaseReaderHandler<UTF8<>, ParseArrayHandler<count> > {
737  ParseArrayHandler() : step_(0) {}
738 
739  bool Default() { ADD_FAILURE(); return false; }
740  bool Uint(unsigned i) { EXPECT_EQ(step_, i); step_++; return true; }
741  bool StartArray() { EXPECT_EQ(0u, step_); step_++; return true; }
742  bool EndArray(SizeType) { step_++; return true; }
743 
744  unsigned step_;
745 };
746 
747 TEST(Reader, ParseEmptyArray) {
748  char *json = StrDup("[ ] ");
749  InsituStringStream s(json);
751  Reader reader;
752  reader.Parse(s, h);
753  EXPECT_EQ(2u, h.step_);
754  free(json);
755 }
756 
757 TEST(Reader, ParseArray) {
758  char *json = StrDup("[1, 2, 3, 4]");
759  InsituStringStream s(json);
761  Reader reader;
762  reader.Parse(s, h);
763  EXPECT_EQ(6u, h.step_);
764  free(json);
765 }
766 
767 TEST(Reader, ParseArray_Error) {
768 #define TEST_ARRAY_ERROR(errorCode, str, errorOffset) \
769  { \
770  int streamPos = errorOffset; \
771  char buffer[1001]; \
772  strncpy(buffer, str, 1000); \
773  InsituStringStream s(buffer); \
774  BaseReaderHandler<> h; \
775  GenericReader<UTF8<>, UTF8<>, CrtAllocator> reader; \
776  EXPECT_FALSE(reader.Parse(s, h)); \
777  EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
778  EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
779  EXPECT_EQ(streamPos, s.Tell());\
780  }
781 
782  // Missing a comma or ']' after an array element.
786 
787  // Array cannot have a trailing comma (without kParseTrailingCommasFlag);
788  // a value must follow a comma
790 
791 #undef TEST_ARRAY_ERROR
792 }
793 
794 struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> {
795  ParseObjectHandler() : step_(0) {}
796 
797  bool Default() { ADD_FAILURE(); return false; }
798  bool Null() { EXPECT_EQ(8u, step_); step_++; return true; }
799  bool Bool(bool b) {
800  switch(step_) {
801  case 4: EXPECT_TRUE(b); step_++; return true;
802  case 6: EXPECT_FALSE(b); step_++; return true;
803  default: ADD_FAILURE(); return false;
804  }
805  }
806  bool Int(int i) {
807  switch(step_) {
808  case 10: EXPECT_EQ(123, i); step_++; return true;
809  case 15: EXPECT_EQ(1, i); step_++; return true;
810  case 16: EXPECT_EQ(2, i); step_++; return true;
811  case 17: EXPECT_EQ(3, i); step_++; return true;
812  default: ADD_FAILURE(); return false;
813  }
814  }
815  bool Uint(unsigned i) { return Int(static_cast<int>(i)); }
816  bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_DOUBLE_EQ(3.1416, d); step_++; return true; }
817  bool String(const char* str, size_t, bool) {
818  switch(step_) {
819  case 1: EXPECT_STREQ("hello", str); step_++; return true;
820  case 2: EXPECT_STREQ("world", str); step_++; return true;
821  case 3: EXPECT_STREQ("t", str); step_++; return true;
822  case 5: EXPECT_STREQ("f", str); step_++; return true;
823  case 7: EXPECT_STREQ("n", str); step_++; return true;
824  case 9: EXPECT_STREQ("i", str); step_++; return true;
825  case 11: EXPECT_STREQ("pi", str); step_++; return true;
826  case 13: EXPECT_STREQ("a", str); step_++; return true;
827  default: ADD_FAILURE(); return false;
828  }
829  }
830  bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
831  bool EndObject(SizeType memberCount) { EXPECT_EQ(19u, step_); EXPECT_EQ(7u, memberCount); step_++; return true; }
832  bool StartArray() { EXPECT_EQ(14u, step_); step_++; return true; }
833  bool EndArray(SizeType elementCount) { EXPECT_EQ(18u, step_); EXPECT_EQ(3u, elementCount); step_++; return true; }
834 
835  unsigned step_;
836 };
837 
838 TEST(Reader, ParseObject) {
839  const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
840 
841  // Insitu
842  {
843  char* json2 = StrDup(json);
844  InsituStringStream s(json2);
846  Reader reader;
847  reader.Parse<kParseInsituFlag>(s, h);
848  EXPECT_EQ(20u, h.step_);
849  free(json2);
850  }
851 
852  // Normal
853  {
854  StringStream s(json);
856  Reader reader;
857  reader.Parse(s, h);
858  EXPECT_EQ(20u, h.step_);
859  }
860 }
861 
862 struct ParseEmptyObjectHandler : BaseReaderHandler<UTF8<>, ParseEmptyObjectHandler> {
863  ParseEmptyObjectHandler() : step_(0) {}
864 
865  bool Default() { ADD_FAILURE(); return false; }
866  bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
867  bool EndObject(SizeType) { EXPECT_EQ(1u, step_); step_++; return true; }
868 
869  unsigned step_;
870 };
871 
872 TEST(Reader, Parse_EmptyObject) {
873  StringStream s("{ } ");
875  Reader reader;
876  reader.Parse(s, h);
877  EXPECT_EQ(2u, h.step_);
878 }
879 
880 struct ParseMultipleRootHandler : BaseReaderHandler<UTF8<>, ParseMultipleRootHandler> {
881  ParseMultipleRootHandler() : step_(0) {}
882 
883  bool Default() { ADD_FAILURE(); return false; }
884  bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; }
885  bool EndObject(SizeType) { EXPECT_EQ(1u, step_); step_++; return true; }
886  bool StartArray() { EXPECT_EQ(2u, step_); step_++; return true; }
887  bool EndArray(SizeType) { EXPECT_EQ(3u, step_); step_++; return true; }
888 
889  unsigned step_;
890 };
891 
892 template <unsigned parseFlags>
894  StringStream s("{}[] a");
896  Reader reader;
897  EXPECT_TRUE(reader.Parse<parseFlags>(s, h));
898  EXPECT_EQ(2u, h.step_);
899  EXPECT_TRUE(reader.Parse<parseFlags>(s, h));
900  EXPECT_EQ(4u, h.step_);
901  EXPECT_EQ(' ', s.Take());
902  EXPECT_EQ('a', s.Take());
903 }
904 
905 TEST(Reader, Parse_MultipleRoot) {
906  TestMultipleRoot<kParseStopWhenDoneFlag>();
907 }
908 
909 TEST(Reader, ParseIterative_MultipleRoot) {
910  TestMultipleRoot<kParseIterativeFlag | kParseStopWhenDoneFlag>();
911 }
912 
913 template <unsigned parseFlags>
915  char* buffer = strdup("{}[] a");
916  InsituStringStream s(buffer);
918  Reader reader;
919  EXPECT_TRUE(reader.Parse<kParseInsituFlag | parseFlags>(s, h));
920  EXPECT_EQ(2u, h.step_);
921  EXPECT_TRUE(reader.Parse<kParseInsituFlag | parseFlags>(s, h));
922  EXPECT_EQ(4u, h.step_);
923  EXPECT_EQ(' ', s.Take());
924  EXPECT_EQ('a', s.Take());
925  free(buffer);
926 }
927 
928 TEST(Reader, ParseInsitu_MultipleRoot) {
929  TestInsituMultipleRoot<kParseStopWhenDoneFlag>();
930 }
931 
932 TEST(Reader, ParseInsituIterative_MultipleRoot) {
933  TestInsituMultipleRoot<kParseIterativeFlag | kParseStopWhenDoneFlag>();
934 }
935 
936 #define TEST_ERROR(errorCode, str, errorOffset) \
937  { \
938  int streamPos = errorOffset; \
939  char buffer[1001]; \
940  strncpy(buffer, str, 1000); \
941  InsituStringStream s(buffer); \
942  BaseReaderHandler<> h; \
943  Reader reader; \
944  EXPECT_FALSE(reader.Parse(s, h)); \
945  EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
946  EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
947  EXPECT_EQ(streamPos, s.Tell());\
948  }
949 
950 TEST(Reader, ParseDocument_Error) {
951  // The document is empty.
955 
956  // The document root must not follow by other values.
961 }
962 
963 TEST(Reader, ParseValue_Error) {
964  // Invalid value.
967  TEST_ERROR(kParseErrorValueInvalid, "falsE", 4);
970 }
971 
972 TEST(Reader, ParseObject_Error) {
973  // Missing a name for object member.
976  TEST_ERROR(kParseErrorObjectMissName, "{null:1}", 1);
977  TEST_ERROR(kParseErrorObjectMissName, "{true:1}", 1);
978  TEST_ERROR(kParseErrorObjectMissName, "{false:1}", 1);
982  TEST_ERROR(kParseErrorObjectMissName, "{xyz:1}", 1);
983 
984  // Missing a colon after a name of object member.
985  TEST_ERROR(kParseErrorObjectMissColon, "{\"a\" 1}", 5);
986  TEST_ERROR(kParseErrorObjectMissColon, "{\"a\",1}", 4);
987 
988  // Must be a comma or '}' after an object member
990 
991  // Object cannot have a trailing comma (without kParseTrailingCommasFlag);
992  // an object member name must follow a comma
993  TEST_ERROR(kParseErrorObjectMissName, "{\"a\":1,}", 7);
994 
995  // This tests that MemoryStream is checking the length in Peek().
996  {
997  MemoryStream ms("{\"a\"", 1);
999  Reader reader;
1000  EXPECT_FALSE(reader.Parse<kParseStopWhenDoneFlag>(ms, h));
1001  EXPECT_EQ(kParseErrorObjectMissName, reader.GetParseErrorCode());
1002  }
1003 }
1004 
1005 #undef TEST_ERROR
1006 
1008  StringStream ss(" A \t\tB\n \n\nC\r\r \rD \t\n\r E");
1009  const char* expected = "ABCDE";
1010  for (size_t i = 0; i < 5; i++) {
1011  SkipWhitespace(ss);
1012  EXPECT_EQ(expected[i], ss.Take());
1013  }
1014 }
1015 
1016 // Test implementing a stream without copy stream optimization.
1017 // Clone from GenericStringStream except that copy constructor is disabled.
1018 template <typename Encoding>
1020 public:
1021  typedef typename Encoding::Ch Ch;
1022 
1023  CustomStringStream(const Ch *src) : src_(src), head_(src) {}
1024 
1025  Ch Peek() const { return *src_; }
1026  Ch Take() { return *src_++; }
1027  size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1028 
1029  Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
1030  void Put(Ch) { RAPIDJSON_ASSERT(false); }
1031  void Flush() { RAPIDJSON_ASSERT(false); }
1032  size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
1033 
1034 private:
1035  // Prohibit copy constructor & assignment operator.
1037  CustomStringStream& operator=(const CustomStringStream&);
1038 
1039  const Ch* src_;
1040  const Ch* head_;
1041 };
1042 
1043 // If the following code is compiled, it should generate compilation error as predicted.
1044 // Because CustomStringStream<> is not copyable via making copy constructor private.
1045 #if 0
1046 namespace rapidjson {
1047 
1048 template <typename Encoding>
1049 struct StreamTraits<CustomStringStream<Encoding> > {
1050  enum { copyOptimization = 1 };
1051 };
1052 
1053 } // namespace rapidjson
1054 #endif
1055 
1057  const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
1060  Reader reader;
1061  reader.Parse(s, h);
1062  EXPECT_EQ(20u, h.step_);
1063 }
1064 
1065 #include <sstream>
1066 
1068 public:
1069  typedef char Ch;
1070 
1071  IStreamWrapper(std::istream& is) : is_(is) {}
1072 
1073  Ch Peek() const {
1074  int c = is_.peek();
1075  return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
1076  }
1077 
1078  Ch Take() {
1079  int c = is_.get();
1080  return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
1081  }
1082 
1083  size_t Tell() const { return static_cast<size_t>(is_.tellg()); }
1084 
1085  Ch* PutBegin() { assert(false); return 0; }
1086  void Put(Ch) { assert(false); }
1087  void Flush() { assert(false); }
1088  size_t PutEnd(Ch*) { assert(false); return 0; }
1089 
1090 private:
1092  IStreamWrapper& operator=(const IStreamWrapper&);
1093 
1094  std::istream& is_;
1095 };
1096 
1097 TEST(Reader, Parse_IStreamWrapper_StringStream) {
1098  const char* json = "[1,2,3,4]";
1099 
1100  std::stringstream ss(json);
1101  IStreamWrapper is(ss);
1102 
1103  Reader reader;
1105  reader.Parse(is, h);
1106  EXPECT_FALSE(reader.HasParseError());
1107 }
1108 
1109 // Test iterative parsing.
1110 
1111 #define TESTERRORHANDLING(text, errorCode, offset)\
1112 {\
1113  int streamPos = offset; \
1114  StringStream json(text); \
1115  BaseReaderHandler<> handler; \
1116  Reader reader; \
1117  reader.Parse<kParseIterativeFlag>(json, handler); \
1118  EXPECT_TRUE(reader.HasParseError()); \
1119  EXPECT_EQ(errorCode, reader.GetParseErrorCode()); \
1120  EXPECT_EQ(offset, reader.GetErrorOffset()); \
1121  EXPECT_EQ(streamPos, json.Tell()); \
1122 }
1123 
1124 TEST(Reader, IterativeParsing_ErrorHandling) {
1125  TESTERRORHANDLING("{\"a\": a}", kParseErrorValueInvalid, 6u);
1126 
1129 
1131  TESTERRORHANDLING("{\"a\", 1}", kParseErrorObjectMissColon, 4u);
1136  TESTERRORHANDLING("{\"a\":}", kParseErrorValueInvalid, 5u);
1137  TESTERRORHANDLING("{\"a\":]", kParseErrorValueInvalid, 5u);
1142 
1143  // Trailing commas are not allowed without kParseTrailingCommasFlag
1144  TESTERRORHANDLING("{\"a\": 1,}", kParseErrorObjectMissName, 8u);
1145  TESTERRORHANDLING("[1,2,3,]", kParseErrorValueInvalid, 7u);
1146 
1147  // Any JSON value can be a valid root element in RFC7159.
1156 }
1157 
1158 template<typename Encoding = UTF8<> >
1160  typedef typename Encoding::Ch Ch;
1161 
1162  const static uint32_t LOG_NULL = 0x10000000;
1163  const static uint32_t LOG_BOOL = 0x20000000;
1164  const static uint32_t LOG_INT = 0x30000000;
1165  const static uint32_t LOG_UINT = 0x40000000;
1166  const static uint32_t LOG_INT64 = 0x50000000;
1167  const static uint32_t LOG_UINT64 = 0x60000000;
1168  const static uint32_t LOG_DOUBLE = 0x70000000;
1169  const static uint32_t LOG_STRING = 0x80000000;
1170  const static uint32_t LOG_STARTOBJECT = 0x90000000;
1171  const static uint32_t LOG_KEY = 0xA0000000;
1172  const static uint32_t LOG_ENDOBJECT = 0xB0000000;
1173  const static uint32_t LOG_STARTARRAY = 0xC0000000;
1174  const static uint32_t LOG_ENDARRAY = 0xD0000000;
1175 
1176  const static size_t LogCapacity = 256;
1177  uint32_t Logs[LogCapacity];
1178  size_t LogCount;
1179 
1181  }
1182 
1183  bool Null() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_NULL; return true; }
1184 
1185  bool Bool(bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_BOOL; return true; }
1186 
1187  bool Int(int) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT; return true; }
1188 
1189  bool Uint(unsigned) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT; return true; }
1190 
1191  bool Int64(int64_t) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_INT64; return true; }
1192 
1193  bool Uint64(uint64_t) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_UINT64; return true; }
1194 
1195  bool Double(double) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_DOUBLE; return true; }
1196 
1197  bool RawNumber(const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STRING; return true; }
1198 
1199  bool String(const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STRING; return true; }
1200 
1201  bool StartObject() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTOBJECT; return true; }
1202 
1203  bool Key (const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_KEY; return true; }
1204 
1206  RAPIDJSON_ASSERT(LogCount < LogCapacity);
1207  RAPIDJSON_ASSERT((static_cast<uint32_t>(c) & 0xF0000000) == 0);
1208  Logs[LogCount++] = LOG_ENDOBJECT | static_cast<uint32_t>(c);
1209  return true;
1210  }
1211 
1212  bool StartArray() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTARRAY; return true; }
1213 
1214  bool EndArray(SizeType c) {
1215  RAPIDJSON_ASSERT(LogCount < LogCapacity);
1216  RAPIDJSON_ASSERT((static_cast<uint32_t>(c) & 0xF0000000) == 0);
1217  Logs[LogCount++] = LOG_ENDARRAY | static_cast<uint32_t>(c);
1218  return true;
1219  }
1220 };
1221 
1222 TEST(Reader, IterativeParsing_General) {
1223  {
1224  StringStream is("[1, {\"k\": [1, 2]}, null, false, true, \"string\", 1.2]");
1225  Reader reader;
1227 
1228  ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1229 
1230  EXPECT_FALSE(r.IsError());
1231  EXPECT_FALSE(reader.HasParseError());
1232 
1233  uint32_t e[] = {
1234  handler.LOG_STARTARRAY,
1235  handler.LOG_INT,
1236  handler.LOG_STARTOBJECT,
1237  handler.LOG_KEY,
1238  handler.LOG_STARTARRAY,
1239  handler.LOG_INT,
1240  handler.LOG_INT,
1241  handler.LOG_ENDARRAY | 2,
1242  handler.LOG_ENDOBJECT | 1,
1243  handler.LOG_NULL,
1244  handler.LOG_BOOL,
1245  handler.LOG_BOOL,
1246  handler.LOG_STRING,
1247  handler.LOG_DOUBLE,
1248  handler.LOG_ENDARRAY | 7
1249  };
1250 
1251  EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
1252 
1253  for (size_t i = 0; i < handler.LogCount; ++i) {
1254  EXPECT_EQ(e[i], handler.Logs[i]) << "i = " << i;
1255  }
1256  }
1257 }
1258 
1259 TEST(Reader, IterativeParsing_Count) {
1260  {
1261  StringStream is("[{}, {\"k\": 1}, [1], []]");
1262  Reader reader;
1264 
1265  ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1266 
1267  EXPECT_FALSE(r.IsError());
1268  EXPECT_FALSE(reader.HasParseError());
1269 
1270  uint32_t e[] = {
1271  handler.LOG_STARTARRAY,
1272  handler.LOG_STARTOBJECT,
1273  handler.LOG_ENDOBJECT | 0,
1274  handler.LOG_STARTOBJECT,
1275  handler.LOG_KEY,
1276  handler.LOG_INT,
1277  handler.LOG_ENDOBJECT | 1,
1278  handler.LOG_STARTARRAY,
1279  handler.LOG_INT,
1280  handler.LOG_ENDARRAY | 1,
1281  handler.LOG_STARTARRAY,
1282  handler.LOG_ENDARRAY | 0,
1283  handler.LOG_ENDARRAY | 4
1284  };
1285 
1286  EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
1287 
1288  for (size_t i = 0; i < handler.LogCount; ++i) {
1289  EXPECT_EQ(e[i], handler.Logs[i]) << "i = " << i;
1290  }
1291  }
1292 }
1293 
1294 TEST(Reader, IterativePullParsing_General) {
1295  {
1297  uint32_t e[] = {
1298  handler.LOG_STARTARRAY,
1299  handler.LOG_INT,
1300  handler.LOG_STARTOBJECT,
1301  handler.LOG_KEY,
1302  handler.LOG_STARTARRAY,
1303  handler.LOG_INT,
1304  handler.LOG_INT,
1305  handler.LOG_ENDARRAY | 2,
1306  handler.LOG_ENDOBJECT | 1,
1307  handler.LOG_NULL,
1308  handler.LOG_BOOL,
1309  handler.LOG_BOOL,
1310  handler.LOG_STRING,
1311  handler.LOG_DOUBLE,
1312  handler.LOG_ENDARRAY | 7
1313  };
1314 
1315  StringStream is("[1, {\"k\": [1, 2]}, null, false, true, \"string\", 1.2]");
1316  Reader reader;
1317 
1318  reader.IterativeParseInit();
1319  while (!reader.IterativeParseComplete()) {
1320  size_t oldLogCount = handler.LogCount;
1321  EXPECT_TRUE(oldLogCount < sizeof(e) / sizeof(int)) << "overrun";
1322 
1323  EXPECT_TRUE(reader.IterativeParseNext<kParseDefaultFlags>(is, handler)) << "parse fail";
1324  EXPECT_EQ(handler.LogCount, oldLogCount + 1) << "handler should be invoked exactly once each time";
1325  EXPECT_EQ(e[oldLogCount], handler.Logs[oldLogCount]) << "wrong event returned";
1326  }
1327 
1328  EXPECT_FALSE(reader.HasParseError());
1329  EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount) << "handler invoked wrong number of times";
1330 
1331  // The handler should not be invoked when the JSON has been fully read, but it should not fail
1332  size_t oldLogCount = handler.LogCount;
1333  EXPECT_TRUE(reader.IterativeParseNext<kParseDefaultFlags>(is, handler)) << "parse-next past complete is allowed";
1334  EXPECT_EQ(handler.LogCount, oldLogCount) << "parse-next past complete should not invoke handler";
1335  EXPECT_FALSE(reader.HasParseError()) << "parse-next past complete should not generate parse error";
1336  }
1337 }
1338 
1339 // Test iterative parsing on kParseErrorTermination.
1341  bool StartObject() { return false; }
1342 };
1343 
1345  bool StartArray() { return false; }
1346 };
1347 
1349  bool EndObject(SizeType) { return false; }
1350 };
1351 
1353  bool EndArray(SizeType) { return false; }
1354 };
1355 
1356 TEST(Reader, IterativeParsing_ShortCircuit) {
1357  {
1359  Reader reader;
1360  StringStream is("[1, {}]");
1361 
1362  ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1363 
1364  EXPECT_TRUE(reader.HasParseError());
1365  EXPECT_EQ(kParseErrorTermination, r.Code());
1366  EXPECT_EQ(4u, r.Offset());
1367  }
1368 
1369  {
1371  Reader reader;
1372  StringStream is("{\"a\": []}");
1373 
1374  ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1375 
1376  EXPECT_TRUE(reader.HasParseError());
1377  EXPECT_EQ(kParseErrorTermination, r.Code());
1378  EXPECT_EQ(6u, r.Offset());
1379  }
1380 
1381  {
1383  Reader reader;
1384  StringStream is("[1, {}]");
1385 
1386  ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1387 
1388  EXPECT_TRUE(reader.HasParseError());
1389  EXPECT_EQ(kParseErrorTermination, r.Code());
1390  EXPECT_EQ(5u, r.Offset());
1391  }
1392 
1393  {
1395  Reader reader;
1396  StringStream is("{\"a\": []}");
1397 
1398  ParseResult r = reader.Parse<kParseIterativeFlag>(is, handler);
1399 
1400  EXPECT_TRUE(reader.HasParseError());
1401  EXPECT_EQ(kParseErrorTermination, r.Code());
1402  EXPECT_EQ(7u, r.Offset());
1403  }
1404 }
1405 
1406 // For covering BaseReaderHandler default functions
1407 TEST(Reader, BaseReaderHandler_Default) {
1409  Reader reader;
1410  StringStream is("[null, true, -1, 1, -1234567890123456789, 1234567890123456789, 3.14, \"s\", { \"a\" : 1 }]");
1411  EXPECT_TRUE(reader.Parse(is, h));
1412 }
1413 
1414 template <int e>
1416  bool Null() { return e != 0; }
1417  bool Bool(bool) { return e != 1; }
1418  bool Int(int) { return e != 2; }
1419  bool Uint(unsigned) { return e != 3; }
1420  bool Int64(int64_t) { return e != 4; }
1421  bool Uint64(uint64_t) { return e != 5; }
1422  bool Double(double) { return e != 6; }
1423  bool RawNumber(const char*, SizeType, bool) { return e != 7; }
1424  bool String(const char*, SizeType, bool) { return e != 8; }
1425  bool StartObject() { return e != 9; }
1426  bool Key(const char*, SizeType, bool) { return e != 10; }
1427  bool EndObject(SizeType) { return e != 11; }
1428  bool StartArray() { return e != 12; }
1429  bool EndArray(SizeType) { return e != 13; }
1430 };
1431 
1432 #define TEST_TERMINATION(e, json)\
1433 {\
1434  Reader reader;\
1435  TerminateHandler<e> h;\
1436  StringStream is(json);\
1437  EXPECT_FALSE(reader.Parse(is, h));\
1438  EXPECT_EQ(kParseErrorTermination, reader.GetParseErrorCode());\
1439 }
1440 
1441 TEST(Reader, ParseTerminationByHandler) {
1442  TEST_TERMINATION(0, "[null");
1443  TEST_TERMINATION(1, "[true");
1444  TEST_TERMINATION(1, "[false");
1445  TEST_TERMINATION(2, "[-1");
1446  TEST_TERMINATION(3, "[1");
1447  TEST_TERMINATION(4, "[-1234567890123456789");
1448  TEST_TERMINATION(5, "[1234567890123456789");
1449  TEST_TERMINATION(6, "[0.5]");
1450  // RawNumber() is never called
1451  TEST_TERMINATION(8, "[\"a\"");
1452  TEST_TERMINATION(9, "[{");
1453  TEST_TERMINATION(10, "[{\"a\"");
1454  TEST_TERMINATION(11, "[{}");
1455  TEST_TERMINATION(11, "[{\"a\":1}"); // non-empty object
1456  TEST_TERMINATION(12, "{\"a\":[");
1457  TEST_TERMINATION(13, "{\"a\":[]");
1458  TEST_TERMINATION(13, "{\"a\":[1]"); // non-empty array
1459 }
1460 
1461 TEST(Reader, ParseComments) {
1462  const char* json =
1463  "// Here is a one-line comment.\n"
1464  "{// And here's another one\n"
1465  " /*And here's an in-line one.*/\"hello\" : \"world\","
1466  " \"t\" :/* And one with '*' symbol*/true ,"
1467  "/* A multiline comment\n"
1468  " goes here*/"
1469  " \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3]"
1470  "}/*And the last one to be sure */";
1471 
1472  StringStream s(json);
1474  Reader reader;
1475  EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1476  EXPECT_EQ(20u, h.step_);
1477 }
1478 
1479 TEST(Reader, ParseEmptyInlineComment) {
1480  const char* json = "{/**/\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1481 
1482  StringStream s(json);
1484  Reader reader;
1485  EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1486  EXPECT_EQ(20u, h.step_);
1487 }
1488 
1489 TEST(Reader, ParseEmptyOnelineComment) {
1490  const char* json = "{//\n\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1491 
1492  StringStream s(json);
1494  Reader reader;
1495  EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1496  EXPECT_EQ(20u, h.step_);
1497 }
1498 
1499 TEST(Reader, ParseMultipleCommentsInARow) {
1500  const char* json =
1501  "{/* first comment *//* second */\n"
1502  "/* third */ /*fourth*/// last one\n"
1503  "\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1504 
1505  StringStream s(json);
1507  Reader reader;
1508  EXPECT_TRUE(reader.Parse<kParseCommentsFlag>(s, h));
1509  EXPECT_EQ(20u, h.step_);
1510 }
1511 
1512 TEST(Reader, InlineCommentsAreDisabledByDefault) {
1513  {
1514  const char* json = "{/* Inline comment. */\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1515 
1516  StringStream s(json);
1518  Reader reader;
1519  EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
1520  }
1521 
1522  {
1523  const char* json =
1524  "{\"hello\" : /* Multiline comment starts here\n"
1525  " continues here\n"
1526  " and ends here */\"world\", \"t\" :true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1527 
1528  StringStream s(json);
1530  Reader reader;
1531  EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
1532  }
1533 }
1534 
1535 TEST(Reader, OnelineCommentsAreDisabledByDefault) {
1536  const char* json = "{// One-line comment\n\"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1537 
1538  StringStream s(json);
1540  Reader reader;
1541  EXPECT_FALSE(reader.Parse<kParseDefaultFlags>(s, h));
1542 }
1543 
1544 TEST(Reader, EofAfterOneLineComment) {
1545  const char* json = "{\"hello\" : \"world\" // EOF is here -->\0 \n}";
1546 
1547  StringStream s(json);
1549  Reader reader;
1550  EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1552 }
1553 
1554 TEST(Reader, IncompleteMultilineComment) {
1555  const char* json = "{\"hello\" : \"world\" /* EOF is here -->\0 */}";
1556 
1557  StringStream s(json);
1559  Reader reader;
1560  EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1562 }
1563 
1564 TEST(Reader, IncompleteMultilineComment2) {
1565  const char* json = "{\"hello\" : \"world\" /* *\0 */}";
1566 
1567  StringStream s(json);
1569  Reader reader;
1570  EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1572 }
1573 
1574 TEST(Reader, UnrecognizedComment) {
1575  const char* json = "{\"hello\" : \"world\" /! }";
1576 
1577  StringStream s(json);
1579  Reader reader;
1580  EXPECT_FALSE(reader.Parse<kParseCommentsFlag>(s, h));
1582 }
1583 
1585  bool Null() { return true; }
1586  bool Bool(bool) { return true; }
1587  bool Int(int) { return true; }
1588  bool Uint(unsigned) { return true; }
1589  bool Int64(int64_t) { return true; }
1590  bool Uint64(uint64_t) { return true; }
1591  bool Double(double) { return true; }
1592  // 'str' is not null-terminated
1593  bool RawNumber(const char* str, SizeType length, bool) {
1594  EXPECT_TRUE(str != 0);
1595  EXPECT_TRUE(expected_len_ == length);
1596  EXPECT_TRUE(strncmp(str, expected_, length) == 0);
1597  return true;
1598  }
1599  bool String(const char*, SizeType, bool) { return true; }
1600  bool StartObject() { return true; }
1601  bool Key(const char*, SizeType, bool) { return true; }
1602  bool EndObject(SizeType) { return true; }
1603  bool StartArray() { return true; }
1604  bool EndArray(SizeType) { return true; }
1605 
1606  NumbersAsStringsHandler(const char* expected)
1607  : expected_(expected)
1608  , expected_len_(strlen(expected)) {}
1609 
1610  const char* expected_;
1612 };
1613 
1614 TEST(Reader, NumbersAsStrings) {
1615  {
1616  const char* json = "{ \"pi\": 3.1416 } ";
1617  StringStream s(json);
1618  NumbersAsStringsHandler h("3.1416");
1619  Reader reader;
1620  EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1621  }
1622  {
1623  char* json = StrDup("{ \"pi\": 3.1416 } ");
1624  InsituStringStream s(json);
1625  NumbersAsStringsHandler h("3.1416");
1626  Reader reader;
1627  EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1628  free(json);
1629  }
1630  {
1631  const char* json = "{ \"gigabyte\": 1.0e9 } ";
1632  StringStream s(json);
1633  NumbersAsStringsHandler h("1.0e9");
1634  Reader reader;
1635  EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1636  }
1637  {
1638  char* json = StrDup("{ \"gigabyte\": 1.0e9 } ");
1639  InsituStringStream s(json);
1640  NumbersAsStringsHandler h("1.0e9");
1641  Reader reader;
1642  EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1643  free(json);
1644  }
1645  {
1646  const char* json = "{ \"pi\": 314.159e-2 } ";
1647  StringStream s(json);
1648  NumbersAsStringsHandler h("314.159e-2");
1649  Reader reader;
1650  EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1651  }
1652  {
1653  char* json = StrDup("{ \"gigabyte\": 314.159e-2 } ");
1654  InsituStringStream s(json);
1655  NumbersAsStringsHandler h("314.159e-2");
1656  Reader reader;
1657  EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1658  free(json);
1659  }
1660  {
1661  const char* json = "{ \"negative\": -1.54321 } ";
1662  StringStream s(json);
1663  NumbersAsStringsHandler h("-1.54321");
1664  Reader reader;
1665  EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1666  }
1667  {
1668  char* json = StrDup("{ \"negative\": -1.54321 } ");
1669  InsituStringStream s(json);
1670  NumbersAsStringsHandler h("-1.54321");
1671  Reader reader;
1672  EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
1673  free(json);
1674  }
1675  {
1676  const char* json = "{ \"pi\": 314.159e-2 } ";
1677  std::stringstream ss(json);
1678  IStreamWrapper s(ss);
1679  NumbersAsStringsHandler h("314.159e-2");
1680  Reader reader;
1681  EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
1682  }
1683 }
1684 
1685 template <unsigned extraFlags>
1687  {
1688  StringStream s("[1,2,3,]");
1690  Reader reader;
1691  EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
1692  EXPECT_EQ(5u, h.step_);
1693  }
1694  {
1695  const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
1696  "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3],}";
1697  StringStream s(json);
1699  Reader reader;
1700  EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
1701  EXPECT_EQ(20u, h.step_);
1702  }
1703  {
1704  // whitespace around trailing commas
1705  const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
1706  "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3\n,\n]\n,\n} ";
1707  StringStream s(json);
1709  Reader reader;
1710  EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
1711  EXPECT_EQ(20u, h.step_);
1712  }
1713  {
1714  // comments around trailing commas
1715  const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null,"
1716  "\"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3/*test*/,/*test*/]/*test*/,/*test*/}";
1717  StringStream s(json);
1719  Reader reader;
1720  EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag|kParseCommentsFlag>(s, h));
1721  EXPECT_EQ(20u, h.step_);
1722  }
1723 }
1724 
1725 TEST(Reader, TrailingCommas) {
1726  TestTrailingCommas<kParseNoFlags>();
1727 }
1728 
1729 TEST(Reader, TrailingCommasIterative) {
1730  TestTrailingCommas<kParseIterativeFlag>();
1731 }
1732 
1733 template <unsigned extraFlags>
1735  // only a single trailing comma is allowed.
1736  {
1737  StringStream s("[1,2,3,,]");
1739  Reader reader;
1740  ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1741  EXPECT_TRUE(reader.HasParseError());
1742  EXPECT_EQ(kParseErrorValueInvalid, r.Code());
1743  EXPECT_EQ(7u, r.Offset());
1744  }
1745  {
1746  const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
1747  "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3,],,}";
1748  StringStream s(json);
1750  Reader reader;
1751  ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1752  EXPECT_TRUE(reader.HasParseError());
1753  EXPECT_EQ(kParseErrorObjectMissName, r.Code());
1754  EXPECT_EQ(95u, r.Offset());
1755  }
1756 }
1757 
1758 TEST(Reader, MultipleTrailingCommaErrors) {
1759  TestMultipleTrailingCommaErrors<kParseNoFlags>();
1760 }
1761 
1762 TEST(Reader, MultipleTrailingCommaErrorsIterative) {
1763  TestMultipleTrailingCommaErrors<kParseIterativeFlag>();
1764 }
1765 
1766 template <unsigned extraFlags>
1768  // not allowed even with trailing commas enabled; the
1769  // trailing comma must follow a value.
1770  {
1771  StringStream s("[,]");
1773  Reader reader;
1774  ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1775  EXPECT_TRUE(reader.HasParseError());
1776  EXPECT_EQ(kParseErrorValueInvalid, r.Code());
1777  EXPECT_EQ(1u, r.Offset());
1778  }
1779  {
1780  StringStream s("{,}");
1782  Reader reader;
1783  ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1784  EXPECT_TRUE(reader.HasParseError());
1785  EXPECT_EQ(kParseErrorObjectMissName, r.Code());
1786  EXPECT_EQ(1u, r.Offset());
1787  }
1788 }
1789 
1790 TEST(Reader, EmptyExceptForCommaErrors) {
1791  TestEmptyExceptForCommaErrors<kParseNoFlags>();
1792 }
1793 
1794 TEST(Reader, EmptyExceptForCommaErrorsIterative) {
1795  TestEmptyExceptForCommaErrors<kParseIterativeFlag>();
1796 }
1797 
1798 template <unsigned extraFlags>
1800  {
1802  Reader reader;
1803  StringStream s("[1,2,3,]");
1804  ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1805  EXPECT_TRUE(reader.HasParseError());
1806  EXPECT_EQ(kParseErrorTermination, r.Code());
1807  EXPECT_EQ(7u, r.Offset());
1808  }
1809  {
1811  Reader reader;
1812  StringStream s("{\"t\": true, \"f\": false,}");
1813  ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
1814  EXPECT_TRUE(reader.HasParseError());
1815  EXPECT_EQ(kParseErrorTermination, r.Code());
1816  EXPECT_EQ(23u, r.Offset());
1817  }
1818 }
1819 
1820 TEST(Reader, TrailingCommaHandlerTermination) {
1821  TestTrailingCommaHandlerTermination<kParseNoFlags>();
1822 }
1823 
1824 TEST(Reader, TrailingCommaHandlerTerminationIterative) {
1825  TestTrailingCommaHandlerTermination<kParseIterativeFlag>();
1826 }
1827 
1828 TEST(Reader, ParseNanAndInfinity) {
1829 #define TEST_NAN_INF(str, x) \
1830  { \
1831  { \
1832  StringStream s(str); \
1833  ParseDoubleHandler h; \
1834  Reader reader; \
1835  ASSERT_EQ(kParseErrorNone, reader.Parse<kParseNanAndInfFlag>(s, h).Code()); \
1836  EXPECT_EQ(1u, h.step_); \
1837  internal::Double e(x), a(h.actual_); \
1838  EXPECT_EQ(e.IsNan(), a.IsNan()); \
1839  EXPECT_EQ(e.IsInf(), a.IsInf()); \
1840  if (!e.IsNan()) \
1841  EXPECT_EQ(e.Sign(), a.Sign()); \
1842  } \
1843  { \
1844  const char* json = "{ \"naninfdouble\": " str " } "; \
1845  StringStream s(json); \
1846  NumbersAsStringsHandler h(str); \
1847  Reader reader; \
1848  EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag|kParseNanAndInfFlag>(s, h)); \
1849  } \
1850  { \
1851  char* json = StrDup("{ \"naninfdouble\": " str " } "); \
1852  InsituStringStream s(json); \
1853  NumbersAsStringsHandler h(str); \
1854  Reader reader; \
1855  EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag|kParseNanAndInfFlag>(s, h)); \
1856  free(json); \
1857  } \
1858  }
1859 #define TEST_NAN_INF_ERROR(errorCode, str, errorOffset) \
1860  { \
1861  int streamPos = errorOffset; \
1862  char buffer[1001]; \
1863  strncpy(buffer, str, 1000); \
1864  InsituStringStream s(buffer); \
1865  BaseReaderHandler<> h; \
1866  Reader reader; \
1867  EXPECT_FALSE(reader.Parse<kParseNanAndInfFlag>(s, h)); \
1868  EXPECT_EQ(errorCode, reader.GetParseErrorCode());\
1869  EXPECT_EQ(errorOffset, reader.GetErrorOffset());\
1870  EXPECT_EQ(streamPos, s.Tell());\
1871  }
1872 
1873  double nan = std::numeric_limits<double>::quiet_NaN();
1874  double inf = std::numeric_limits<double>::infinity();
1875 
1876  TEST_NAN_INF("NaN", nan);
1877  TEST_NAN_INF("-NaN", nan);
1878  TEST_NAN_INF("Inf", inf);
1879  TEST_NAN_INF("Infinity", inf);
1880  TEST_NAN_INF("-Inf", -inf);
1881  TEST_NAN_INF("-Infinity", -inf);
1890 
1891 #undef TEST_NAN_INF_ERROR
1892 #undef TEST_NAN_INF
1893 }
1894 
1895 RAPIDJSON_DIAG_POP
No error.
Definition: error.h:65
d
#define TEST_INTEGER(Handler, str, x)
BasicIStreamWrapper< std::istream > IStreamWrapper
bool String(const char *, SizeType, bool)
bool Bool(bool b)
Definition: readertest.cpp:47
char * u64toa(uint64_t value, char *buffer)
Definition: itoa.h:123
unsigned step_
Definition: readertest.cpp:73
#define TEST_NAN_INF_ERROR(errorCode, str, errorOffset)
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
Definition: reader.h:558
IStreamWrapper(std::istream &is)
#define TEST_ERROR(errorCode, str, errorOffset)
Definition: readertest.cpp:936
void TestEmptyExceptForCommaErrors()
Invalid value.
Definition: error.h:70
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:389
Iterative(constant complexity in terms of function call stack size) parsing.
Definition: reader.h:151
uint32_t Logs[LogCapacity]
Represents an in-memory input byte stream.
Definition: memorystream.h:40
bool EndArray(SizeType elementCount)
Definition: readertest.cpp:833
Ch Peek() const
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:411
bool RawNumber(const Ch *, SizeType, bool)
Parsing was terminated.
Definition: error.h:88
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition: error.h:118
Missing a comma or &#39;}&#39; after an object member.
Definition: error.h:74
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:294
size_t Tell() const
Default implementation of Handler.
Definition: fwd.h:85
ASCII encoding.
Definition: encodings.h:542
Read-only string stream.
Definition: fwd.h:47
bool EndObject(SizeType)
Definition: readertest.cpp:885
The document is empty.
Definition: error.h:67
Missing a comma or &#39;]&#39; after an array element.
Definition: error.h:76
#define TEST_NUMBER_ERROR(errorCode, str, errorOffset, streamPos)
size_t PutEnd(Ch *)
const Ch * src_
Current read position.
#define TEST_TERMINATION(e, json)
bool Key(const char *, SizeType, bool)
static const uint32_t LOG_STARTOBJECT
RAPIDJSON_FORCEINLINE bool IterativeParseComplete()
Check if token-by-token parsing JSON text is complete.
Definition: reader.h:676
bool EndObject(SizeType memberCount)
Definition: readertest.cpp:831
XmlRpcServer s
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
Definition: reader.h:684
UTF-16 encoding.
Definition: encodings.h:269
void TestInsituMultipleRoot()
Definition: readertest.cpp:914
bool Double(double)
Missing a name for object member.
Definition: error.h:72
size_t PutEnd(Ch *)
bool Uint(unsigned)
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
Allow trailing commas at the end of objects and arrays.
Definition: reader.h:156
bool EndObject(SizeType)
bool Uint(unsigned i)
Definition: readertest.cpp:815
static const uint32_t LOG_DOUBLE
double Value() const
Definition: ieee754.h:29
bool IsInf() const
Definition: ieee754.h:42
Number too big to be stored in double.
Definition: error.h:84
bool IsNormal() const
Definition: ieee754.h:44
bool Sign() const
Definition: ieee754.h:37
static void TestParseDouble()
Definition: readertest.cpp:188
Parse all numbers (ints/doubles) as strings.
Definition: reader.h:155
bool EndObject(SizeType)
After parsing a complete JSON root from stream, stop further processing the rest of stream...
Definition: reader.h:152
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS. ...
Definition: reader.h:158
#define TEST_STRINGARRAY(Encoding, utype, array, x)
bool IsNan() const
Definition: ieee754.h:41
bool EndObject(SizeType)
Definition: readertest.cpp:867
bool Uint64(uint64_t i)
Definition: readertest.cpp:98
Parse number in full precision (but slower).
Definition: reader.h:153
UTF-8 encoding.
Definition: encodings.h:96
bool Key(const char *, SizeType, bool)
bool Int64(int64_t i)
Definition: readertest.cpp:89
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: reader.h:681
static const char json[]
#define TEST_ARRAY_ERROR(errorCode, str, errorOffset)
bool RawNumber(const char *str, SizeType length, bool)
static const uint32_t LOG_ENDARRAY
unsigned int uint32_t
Definition: stdint.h:126
bool Bool(bool b)
Definition: readertest.cpp:799
ParseErrorCode
Error code of parsing.
Definition: error.h:64
void TestTrailingCommas()
bool Uint64(uint64_t)
#define TEST_DOUBLE(fullPrecision, str, x)
void TestTrailingCommaHandlerTermination()
bool Double(double d)
Definition: readertest.cpp:107
Ch * StrDup(const Ch *str)
Definition: unittest.h:73
unsigned __int64 uint64_t
Definition: stdint.h:136
UTF-32 encoding.
Definition: encodings.h:418
ParseErrorCode Code() const
Get the error code.
Definition: error.h:116
TEST(Reader, ParseTrue)
Definition: readertest.cpp:52
bool Uint(unsigned i)
Definition: readertest.cpp:740
#define TESTERRORHANDLING(text, errorCode, offset)
std::istream & is_
bool IterativeParseNext(InputStream &is, Handler &handler)
Parse one token from JSON text.
Definition: reader.h:619
CharType Ch
Definition: encodings.h:270
Provides additional information for stream.
Definition: stream.h:73
bool String(const typename Encoding::Ch *str, size_t length, bool copy)
Definition: readertest.cpp:469
Miss exponent in number.
Definition: error.h:86
unsigned actual_
Definition: readertest.cpp:83
bool EndArray(SizeType)
Invalid escape character in string.
Definition: error.h:80
static const uint32_t LOG_KEY
Invalid encoding in string.
Definition: error.h:82
#define TEST_STRINGENCODING_ERROR(Encoding, TargetEncoding, utype, array)
main RapidJSON namespace
bool String(const Ch *, SizeType, bool)
bool Double(double d)
Definition: readertest.cpp:816
char * u32toa(uint32_t value, char *buffer)
Definition: itoa.h:39
#define TEST_STRING_ERROR(errorCode, str, errorOffset, streamPos)
bool Key(const Ch *, SizeType, bool)
bool RawNumber(const char *, SizeType, bool)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1121
int StrCmp(const Ch *s1, const Ch *s2)
Definition: unittest.h:67
#define TEST_STRINGARRAY2(Encoding, utype, earray, xarray)
bool EndArray(SizeType)
Definition: readertest.cpp:742
size_t Tell() const
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
Definition: reader.h:266
bool IsError() const
Whether the result is an error.
Definition: error.h:123
bool String(const char *, SizeType, bool)
static const uint32_t LOG_ENDOBJECT
void TestMultipleTrailingCommaErrors()
static const uint32_t LOG_BOOL
uint64_t Uint64Value() const
Definition: ieee754.h:30
NumbersAsStringsHandler(const char *expected)
unsigned StrLen(const Ch *s)
Definition: unittest.h:60
#define TEST_NAN_INF(str, x)
Validate encoding of JSON strings.
Definition: reader.h:150
signed __int64 int64_t
Definition: stdint.h:135
Miss fraction part in number.
Definition: error.h:85
Incorrect hex digit after \u escape in string.
Definition: error.h:78
bool String(const char *str, size_t, bool)
Definition: readertest.cpp:817
Unspecific syntax error.
Definition: error.h:89
static const uint32_t LOG_STRING
static const uint32_t LOG_STARTARRAY
void IterativeParseInit()
Initialize JSON text token-by-token parsing.
Definition: reader.h:606
void TestMultipleRoot()
Definition: readertest.cpp:893
CustomStringStream(const Ch *src)
The surrogate pair in string is invalid.
Definition: error.h:79
signed int int32_t
Definition: stdint.h:123
static const uint32_t LOG_NULL
Missing a colon after a name of object member.
Definition: error.h:73
#define ARRAY(...)
#define TEST_STRING(Encoding, e, x)
char * i64toa(int64_t value, char *buffer)
Definition: itoa.h:291
bool Int(int i)
Definition: readertest.cpp:71
Missing a closing quotation mark in string.
Definition: error.h:81
bool Int64(int64_t)
char * i32toa(int32_t value, char *buffer)
Definition: itoa.h:113
static const uint32_t LOG_INT
const Ch * head_
Original head of the string.
char * dtoa(double value, char *buffer, int maxDecimalPlaces=324)
Definition: dtoa.h:216
bool Uint(unsigned i)
Definition: readertest.cpp:80
bool EndArray(SizeType)
Definition: readertest.cpp:887
The document root must not follow by other values.
Definition: error.h:68
In-situ(destructive) parsing.
Definition: reader.h:149
ParseErrorCode TestString(const typename Encoding::Ch *str)
Definition: readertest.cpp:604
bool EndArray(SizeType)
uint64_t ToBias() const
Definition: ieee754.h:49
Allow one-line (//) and multi-line (/**/) comments.
Definition: reader.h:154
const Encoding::Ch * str_
Definition: readertest.cpp:482


choreo_rapidjson
Author(s):
autogenerated on Thu Jul 18 2019 03:59:09