From 8d53689432f85dc285602dce9e5d28f8ca5704b7 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:17:39 +0200 Subject: [PATCH 01/15] (Pretty)Writer: drop restriction to object/array roots --- include/rapidjson/prettywriter.h | 1 - include/rapidjson/writer.h | 1 - test/unittest/writertest.cpp | 39 ++++++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/include/rapidjson/prettywriter.h b/include/rapidjson/prettywriter.h index b9d7510..eb778b3 100644 --- a/include/rapidjson/prettywriter.h +++ b/include/rapidjson/prettywriter.h @@ -174,7 +174,6 @@ protected: level->valueCount++; } else { - RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType); RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root. Base::hasRoot_ = true; } diff --git a/include/rapidjson/writer.h b/include/rapidjson/writer.h index 9fdfde2..7927a0c 100644 --- a/include/rapidjson/writer.h +++ b/include/rapidjson/writer.h @@ -321,7 +321,6 @@ protected: level->valueCount++; } else { - RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType); RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root. hasRoot_ = true; } diff --git a/test/unittest/writertest.cpp b/test/unittest/writertest.cpp index 2d83418..9529ad9 100644 --- a/test/unittest/writertest.cpp +++ b/test/unittest/writertest.cpp @@ -155,12 +155,12 @@ TEST(Writer, OStreamWrapper) { EXPECT_STREQ("{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3]}", actual.c_str()); } -TEST(Writer, AssertRootMustBeArrayOrObject) { +TEST(Writer, AssertRootMayBeAnyValue) { #define T(x)\ {\ StringBuffer buffer;\ Writer writer(buffer);\ - ASSERT_THROW(x, AssertException);\ + EXPECT_TRUE(x);\ } T(writer.Bool(false)); T(writer.Bool(true)); @@ -228,9 +228,23 @@ TEST(Writer, AssertObjectKeyNotString) { TEST(Writer, AssertMultipleRoot) { StringBuffer buffer; Writer writer(buffer); + writer.StartObject(); writer.EndObject(); ASSERT_THROW(writer.StartObject(), AssertException); + + writer.Reset(buffer); + writer.Null(); + ASSERT_THROW(writer.Int(0), AssertException); + + writer.Reset(buffer); + writer.String("foo"); + ASSERT_THROW(writer.StartArray(), AssertException); + + writer.Reset(buffer); + writer.StartArray(); + writer.EndArray(); + ASSERT_THROW(writer.Double(3.14), AssertException); } TEST(Writer, RootObjectIsComplete) { @@ -260,3 +274,24 @@ TEST(Writer, RootArrayIsComplete) { writer.EndArray(); EXPECT_TRUE(writer.IsComplete()); } + +TEST(Writer, RootValueIsComplete) { +#define T(x)\ + {\ + StringBuffer buffer;\ + Writer writer(buffer);\ + EXPECT_FALSE(writer.IsComplete()); \ + x; \ + EXPECT_TRUE(writer.IsComplete()); \ + } + T(writer.Null()); + T(writer.Bool(true)); + T(writer.Bool(false)); + T(writer.Int(0)); + T(writer.Uint(0)); + T(writer.Int64(0)); + T(writer.Uint64(0)); + T(writer.Double(0)); + T(writer.String("")); +#undef T +} From edccda00bdc9cb6661bb79df25dcdd23a1ee2dee Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:24:03 +0200 Subject: [PATCH 02/15] drop object/array root restriction from recursive parser --- include/rapidjson/reader.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index d0f7ea4..0589273 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -381,11 +381,7 @@ public: RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); } else { - switch (is.Peek()) { - case '{': ParseObject(is, handler); break; - case '[': ParseArray(is, handler); break; - default: RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotObjectOrArray, is.Tell()); - } + ParseValue(is, handler); RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); if (!(parseFlags & kParseStopWhenDoneFlag)) { From c9f2715115cdab136fa156d82ac7db4ab07c2c05 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:24:56 +0200 Subject: [PATCH 03/15] Reader: drop object/array root restrction from iterative parser --- include/rapidjson/reader.h | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index 0589273..49a2fb0 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -903,6 +903,9 @@ private: IterativeParsingElementDelimiterState, IterativeParsingArrayFinishState, + // Single value state + IterativeParsingValueState, + cIterativeParsingStateCount }; @@ -961,11 +964,11 @@ private: IterativeParsingErrorState, // Right curly bracket IterativeParsingErrorState, // Comma IterativeParsingErrorState, // Colon - IterativeParsingErrorState, // String - IterativeParsingErrorState, // False - IterativeParsingErrorState, // True - IterativeParsingErrorState, // Null - IterativeParsingErrorState // Number + IterativeParsingValueState, // String + IterativeParsingValueState, // False + IterativeParsingValueState, // True + IterativeParsingValueState, // Null + IterativeParsingValueState // Number }, // Finish(sink state) { @@ -1102,6 +1105,12 @@ private: IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState + }, + // Single Value (sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState } }; // End of G @@ -1238,6 +1247,14 @@ private: } } + case IterativeParsingValueState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return IterativeParsingFinishState; + default: RAPIDJSON_ASSERT(false); return IterativeParsingErrorState; @@ -1252,7 +1269,7 @@ private: } switch (src) { - case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(is.Peek() == '\0' ? kParseErrorDocumentEmpty : kParseErrorDocumentRootNotObjectOrArray, is.Tell()); + case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); case IterativeParsingObjectInitialState: case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); From c0c0c398b6f9c630323216775dbf08b775dbce63 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:26:17 +0200 Subject: [PATCH 04/15] jsoncheckertest: skip "fail1.json", as it is now accepted by RapidJSON --- test/unittest/jsoncheckertest.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/unittest/jsoncheckertest.cpp b/test/unittest/jsoncheckertest.cpp index d661528..75ef3e8 100644 --- a/test/unittest/jsoncheckertest.cpp +++ b/test/unittest/jsoncheckertest.cpp @@ -46,6 +46,8 @@ TEST(JsonChecker, Reader) { // jsonchecker/failXX.json for (int i = 1; i <= 33; i++) { + if (i == 1) // fail1.json is valid in rapidjson, which has no limitation on type of root element (RFC 7159). + continue; if (i == 18) // fail18.json is valid in rapidjson, which has no limitation on depth of nesting. continue; @@ -57,14 +59,15 @@ TEST(JsonChecker, Reader) { json = ReadFile(filename, length); if (!json) { printf("jsonchecker file %s not found", filename); + ADD_FAILURE(); continue; } } GenericDocument, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak) if (!document.Parse((const char*)json).HasParseError()) - FAIL(); - //printf("%s(%u):%s\n", filename, (unsigned)document.GetErrorOffset(), document.GetParseError()); + ADD_FAILURE_AT(filename, document.GetErrorOffset()); + free(json); } From e45557e28e5026697fb5496b2b8e89631874476c Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:26:44 +0200 Subject: [PATCH 05/15] writertest: add some roundtrip tests for non-compound root values --- test/unittest/writertest.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/unittest/writertest.cpp b/test/unittest/writertest.cpp index 9529ad9..fd42e8d 100644 --- a/test/unittest/writertest.cpp +++ b/test/unittest/writertest.cpp @@ -50,6 +50,16 @@ TEST(Writer, Compact) { EXPECT_TRUE(writer.IsComplete()); \ } +TEST(Writer, Root) { + TEST_ROUNDTRIP("null"); + TEST_ROUNDTRIP("true"); + TEST_ROUNDTRIP("false"); + TEST_ROUNDTRIP("0"); + TEST_ROUNDTRIP("\"foo\""); + TEST_ROUNDTRIP("[]"); + TEST_ROUNDTRIP("{}"); +} + TEST(Writer, Int) { TEST_ROUNDTRIP("[-1]"); TEST_ROUNDTRIP("[-123]"); From c2567526688f3b90ab0a805b302fde19fd38df25 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:29:01 +0200 Subject: [PATCH 06/15] readertest: drop object/array root restriction tests --- test/unittest/readertest.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index e403bb8..bb7a62a 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -640,13 +640,6 @@ TEST(Reader, ParseDocument_Error) { TEST_ERROR(kParseErrorDocumentEmpty, " "); TEST_ERROR(kParseErrorDocumentEmpty, " \n"); - // The document root must be either object or array. - TEST_ERROR(kParseErrorDocumentRootNotObjectOrArray, "null"); - TEST_ERROR(kParseErrorDocumentRootNotObjectOrArray, "true"); - TEST_ERROR(kParseErrorDocumentRootNotObjectOrArray, "false"); - TEST_ERROR(kParseErrorDocumentRootNotObjectOrArray, "\"s\""); - TEST_ERROR(kParseErrorDocumentRootNotObjectOrArray, "0"); - // The document root must not follow by other values. TEST_ERROR(kParseErrorDocumentRootNotSingular, "[] 0"); TEST_ERROR(kParseErrorDocumentRootNotSingular, "{} 0"); @@ -802,7 +795,6 @@ TEST(Reader, IterativeParsing_ErrorHandling) { TESTERRORHANDLING("{\"a\": a}", kParseErrorValueInvalid, 6u); TESTERRORHANDLING("", kParseErrorDocumentEmpty, 0u); - TESTERRORHANDLING("1", kParseErrorDocumentRootNotObjectOrArray, 0u); TESTERRORHANDLING("{}{}", kParseErrorDocumentRootNotSingular, 2u); TESTERRORHANDLING("{1}", kParseErrorObjectMissName, 1u); From 89793599ceddbd431ae1bee68ce37d11fe6b1490 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:29:31 +0200 Subject: [PATCH 07/15] error/{en,error}.h: drop unused kParseErrorDocumentRootNotObjectOrArray error --- include/rapidjson/error/en.h | 1 - include/rapidjson/error/error.h | 1 - 2 files changed, 2 deletions(-) diff --git a/include/rapidjson/error/en.h b/include/rapidjson/error/en.h index b4a3ae1..c668ac7 100644 --- a/include/rapidjson/error/en.h +++ b/include/rapidjson/error/en.h @@ -37,7 +37,6 @@ inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErro case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error."); case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty."); - case kParseErrorDocumentRootNotObjectOrArray: return RAPIDJSON_ERROR_STRING("The document root must be either object or array."); case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not follow by other values."); case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value."); diff --git a/include/rapidjson/error/error.h b/include/rapidjson/error/error.h index bc5462a..3db6f16 100644 --- a/include/rapidjson/error/error.h +++ b/include/rapidjson/error/error.h @@ -57,7 +57,6 @@ enum ParseErrorCode { kParseErrorNone = 0, //!< No error. kParseErrorDocumentEmpty, //!< The document is empty. - kParseErrorDocumentRootNotObjectOrArray, //!< The document root must be either object or array. kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values. kParseErrorValueInvalid, //!< Invalid value. From 4d031d054a89ce997c3ca5132a26e902e2696155 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:33:27 +0200 Subject: [PATCH 08/15] readme.md: reference RFC7159 instead of RFC4627 --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 8141c8b..d4c8f85 100644 --- a/readme.md +++ b/readme.md @@ -22,9 +22,9 @@ RapidJSON is a JSON parser and generator for C++. It was inspired by [RapidXml]( More features can be read [here](doc/features.md). -JSON(JavaScript Object Notation) is a light-weight data exchange format. RapidJSON should be in fully compliance with RFC4627/ECMA-404. More information about JSON can be obtained at +JSON(JavaScript Object Notation) is a light-weight data exchange format. RapidJSON should be in fully compliance with RFC7159/ECMA-404. More information about JSON can be obtained at * [Introducing JSON](http://json.org/) -* [RFC4627: The application/json Media Type for JavaScript Object Notation (JSON)](http://www.ietf.org/rfc/rfc4627.txt) +* [RFC7159: The JavaScript Object Notation (JSON) Data Interchange Format](http://www.ietf.org/rfc/rfc7159.txt) * [Standard ECMA-404: The JSON Data Interchange Format](http://www.ecma-international.org/publications/standards/Ecma-404.htm) ## Compatibility From 24b797614568c3e22899dffb7baaf3fc34261119 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:39:11 +0200 Subject: [PATCH 09/15] tutorial.md: lift restriction to object/array root values --- doc/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 66c9a50..d22b6a3 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -42,7 +42,7 @@ The JSON is now parsed into `document` as a *DOM tree*: ![DOM in the tutorial](diagram/tutorial.png) -The root of a conforming JSON should be either an object or an array. In this case, the root is an object. +Since the update to RFC7159, the root of a conforming JSON document can be any JSON value. In RFC4627, only objects or arrays were allowed as root values. In this case, the root is an object. ~~~~~~~~~~cpp assert(document.IsObject()); ~~~~~~~~~~ From e29a4521b114b015a80b55c4a465a18c55fcce05 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:43:50 +0200 Subject: [PATCH 10/15] readertest.cpp: use top-level Parse functions, instead of internal ones With the allowance of arbitrary root value types, the individual tests can use the top-level Parse functions, instead of ParseFoo() variants. Secondly, some unneeded array wrappers have been dropped and non-singular tests starting with other values than objects or arrays have been added. --- test/unittest/readertest.cpp | 50 +++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index bb7a62a..194a6bb 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -45,7 +45,7 @@ TEST(Reader, ParseTrue) { StringStream s("true"); ParseBoolHandler h; Reader reader; - reader.ParseTrue<0>(s, h); + reader.Parse(s, h); EXPECT_EQ(1u, h.step_); } @@ -53,11 +53,11 @@ TEST(Reader, ParseFalse) { StringStream s("false"); ParseBoolHandler h; Reader reader; - reader.ParseFalse<0>(s, h); + reader.Parse(s, h); EXPECT_EQ(1u, h.step_); } -struct ParseIntHandler : BaseReaderHandler<> { +struct ParseIntHandler : BaseReaderHandler, ParseIntHandler> { ParseIntHandler() : step_(0), actual_() {} bool Default() { ADD_FAILURE(); return false; } bool Int(int i) { actual_ = i; step_++; return true; } @@ -108,7 +108,7 @@ TEST(Reader, ParseNumberHandler) { StringStream s(str); \ Handler h; \ Reader reader; \ - reader.ParseNumber<0>(s, h); \ + reader.Parse(s, h); \ EXPECT_EQ(1u, h.step_); \ EXPECT_EQ(double(x), h.actual_); \ } @@ -118,7 +118,7 @@ TEST(Reader, ParseNumberHandler) { StringStream s(str); \ ParseDoubleHandler h; \ Reader reader; \ - reader.ParseNumber<0>(s, h); \ + reader.Parse(s, h); \ EXPECT_EQ(1u, h.step_); \ EXPECT_DOUBLE_EQ(x, h.actual_); \ } @@ -178,11 +178,11 @@ TEST(Reader, ParseNumber_Error) { #define TEST_NUMBER_ERROR(errorCode, str) \ { \ char buffer[1001]; \ - sprintf(buffer, "[%s]", str); \ + sprintf(buffer, "%s", str); \ InsituStringStream s(buffer); \ BaseReaderHandler<> h; \ Reader reader; \ - EXPECT_FALSE(reader.Parse<0>(s, h)); \ + EXPECT_FALSE(reader.Parse(s, h)); \ EXPECT_EQ(errorCode, reader.GetParseErrorCode());\ } @@ -242,14 +242,14 @@ TEST(Reader, ParseString) { GenericInsituStringStream is(buffer); \ ParseStringHandler h; \ GenericReader reader; \ - reader.ParseString(is, h); \ + reader.Parse(is, h); \ EXPECT_EQ(0, StrCmp(e, h.str_)); \ EXPECT_EQ(StrLen(e), h.length_); \ free(buffer); \ GenericStringStream s(x); \ ParseStringHandler h2; \ GenericReader reader2; \ - reader2.ParseString<0>(s, h2); \ + reader2.Parse(s, h2); \ EXPECT_EQ(0, StrCmp(e, h2.str_)); \ EXPECT_EQ(StrLen(e), h2.length_); \ } @@ -314,7 +314,7 @@ TEST(Reader, ParseString) { const char e[] = "Hello\0World"; ParseStringHandler > h; Reader reader; - reader.ParseString<0>(s, h); + reader.Parse(s, h); EXPECT_EQ(0, memcmp(e, h.str_, h.length_ + 1)); EXPECT_EQ(11u, h.length_); } @@ -326,7 +326,7 @@ TEST(Reader, ParseString_Transcoding) { GenericStringStream > is(x); GenericReader, UTF16<> > reader; ParseStringHandler > h; - reader.ParseString<0>(is, h); + reader.Parse(is, h); EXPECT_EQ(0, StrCmp::Ch>(e, h.str_)); EXPECT_EQ(StrLen(e), h.length_); } @@ -335,7 +335,7 @@ TEST(Reader, ParseString_NonDestructive) { StringStream s("\"Hello\\nWorld\""); ParseStringHandler > h; Reader reader; - reader.ParseString<0>(s, h); + reader.Parse(s, h); EXPECT_EQ(0, StrCmp("Hello\nWorld", h.str_)); EXPECT_EQ(11u, h.length_); } @@ -447,7 +447,7 @@ TEST(Reader, ParseEmptyArray) { InsituStringStream s(json); ParseArrayHandler<0> h; Reader reader; - reader.ParseArray<0>(s, h); + reader.Parse(s, h); EXPECT_EQ(2u, h.step_); free(json); } @@ -457,7 +457,7 @@ TEST(Reader, ParseArray) { InsituStringStream s(json); ParseArrayHandler<4> h; Reader reader; - reader.ParseArray<0>(s, h); + reader.Parse(s, h); EXPECT_EQ(6u, h.step_); free(json); } @@ -470,7 +470,7 @@ TEST(Reader, ParseArray_Error) { InsituStringStream s(buffer); \ BaseReaderHandler<> h; \ GenericReader, UTF8<>, CrtAllocator> reader; \ - EXPECT_FALSE(reader.Parse<0>(s, h)); \ + EXPECT_FALSE(reader.Parse(s, h)); \ EXPECT_EQ(errorCode, reader.GetParseErrorCode());\ } @@ -534,7 +534,7 @@ TEST(Reader, ParseObject) { InsituStringStream s(json2); ParseObjectHandler h; Reader reader; - reader.ParseObject(s, h); + reader.Parse(s, h); EXPECT_EQ(20u, h.step_); free(json2); } @@ -544,7 +544,7 @@ TEST(Reader, ParseObject) { StringStream s(json); ParseObjectHandler h; Reader reader; - reader.ParseObject<0>(s, h); + reader.Parse(s, h); EXPECT_EQ(20u, h.step_); } } @@ -563,7 +563,7 @@ TEST(Reader, Parse_EmptyObject) { StringStream s("{ } "); ParseEmptyObjectHandler h; Reader reader; - reader.ParseObject<0>(s, h); + reader.Parse(s, h); EXPECT_EQ(2u, h.step_); } @@ -630,7 +630,7 @@ TEST(Reader, ParseInsituIterative_MultipleRoot) { InsituStringStream s(buffer); \ BaseReaderHandler<> h; \ Reader reader; \ - EXPECT_FALSE(reader.Parse<0>(s, h)); \ + EXPECT_FALSE(reader.Parse(s, h)); \ EXPECT_EQ(errorCode, reader.GetParseErrorCode());\ } @@ -643,15 +643,17 @@ TEST(Reader, ParseDocument_Error) { // The document root must not follow by other values. TEST_ERROR(kParseErrorDocumentRootNotSingular, "[] 0"); TEST_ERROR(kParseErrorDocumentRootNotSingular, "{} 0"); + TEST_ERROR(kParseErrorDocumentRootNotSingular, "null []"); + TEST_ERROR(kParseErrorDocumentRootNotSingular, "0 {}"); } TEST(Reader, ParseValue_Error) { // Invalid value. - TEST_ERROR(kParseErrorValueInvalid, "[nulL]"); - TEST_ERROR(kParseErrorValueInvalid, "[truE]"); - TEST_ERROR(kParseErrorValueInvalid, "[falsE]"); - TEST_ERROR(kParseErrorValueInvalid, "[a]"); - TEST_ERROR(kParseErrorValueInvalid, "[.1]"); + TEST_ERROR(kParseErrorValueInvalid, "nulL"); + TEST_ERROR(kParseErrorValueInvalid, "truE"); + TEST_ERROR(kParseErrorValueInvalid, "falsE"); + TEST_ERROR(kParseErrorValueInvalid, "a]"); + TEST_ERROR(kParseErrorValueInvalid, ".1"); } TEST(Reader, ParseObject_Error) { From 3755470f0f24225ad22abc925cd093f407b7c1a7 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:48:43 +0200 Subject: [PATCH 11/15] BaseReaderHandler: allow overriding of Default() implementation By adding an optional CRTP template parameter, the BaseReaderHandler can call the "overridden" `Default()` function from the `Derived` class. See https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern --- include/rapidjson/internal/meta.h | 9 +++++++++ include/rapidjson/reader.h | 33 ++++++++++++++++--------------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/include/rapidjson/internal/meta.h b/include/rapidjson/internal/meta.h index 62d5224..b19a9f4 100644 --- a/include/rapidjson/internal/meta.h +++ b/include/rapidjson/internal/meta.h @@ -21,6 +21,11 @@ #ifndef RAPIDJSON_INTERNAL_META_H_ #define RAPIDJSON_INTERNAL_META_H_ +#ifdef __GNUC__ +RAPIDJSON_DIAG_PUSH +RAPIDJSON_DIAG_OFF(effc++) +#endif + //@cond RAPIDJSON_INTERNAL namespace rapidjson { namespace internal { @@ -94,4 +99,8 @@ template struct RemoveSfinaeFptr { typedef } // namespace rapidjson //@endcond +#ifdef __GNUC__ +RAPIDJSON_DIAG_POP +#endif + #endif // RAPIDJSON_INTERNAL_META_H_ diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index 49a2fb0..25c286b 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -26,6 +26,7 @@ #include "rapidjson.h" #include "encodings.h" +#include "internal/meta.h" #include "internal/pow10.h" #include "internal/stack.h" @@ -120,25 +121,25 @@ concept Handler { //! Default implementation of Handler. /*! This can be used as base class of any reader handler. - \note implements Handler concept + \note implements Handler concept */ -template > +template, typename Derived = void> struct BaseReaderHandler { - typedef typename Encoding::Ch Ch; + typedef typename Encoding::Ch Ch; - bool Default() { return true; } - bool Null() { return Default(); } - bool Bool(bool) { return Default(); } - bool Int(int) { return Default(); } - bool Uint(unsigned) { return Default(); } - bool Int64(int64_t) { return Default(); } - bool Uint64(uint64_t) { return Default(); } - bool Double(double) { return Default(); } - bool String(const Ch*, SizeType, bool) { return Default(); } - bool StartObject() { return Default(); } - bool EndObject(SizeType) { return Default(); } - bool StartArray() { return Default(); } - bool EndArray(SizeType) { return Default(); } + bool Default() { return true; } + bool Null() { return static_cast(*this).Default(); } + bool Bool(bool) { return static_cast(*this).Default(); } + bool Int(int) { return static_cast(*this).Default(); } + bool Uint(unsigned) { return static_cast(*this).Default(); } + bool Int64(int64_t) { return static_cast(*this).Default(); } + bool Uint64(uint64_t) { return static_cast(*this).Default(); } + bool Double(double) { return static_cast(*this).Default(); } + bool String(const Ch*, SizeType, bool) { return static_cast(*this).Default(); } + bool StartObject() { return static_cast(*this).Default(); } + bool EndObject(SizeType) { return static_cast(*this).Default(); } + bool StartArray() { return static_cast(*this).Default(); } + bool EndArray(SizeType) { return static_cast(*this).Default(); } }; /////////////////////////////////////////////////////////////////////////////// From 834109557d4822a51ec47105ca5a76c73cb584e9 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 15:50:47 +0200 Subject: [PATCH 12/15] readertest.cpp: use CRTP to activate "ADD_FAILURE()" calls in handlers --- test/unittest/readertest.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index 194a6bb..7f4e167 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -31,7 +31,7 @@ RAPIDJSON_DIAG_OFF(effc++) #endif template -struct ParseBoolHandler : BaseReaderHandler<> { +struct ParseBoolHandler : BaseReaderHandler, ParseBoolHandler > { ParseBoolHandler() : step_(0) {} bool Default() { ADD_FAILURE(); return false; } // gcc 4.8.x generates warning in EXPECT_EQ(bool, bool) on this gtest version. @@ -66,7 +66,7 @@ struct ParseIntHandler : BaseReaderHandler, ParseIntHandler> { int actual_; }; -struct ParseUintHandler : BaseReaderHandler<> { +struct ParseUintHandler : BaseReaderHandler, ParseUintHandler> { ParseUintHandler() : step_(0), actual_() {} bool Default() { ADD_FAILURE(); return false; } bool Uint(unsigned i) { actual_ = i; step_++; return true; } @@ -75,7 +75,7 @@ struct ParseUintHandler : BaseReaderHandler<> { unsigned actual_; }; -struct ParseInt64Handler : BaseReaderHandler<> { +struct ParseInt64Handler : BaseReaderHandler, ParseInt64Handler> { ParseInt64Handler() : step_(0), actual_() {} bool Default() { ADD_FAILURE(); return false; } bool Int64(int64_t i) { actual_ = i; step_++; return true; } @@ -84,7 +84,7 @@ struct ParseInt64Handler : BaseReaderHandler<> { int64_t actual_; }; -struct ParseUint64Handler : BaseReaderHandler<> { +struct ParseUint64Handler : BaseReaderHandler, ParseUint64Handler> { ParseUint64Handler() : step_(0), actual_() {} bool Default() { ADD_FAILURE(); return false; } bool Uint64(uint64_t i) { actual_ = i; step_++; return true; } @@ -93,7 +93,7 @@ struct ParseUint64Handler : BaseReaderHandler<> { uint64_t actual_; }; -struct ParseDoubleHandler : BaseReaderHandler<> { +struct ParseDoubleHandler : BaseReaderHandler, ParseDoubleHandler> { ParseDoubleHandler() : step_(0), actual_() {} bool Default() { ADD_FAILURE(); return false; } bool Double(double d) { actual_ = d; step_++; return true; } @@ -209,7 +209,7 @@ TEST(Reader, ParseNumber_Error) { } template -struct ParseStringHandler : BaseReaderHandler { +struct ParseStringHandler : BaseReaderHandler > { ParseStringHandler() : str_(0), length_(0), copy_() {} ~ParseStringHandler() { EXPECT_TRUE(str_ != 0); if (copy_) free(const_cast(str_)); } @@ -431,7 +431,7 @@ TEST(Reader, ParseString_Error) { } template -struct ParseArrayHandler : BaseReaderHandler<> { +struct ParseArrayHandler : BaseReaderHandler, ParseArrayHandler > { ParseArrayHandler() : step_(0) {} bool Default() { ADD_FAILURE(); return false; } @@ -482,9 +482,10 @@ TEST(Reader, ParseArray_Error) { #undef TEST_ARRAY_ERROR } -struct ParseObjectHandler : BaseReaderHandler<> { +struct ParseObjectHandler : BaseReaderHandler, ParseObjectHandler> { ParseObjectHandler() : step_(0) {} + bool Default() { ADD_FAILURE(); return false; } bool Null() { EXPECT_EQ(8u, step_); step_++; return true; } bool Bool(bool b) { switch(step_) { @@ -549,7 +550,7 @@ TEST(Reader, ParseObject) { } } -struct ParseEmptyObjectHandler : BaseReaderHandler<> { +struct ParseEmptyObjectHandler : BaseReaderHandler, ParseEmptyObjectHandler> { ParseEmptyObjectHandler() : step_(0) {} bool Default() { ADD_FAILURE(); return false; } @@ -567,7 +568,7 @@ TEST(Reader, Parse_EmptyObject) { EXPECT_EQ(2u, h.step_); } -struct ParseMultipleRootHandler : BaseReaderHandler<> { +struct ParseMultipleRootHandler : BaseReaderHandler, ParseMultipleRootHandler> { ParseMultipleRootHandler() : step_(0) {} bool Default() { ADD_FAILURE(); return false; } From d84c051564b735d438e45f0a0c1657575813c9c8 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 16:11:57 +0200 Subject: [PATCH 13/15] jsoncheckertest: add checks for iterative parser as well --- test/unittest/jsoncheckertest.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/test/unittest/jsoncheckertest.cpp b/test/unittest/jsoncheckertest.cpp index 75ef3e8..f4169dc 100644 --- a/test/unittest/jsoncheckertest.cpp +++ b/test/unittest/jsoncheckertest.cpp @@ -65,8 +65,11 @@ TEST(JsonChecker, Reader) { } GenericDocument, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak) - if (!document.Parse((const char*)json).HasParseError()) - ADD_FAILURE_AT(filename, document.GetErrorOffset()); + document.Parse((const char*)json); + EXPECT_TRUE(document.HasParseError()); + + document.Parse((const char*)json); + EXPECT_TRUE(document.HasParseError()); free(json); } @@ -87,7 +90,11 @@ TEST(JsonChecker, Reader) { GenericDocument, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak) document.Parse((const char*)json); - EXPECT_TRUE(!document.HasParseError()); + EXPECT_FALSE(document.HasParseError()); + + document.Parse((const char*)json); + EXPECT_FALSE(document.HasParseError()); + free(json); } } From 453eda5f94c0a9eb165b6945383ffe864a2d1087 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 17:11:59 +0200 Subject: [PATCH 14/15] tabs to 4 spaces (following 0dbcc1cf) --- include/rapidjson/reader.h | 76 ++++++++++++++++--------------- test/unittest/jsoncheckertest.cpp | 20 ++++---- test/unittest/readertest.cpp | 52 ++++++++++----------- test/unittest/writertest.cpp | 68 +++++++++++++-------------- 4 files changed, 109 insertions(+), 107 deletions(-) diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index 25c286b..eacdacb 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -121,25 +121,27 @@ concept Handler { //! Default implementation of Handler. /*! This can be used as base class of any reader handler. - \note implements Handler concept + \note implements Handler concept */ template, typename Derived = void> struct BaseReaderHandler { - typedef typename Encoding::Ch Ch; + typedef typename Encoding::Ch Ch; - bool Default() { return true; } - bool Null() { return static_cast(*this).Default(); } - bool Bool(bool) { return static_cast(*this).Default(); } - bool Int(int) { return static_cast(*this).Default(); } - bool Uint(unsigned) { return static_cast(*this).Default(); } - bool Int64(int64_t) { return static_cast(*this).Default(); } - bool Uint64(uint64_t) { return static_cast(*this).Default(); } - bool Double(double) { return static_cast(*this).Default(); } - bool String(const Ch*, SizeType, bool) { return static_cast(*this).Default(); } - bool StartObject() { return static_cast(*this).Default(); } - bool EndObject(SizeType) { return static_cast(*this).Default(); } - bool StartArray() { return static_cast(*this).Default(); } - bool EndArray(SizeType) { return static_cast(*this).Default(); } + typedef typename internal::SelectIf, BaseReaderHandler, Derived>::Type Override; + + bool Default() { return true; } + bool Null() { return static_cast(*this).Default(); } + bool Bool(bool) { return static_cast(*this).Default(); } + bool Int(int) { return static_cast(*this).Default(); } + bool Uint(unsigned) { return static_cast(*this).Default(); } + bool Int64(int64_t) { return static_cast(*this).Default(); } + bool Uint64(uint64_t) { return static_cast(*this).Default(); } + bool Double(double) { return static_cast(*this).Default(); } + bool String(const Ch*, SizeType, bool) { return static_cast(*this).Default(); } + bool StartObject() { return static_cast(*this).Default(); } + bool EndObject(SizeType) { return static_cast(*this).Default(); } + bool StartArray() { return static_cast(*this).Default(); } + bool EndArray(SizeType) { return static_cast(*this).Default(); } }; /////////////////////////////////////////////////////////////////////////////// @@ -382,7 +384,7 @@ public: RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); } else { - ParseValue(is, handler); + ParseValue(is, handler); RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_); if (!(parseFlags & kParseStopWhenDoneFlag)) { @@ -904,8 +906,8 @@ private: IterativeParsingElementDelimiterState, IterativeParsingArrayFinishState, - // Single value state - IterativeParsingValueState, + // Single value state + IterativeParsingValueState, cIterativeParsingStateCount }; @@ -965,11 +967,11 @@ private: IterativeParsingErrorState, // Right curly bracket IterativeParsingErrorState, // Comma IterativeParsingErrorState, // Colon - IterativeParsingValueState, // String - IterativeParsingValueState, // False - IterativeParsingValueState, // True - IterativeParsingValueState, // Null - IterativeParsingValueState // Number + IterativeParsingValueState, // String + IterativeParsingValueState, // False + IterativeParsingValueState, // True + IterativeParsingValueState, // Null + IterativeParsingValueState // Number }, // Finish(sink state) { @@ -1106,12 +1108,12 @@ private: IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState - }, - // Single Value (sink state) - { - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, - IterativeParsingErrorState + }, + // Single Value (sink state) + { + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, + IterativeParsingErrorState } }; // End of G @@ -1248,13 +1250,13 @@ private: } } - case IterativeParsingValueState: - // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. - ParseValue(is, handler); - if (HasParseError()) { - return IterativeParsingErrorState; - } - return IterativeParsingFinishState; + case IterativeParsingValueState: + // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state. + ParseValue(is, handler); + if (HasParseError()) { + return IterativeParsingErrorState; + } + return IterativeParsingFinishState; default: RAPIDJSON_ASSERT(false); @@ -1270,7 +1272,7 @@ private: } switch (src) { - case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); + case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); case IterativeParsingObjectInitialState: case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); diff --git a/test/unittest/jsoncheckertest.cpp b/test/unittest/jsoncheckertest.cpp index f4169dc..caa1b8a 100644 --- a/test/unittest/jsoncheckertest.cpp +++ b/test/unittest/jsoncheckertest.cpp @@ -46,8 +46,8 @@ TEST(JsonChecker, Reader) { // jsonchecker/failXX.json for (int i = 1; i <= 33; i++) { - if (i == 1) // fail1.json is valid in rapidjson, which has no limitation on type of root element (RFC 7159). - continue; + if (i == 1) // fail1.json is valid in rapidjson, which has no limitation on type of root element (RFC 7159). + continue; if (i == 18) // fail18.json is valid in rapidjson, which has no limitation on depth of nesting. continue; @@ -59,17 +59,17 @@ TEST(JsonChecker, Reader) { json = ReadFile(filename, length); if (!json) { printf("jsonchecker file %s not found", filename); - ADD_FAILURE(); + ADD_FAILURE(); continue; } } GenericDocument, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak) - document.Parse((const char*)json); - EXPECT_TRUE(document.HasParseError()); + document.Parse((const char*)json); + EXPECT_TRUE(document.HasParseError()); - document.Parse((const char*)json); - EXPECT_TRUE(document.HasParseError()); + document.Parse((const char*)json); + EXPECT_TRUE(document.HasParseError()); free(json); } @@ -90,10 +90,10 @@ TEST(JsonChecker, Reader) { GenericDocument, CrtAllocator> document; // Use Crt allocator to check exception-safety (no memory leak) document.Parse((const char*)json); - EXPECT_FALSE(document.HasParseError()); + EXPECT_FALSE(document.HasParseError()); - document.Parse((const char*)json); - EXPECT_FALSE(document.HasParseError()); + document.Parse((const char*)json); + EXPECT_FALSE(document.HasParseError()); free(json); } diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index 7f4e167..9a19f96 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -45,7 +45,7 @@ TEST(Reader, ParseTrue) { StringStream s("true"); ParseBoolHandler h; Reader reader; - reader.Parse(s, h); + reader.Parse(s, h); EXPECT_EQ(1u, h.step_); } @@ -53,7 +53,7 @@ TEST(Reader, ParseFalse) { StringStream s("false"); ParseBoolHandler h; Reader reader; - reader.Parse(s, h); + reader.Parse(s, h); EXPECT_EQ(1u, h.step_); } @@ -108,7 +108,7 @@ TEST(Reader, ParseNumberHandler) { StringStream s(str); \ Handler h; \ Reader reader; \ - reader.Parse(s, h); \ + reader.Parse(s, h); \ EXPECT_EQ(1u, h.step_); \ EXPECT_EQ(double(x), h.actual_); \ } @@ -118,7 +118,7 @@ TEST(Reader, ParseNumberHandler) { StringStream s(str); \ ParseDoubleHandler h; \ Reader reader; \ - reader.Parse(s, h); \ + reader.Parse(s, h); \ EXPECT_EQ(1u, h.step_); \ EXPECT_DOUBLE_EQ(x, h.actual_); \ } @@ -178,11 +178,11 @@ TEST(Reader, ParseNumber_Error) { #define TEST_NUMBER_ERROR(errorCode, str) \ { \ char buffer[1001]; \ - sprintf(buffer, "%s", str); \ + sprintf(buffer, "%s", str); \ InsituStringStream s(buffer); \ BaseReaderHandler<> h; \ Reader reader; \ - EXPECT_FALSE(reader.Parse(s, h)); \ + EXPECT_FALSE(reader.Parse(s, h)); \ EXPECT_EQ(errorCode, reader.GetParseErrorCode());\ } @@ -242,14 +242,14 @@ TEST(Reader, ParseString) { GenericInsituStringStream is(buffer); \ ParseStringHandler h; \ GenericReader reader; \ - reader.Parse(is, h); \ + reader.Parse(is, h); \ EXPECT_EQ(0, StrCmp(e, h.str_)); \ EXPECT_EQ(StrLen(e), h.length_); \ free(buffer); \ GenericStringStream s(x); \ ParseStringHandler h2; \ GenericReader reader2; \ - reader2.Parse(s, h2); \ + reader2.Parse(s, h2); \ EXPECT_EQ(0, StrCmp(e, h2.str_)); \ EXPECT_EQ(StrLen(e), h2.length_); \ } @@ -314,7 +314,7 @@ TEST(Reader, ParseString) { const char e[] = "Hello\0World"; ParseStringHandler > h; Reader reader; - reader.Parse(s, h); + reader.Parse(s, h); EXPECT_EQ(0, memcmp(e, h.str_, h.length_ + 1)); EXPECT_EQ(11u, h.length_); } @@ -326,7 +326,7 @@ TEST(Reader, ParseString_Transcoding) { GenericStringStream > is(x); GenericReader, UTF16<> > reader; ParseStringHandler > h; - reader.Parse(is, h); + reader.Parse(is, h); EXPECT_EQ(0, StrCmp::Ch>(e, h.str_)); EXPECT_EQ(StrLen(e), h.length_); } @@ -335,7 +335,7 @@ TEST(Reader, ParseString_NonDestructive) { StringStream s("\"Hello\\nWorld\""); ParseStringHandler > h; Reader reader; - reader.Parse(s, h); + reader.Parse(s, h); EXPECT_EQ(0, StrCmp("Hello\nWorld", h.str_)); EXPECT_EQ(11u, h.length_); } @@ -447,7 +447,7 @@ TEST(Reader, ParseEmptyArray) { InsituStringStream s(json); ParseArrayHandler<0> h; Reader reader; - reader.Parse(s, h); + reader.Parse(s, h); EXPECT_EQ(2u, h.step_); free(json); } @@ -457,7 +457,7 @@ TEST(Reader, ParseArray) { InsituStringStream s(json); ParseArrayHandler<4> h; Reader reader; - reader.Parse(s, h); + reader.Parse(s, h); EXPECT_EQ(6u, h.step_); free(json); } @@ -470,7 +470,7 @@ TEST(Reader, ParseArray_Error) { InsituStringStream s(buffer); \ BaseReaderHandler<> h; \ GenericReader, UTF8<>, CrtAllocator> reader; \ - EXPECT_FALSE(reader.Parse(s, h)); \ + EXPECT_FALSE(reader.Parse(s, h)); \ EXPECT_EQ(errorCode, reader.GetParseErrorCode());\ } @@ -485,7 +485,7 @@ TEST(Reader, ParseArray_Error) { struct ParseObjectHandler : BaseReaderHandler, ParseObjectHandler> { ParseObjectHandler() : step_(0) {} - bool Default() { ADD_FAILURE(); return false; } + bool Default() { ADD_FAILURE(); return false; } bool Null() { EXPECT_EQ(8u, step_); step_++; return true; } bool Bool(bool b) { switch(step_) { @@ -535,7 +535,7 @@ TEST(Reader, ParseObject) { InsituStringStream s(json2); ParseObjectHandler h; Reader reader; - reader.Parse(s, h); + reader.Parse(s, h); EXPECT_EQ(20u, h.step_); free(json2); } @@ -545,7 +545,7 @@ TEST(Reader, ParseObject) { StringStream s(json); ParseObjectHandler h; Reader reader; - reader.Parse(s, h); + reader.Parse(s, h); EXPECT_EQ(20u, h.step_); } } @@ -564,7 +564,7 @@ TEST(Reader, Parse_EmptyObject) { StringStream s("{ } "); ParseEmptyObjectHandler h; Reader reader; - reader.Parse(s, h); + reader.Parse(s, h); EXPECT_EQ(2u, h.step_); } @@ -631,7 +631,7 @@ TEST(Reader, ParseInsituIterative_MultipleRoot) { InsituStringStream s(buffer); \ BaseReaderHandler<> h; \ Reader reader; \ - EXPECT_FALSE(reader.Parse(s, h)); \ + EXPECT_FALSE(reader.Parse(s, h)); \ EXPECT_EQ(errorCode, reader.GetParseErrorCode());\ } @@ -644,17 +644,17 @@ TEST(Reader, ParseDocument_Error) { // The document root must not follow by other values. TEST_ERROR(kParseErrorDocumentRootNotSingular, "[] 0"); TEST_ERROR(kParseErrorDocumentRootNotSingular, "{} 0"); - TEST_ERROR(kParseErrorDocumentRootNotSingular, "null []"); - TEST_ERROR(kParseErrorDocumentRootNotSingular, "0 {}"); + TEST_ERROR(kParseErrorDocumentRootNotSingular, "null []"); + TEST_ERROR(kParseErrorDocumentRootNotSingular, "0 {}"); } TEST(Reader, ParseValue_Error) { // Invalid value. - TEST_ERROR(kParseErrorValueInvalid, "nulL"); - TEST_ERROR(kParseErrorValueInvalid, "truE"); - TEST_ERROR(kParseErrorValueInvalid, "falsE"); - TEST_ERROR(kParseErrorValueInvalid, "a]"); - TEST_ERROR(kParseErrorValueInvalid, ".1"); + TEST_ERROR(kParseErrorValueInvalid, "nulL"); + TEST_ERROR(kParseErrorValueInvalid, "truE"); + TEST_ERROR(kParseErrorValueInvalid, "falsE"); + TEST_ERROR(kParseErrorValueInvalid, "a]"); + TEST_ERROR(kParseErrorValueInvalid, ".1"); } TEST(Reader, ParseObject_Error) { diff --git a/test/unittest/writertest.cpp b/test/unittest/writertest.cpp index fd42e8d..e313c8b 100644 --- a/test/unittest/writertest.cpp +++ b/test/unittest/writertest.cpp @@ -51,13 +51,13 @@ TEST(Writer, Compact) { } TEST(Writer, Root) { - TEST_ROUNDTRIP("null"); - TEST_ROUNDTRIP("true"); - TEST_ROUNDTRIP("false"); - TEST_ROUNDTRIP("0"); - TEST_ROUNDTRIP("\"foo\""); - TEST_ROUNDTRIP("[]"); - TEST_ROUNDTRIP("{}"); + TEST_ROUNDTRIP("null"); + TEST_ROUNDTRIP("true"); + TEST_ROUNDTRIP("false"); + TEST_ROUNDTRIP("0"); + TEST_ROUNDTRIP("\"foo\""); + TEST_ROUNDTRIP("[]"); + TEST_ROUNDTRIP("{}"); } TEST(Writer, Int) { @@ -170,7 +170,7 @@ TEST(Writer, AssertRootMayBeAnyValue) { {\ StringBuffer buffer;\ Writer writer(buffer);\ - EXPECT_TRUE(x);\ + EXPECT_TRUE(x);\ } T(writer.Bool(false)); T(writer.Bool(true)); @@ -243,18 +243,18 @@ TEST(Writer, AssertMultipleRoot) { writer.EndObject(); ASSERT_THROW(writer.StartObject(), AssertException); - writer.Reset(buffer); - writer.Null(); - ASSERT_THROW(writer.Int(0), AssertException); + writer.Reset(buffer); + writer.Null(); + ASSERT_THROW(writer.Int(0), AssertException); - writer.Reset(buffer); - writer.String("foo"); - ASSERT_THROW(writer.StartArray(), AssertException); + writer.Reset(buffer); + writer.String("foo"); + ASSERT_THROW(writer.StartArray(), AssertException); - writer.Reset(buffer); - writer.StartArray(); - writer.EndArray(); - ASSERT_THROW(writer.Double(3.14), AssertException); + writer.Reset(buffer); + writer.StartArray(); + writer.EndArray(); + ASSERT_THROW(writer.Double(3.14), AssertException); } TEST(Writer, RootObjectIsComplete) { @@ -287,21 +287,21 @@ TEST(Writer, RootArrayIsComplete) { TEST(Writer, RootValueIsComplete) { #define T(x)\ - {\ - StringBuffer buffer;\ - Writer writer(buffer);\ - EXPECT_FALSE(writer.IsComplete()); \ - x; \ - EXPECT_TRUE(writer.IsComplete()); \ - } - T(writer.Null()); - T(writer.Bool(true)); - T(writer.Bool(false)); - T(writer.Int(0)); - T(writer.Uint(0)); - T(writer.Int64(0)); - T(writer.Uint64(0)); - T(writer.Double(0)); - T(writer.String("")); + {\ + StringBuffer buffer;\ + Writer writer(buffer);\ + EXPECT_FALSE(writer.IsComplete()); \ + x; \ + EXPECT_TRUE(writer.IsComplete()); \ + } + T(writer.Null()); + T(writer.Bool(true)); + T(writer.Bool(false)); + T(writer.Int(0)); + T(writer.Uint(0)); + T(writer.Int64(0)); + T(writer.Uint64(0)); + T(writer.Double(0)); + T(writer.String("")); #undef T } From 6863033652ff720551dbf01db66c639dc693e7b9 Mon Sep 17 00:00:00 2001 From: "Philipp A. Hartmann" Date: Mon, 11 Aug 2014 17:27:38 +0200 Subject: [PATCH 15/15] readertest.cpp: remove remaining use of private functions --- test/unittest/readertest.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index 9a19f96..09560d8 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -20,7 +20,6 @@ #include "unittest.h" -#define private public // For testing private members #include "rapidjson/reader.h" using namespace rapidjson; @@ -733,7 +732,7 @@ TEST(Reader, CustomStringStream) { CustomStringStream > s(json); ParseObjectHandler h; Reader reader; - reader.ParseObject<0>(s, h); + reader.Parse(s, h); EXPECT_EQ(20u, h.step_); } @@ -777,7 +776,7 @@ TEST(Reader, Parse_IStreamWrapper_StringStream) { Reader reader; ParseArrayHandler<4> h; - reader.ParseArray<0>(is, h); + reader.Parse(is, h); EXPECT_FALSE(reader.HasParseError()); } @@ -788,7 +787,7 @@ TEST(Reader, Parse_IStreamWrapper_StringStream) { StringStream json(text); \ BaseReaderHandler<> handler; \ Reader reader; \ - reader.IterativeParse(json, handler); \ + reader.Parse(json, handler); \ EXPECT_TRUE(reader.HasParseError()); \ EXPECT_EQ(errorCode, reader.GetParseErrorCode()); \ EXPECT_EQ(offset, reader.GetErrorOffset()); \ @@ -872,7 +871,7 @@ TEST(Reader, IterativeParsing_General) { Reader reader; IterativeParsingReaderHandler<> handler; - ParseResult r = reader.IterativeParse(is, handler); + ParseResult r = reader.Parse(is, handler); EXPECT_FALSE(r.IsError()); EXPECT_FALSE(reader.HasParseError()); @@ -909,7 +908,7 @@ TEST(Reader, IterativeParsing_Count) { Reader reader; IterativeParsingReaderHandler<> handler; - ParseResult r = reader.IterativeParse(is, handler); + ParseResult r = reader.Parse(is, handler); EXPECT_FALSE(r.IsError()); EXPECT_FALSE(reader.HasParseError());