From 0c5b2cf69ae20f83cbd894bb19d0e111623bae0f Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 15:53:54 +0200 Subject: [PATCH] univalue: add support for real, fix percision and make it json_spirit compatible - avoid breaking the API because of different number/percision handling --- src/rpcclient.cpp | 5 +++-- src/test/univalue_tests.cpp | 10 +++++----- src/univalue/univalue.cpp | 8 ++++++-- src/univalue/univalue.h | 3 ++- src/univalue/univalue_write.cpp | 9 +++++++++ 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index bedf9ffbcb..aa6d1eff59 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -146,8 +146,9 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 0)) + if(!jVal.setNumStr(strVal) || jVal.isNull()) + throw runtime_error(string("Error parsing JSON:")+strVal); } params.push_back(jVal); } diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 6df980ad0c..87186cac44 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(univalue_constructor) double vd = -7.21; UniValue v7(vd); - BOOST_CHECK(v7.isNum()); + BOOST_CHECK(v7.isReal()); BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21"); string vs("yawn"); @@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(univalue_set) BOOST_CHECK_EQUAL(v.getValStr(), "zum"); BOOST_CHECK(v.setFloat(-1.01)); - BOOST_CHECK(v.isNum()); + BOOST_CHECK(v.isReal()); BOOST_CHECK_EQUAL(v.getValStr(), "-1.01"); BOOST_CHECK(v.setInt((int)1023)); @@ -230,7 +230,7 @@ BOOST_AUTO_TEST_CASE(univalue_object) objTypes["distance"] = UniValue::VNUM; objTypes["time"] = UniValue::VNUM; objTypes["calories"] = UniValue::VNUM; - objTypes["temperature"] = UniValue::VNUM; + objTypes["temperature"] = UniValue::VREAL; objTypes["cat1"] = UniValue::VNUM; objTypes["cat2"] = UniValue::VNUM; BOOST_CHECK(obj.checkObject(objTypes)); @@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(univalue_object) } static const char *json1 = -"[1.1,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]"; +"[1.10000000,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]"; BOOST_AUTO_TEST_CASE(univalue_readwrite) { @@ -257,7 +257,7 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite) BOOST_CHECK(v.isArray()); BOOST_CHECK_EQUAL(v.size(), 2); - BOOST_CHECK_EQUAL(v[0].getValStr(), "1.1"); + BOOST_CHECK_EQUAL(v[0].getValStr(), "1.10000000"); UniValue obj = v[1]; BOOST_CHECK(obj.isObject()); diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index 6870ce59eb..994d93113a 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include "univalue.h" @@ -78,9 +79,11 @@ bool UniValue::setFloat(double val) string s; ostringstream oss; - oss << val; + oss << std::setprecision(16) << val; - return setNumStr(oss.str()); + bool ret = setNumStr(oss.str()); + typ = VREAL; + return ret; } bool UniValue::setStr(const string& val_) @@ -203,6 +206,7 @@ const char *uvTypeName(UniValue::VType t) case UniValue::VARR: return "array"; case UniValue::VSTR: return "string"; case UniValue::VNUM: return "number"; + case UniValue::VREAL: return "number"; } // not reached diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index 28d6e3d3cd..efcf202bdd 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -17,7 +17,7 @@ class UniValue { public: - enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, }; + enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VREAL, VBOOL, }; UniValue() { typ = VNULL; } UniValue(UniValue::VType initialType, const std::string& initialStr = "") { @@ -76,6 +76,7 @@ public: bool isBool() const { return (typ == VBOOL); } bool isStr() const { return (typ == VSTR); } bool isNum() const { return (typ == VNUM); } + bool isReal() const { return (typ == VREAL); } bool isArray() const { return (typ == VARR); } bool isObject() const { return (typ == VOBJ); } diff --git a/src/univalue/univalue_write.cpp b/src/univalue/univalue_write.cpp index 9a1d364c95..d360c253b0 100644 --- a/src/univalue/univalue_write.cpp +++ b/src/univalue/univalue_write.cpp @@ -3,6 +3,8 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include +#include #include #include "univalue.h" #include "univalue_escapes.h" @@ -59,6 +61,13 @@ string UniValue::write(unsigned int prettyIndent, case VSTR: s += "\"" + json_escape(val) + "\""; break; + case VREAL: + { + std::stringstream ss; + ss << std::showpoint << std::fixed << std::setprecision(8) << get_real(); + s += ss.str(); + } + break; case VNUM: s += val; break;