28 RAPIDJSON_DIAG_OFF(effc++)
29 RAPIDJSON_DIAG_OFF(
float-equal)
30 RAPIDJSON_DIAG_OFF(missing-noreturn)
32 RAPIDJSON_DIAG_OFF(dangling-
else)
37 RAPIDJSON_DIAG_OFF(variadic-macros)
38 RAPIDJSON_DIAG_OFF(c++98-compat-pedantic)
44 bool Default() { ADD_FAILURE();
return false; }
47 bool Bool(
bool b) { EXPECT_TRUE(expect == b); ++step_;
return true; }
57 EXPECT_EQ(1u, h.
step_);
65 EXPECT_EQ(1u, h.
step_);
70 bool Default() { ADD_FAILURE();
return false; }
71 bool Int(
int i) { actual_ = i; step_++;
return true; }
79 bool Default() { ADD_FAILURE();
return false; }
80 bool Uint(
unsigned i) { actual_ = i; step_++;
return true; }
88 bool Default() { ADD_FAILURE();
return false; }
97 bool Default() { ADD_FAILURE();
return false; }
106 bool Default() { ADD_FAILURE();
return false; }
107 bool Double(
double d) { actual_ = d; step_++;
return true; }
114 #define TEST_INTEGER(Handler, str, x) \ 116 StringStream s(str); \ 119 reader.Parse(s, h); \ 120 EXPECT_EQ(1u, h.step_); \ 121 EXPECT_EQ(x, h.actual_); \ 146 for (
unsigned i = 0; i < 100000; i++) {
168 for (
unsigned i = 0; i < 100000; i++) {
178 if (u.i < -
int64_t(2147483648u)) {
187 template<
bool fullPrecision>
189 #define TEST_DOUBLE(fullPrecision, str, x) \ 191 StringStream s(str); \ 192 ParseDoubleHandler h; \ 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); \ 203 EXPECT_EQ(e.Sign(), a.Sign()); \ 204 EXPECT_DOUBLE_EQ(x, h.actual_); \ 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);
230 TEST_DOUBLE(fullPrecision,
"2.2250738585072009e-308", 2.2250738585072009e-308);
231 TEST_DOUBLE(fullPrecision,
"2.2250738585072014e-308", 2.2250738585072014e-308);
232 TEST_DOUBLE(fullPrecision,
"1.7976931348623157e+308", 1.7976931348623157e+308);
234 TEST_DOUBLE(fullPrecision,
"18446744073709551616", 18446744073709551616.0);
235 TEST_DOUBLE(fullPrecision,
"-9223372036854775809", -9223372036854775809.0);
236 TEST_DOUBLE(fullPrecision,
"0.9868011474609375", 0.9868011474609375);
238 TEST_DOUBLE(fullPrecision,
"45913141877270640000.0", 45913141877270640000.0);
239 TEST_DOUBLE(fullPrecision,
"2.2250738585072011e-308", 2.2250738585072011e-308);
240 TEST_DOUBLE(fullPrecision,
"1e-00011111111111", 0.0);
241 TEST_DOUBLE(fullPrecision,
"-1e-00011111111111", -0.0);
245 TEST_DOUBLE(fullPrecision,
"0.017976931348623157e+310", 1.7976931348623157e+308);
251 TEST_DOUBLE(fullPrecision,
"2.2250738585072012e-308", 2.2250738585072014e-308);
255 TEST_DOUBLE(fullPrecision,
"2.22507385850720113605740979670913197593481954635164564e-308", 2.2250738585072009e-308);
256 TEST_DOUBLE(fullPrecision,
"2.22507385850720113605740979670913197593481954635164565e-308", 2.2250738585072014e-308);
260 TEST_DOUBLE(fullPrecision,
"0.999999999999999944488848768742172978818416595458984375", 1.0);
261 TEST_DOUBLE(fullPrecision,
"0.999999999999999944488848768742172978818416595458984374", 0.99999999999999989);
262 TEST_DOUBLE(fullPrecision,
"0.999999999999999944488848768742172978818416595458984376", 1.0);
264 TEST_DOUBLE(fullPrecision,
"1.00000000000000011102230246251565404236316680908203125", 1.0);
265 TEST_DOUBLE(fullPrecision,
"1.00000000000000011102230246251565404236316680908203124", 1.0);
266 TEST_DOUBLE(fullPrecision,
"1.00000000000000011102230246251565404236316680908203126", 1.00000000000000022);
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);
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);
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);
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);
297 for (
int i = 1; i < 309; i++)
305 "2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508" 306 "7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012" 307 "9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306" 308 "6665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505" 309 "1080609940730262937128958950003583799967207254304360284078895771796150945516748243471030702609144621" 310 "5722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844" 311 "2390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042" 312 "7567186443383770486037861622771738545623065874679014086723327636718751234567890123456789012345678901" 314 2.2250738585072014e-308);
317 static const unsigned count = 100;
322 for (
uint64_t exp = 0; exp < 2047; exp++) {
324 for (
unsigned i = 0; i < count; i++) {
336 EXPECT_EQ(1u, h.
step_);
341 printf(
" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.
actual_, d.
Value());
352 TEST_DOUBLE(fullPrecision,
"7.450580596923828e-9", 7.450580596923828e-9);
355 for (
int i = 0; i < 324; i++) {
363 EXPECT_EQ(1u, h.
step_);
368 printf(
" String: %s\n Actual: %.17g\nExpected: %.17g\n", buffer, h.
actual_, d.
Value());
383 TestParseDouble<false>();
387 TestParseDouble<true>();
391 static unsigned count = 1000000;
396 for (
unsigned i = 0; i < count; i++) {
412 EXPECT_EQ(1u, h.
step_);
417 double ulp =
static_cast<double>(bias1 >= bias2 ? bias1 - bias2 : bias2 - bias1);
418 ulpMax = std::max(ulpMax, ulp);
421 printf(
"ULP Average = %g, Max = %g \n", ulpSum / count, ulpMax);
425 #define TEST_NUMBER_ERROR(errorCode, str, errorOffset, streamPos) \ 428 sprintf(buffer, "%s", str); \ 429 InsituStringStream s(buffer); \ 430 BaseReaderHandler<> h; \ 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());\ 442 for (
int i = 1; i < 310; i++)
457 #undef TEST_NUMBER_ERROR 460 template <
typename Encoding>
463 ~ParseStringHandler() { EXPECT_TRUE(str_ != 0);
if (copy_) free(const_cast<typename Encoding::Ch*>(str_)); }
468 bool Default() { ADD_FAILURE();
return false; }
469 bool String(
const typename Encoding::Ch* str,
size_t length,
bool 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));
482 const typename Encoding::Ch*
str_;
488 #define TEST_STRING(Encoding, e, x) \ 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_); \ 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_); \ 510 #define ARRAY(...) { __VA_ARGS__ } 511 #define TEST_STRINGARRAY(Encoding, utype, array, x) \ 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); \ 518 #define TEST_STRINGARRAY2(Encoding, utype, earray, xarray) \ 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); \ 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'));
553 TEST_STRINGARRAY2(
UTF32<>,
unsigned,
ARRAY(0x020AC, 0x0000),
ARRAY(
'\"',
'\\',
'u',
'2',
'0',
'A',
'C',
'\"',
'\0'));
554 TEST_STRINGARRAY2(
UTF32<>,
unsigned,
ARRAY(0x1D11E, 0x0000),
ARRAY(
'\"',
'\\',
'u',
'D',
'8',
'3',
'4',
'\\',
'u',
'D',
'D',
'1',
'E',
'\"',
'\0'));
556 #undef TEST_STRINGARRAY 563 const char e[] =
"Hello\0World";
573 const char* x =
"\"Hello\"";
574 const wchar_t* e = L
"Hello";
584 const char* x =
"\"Hello\"";
585 const wchar_t* e = L
"Hello";
603 template <
typename Encoding>
608 reader.template Parse<kParseValidateEncodingFlag>(s, h);
613 #define TEST_STRING_ERROR(errorCode, str, errorOffset, streamPos)\ 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());\ 624 #define ARRAY(...) { __VA_ARGS__ } 625 #define TEST_STRINGENCODING_ERROR(Encoding, TargetEncoding, utype, array) \ 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));\ 631 GenericStringStream<Encoding> s(e);\ 632 BaseReaderHandler<TargetEncoding> h;\ 633 GenericReader<Encoding, TargetEncoding> reader;\ 635 EXPECT_EQ(kParseErrorStringInvalidEncoding, reader.GetParseErrorCode());\ 661 char e[] = {
'[',
'\"', 0,
'\"',
']',
'\0' };
662 for (
unsigned char c = 0x80u; c <= 0xBFu; c++) {
663 e[2] =
static_cast<char>(c);
667 std::cout << static_cast<unsigned>(c) << std::endl;
673 char e[] = {
'[',
'\"', 0,
' ',
'\"',
']',
'\0' };
674 for (
unsigned c = 0xC0u; c <= 0xFFu; c++) {
675 e[2] =
static_cast<char>(c);
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'));
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'));
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'));
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'));
732 #undef TEST_STRINGARRAY_ERROR 735 template <
unsigned count>
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; }
753 EXPECT_EQ(2u, h.
step_);
763 EXPECT_EQ(6u, h.
step_);
768 #define TEST_ARRAY_ERROR(errorCode, str, errorOffset) \ 770 int streamPos = errorOffset; \ 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());\ 791 #undef TEST_ARRAY_ERROR 797 bool Default() { ADD_FAILURE();
return false; }
798 bool Null() { EXPECT_EQ(8u, step_); step_++;
return true; }
801 case 4: EXPECT_TRUE(b); step_++;
return true;
802 case 6: EXPECT_FALSE(b); step_++;
return true;
803 default: ADD_FAILURE();
return false;
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;
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) {
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;
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; }
839 const char*
json =
"{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
843 char* json2 =
StrDup(json);
848 EXPECT_EQ(20u, h.
step_);
858 EXPECT_EQ(20u, h.
step_);
865 bool Default() { ADD_FAILURE();
return false; }
866 bool StartObject() { EXPECT_EQ(0u, step_); step_++;
return true; }
877 EXPECT_EQ(2u, h.
step_);
883 bool Default() { ADD_FAILURE();
return false; }
884 bool StartObject() { EXPECT_EQ(0u, step_); step_++;
return true; }
886 bool StartArray() { EXPECT_EQ(2u, step_); step_++;
return true; }
892 template <
unsigned parseFlags>
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());
906 TestMultipleRoot<kParseStopWhenDoneFlag>();
910 TestMultipleRoot<kParseIterativeFlag | kParseStopWhenDoneFlag>();
913 template <
unsigned parseFlags>
915 char* buffer = strdup(
"{}[] a");
920 EXPECT_EQ(2u, h.
step_);
922 EXPECT_EQ(4u, h.
step_);
923 EXPECT_EQ(
' ', s.
Take());
924 EXPECT_EQ(
'a', s.
Take());
929 TestInsituMultipleRoot<kParseStopWhenDoneFlag>();
933 TestInsituMultipleRoot<kParseIterativeFlag | kParseStopWhenDoneFlag>();
936 #define TEST_ERROR(errorCode, str, errorOffset) \ 938 int streamPos = errorOffset; \ 940 strncpy(buffer, str, 1000); \ 941 InsituStringStream s(buffer); \ 942 BaseReaderHandler<> h; \ 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());\ 1009 const char* expected =
"ABCDE";
1010 for (
size_t i = 0; i < 5; i++) {
1012 EXPECT_EQ(expected[i], ss.
Take());
1018 template <
typename Encoding>
1021 typedef typename Encoding::Ch
Ch;
1027 size_t Tell()
const {
return static_cast<size_t>(src_ - head_); }
1048 template <
typename Encoding>
1050 enum { copyOptimization = 1 };
1057 const char*
json =
"{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
1062 EXPECT_EQ(20u, h.
step_);
1075 return c == std::char_traits<char>::eof() ?
'\0' :
static_cast<Ch
>(c);
1080 return c == std::char_traits<char>::eof() ?
'\0' :
static_cast<Ch
>(c);
1083 size_t Tell()
const {
return static_cast<size_t>(is_.tellg()); }
1086 void Put(Ch) { assert(
false); }
1088 size_t PutEnd(Ch*) { assert(
false);
return 0; }
1098 const char*
json =
"[1,2,3,4]";
1100 std::stringstream ss(json);
1105 reader.
Parse(is, h);
1111 #define TESTERRORHANDLING(text, errorCode, offset)\ 1113 int streamPos = offset; \ 1114 StringStream json(text); \ 1115 BaseReaderHandler<> handler; \ 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()); \ 1158 template<
typename Encoding = UTF8<> >
1160 typedef typename Encoding::Ch
Ch;
1176 const static size_t LogCapacity = 256;
1208 Logs[LogCount++] = LOG_ENDOBJECT |
static_cast<uint32_t>(c);
1217 Logs[LogCount++] = LOG_ENDARRAY |
static_cast<uint32_t>(c);
1224 StringStream is(
"[1, {\"k\": [1, 2]}, null, false, true, \"string\", 1.2]");
1251 EXPECT_EQ(
sizeof(e) /
sizeof(
int), handler.
LogCount);
1253 for (
size_t i = 0; i < handler.
LogCount; ++i) {
1254 EXPECT_EQ(e[i], handler.
Logs[i]) <<
"i = " << i;
1286 EXPECT_EQ(
sizeof(e) /
sizeof(
int), handler.
LogCount);
1288 for (
size_t i = 0; i < handler.
LogCount; ++i) {
1289 EXPECT_EQ(e[i], handler.
Logs[i]) <<
"i = " << i;
1315 StringStream is(
"[1, {\"k\": [1, 2]}, null, false, true, \"string\", 1.2]");
1320 size_t oldLogCount = handler.
LogCount;
1321 EXPECT_TRUE(oldLogCount <
sizeof(e) /
sizeof(
int)) <<
"overrun";
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";
1329 EXPECT_EQ(
sizeof(e) /
sizeof(
int), handler.
LogCount) <<
"handler invoked wrong number of times";
1332 size_t oldLogCount = handler.
LogCount;
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";
1366 EXPECT_EQ(4u, r.
Offset());
1378 EXPECT_EQ(6u, r.
Offset());
1390 EXPECT_EQ(5u, r.
Offset());
1402 EXPECT_EQ(7u, r.
Offset());
1410 StringStream is(
"[null, true, -1, 1, -1234567890123456789, 1234567890123456789, 3.14, \"s\", { \"a\" : 1 }]");
1411 EXPECT_TRUE(reader.
Parse(is, h));
1418 bool Int(
int) {
return e != 2; }
1419 bool Uint(
unsigned) {
return e != 3; }
1432 #define TEST_TERMINATION(e, json)\ 1435 TerminateHandler<e> h;\ 1436 StringStream is(json);\ 1437 EXPECT_FALSE(reader.Parse(is, h));\ 1438 EXPECT_EQ(kParseErrorTermination, reader.GetParseErrorCode());\ 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" 1469 " \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3]" 1470 "}/*And the last one to be sure */";
1476 EXPECT_EQ(20u, h.
step_);
1480 const char*
json =
"{/**/\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1486 EXPECT_EQ(20u, h.
step_);
1490 const char*
json =
"{//\n\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1496 EXPECT_EQ(20u, h.
step_);
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] }";
1509 EXPECT_EQ(20u, h.
step_);
1514 const char*
json =
"{/* Inline comment. */\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
1524 "{\"hello\" : /* Multiline comment starts here\n" 1526 " and ends here */\"world\", \"t\" :true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
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] }";
1545 const char*
json =
"{\"hello\" : \"world\" // EOF is here -->\0 \n}";
1555 const char*
json =
"{\"hello\" : \"world\" /* EOF is here -->\0 */}";
1565 const char*
json =
"{\"hello\" : \"world\" /* *\0 */}";
1575 const char*
json =
"{\"hello\" : \"world\" /! }";
1587 bool Int(
int) {
return true; }
1588 bool Uint(
unsigned) {
return true; }
1594 EXPECT_TRUE(str != 0);
1595 EXPECT_TRUE(expected_len_ == length);
1596 EXPECT_TRUE(strncmp(str, expected_, length) == 0);
1607 : expected_(expected)
1608 , expected_len_(strlen(expected)) {}
1616 const char*
json =
"{ \"pi\": 3.1416 } ";
1631 const char*
json =
"{ \"gigabyte\": 1.0e9 } ";
1638 char*
json =
StrDup(
"{ \"gigabyte\": 1.0e9 } ");
1646 const char*
json =
"{ \"pi\": 314.159e-2 } ";
1653 char*
json =
StrDup(
"{ \"gigabyte\": 314.159e-2 } ");
1661 const char*
json =
"{ \"negative\": -1.54321 } ";
1668 char*
json =
StrDup(
"{ \"negative\": -1.54321 } ");
1676 const char*
json =
"{ \"pi\": 314.159e-2 } ";
1677 std::stringstream ss(json);
1685 template <
unsigned extraFlags>
1692 EXPECT_EQ(5u, h.
step_);
1695 const char*
json =
"{ \"hello\" : \"world\", \"t\" : true , \"f\" : false," 1696 "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3],}";
1701 EXPECT_EQ(20u, h.
step_);
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} ";
1711 EXPECT_EQ(20u, h.
step_);
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*/}";
1721 EXPECT_EQ(20u, h.
step_);
1726 TestTrailingCommas<kParseNoFlags>();
1730 TestTrailingCommas<kParseIterativeFlag>();
1733 template <
unsigned extraFlags>
1743 EXPECT_EQ(7u, r.
Offset());
1746 const char*
json =
"{ \"hello\" : \"world\", \"t\" : true , \"f\" : false," 1747 "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3,],,}";
1754 EXPECT_EQ(95u, r.
Offset());
1759 TestMultipleTrailingCommaErrors<kParseNoFlags>();
1763 TestMultipleTrailingCommaErrors<kParseIterativeFlag>();
1766 template <
unsigned extraFlags>
1777 EXPECT_EQ(1u, r.
Offset());
1786 EXPECT_EQ(1u, r.
Offset());
1791 TestEmptyExceptForCommaErrors<kParseNoFlags>();
1795 TestEmptyExceptForCommaErrors<kParseIterativeFlag>();
1798 template <
unsigned extraFlags>
1807 EXPECT_EQ(7u, r.
Offset());
1816 EXPECT_EQ(23u, r.
Offset());
1821 TestTrailingCommaHandlerTermination<kParseNoFlags>();
1825 TestTrailingCommaHandlerTermination<kParseIterativeFlag>();
1829 #define TEST_NAN_INF(str, x) \ 1832 StringStream s(str); \ 1833 ParseDoubleHandler h; \ 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()); \ 1841 EXPECT_EQ(e.Sign(), a.Sign()); \ 1844 const char* json = "{ \"naninfdouble\": " str " } "; \ 1845 StringStream s(json); \ 1846 NumbersAsStringsHandler h(str); \ 1848 EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag|kParseNanAndInfFlag>(s, h)); \ 1851 char* json = StrDup("{ \"naninfdouble\": " str " } "); \ 1852 InsituStringStream s(json); \ 1853 NumbersAsStringsHandler h(str); \ 1855 EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag|kParseNanAndInfFlag>(s, h)); \ 1859 #define TEST_NAN_INF_ERROR(errorCode, str, errorOffset) \ 1861 int streamPos = errorOffset; \ 1862 char buffer[1001]; \ 1863 strncpy(buffer, str, 1000); \ 1864 InsituStringStream s(buffer); \ 1865 BaseReaderHandler<> h; \ 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());\ 1873 double nan = std::numeric_limits<double>::quiet_NaN();
1874 double inf = std::numeric_limits<double>::infinity();
1891 #undef TEST_NAN_INF_ERROR
#define TEST_INTEGER(Handler, str, x)
BasicIStreamWrapper< std::istream > IStreamWrapper
bool String(const char *, SizeType, bool)
char * u64toa(uint64_t value, char *buffer)
#define TEST_NAN_INF_ERROR(errorCode, str, errorOffset)
ParseResult Parse(InputStream &is, Handler &handler)
Parse JSON text.
IStreamWrapper(std::istream &is)
#define TEST_ERROR(errorCode, str, errorOffset)
void TestEmptyExceptForCommaErrors()
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Iterative(constant complexity in terms of function call stack size) parsing.
uint32_t Logs[LogCapacity]
Represents an in-memory input byte stream.
bool EndArray(SizeType elementCount)
#define RAPIDJSON_ASSERT(x)
Assertion.
bool RawNumber(const Ch *, SizeType, bool)
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Missing a comma or '}' after an object member.
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Default implementation of Handler.
bool EndArray(SizeType c)
Missing a comma or ']' after an array element.
#define TEST_NUMBER_ERROR(errorCode, str, errorOffset, streamPos)
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.
bool EndObject(SizeType memberCount)
ParseErrorCode GetParseErrorCode() const
Get the ParseErrorCode of last parsing.
void TestInsituMultipleRoot()
Missing a name for object member.
Result of parsing (wraps ParseErrorCode)
Allow trailing commas at the end of objects and arrays.
static const uint32_t LOG_DOUBLE
Number too big to be stored in double.
static void TestParseDouble()
Parse all numbers (ints/doubles) as strings.
After parsing a complete JSON root from stream, stop further processing the rest of stream...
Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS. ...
#define TEST_STRINGARRAY(Encoding, utype, array, x)
Parse number in full precision (but slower).
bool Key(const char *, SizeType, bool)
bool HasParseError() const
Whether a parse error has occured in the last parsing.
#define TEST_ARRAY_ERROR(errorCode, str, errorOffset)
bool RawNumber(const char *str, SizeType length, bool)
ParseMultipleRootHandler()
static const uint32_t LOG_ENDARRAY
bool EndObject(SizeType c)
ParseErrorCode
Error code of parsing.
void TestTrailingCommas()
#define TEST_DOUBLE(fullPrecision, str, x)
void TestTrailingCommaHandlerTermination()
Ch * StrDup(const Ch *str)
unsigned __int64 uint64_t
ParseErrorCode Code() const
Get the error code.
#define TESTERRORHANDLING(text, errorCode, offset)
bool IterativeParseNext(InputStream &is, Handler &handler)
Parse one token from JSON text.
Provides additional information for stream.
bool String(const typename Encoding::Ch *str, size_t length, bool copy)
Invalid escape character in string.
static const uint32_t LOG_KEY
Invalid encoding in string.
ParseEmptyObjectHandler()
#define TEST_STRINGENCODING_ERROR(Encoding, TargetEncoding, utype, array)
bool String(const Ch *, SizeType, bool)
char * u32toa(uint32_t value, char *buffer)
#define TEST_STRING_ERROR(errorCode, str, errorOffset, streamPos)
bool Key(const Ch *, SizeType, bool)
IterativeParsingReaderHandler()
bool RawNumber(const char *, SizeType, bool)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
int StrCmp(const Ch *s1, const Ch *s2)
#define TEST_STRINGARRAY2(Encoding, utype, earray, xarray)
void SkipWhitespace(InputStream &is)
Skip the JSON white spaces in a stream.
bool IsError() const
Whether the result is an error.
bool String(const char *, SizeType, bool)
static const uint32_t LOG_ENDOBJECT
void TestMultipleTrailingCommaErrors()
static const uint32_t LOG_BOOL
uint64_t Uint64Value() const
NumbersAsStringsHandler(const char *expected)
unsigned StrLen(const Ch *s)
#define TEST_NAN_INF(str, x)
Validate encoding of JSON strings.
Miss fraction part in number.
Incorrect hex digit after \u escape in string.
bool String(const char *str, size_t, bool)
static const uint32_t LOG_STRING
static const uint32_t LOG_STARTARRAY
void IterativeParseInit()
Initialize JSON text token-by-token parsing.
CustomStringStream(const Ch *src)
The surrogate pair in string is invalid.
static const uint32_t LOG_NULL
Missing a colon after a name of object member.
#define TEST_STRING(Encoding, e, x)
char * i64toa(int64_t value, char *buffer)
Missing a closing quotation mark in string.
char * i32toa(int32_t value, char *buffer)
static const uint32_t LOG_INT
const Ch * head_
Original head of the string.
char * dtoa(double value, char *buffer, int maxDecimalPlaces=324)
The document root must not follow by other values.
In-situ(destructive) parsing.
ParseErrorCode TestString(const typename Encoding::Ch *str)
Allow one-line (//) and multi-line (/**/) comments.
const Encoding::Ch * str_