Commit b55fcbd3 authored by Milo Yip's avatar Milo Yip

Merge pull request #61 from miloyip/issue59terminate

Fixes #59 by adding bool return value for each event handler function
parents 75cee948 f1ae39f9
......@@ -1015,44 +1015,45 @@ int z = a[0u].GetInt(); // This works too.
\param handler An object implementing concept Handler.
*/
template <typename Handler>
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<Encoding,Allocator>; // for deep copying
// Implementation of Handler
void Null() { new (stack_.template Push<ValueType>()) ValueType(); }
void Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); }
void Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); }
void Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); }
void Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); }
void Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); }
void Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); }
void String(const Ch* str, SizeType length, bool copy) {
bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
bool String(const Ch* str, SizeType length, bool copy) {
if (copy)
new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
else
new (stack_.template Push<ValueType>()) ValueType(str, length);
return true;
}
void StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); }
bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
void EndObject(SizeType memberCount) {
bool EndObject(SizeType memberCount) {
typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator());
return true;
}
void StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); }
bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
void EndArray(SizeType elementCount) {
bool EndArray(SizeType elementCount) {
ValueType* elements = stack_.template Pop<ValueType>(elementCount);
stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
return true;
}
private:
......
......@@ -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; }
PrettyWriter& String(const Ch* str, SizeType length, bool copy = false) {
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); }
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>()) 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<typename Base::Level>()->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>()) 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<typename Base::Level>()->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;
}
//@}
......
......@@ -79,7 +79,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.
};
///////////////////////////////////////////////////////////////////////////////
......@@ -87,22 +89,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
*/
......@@ -117,19 +121,19 @@ template<typename Encoding = UTF8<> >
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(); }
};
///////////////////////////////////////////////////////////////////////////////
......@@ -355,12 +359,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;
}
......@@ -387,9 +395,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());
}
}
......@@ -400,12 +412,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;
}
......@@ -419,7 +435,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());
}
}
......@@ -430,8 +450,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);
}
......@@ -441,10 +463,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<unsigned parseFlags, typename InputStream, typename Handler>
......@@ -452,8 +476,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);
}
......@@ -510,14 +536,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<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
if (HasParseError())
return;
handler.String(stack_.template Pop<typename TargetEncoding::Ch>(stackStream.length_), stackStream.length_ - 1, true);
if (!handler.String(stack_.template Pop<typename TargetEncoding::Ch>(stackStream.length_), stackStream.length_ - 1, true))
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
}
}
......@@ -719,6 +747,7 @@ private:
}
// Finish parsing, call event according to the type of number.
bool cont = true;
if (useDouble) {
int expSum = exp + expFrac;
if (expSum < -308) {
......@@ -729,22 +758,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
......
......@@ -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>()) 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<Level>()->inArray);
level_stack_.template Pop<Level>(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>()) 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<Level>()->inArray);
level_stack_.template Pop<Level>(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<SourceEncoding, TargetEncoding>::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;
......
......@@ -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
......
......@@ -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_;
};
......
......@@ -13,10 +13,10 @@ RAPIDJSON_DIAG_OFF(effc++)
template<bool expect>
struct ParseBoolHandler : BaseReaderHandler<> {
ParseBoolHandler() : step_(0) {}
void Default() { FAIL(); }
bool Default() { ADD_FAILURE(); return false; }
// 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<Encoding> {
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<Encoding> {
else
str_ = str;
length_ = length;
copy_ = copy;
copy_ = copy;
return true;
}
const typename Encoding::Ch* str_;
......@@ -411,10 +412,10 @@ template <unsigned count>
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_;
};
......
......@@ -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());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment