GH #144: Poco::Dynamic emits invalid JSON

GH #144: Poco::Dynamic emits invalid JSON
This commit is contained in:
Aleksandar Fabijanic 2013-04-06 11:04:33 -05:00
parent d0ff7ccf7c
commit f9aea9acdf
7 changed files with 74 additions and 22 deletions

View File

@ -1,6 +1,6 @@
This is the changelog file for the POCO C++ Libraries.
Release 1.5.2 (2013-03-??)
Release 1.5.2 (2013-04-29)
==========================
- added MongoDB library (Franky Braem)
- fixed GH #57: poco-1.5.1: Doesn't compile for Android
@ -38,6 +38,7 @@ Release 1.5.2 (2013-03-??)
- simplified default TCP/HTTPServer construction
- fixed GH #141: Application::run() documentation/implementation discrepancy
- changed RowFormatter to SharedPtr<RowFormatter> in Data::RecordSet interface (breaking change!)
- fixed GH #144: Poco::Dynamic emits invalid JSON
Release 1.5.1 (2013-01-11)
==========================

View File

@ -120,6 +120,13 @@ public:
return _data.second;
}
std::string toString()
{
std::string str;
Var(*this).convert<std::string>(str);
return str;
}
private:
Data _data;
};
@ -208,9 +215,9 @@ public:
// JSON format definition: { string ':' value } string:value pair n-times, sep. by ','
val.append("{ ");
Var key(_val.first());
appendJSONString(val, key);
appendJSONKey(val, key);
val.append(" : ");
appendJSONString(val, _val.second());
appendJSONValue(val, _val.second());
val.append(" }");
}
@ -357,9 +364,9 @@ public:
// JSON format definition: { string ':' value } string:value pair n-times, sep. by ','
val.append("{ ");
Var key(_val.first());
appendJSONString(val, key);
appendJSONKey(val, key);
val.append(" : ");
appendJSONString(val, _val.second());
appendJSONValue(val, _val.second());
val.append(" }");
}

View File

@ -204,6 +204,13 @@ public:
return keys;
}
std::string toString()
{
std::string str;
Var(*this).convert<std::string>(str);
return str;
}
private:
Data _data;
};
@ -294,20 +301,20 @@ public:
if (!_val.empty())
{
Var key(it->first);
appendJSONString(val, key);
appendJSONKey(val, key);
val.append(" : ");
appendJSONString(val, it->second);
appendJSONValue(val, it->second);
++it;
}
for (; it != itEnd; ++it)
{
val.append(", ");
Var key(it->first);
appendJSONString(val, key);
appendJSONKey(val, key);
val.append(" : ");
appendJSONString(val, it->second);
appendJSONValue(val, it->second);
}
val.append(" }");
val.append(" }");
}
void convert(Poco::DateTime&) const
@ -465,18 +472,18 @@ public:
if (!_val.empty())
{
Var key(it->first);
appendJSONString(val, key);
appendJSONKey(val, key);
val.append(" : ");
appendJSONString(val, it->second);
appendJSONValue(val, it->second);
++it;
}
for (; it != itEnd; ++it)
{
val.append(", ");
Var key(it->first);
appendJSONString(val, key);
appendJSONKey(val, key);
val.append(" : ");
appendJSONString(val, it->second);
appendJSONValue(val, it->second);
}
val.append(" }");
}

View File

@ -70,8 +70,20 @@ bool Foundation_API isJSONString(const Var& any);
/// Returns true for values that should be JSON-formatted as string.
void Foundation_API appendJSONKey(std::string& val, const Var& any);
/// Converts the any to a JSON key (i.e. wraps it into double quotes
/// regardless of the underlying type) and appends it to val.
void Foundation_API appendJSONString(std::string& val, const Var& any);
/// Converts the any to a JSON value and adds it to val
/// Converts the any to a JSON string (i.e. wraps it into double quotes)
/// regardless of the underlying type) and appends it to val.
void Foundation_API appendJSONValue(std::string& val, const Var& any);
/// Converts the any to a JSON value (if underlying type qualifies
/// as string - see isJSONString() - , it is wrapped into double quotes)
/// and appends it to val
class Foundation_API VarHolder
@ -2694,14 +2706,14 @@ public:
typename std::vector<T>::const_iterator itEnd = _val.end();
if (!_val.empty())
{
appendJSONString(val, *it);
appendJSONValue(val, *it);
++it;
}
for (; it != itEnd; ++it)
{
val.append(", ");
appendJSONString(val, *it);
appendJSONValue(val, *it);
}
val.append(" ]");
}

