mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 13:03:17 +01:00
univalue: Avoid unnecessary roundtrip through double for numbers
JSON makes no distinction between numbers and reals, and our code doesn't need to do so either. This removes VREAL, as well as its specific post-processing in `UniValue::write`. Non-monetary amounts do not need to be forcibly formatted with 8 decimals, so the extra roundtrip was unnecessary (and potentially loses precision).
This commit is contained in:
parent
e061e2778d
commit
7650449a67
@ -14,6 +14,7 @@ from struct import *
|
|||||||
import binascii
|
import binascii
|
||||||
import json
|
import json
|
||||||
import StringIO
|
import StringIO
|
||||||
|
import decimal
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import http.client as httplib
|
import http.client as httplib
|
||||||
@ -243,7 +244,7 @@ class RESTTest (BitcoinTestFramework):
|
|||||||
response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"json", "", True)
|
response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"json", "", True)
|
||||||
assert_equal(response_header_json.status, 200)
|
assert_equal(response_header_json.status, 200)
|
||||||
response_header_json_str = response_header_json.read()
|
response_header_json_str = response_header_json.read()
|
||||||
json_obj = json.loads(response_header_json_str)
|
json_obj = json.loads(response_header_json_str, parse_float=decimal.Decimal)
|
||||||
assert_equal(len(json_obj), 1) #ensure that there is one header in the json response
|
assert_equal(len(json_obj), 1) #ensure that there is one header in the json response
|
||||||
assert_equal(json_obj[0]['hash'], bb_hash) #request/response hash should be the same
|
assert_equal(json_obj[0]['hash'], bb_hash) #request/response hash should be the same
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ void RPCTypeCheckObj(const UniValue& o,
|
|||||||
|
|
||||||
CAmount AmountFromValue(const UniValue& value)
|
CAmount AmountFromValue(const UniValue& value)
|
||||||
{
|
{
|
||||||
if (!value.isReal() && !value.isNum())
|
if (!value.isNum())
|
||||||
throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number");
|
throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number");
|
||||||
CAmount amount;
|
CAmount amount;
|
||||||
if (!ParseFixedPoint(value.getValStr(), 8, &amount))
|
if (!ParseFixedPoint(value.getValStr(), 8, &amount))
|
||||||
|
@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(univalue_constructor)
|
|||||||
|
|
||||||
double vd = -7.21;
|
double vd = -7.21;
|
||||||
UniValue v7(vd);
|
UniValue v7(vd);
|
||||||
BOOST_CHECK(v7.isReal());
|
BOOST_CHECK(v7.isNum());
|
||||||
BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21");
|
BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21");
|
||||||
|
|
||||||
string vs("yawn");
|
string vs("yawn");
|
||||||
@ -127,7 +127,7 @@ BOOST_AUTO_TEST_CASE(univalue_set)
|
|||||||
BOOST_CHECK_EQUAL(v.getValStr(), "zum");
|
BOOST_CHECK_EQUAL(v.getValStr(), "zum");
|
||||||
|
|
||||||
BOOST_CHECK(v.setFloat(-1.01));
|
BOOST_CHECK(v.setFloat(-1.01));
|
||||||
BOOST_CHECK(v.isReal());
|
BOOST_CHECK(v.isNum());
|
||||||
BOOST_CHECK_EQUAL(v.getValStr(), "-1.01");
|
BOOST_CHECK_EQUAL(v.getValStr(), "-1.01");
|
||||||
|
|
||||||
BOOST_CHECK(v.setInt((int)1023));
|
BOOST_CHECK(v.setInt((int)1023));
|
||||||
@ -272,7 +272,7 @@ BOOST_AUTO_TEST_CASE(univalue_object)
|
|||||||
objTypes["distance"] = UniValue::VNUM;
|
objTypes["distance"] = UniValue::VNUM;
|
||||||
objTypes["time"] = UniValue::VNUM;
|
objTypes["time"] = UniValue::VNUM;
|
||||||
objTypes["calories"] = UniValue::VNUM;
|
objTypes["calories"] = UniValue::VNUM;
|
||||||
objTypes["temperature"] = UniValue::VREAL;
|
objTypes["temperature"] = UniValue::VNUM;
|
||||||
objTypes["cat1"] = UniValue::VNUM;
|
objTypes["cat1"] = UniValue::VNUM;
|
||||||
objTypes["cat2"] = UniValue::VNUM;
|
objTypes["cat2"] = UniValue::VNUM;
|
||||||
BOOST_CHECK(obj.checkObject(objTypes));
|
BOOST_CHECK(obj.checkObject(objTypes));
|
||||||
|
@ -86,7 +86,7 @@ bool UniValue::setFloat(double val)
|
|||||||
oss << std::setprecision(16) << val;
|
oss << std::setprecision(16) << val;
|
||||||
|
|
||||||
bool ret = setNumStr(oss.str());
|
bool ret = setNumStr(oss.str());
|
||||||
typ = VREAL;
|
typ = VNUM;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +210,6 @@ const char *uvTypeName(UniValue::VType t)
|
|||||||
case UniValue::VARR: return "array";
|
case UniValue::VARR: return "array";
|
||||||
case UniValue::VSTR: return "string";
|
case UniValue::VSTR: return "string";
|
||||||
case UniValue::VNUM: return "number";
|
case UniValue::VNUM: return "number";
|
||||||
case UniValue::VREAL: return "number";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// not reached
|
// not reached
|
||||||
@ -280,7 +279,7 @@ int64_t UniValue::get_int64() const
|
|||||||
|
|
||||||
double UniValue::get_real() const
|
double UniValue::get_real() const
|
||||||
{
|
{
|
||||||
if (typ != VREAL && typ != VNUM)
|
if (typ != VNUM)
|
||||||
throw std::runtime_error("JSON value is not a number as expected");
|
throw std::runtime_error("JSON value is not a number as expected");
|
||||||
double retval;
|
double retval;
|
||||||
if (!ParseDouble(getValStr(), &retval))
|
if (!ParseDouble(getValStr(), &retval))
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
class UniValue {
|
class UniValue {
|
||||||
public:
|
public:
|
||||||
enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VREAL, VBOOL, };
|
enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
|
||||||
|
|
||||||
UniValue() { typ = VNULL; }
|
UniValue() { typ = VNULL; }
|
||||||
UniValue(UniValue::VType initialType, const std::string& initialStr = "") {
|
UniValue(UniValue::VType initialType, const std::string& initialStr = "") {
|
||||||
@ -78,7 +78,6 @@ public:
|
|||||||
bool isBool() const { return (typ == VBOOL); }
|
bool isBool() const { return (typ == VBOOL); }
|
||||||
bool isStr() const { return (typ == VSTR); }
|
bool isStr() const { return (typ == VSTR); }
|
||||||
bool isNum() const { return (typ == VNUM); }
|
bool isNum() const { return (typ == VNUM); }
|
||||||
bool isReal() const { return (typ == VREAL); }
|
|
||||||
bool isArray() const { return (typ == VARR); }
|
bool isArray() const { return (typ == VARR); }
|
||||||
bool isObject() const { return (typ == VOBJ); }
|
bool isObject() const { return (typ == VOBJ); }
|
||||||
|
|
||||||
|
@ -61,13 +61,6 @@ string UniValue::write(unsigned int prettyIndent,
|
|||||||
case VSTR:
|
case VSTR:
|
||||||
s += "\"" + json_escape(val) + "\"";
|
s += "\"" + json_escape(val) + "\"";
|
||||||
break;
|
break;
|
||||||
case VREAL:
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << std::showpoint << std::fixed << std::setprecision(8) << get_real();
|
|
||||||
s += ss.str();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VNUM:
|
case VNUM:
|
||||||
s += val;
|
s += val;
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user