aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schnelli <jonas.schnelli@include7.ch>2015-05-10 15:53:54 +0200
committerJonas Schnelli <jonas.schnelli@include7.ch>2015-06-04 09:16:06 +0200
commit0c5b2cf69ae20f83cbd894bb19d0e111623bae0f (patch)
tree5adf63f805d4908ce5224c83bea99a763dfdf21d
parent21c10de8c2de17a6357dbbcea7613b41f6ab8449 (diff)
downloadbitcoin-0c5b2cf69ae20f83cbd894bb19d0e111623bae0f.tar.xz
univalue: add support for real, fix percision and make it json_spirit compatible
- avoid breaking the API because of different number/percision handling
-rw-r--r--src/rpcclient.cpp5
-rw-r--r--src/test/univalue_tests.cpp10
-rw-r--r--src/univalue/univalue.cpp8
-rw-r--r--src/univalue/univalue.h3
-rw-r--r--src/univalue/univalue_write.cpp9
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<std::stri
jVal.setBool(false);
else
{
- if (!jVal.read(strVal))
- throw runtime_error(string("Error parsing JSON:")+strVal);
+ if (!jVal.read(strVal) || (jVal.isNull() && strVal.size() > 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 <stdint.h>
#include <ctype.h>
+#include <iomanip>
#include <sstream>
#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 <ctype.h>
+#include <iomanip>
+#include <sstream>
#include <stdio.h>
#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;