diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 74e5c66..c37f7f0 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -1015,44 +1015,45 @@ int z = a[0u].GetInt(); // This works too. \param handler An object implementing concept Handler. */ template - const GenericValue& Accept(Handler& handler) const { + bool Accept(Handler& handler) const { switch(GetType()) { - case kNullType: handler.Null(); break; - case kFalseType: handler.Bool(false); break; - case kTrueType: handler.Bool(true); break; + case kNullType: return handler.Null(); + case kFalseType: return handler.Bool(false); + case kTrueType: return handler.Bool(true); case kObjectType: - handler.StartObject(); + if (!handler.StartObject()) + return false; for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { - handler.String(m->name.data_.s.str, m->name.data_.s.length, (m->name.flags_ & kCopyFlag) != 0); - m->value.Accept(handler); + if (!handler.String(m->name.data_.s.str, m->name.data_.s.length, (m->name.flags_ & kCopyFlag) != 0)) + return false; + if (!m->value.Accept(handler)) + return false; } - handler.EndObject(data_.o.size); - break; + return handler.EndObject(data_.o.size); case kArrayType: - handler.StartArray(); + if (!handler.StartArray()) + return false; for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v) - v->Accept(handler); - handler.EndArray(data_.a.size); - break; - + if (!v->Accept(handler)) + return false; + return handler.EndArray(data_.a.size); + case kStringType: - handler.String(data_.s.str, data_.s.length, (flags_ & kCopyFlag) != 0); - break; - + return handler.String(data_.s.str, data_.s.length, (flags_ & kCopyFlag) != 0); + case kNumberType: - if (IsInt()) handler.Int(data_.n.i.i); - else if (IsUint()) handler.Uint(data_.n.u.u); - else if (IsInt64()) handler.Int64(data_.n.i64); - else if (IsUint64()) handler.Uint64(data_.n.u64); - else handler.Double(data_.n.d); - break; - + if (IsInt()) return handler.Int(data_.n.i.i); + else if (IsUint()) return handler.Uint(data_.n.u.u); + else if (IsInt64()) return handler.Int64(data_.n.i64); + else if (IsUint64()) return handler.Uint64(data_.n.u64); + else return handler.Double(data_.n.d); + default: RAPIDJSON_ASSERT(false); } - return *this; + return false; } private: @@ -1354,33 +1355,36 @@ private: friend class GenericValue; // for deep copying // Implementation of Handler - void Null() { new (stack_.template Push()) ValueType(); } - void Bool(bool b) { new (stack_.template Push()) ValueType(b); } - void Int(int i) { new (stack_.template Push()) ValueType(i); } - void Uint(unsigned i) { new (stack_.template Push()) ValueType(i); } - void Int64(int64_t i) { new (stack_.template Push()) ValueType(i); } - void Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); } - void Double(double d) { new (stack_.template Push()) ValueType(d); } + bool Null() { new (stack_.template Push()) ValueType(); return true; } + bool Bool(bool b) { new (stack_.template Push()) ValueType(b); return true; } + bool Int(int i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint(unsigned i) { new (stack_.template Push()) ValueType(i); return true; } + bool Int64(int64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Uint64(uint64_t i) { new (stack_.template Push()) ValueType(i); return true; } + bool Double(double d) { new (stack_.template Push()) ValueType(d); return true; } - void String(const Ch* str, SizeType length, bool copy) { + bool String(const Ch* str, SizeType length, bool copy) { if (copy) new (stack_.template Push()) ValueType(str, length, GetAllocator()); else new (stack_.template Push()) ValueType(str, length); + return true; } - void StartObject() { new (stack_.template Push()) ValueType(kObjectType); } + bool StartObject() { new (stack_.template Push()) ValueType(kObjectType); return true; } - void EndObject(SizeType memberCount) { + bool EndObject(SizeType memberCount) { typename ValueType::Member* members = stack_.template Pop(memberCount); stack_.template Top()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator()); + return true; } - void StartArray() { new (stack_.template Push()) ValueType(kArrayType); } + bool StartArray() { new (stack_.template Push()) ValueType(kArrayType); return true; } - void EndArray(SizeType elementCount) { + bool EndArray(SizeType elementCount) { ValueType* elements = stack_.template Pop(elementCount); stack_.template Top()->SetArrayRaw(elements, elementCount, GetAllocator()); + return true; } private: diff --git a/include/rapidjson/prettywriter.h b/include/rapidjson/prettywriter.h index 031f5de..f01e53e 100644 --- a/include/rapidjson/prettywriter.h +++ b/include/rapidjson/prettywriter.h @@ -51,29 +51,27 @@ public: */ //@{ - PrettyWriter& Null() { PrettyPrefix(kNullType); Base::WriteNull(); return *this; } - PrettyWriter& Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); Base::WriteBool(b); return *this; } - PrettyWriter& Int(int i) { PrettyPrefix(kNumberType); Base::WriteInt(i); return *this; } - PrettyWriter& Uint(unsigned u) { PrettyPrefix(kNumberType); Base::WriteUint(u); return *this; } - PrettyWriter& Int64(int64_t i64) { PrettyPrefix(kNumberType); Base::WriteInt64(i64); return *this; } - PrettyWriter& Uint64(uint64_t u64) { PrettyPrefix(kNumberType); Base::WriteUint64(u64); return *this; } - PrettyWriter& Double(double d) { PrettyPrefix(kNumberType); Base::WriteDouble(d); return *this; } + bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); } + bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); } + bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); } + bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); } + bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); } + bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); } + bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); } - PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) { + bool String(const Ch* str, SizeType length, bool copy = false) { (void)copy; PrettyPrefix(kStringType); - Base::WriteString(str, length); - return *this; + return Base::WriteString(str, length); } - PrettyWriter& StartObject() { + bool StartObject() { PrettyPrefix(kObjectType); new (Base::level_stack_.template Push()) typename Base::Level(false); - Base::WriteStartObject(); - return *this; + return Base::WriteStartObject(); } - PrettyWriter& EndObject(SizeType memberCount = 0) { + bool EndObject(SizeType memberCount = 0) { (void)memberCount; RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); RAPIDJSON_ASSERT(!Base::level_stack_.template Top()->inArray); @@ -83,20 +81,20 @@ public: Base::os_.Put('\n'); WriteIndent(); } - Base::WriteEndObject(); + if (!Base::WriteEndObject()) + return false; if (Base::level_stack_.Empty()) // end of json text Base::os_.Flush(); - return *this; + return true; } - PrettyWriter& StartArray() { + bool StartArray() { PrettyPrefix(kArrayType); new (Base::level_stack_.template Push()) typename Base::Level(true); - Base::WriteStartArray(); - return *this; + return Base::WriteStartArray(); } - PrettyWriter& EndArray(SizeType memberCount = 0) { + bool EndArray(SizeType memberCount = 0) { (void)memberCount; RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); RAPIDJSON_ASSERT(Base::level_stack_.template Top()->inArray); @@ -106,10 +104,11 @@ public: Base::os_.Put('\n'); WriteIndent(); } - Base::WriteEndArray(); + if (!Base::WriteEndArray()) + return false; if (Base::level_stack_.Empty()) // end of json text Base::os_.Flush(); - return *this; + return true; } //@} @@ -118,12 +117,15 @@ public: //@{ //! Simpler but slower overload. - PrettyWriter& String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } //! Overridden for fluent API, see \ref Writer::Double() - PrettyWriter& Double(double d, int precision) { + bool Double(double d, int precision) { int oldPrecision = Base::GetDoublePrecision(); - return SetDoublePrecision(precision).Double(d).SetDoublePrecision(oldPrecision); + SetDoublePrecision(precision); + bool ret = Double(d); + SetDoublePrecision(oldPrecision); + return ret; } //@} diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index 59d03b6..2e1480d 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -75,7 +75,9 @@ enum ParseErrorCode { kParseErrorNumberTooBig, //!< Number too big to be stored in double. kParseErrorNumberMissFraction, //!< Miss fraction part in number. - kParseErrorNumberMissExponent //!< Miss exponent in number. + kParseErrorNumberMissExponent, //!< Miss exponent in number. + + kParseErrorTermination //!< Parsing was terminated. }; /////////////////////////////////////////////////////////////////////////////// @@ -83,22 +85,24 @@ enum ParseErrorCode { /*! \class rapidjson::Handler \brief Concept for receiving events from GenericReader upon parsing. + The functions return true if no error occurs. If they return false, + the event publisher should terminate the process. \code concept Handler { typename Ch; - void Null(); - void Bool(bool b); - void Int(int i); - void Uint(unsigned i); - void Int64(int64_t i); - void Uint64(uint64_t i); - void Double(double d); - void String(const Ch* str, SizeType length, bool copy); - void StartObject(); - void EndObject(SizeType memberCount); - void StartArray(); - void EndArray(SizeType elementCount); + bool Null(); + bool Bool(bool b); + bool Int(int i); + bool Uint(unsigned i); + bool Int64(int64_t i); + bool Uint64(uint64_t i); + bool Double(double d); + bool String(const Ch* str, SizeType length, bool copy); + bool StartObject(); + bool EndObject(SizeType memberCount); + bool StartArray(); + bool EndArray(SizeType elementCount); }; \endcode */ @@ -113,19 +117,19 @@ template > struct BaseReaderHandler { typedef typename Encoding::Ch Ch; - void Default() {} - void Null() { Default(); } - void Bool(bool) { Default(); } - void Int(int) { Default(); } - void Uint(unsigned) { Default(); } - void Int64(int64_t) { Default(); } - void Uint64(uint64_t) { Default(); } - void Double(double) { Default(); } - void String(const Ch*, SizeType, bool) { Default(); } - void StartObject() { Default(); } - void EndObject(SizeType) { Default(); } - void StartArray() { Default(); } - void EndArray(SizeType) { Default(); } + 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(); } }; /////////////////////////////////////////////////////////////////////////////// @@ -351,12 +355,16 @@ private: void ParseObject(InputStream& is, Handler& handler) { RAPIDJSON_ASSERT(is.Peek() == '{'); is.Take(); // Skip '{' - handler.StartObject(); + + if (!handler.StartObject()) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + SkipWhitespace(is); if (is.Peek() == '}') { is.Take(); - handler.EndObject(0); // empty object + if (!handler.EndObject(0)) // empty object + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); return; } @@ -383,9 +391,13 @@ private: ++memberCount; - switch(is.Take()) { + switch (is.Take()) { case ',': SkipWhitespace(is); break; - case '}': handler.EndObject(memberCount); return; + case '}': + if (!handler.EndObject(memberCount)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + else + return; default: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); } } @@ -396,12 +408,16 @@ private: void ParseArray(InputStream& is, Handler& handler) { RAPIDJSON_ASSERT(is.Peek() == '['); is.Take(); // Skip '[' - handler.StartArray(); + + if (!handler.StartArray()) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + SkipWhitespace(is); if (is.Peek() == ']') { is.Take(); - handler.EndArray(0); // empty array + if (!handler.EndArray(0)) // empty array + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); return; } @@ -415,7 +431,11 @@ private: switch (is.Take()) { case ',': SkipWhitespace(is); break; - case ']': handler.EndArray(elementCount); return; + case ']': + if (!handler.EndArray(elementCount)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + else + return; default: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); } } @@ -426,8 +446,10 @@ private: RAPIDJSON_ASSERT(is.Peek() == 'n'); is.Take(); - if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l') - handler.Null(); + if (is.Take() == 'u' && is.Take() == 'l' && is.Take() == 'l') { + if (!handler.Null()) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } else RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1); } @@ -437,10 +459,12 @@ private: RAPIDJSON_ASSERT(is.Peek() == 't'); is.Take(); - if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e') - handler.Bool(true); + if (is.Take() == 'r' && is.Take() == 'u' && is.Take() == 'e') { + if (!handler.Bool(true)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } else - RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); + RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1); } template @@ -448,8 +472,10 @@ private: RAPIDJSON_ASSERT(is.Peek() == 'f'); is.Take(); - if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e') - handler.Bool(false); + if (is.Take() == 'a' && is.Take() == 'l' && is.Take() == 's' && is.Take() == 'e') { + if (!handler.Bool(false)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell()); + } else RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1); } @@ -506,14 +532,16 @@ private: return; size_t length = s.PutEnd(head) - 1; RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); - handler.String((typename TargetEncoding::Ch*)head, SizeType(length), false); + if (!handler.String((typename TargetEncoding::Ch*)head, SizeType(length), false)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); } else { StackStream stackStream(stack_); ParseStringToStream(s, stackStream); if (HasParseError()) return; - handler.String(stack_.template Pop(stackStream.length_), stackStream.length_ - 1, true); + if (!handler.String(stack_.template Pop(stackStream.length_), stackStream.length_ - 1, true)) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); } } @@ -715,6 +743,7 @@ private: } // Finish parsing, call event according to the type of number. + bool cont = true; if (useDouble) { int expSum = exp + expFrac; if (expSum < -308) { @@ -725,22 +754,24 @@ private: else d *= internal::Pow10(expSum); - handler.Double(minus ? -d : d); + cont = handler.Double(minus ? -d : d); } else { if (try64bit) { if (minus) - handler.Int64(-(int64_t)i64); + cont = handler.Int64(-(int64_t)i64); else - handler.Uint64(i64); + cont = handler.Uint64(i64); } else { if (minus) - handler.Int(-(int)i); + cont = handler.Int(-(int)i); else - handler.Uint(i); + cont = handler.Uint(i); } } + if (!cont) + RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); } // Parse any JSON value diff --git a/include/rapidjson/writer.h b/include/rapidjson/writer.h index 979b781..33bf71b 100644 --- a/include/rapidjson/writer.h +++ b/include/rapidjson/writer.h @@ -64,12 +64,12 @@ public: */ //@{ - Writer& Null() { Prefix(kNullType); WriteNull(); return *this; } - Writer& Bool(bool b) { Prefix(b ? kTrueType : kFalseType); WriteBool(b); return *this; } - Writer& Int(int i) { Prefix(kNumberType); WriteInt(i); return *this; } - Writer& Uint(unsigned u) { Prefix(kNumberType); WriteUint(u); return *this; } - Writer& Int64(int64_t i64) { Prefix(kNumberType); WriteInt64(i64); return *this; } - Writer& Uint64(uint64_t u64) { Prefix(kNumberType); WriteUint64(u64); return *this; } + bool Null() { Prefix(kNullType); return WriteNull(); } + bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return WriteBool(b); } + bool Int(int i) { Prefix(kNumberType); return WriteInt(i); } + bool Uint(unsigned u) { Prefix(kNumberType); return WriteUint(u); } + bool Int64(int64_t i64) { Prefix(kNumberType); return WriteInt64(i64); } + bool Uint64(uint64_t u64) { Prefix(kNumberType); return WriteUint64(u64); } //! Writes the given \c double value to the stream /*! @@ -80,51 +80,48 @@ public: writer.SetDoublePrecision(12).Double(M_PI); \endcode \param d The value to be written. - \return The Writer itself for fluent API. + \return Whether it is succeed. */ - Writer& Double(double d) { Prefix(kNumberType); WriteDouble(d); return *this; } + bool Double(double d) { Prefix(kNumberType); return WriteDouble(d); } - Writer& String(const Ch* str, SizeType length, bool copy = false) { + bool String(const Ch* str, SizeType length, bool copy = false) { (void)copy; Prefix(kStringType); - WriteString(str, length); - return *this; + return WriteString(str, length); } - Writer& StartObject() { + bool StartObject() { Prefix(kObjectType); new (level_stack_.template Push()) Level(false); - WriteStartObject(); - return *this; + return WriteStartObject(); } - Writer& EndObject(SizeType memberCount = 0) { + bool EndObject(SizeType memberCount = 0) { (void)memberCount; RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); level_stack_.template Pop(1); - WriteEndObject(); + bool ret = WriteEndObject(); if (level_stack_.Empty()) // end of json text os_.Flush(); - return *this; + return ret; } - Writer& StartArray() { + bool StartArray() { Prefix(kArrayType); new (level_stack_.template Push()) Level(true); - WriteStartArray(); - return *this; + return WriteStartArray(); } - Writer& EndArray(SizeType elementCount = 0) { + bool EndArray(SizeType elementCount = 0) { (void)elementCount; RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); level_stack_.template Pop(1); - WriteEndArray(); + bool ret = WriteEndArray(); if (level_stack_.Empty()) // end of json text os_.Flush(); - return *this; + return ret; } //@} @@ -138,15 +135,18 @@ public: \see Double(), SetDoublePrecision(), GetDoublePrecision() \param d The value to be written \param precision The number of significant digits for this value - \return The Writer itself for fluent API. + \return Whether it is succeeded. */ - Writer& Double(double d, int precision) { + bool Double(double d, int precision) { int oldPrecision = GetDoublePrecision(); - return SetDoublePrecision(precision).Double(d).SetDoublePrecision(oldPrecision); + SetDoublePrecision(precision); + bool ret = Double(d); + SetDoublePrecision(oldPrecision); + return ret; } //! Simpler but slower overload. - Writer& String(const Ch* str) { return String(str, internal::StrLen(str)); } + bool String(const Ch* str) { return String(str, internal::StrLen(str)); } //@} @@ -160,28 +160,29 @@ protected: static const size_t kDefaultLevelDepth = 32; - void WriteNull() { - os_.Put('n'); os_.Put('u'); os_.Put('l'); os_.Put('l'); + bool WriteNull() { + os_.Put('n'); os_.Put('u'); os_.Put('l'); os_.Put('l'); return true; } - void WriteBool(bool b) { + bool WriteBool(bool b) { if (b) { os_.Put('t'); os_.Put('r'); os_.Put('u'); os_.Put('e'); } else { os_.Put('f'); os_.Put('a'); os_.Put('l'); os_.Put('s'); os_.Put('e'); } + return true; } - void WriteInt(int i) { + bool WriteInt(int i) { if (i < 0) { os_.Put('-'); i = -i; } - WriteUint((unsigned)i); + return WriteUint((unsigned)i); } - void WriteUint(unsigned u) { + bool WriteUint(unsigned u) { char buffer[10]; char *p = buffer; do { @@ -193,17 +194,19 @@ protected: --p; os_.Put(*p); } while (p != buffer); + return true; } - void WriteInt64(int64_t i64) { + bool WriteInt64(int64_t i64) { if (i64 < 0) { os_.Put('-'); i64 = -i64; } WriteUint64((uint64_t)i64); + return true; } - void WriteUint64(uint64_t u64) { + bool WriteUint64(uint64_t u64) { char buffer[20]; char *p = buffer; do { @@ -215,6 +218,7 @@ protected: --p; os_.Put(*p); } while (p != buffer); + return true; } #ifdef _MSC_VER @@ -224,16 +228,17 @@ protected: #endif //! \todo Optimization with custom double-to-string converter. - void WriteDouble(double d) { + bool WriteDouble(double d) { char buffer[100]; int ret = RAPIDJSON_SNPRINTF(buffer, sizeof(buffer), "%.*g", doublePrecision_, d); RAPIDJSON_ASSERT(ret >= 1); for (int i = 0; i < ret; i++) os_.Put(buffer[i]); + return true; } #undef RAPIDJSON_SNPRINTF - void WriteString(const Ch* str, SizeType length) { + bool WriteString(const Ch* str, SizeType length) { static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; static const char escape[256] = { #define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 @@ -266,12 +271,13 @@ protected: Transcoder::Transcode(is, os_); } os_.Put('\"'); + return true; } - void WriteStartObject() { os_.Put('{'); } - void WriteEndObject() { os_.Put('}'); } - void WriteStartArray() { os_.Put('['); } - void WriteEndArray() { os_.Put(']'); } + bool WriteStartObject() { os_.Put('{'); return true; } + bool WriteEndObject() { os_.Put('}'); return true; } + bool WriteStartArray() { os_.Put('['); return true; } + bool WriteEndArray() { os_.Put(']'); return true; } void Prefix(Type type) { (void)type; diff --git a/test/perftest/perftest.h b/test/perftest/perftest.h index 0f42a6c..be36920 100644 --- a/test/perftest/perftest.h +++ b/test/perftest/perftest.h @@ -8,7 +8,11 @@ #define TEST_PLATFORM 0 #define TEST_MISC 0 -#if TEST_RAPIDJSON +#define TEST_VERSION_CODE(x,y,z) \ + (((x)*100000) + ((y)*100) + (z)) + +// Only gcc >4.3 supports SSE4.2 +#if TEST_RAPIDJSON && !(defined(__GNUC__) && TEST_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) < TEST_VERSION_CODE(4,3,0)) //#define RAPIDJSON_SSE2 #define RAPIDJSON_SSE42 #endif diff --git a/test/perftest/rapidjsontest.cpp b/test/perftest/rapidjsontest.cpp index dd8bc30..6eb6e2a 100644 --- a/test/perftest/rapidjsontest.cpp +++ b/test/perftest/rapidjsontest.cpp @@ -179,8 +179,8 @@ RAPIDJSON_DIAG_OFF(effc++) struct ValueCounter : public BaseReaderHandler<> { ValueCounter() : count_(1) {} // root - void EndObject(SizeType memberCount) { count_ += memberCount * 2; } - void EndArray(SizeType elementCount) { count_ += elementCount; } + bool EndObject(SizeType memberCount) { count_ += memberCount * 2; return true; } + bool EndArray(SizeType elementCount) { count_ += elementCount; return true; } SizeType count_; }; diff --git a/test/unittest/readertest.cpp b/test/unittest/readertest.cpp index 494a9f2..fe6613a 100644 --- a/test/unittest/readertest.cpp +++ b/test/unittest/readertest.cpp @@ -13,10 +13,10 @@ RAPIDJSON_DIAG_OFF(effc++) template struct ParseBoolHandler : BaseReaderHandler<> { ParseBoolHandler() : step_(0) {} - void Default() { FAIL(); } + bool Default() { FAIL(); } // gcc 4.8.x generates warning in EXPECT_EQ(bool, bool) on this gtest version. // Workaround with EXPECT_TRUE(). - void Bool(bool b) { /*EXPECT_EQ(expect, b); */EXPECT_TRUE(expect == b); ++step_; } + bool Bool(bool b) { /*EXPECT_EQ(expect, b); */EXPECT_TRUE(expect == b); ++step_; return true; } unsigned step_; }; @@ -39,8 +39,8 @@ TEST(Reader, ParseFalse) { struct ParseIntHandler : BaseReaderHandler<> { ParseIntHandler() : step_(0), actual_() {} - void Default() { FAIL(); } - void Int(int i) { actual_ = i; step_++; } + bool Default() { ADD_FAILURE(); return false; } + bool Int(int i) { actual_ = i; step_++; return true; } unsigned step_; int actual_; @@ -48,8 +48,8 @@ struct ParseIntHandler : BaseReaderHandler<> { struct ParseUintHandler : BaseReaderHandler<> { ParseUintHandler() : step_(0), actual_() {} - void Default() { FAIL(); } - void Uint(unsigned i) { actual_ = i; step_++; } + bool Default() { ADD_FAILURE(); return false; } + bool Uint(unsigned i) { actual_ = i; step_++; return true; } unsigned step_; unsigned actual_; @@ -57,8 +57,8 @@ struct ParseUintHandler : BaseReaderHandler<> { struct ParseInt64Handler : BaseReaderHandler<> { ParseInt64Handler() : step_(0), actual_() {} - void Default() { FAIL(); } - void Int64(int64_t i) { actual_ = i; step_++; } + bool Default() { ADD_FAILURE(); return false; } + bool Int64(int64_t i) { actual_ = i; step_++; return true; } unsigned step_; int64_t actual_; @@ -66,8 +66,8 @@ struct ParseInt64Handler : BaseReaderHandler<> { struct ParseUint64Handler : BaseReaderHandler<> { ParseUint64Handler() : step_(0), actual_() {} - void Default() { FAIL(); } - void Uint64(uint64_t i) { actual_ = i; step_++; } + bool Default() { ADD_FAILURE(); return false; } + bool Uint64(uint64_t i) { actual_ = i; step_++; return true; } unsigned step_; uint64_t actual_; @@ -75,8 +75,8 @@ struct ParseUint64Handler : BaseReaderHandler<> { struct ParseDoubleHandler : BaseReaderHandler<> { ParseDoubleHandler() : step_(0), actual_() {} - void Default() { FAIL(); } - void Double(double d) { actual_ = d; step_++; } + bool Default() { ADD_FAILURE(); return false; } + bool Double(double d) { actual_ = d; step_++; return true; } unsigned step_; double actual_; @@ -194,8 +194,8 @@ struct ParseStringHandler : BaseReaderHandler { ParseStringHandler(const ParseStringHandler&); ParseStringHandler& operator=(const ParseStringHandler&); - void Default() { FAIL(); } - void String(const typename Encoding::Ch* str, size_t length, bool copy) { + bool Default() { ADD_FAILURE(); return false; } + bool String(const typename Encoding::Ch* str, size_t length, bool copy) { EXPECT_EQ(0, str_); if (copy) { str_ = (typename Encoding::Ch*)malloc((length + 1) * sizeof(typename Encoding::Ch)); @@ -204,7 +204,8 @@ struct ParseStringHandler : BaseReaderHandler { else str_ = str; length_ = length; - copy_ = copy; + copy_ = copy; + return true; } const typename Encoding::Ch* str_; @@ -411,10 +412,10 @@ template struct ParseArrayHandler : BaseReaderHandler<> { ParseArrayHandler() : step_(0) {} - void Default() { FAIL(); } - void Uint(unsigned i) { EXPECT_EQ(step_, i); step_++; } - void StartArray() { EXPECT_EQ(0u, step_); step_++; } - void EndArray(SizeType) { step_++; } + bool Default() { ADD_FAILURE(); return false; } + bool Uint(unsigned i) { EXPECT_EQ(step_, i); step_++; return true; } + bool StartArray() { EXPECT_EQ(0u, step_); step_++; return true; } + bool EndArray(SizeType) { step_++; return true; } unsigned step_; }; @@ -462,42 +463,42 @@ TEST(Reader, ParseArray_Error) { struct ParseObjectHandler : BaseReaderHandler<> { ParseObjectHandler() : step_(0) {} - void Null() { EXPECT_EQ(8u, step_); step_++; } - void Bool(bool b) { + bool Null() { EXPECT_EQ(8u, step_); step_++; return true; } + bool Bool(bool b) { switch(step_) { - case 4: EXPECT_TRUE(b); step_++; break; - case 6: EXPECT_FALSE(b); step_++; break; - default: FAIL(); + case 4: EXPECT_TRUE(b); step_++; return true; + case 6: EXPECT_FALSE(b); step_++; return true; + default: ADD_FAILURE(); return false; } } - void Int(int i) { + bool Int(int i) { switch(step_) { - case 10: EXPECT_EQ(123, i); step_++; break; - case 15: EXPECT_EQ(1, i); step_++; break; - case 16: EXPECT_EQ(2, i); step_++; break; - case 17: EXPECT_EQ(3, i); step_++; break; - default: FAIL(); + case 10: EXPECT_EQ(123, i); step_++; return true; + case 15: EXPECT_EQ(1, i); step_++; return true; + case 16: EXPECT_EQ(2, i); step_++; return true; + case 17: EXPECT_EQ(3, i); step_++; return true; + default: ADD_FAILURE(); return false; } } - void Uint(unsigned i) { Int(i); } - void Double(double d) { EXPECT_EQ(12u, step_); EXPECT_EQ(3.1416, d); step_++; } - void String(const char* str, size_t, bool) { + bool Uint(unsigned i) { return Int(i); } + bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_EQ(3.1416, d); step_++; return true; } + bool String(const char* str, size_t, bool) { switch(step_) { - case 1: EXPECT_STREQ("hello", str); step_++; break; - case 2: EXPECT_STREQ("world", str); step_++; break; - case 3: EXPECT_STREQ("t", str); step_++; break; - case 5: EXPECT_STREQ("f", str); step_++; break; - case 7: EXPECT_STREQ("n", str); step_++; break; - case 9: EXPECT_STREQ("i", str); step_++; break; - case 11: EXPECT_STREQ("pi", str); step_++; break; - case 13: EXPECT_STREQ("a", str); step_++; break; - default: FAIL(); + case 1: EXPECT_STREQ("hello", str); step_++; return true; + case 2: EXPECT_STREQ("world", str); step_++; return true; + case 3: EXPECT_STREQ("t", str); step_++; return true; + case 5: EXPECT_STREQ("f", str); step_++; return true; + case 7: EXPECT_STREQ("n", str); step_++; return true; + case 9: EXPECT_STREQ("i", str); step_++; return true; + case 11: EXPECT_STREQ("pi", str); step_++; return true; + case 13: EXPECT_STREQ("a", str); step_++; return true; + default: ADD_FAILURE(); return false; } } - void StartObject() { EXPECT_EQ(0u, step_); step_++; } - void EndObject(SizeType memberCount) { EXPECT_EQ(19u, step_); EXPECT_EQ(7u, memberCount); step_++;} - void StartArray() { EXPECT_EQ(14u, step_); step_++; } - void EndArray(SizeType elementCount) { EXPECT_EQ(18u, step_); EXPECT_EQ(3u, elementCount); step_++;} + bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; } + bool EndObject(SizeType memberCount) { EXPECT_EQ(19u, step_); EXPECT_EQ(7u, memberCount); step_++; return true; } + bool StartArray() { EXPECT_EQ(14u, step_); step_++; return true; } + bool EndArray(SizeType elementCount) { EXPECT_EQ(18u, step_); EXPECT_EQ(3u, elementCount); step_++; return true; } unsigned step_; }; @@ -529,9 +530,9 @@ TEST(Reader, ParseObject) { struct ParseEmptyObjectHandler : BaseReaderHandler<> { ParseEmptyObjectHandler() : step_(0) {} - void Default() { FAIL(); } - void StartObject() { EXPECT_EQ(0u, step_); step_++; } - void EndObject(SizeType) { EXPECT_EQ(1u, step_); step_++; } + bool Default() { ADD_FAILURE(); return false; } + bool StartObject() { EXPECT_EQ(0u, step_); step_++; return true; } + bool EndObject(SizeType) { EXPECT_EQ(1u, step_); step_++; return true; } unsigned step_; }; diff --git a/test/unittest/writertest.cpp b/test/unittest/writertest.cpp index d189fa1..be3d77b 100644 --- a/test/unittest/writertest.cpp +++ b/test/unittest/writertest.cpp @@ -83,13 +83,13 @@ TEST(Writer,DoublePrecision) { buffer.Clear(); } { // explicit individual double precisions - writer.SetDoublePrecision(2) - .StartArray() - .Double(1.2345,5) - .Double(1.2345678,9) - .Double(0.123456789012,12) - .Double(1234567.8,8) - .EndArray(); + writer.SetDoublePrecision(2); + writer.StartArray(); + writer.Double(1.2345, 5); + writer.Double(1.2345678, 9); + writer.Double(0.123456789012, 12); + writer.Double(1234567.8, 8); + writer.EndArray(); EXPECT_EQ(writer.GetDoublePrecision(), 2); EXPECT_STREQ(json, buffer.GetString());