View File

@ -499,7 +499,7 @@ void Var::skipWhiteSpace(const std::string& val, std::string::size_type& pos)
std::string Var::toString(const Var& any)
{
std::string res;
appendJSONString(res, any);
appendJSONValue(res, any);
return res;
}

View File

@ -56,12 +56,28 @@ bool isJSONString(const Var& any)
{
return any.type() == typeid(std::string) ||
any.type() == typeid(char) ||
any.type() == typeid(char*) ||
any.type() == typeid(Poco::DateTime) ||
any.type() == typeid(Poco::LocalDateTime);
any.type() == typeid(Poco::LocalDateTime) ||
any.type() == typeid(Poco::Timestamp);
}
void appendJSONString(std::string& val, const Var& any)
{
val.append(1, '"');
val.append(any.convert<std::string>());
val.append(1, '"');
}
void appendJSONKey(std::string& val, const Var& any)
{
return appendJSONString(val, any);
}
void appendJSONValue(std::string& val, const Var& any)
{
if (any.isEmpty()) val.append("null");
else

View File

@ -1999,9 +1999,11 @@ void VarTest::testDynamicStructInt()
Dynamic::Struct<int> aStruct;
aStruct[0] = "Junior";
aStruct[1] = "POCO";
aStruct[2] = 10;
Var a1(aStruct);
assert (a1[0] == "Junior");
assert (a1[1] == "POCO");
assert (a1[2] == 10);
a1[0] = "Senior";
assert (a1[0] == "Senior");
@ -2039,13 +2041,15 @@ void VarTest::testDynamicPair()
catch (InvalidAccessException&) { }
Var va(aPair);
assert ("{ 0 : null }" == va.convert<std::string>());
assert ("{ \"0\" : null }" == va.convert<std::string>());
assert (aPair.toString() == va.convert<std::string>());
aPair = Pair<int>(4, "123");
assert ("123" == aPair.second());
va = aPair;
assert ("{ 4 : \"123\" }" == va.convert<std::string>());
assert ("{ \"4\" : \"123\" }" == va.convert<std::string>());
assert (aPair.toString() == va.convert<std::string>());
int i = 1;
std::string s = "2";
@ -2063,10 +2067,12 @@ void VarTest::testDynamicPair()
assert ("2" == pPair.second());
Var vp(pPair);
assert ("{ 1 : \"2\" }" == vp.convert<std::string>());
assert ("{ \"1\" : \"2\" }" == vp.convert<std::string>());
assert (pPair.toString() == vp.convert<std::string>());
Var vs(sPair);
assert ("{ \"2\" : 1 }" == vs.convert<std::string>());
assert (sPair.toString() == vs.convert<std::string>());
}
@ -2094,6 +2100,7 @@ void VarTest::testStructToString()
std::string res = a1.convert<std::string>();
std::string expected = "{ \"Age\" : 1, \"First Name\" : \"Junior\", \"Last Name\" : \"POCO\" }";
assert (res == expected);
assert (aStruct.toString() == res);
}
@ -2127,6 +2134,7 @@ void VarTest::testArrayOfStructsToString()
"] ] ]";
assert (res == expected);
assert (a1.toString() == res);
}
@ -2153,6 +2161,7 @@ void VarTest::testStructWithArraysToString()
"\"Age\" : 1, \"First Name\" : \"Junior\", \"Last Name\" : [ \"string\", 23 ] }";
assert (res == expected);
assert (aStruct.toString() == res);
}