Try to save the type for Var with Json serialize/deserialize (#1703)

* Fix JSON to Var parsing (save the type)

* fix formatting

* remove redundant include <iostream>

* fix c++98 compatibility
This commit is contained in:
Marian Krivoš 2017-07-03 23:33:32 +02:00 committed by Aleksandar Fabijanic
parent 3ec9316ab0
commit 7f193697db
3 changed files with 98 additions and 12 deletions

View File

@ -404,7 +404,63 @@ Var Var::parse(const std::string& val, std::string::size_type& pos)
case '"':
return parseJSONString(val, pos);
default:
return parseString(val, pos);
{
std::string str = parseString(val, pos);
if (str == "false")
return false;
if (str == "true")
return true;
bool isNumber = false;
bool isSigned = false;
int separators = 0;
int separator = 0;
int index = 0;
size_t size = str.size();
for (size_t i = 0; i < size ; ++i)
{
int ch = str[i];
if ((ch == '-' || ch == '+') && index == 0)
{
if (ch == '-')
isSigned = true;
}
else if (Ascii::isDigit(ch))
{
isNumber |= true;
}
else if (ch == '.' || ch == ',')
{
separator = ch;
++separators;
if (separators > 1)
return str;
}
else
return str;
++index;
}
if (separator && isNumber)
{
const double number = NumberParser::parseFloat(str, separator);
return Var(number);
}
else if (separator == 0 && isNumber && isSigned)
{
const Poco::Int64 number = NumberParser::parse64(str);
return number;
}
else if (separator == 0 && isNumber && !isSigned)
{
const Poco::UInt64 number = NumberParser::parseUnsigned64(str);
return number;
}
return str;
}
}
}
std::string empty;

View File

@ -2203,11 +2203,11 @@ void VarTest::testJSONDeserializeString()
char cc = b2.convert<char>();
assert (cc == 'c');
tst = "{ \"a\" : 1, \"b\" : 2 \n}";
tst = "{ \"a\" : \"1\", \"b\" : \"2\" \n}";
a = Var::parse(tst);
assert(a.toString() == "{ \"a\" : \"1\", \"b\" : \"2\" }");
tst = "{ \"a\" : 1, \"b\" : 2\n}";
tst = "{ \"a\" : \"1\", \"b\" : \"2\"\n}";
a = Var::parse(tst);
assert(a.toString() == "{ \"a\" : \"1\", \"b\" : \"2\" }");
}
@ -2373,15 +2373,43 @@ void VarTest::testJSONDeserializeStruct()
std::string sStr = Var::toString(aStr);
Var a = Var::parse(sStr);
assert (aStr["i8"] == i8);
assert (aStr["u16"] == u16);
assert (aStr["i32"] == i32);
assert (aStr["u64"] == u64);
assert (aStr["b"] == b);
assert (aStr["f"] == f);
assert (aStr["d"] == d);
assert (aStr["s"] == s);
assert (aStr["c"] == c);
assert (a["i8"] == i8);
assert (a["u16"] == u16);
assert (a["i32"] == i32);
assert (a["u64"] == u64);
assert (a["b"] == b);
assert (a["f"] == f);
assert (a["d"] == d);
assert (a["s"] == s);
assert (a["c"] == c);
}
void VarTest::testJSONRoundtripStruct()
{
Poco::Int64 i64(-1234567890);
Poco::UInt64 u64(1234567890);
u64 *= u64;
bool b = false;
double d = 3.1415;
std::string s("test string");
DynamicStruct aStr;
aStr["i64"] = i64;
aStr["u64"] = u64;
aStr["b"] = b;
aStr["d"] = d;
aStr["s"] = s;
std::string sStr = Var::toString(aStr);
Var a = Var::parse(sStr);
assert (a["i64"].isInteger());
assert (!a["u64"].isSigned());
assert (a["b"].isBoolean());
assert (a["d"].isNumeric());
assert (a["s"].isString());
std::string serialized = Var::toString(a);
assert (sStr == serialized);
}
@ -2642,6 +2670,7 @@ CppUnit::Test* VarTest::suite()
CppUnit_addTest(pSuite, VarTest, testJSONDeserializeArray);
CppUnit_addTest(pSuite, VarTest, testJSONDeserializeStruct);
CppUnit_addTest(pSuite, VarTest, testJSONDeserializeComplex);
CppUnit_addTest(pSuite, VarTest, testJSONRoundtripStruct);
CppUnit_addTest(pSuite, VarTest, testDate);
CppUnit_addTest(pSuite, VarTest, testEmpty);
CppUnit_addTest(pSuite, VarTest, testIterator);

View File

@ -67,6 +67,7 @@ public:
void testJSONDeserializePrimitives();
void testJSONDeserializeArray();
void testJSONDeserializeStruct();
void testJSONRoundtripStruct();
void testJSONDeserializeComplex();
void testDate();
void testEmpty();