From efc78837728bebcf2030d1d495018e563eb10c71 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 20 Aug 2014 09:59:31 -0400 Subject: UniValue: prefer .size() to .count(), to harmonize w/ existing tree --- src/bitcoin-tx.cpp | 4 ++-- src/test/univalue_tests.cpp | 16 ++++++++-------- src/univalue/univalue.h | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index c82d4f93a8..45990f6bd8 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -346,7 +346,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) UniValue keysObj = registers["privatekeys"]; fGivenKeys = true; - for (unsigned int kidx = 0; kidx < keysObj.count(); kidx++) { + for (unsigned int kidx = 0; kidx < keysObj.size(); kidx++) { if (!keysObj[kidx].isStr()) throw runtime_error("privatekey not a string"); CBitcoinSecret vchSecret; @@ -363,7 +363,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) throw runtime_error("prevtxs register variable must be set."); UniValue prevtxsObj = registers["prevtxs"]; { - for (unsigned int previdx = 0; previdx < prevtxsObj.count(); previdx++) { + for (unsigned int previdx = 0; previdx < prevtxsObj.size(); previdx++) { UniValue prevOut = prevtxsObj[previdx]; if (!prevOut.isObject()) throw runtime_error("expected prevtxs internal object"); diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 8cecfbf651..6df980ad0c 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -72,13 +72,13 @@ BOOST_AUTO_TEST_CASE(univalue_set) BOOST_CHECK(v.setObject()); BOOST_CHECK(v.isObject()); - BOOST_CHECK_EQUAL(v.count(), 0); + BOOST_CHECK_EQUAL(v.size(), 0); BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ); BOOST_CHECK(v.empty()); BOOST_CHECK(v.setArray()); BOOST_CHECK(v.isArray()); - BOOST_CHECK_EQUAL(v.count(), 0); + BOOST_CHECK_EQUAL(v.size(), 0); BOOST_CHECK(v.setStr("zum")); BOOST_CHECK(v.isStr()); @@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(univalue_array) BOOST_CHECK(arr.push_backV(vec)); BOOST_CHECK_EQUAL(arr.empty(), false); - BOOST_CHECK_EQUAL(arr.count(), 5); + BOOST_CHECK_EQUAL(arr.size(), 5); BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023"); BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy"); @@ -157,7 +157,7 @@ BOOST_AUTO_TEST_CASE(univalue_array) arr.clear(); BOOST_CHECK(arr.empty()); - BOOST_CHECK_EQUAL(arr.count(), 0); + BOOST_CHECK_EQUAL(arr.size(), 0); } BOOST_AUTO_TEST_CASE(univalue_object) @@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(univalue_object) BOOST_CHECK(obj.pushKVs(obj2)); BOOST_CHECK_EQUAL(obj.empty(), false); - BOOST_CHECK_EQUAL(obj.count(), 9); + BOOST_CHECK_EQUAL(obj.size(), 9); BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100"); BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John"); @@ -240,7 +240,7 @@ BOOST_AUTO_TEST_CASE(univalue_object) obj.clear(); BOOST_CHECK(obj.empty()); - BOOST_CHECK_EQUAL(obj.count(), 0); + BOOST_CHECK_EQUAL(obj.size(), 0); } static const char *json1 = @@ -255,13 +255,13 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite) BOOST_CHECK(v.read(strJson1)); BOOST_CHECK(v.isArray()); - BOOST_CHECK_EQUAL(v.count(), 2); + BOOST_CHECK_EQUAL(v.size(), 2); BOOST_CHECK_EQUAL(v[0].getValStr(), "1.1"); UniValue obj = v[1]; BOOST_CHECK(obj.isObject()); - BOOST_CHECK_EQUAL(obj.count(), 3); + BOOST_CHECK_EQUAL(obj.size(), 3); BOOST_CHECK(obj["key1"].isStr()); BOOST_CHECK_EQUAL(obj["key1"].getValStr(), "str"); diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index 88d73b8c64..d31c596a61 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -58,7 +58,7 @@ public: std::string getValStr() const { return val; } bool empty() const { return (values.size() == 0); } - size_t count() const { return values.size(); } + size_t size() const { return values.size(); } bool getBool() const { return isTrue(); } bool checkObject(const std::map& memberTypes); -- cgit v1.2.3 From 5e3060c0d104c734e7e2a200e2d937ea01166c8a Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 20 Aug 2014 11:13:52 -0400 Subject: UniValue: export NullUniValue global constant --- src/univalue/univalue.cpp | 10 +++++----- src/univalue/univalue.h | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index 4e445a542a..6870ce59eb 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -9,7 +9,7 @@ using namespace std; -static const UniValue nullValue; +const UniValue NullUniValue; void UniValue::clear() { @@ -175,11 +175,11 @@ bool UniValue::checkObject(const std::map& t) const UniValue& UniValue::operator[](const std::string& key) const { if (typ != VOBJ) - return nullValue; + return NullUniValue; int index = findKey(key); if (index < 0) - return nullValue; + return NullUniValue; return values[index]; } @@ -187,9 +187,9 @@ const UniValue& UniValue::operator[](const std::string& key) const const UniValue& UniValue::operator[](unsigned int index) const { if (typ != VOBJ && typ != VARR) - return nullValue; + return NullUniValue; if (index >= values.size()) - return nullValue; + return NullUniValue; return values[index]; } diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index d31c596a61..afe751ed9d 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -152,4 +152,6 @@ extern enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed, const char *raw); extern const char *uvTypeName(UniValue::VType t); +extern const UniValue NullUniValue; #endif // BITCOIN_UNIVALUE_UNIVALUE_H + -- cgit v1.2.3 From 15982a8b69ec6ab3c3a6bf71fc6a9b681d3ff541 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 20 Aug 2014 15:15:16 -0400 Subject: Convert tree to using univalue. Eliminate all json_spirit uses. --- src/Makefile.am | 1 + src/bitcoin-cli.cpp | 20 +++++----- src/json_spirit_wrapper.h | 17 +++++++++ src/qt/rpcconsole.cpp | 18 +++++---- src/rpcblockchain.cpp | 16 +++++--- src/rpcclient.cpp | 2 +- src/rpcclient.h | 4 +- src/rpcmining.cpp | 19 +++++----- src/rpcmisc.cpp | 5 +-- src/rpcnet.cpp | 8 ++-- src/rpcprotocol.cpp | 10 ++--- src/rpcprotocol.h | 4 +- src/rpcrawtransaction.cpp | 47 ++++++++++++----------- src/rpcserver.cpp | 51 ++++++++++++------------- src/rpcserver.h | 18 ++++----- src/test/base58_tests.cpp | 40 +++++++++----------- src/test/rpc_tests.cpp | 18 ++++----- src/test/script_tests.cpp | 22 +++++------ src/test/sighash_tests.cpp | 11 ++---- src/test/transaction_tests.cpp | 33 ++++++++++++----- src/univalue/univalue.h | 84 ++++++++++++++++++++++++++++++++++++++++++ src/wallet/rpcdump.cpp | 14 +++---- src/wallet/rpcwallet.cpp | 64 +++++++++++++++++--------------- 23 files changed, 321 insertions(+), 205 deletions(-) create mode 100644 src/json_spirit_wrapper.h diff --git a/src/Makefile.am b/src/Makefile.am index 1c2f770418..63332f9acd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -342,6 +342,7 @@ endif bitcoin_cli_LDADD = \ $(LIBBITCOIN_CLI) \ + $(LIBBITCOIN_UNIVALUE) \ $(LIBBITCOIN_UTIL) \ $(LIBSECP256K1) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 1269d7a119..9950153a65 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -143,7 +143,7 @@ Object CallRPC(const string& strMethod, const Array& params) // Parse reply Value valReply; - if (!read_string(strReply, valReply)) + if (!valReply.read(strReply)) throw runtime_error("couldn't parse reply from server"); const Object& reply = valReply.get_obj(); if (reply.empty()) @@ -176,29 +176,27 @@ int CommandLineRPC(int argc, char *argv[]) const bool fWait = GetBoolArg("-rpcwait", false); do { try { - const Object reply = CallRPC(strMethod, params); + // Execute + Object reply = CallRPC(strMethod, params); // Parse reply const Value& result = find_value(reply, "result"); const Value& error = find_value(reply, "error"); - if (error.type() != null_type) { + if (!error.isNull()) { // Error - const int code = find_value(error.get_obj(), "code").get_int(); - if (fWait && code == RPC_IN_WARMUP) - throw CConnectionFailed("server in warmup"); - strPrint = "error: " + write_string(error, false); + strPrint = "error: " + error.write(); + int code = error["code"].get_int(); nRet = abs(code); } else { // Result - if (result.type() == null_type) + if (result.isNull()) strPrint = ""; - else if (result.type() == str_type) + else if (result.isStr()) strPrint = result.get_str(); else - strPrint = write_string(result, true); + strPrint = result.write(2); } - // Connection succeeded, no need to retry. break; } diff --git a/src/json_spirit_wrapper.h b/src/json_spirit_wrapper.h new file mode 100644 index 0000000000..1962cf6431 --- /dev/null +++ b/src/json_spirit_wrapper.h @@ -0,0 +1,17 @@ +#ifndef __JSON_SPIRIT_WRAPPER_H__ +#define __JSON_SPIRIT_WRAPPER_H__ + +#include "univalue/univalue.h" + +namespace json_spirit { + +typedef UniValue Value; +typedef UniValue Array; +typedef UniValue Object; +typedef UniValue::VType Value_type; + +} + +#define find_value(val,key) (val[key]) + +#endif // __JSON_SPIRIT_WRAPPER_H__ diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 29c971ec79..29b1e8f262 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -16,10 +16,10 @@ #include "rpcclient.h" #include "util.h" -#include "json/json_spirit_value.h" - #include +#include "univalue/univalue.h" + #ifdef ENABLE_WALLET #include #endif @@ -167,21 +167,25 @@ void RPCExecutor::request(const QString &command) std::string strPrint; // Convert argument list to JSON objects in method-dependent way, // and pass it along with the method name to the dispatcher. - json_spirit::Value result = tableRPC.execute( + UniValue result = tableRPC.execute( args[0], RPCConvertValues(args[0], std::vector(args.begin() + 1, args.end()))); // Format result reply - if (result.type() == json_spirit::null_type) + if (result.isNull()) strPrint = ""; - else if (result.type() == json_spirit::str_type) + else if (result.isStr()) strPrint = result.get_str(); else - strPrint = write_string(result, true); + strPrint = result.write(2); emit reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); } +<<<<<<< HEAD catch (const json_spirit::Object& objError) +======= + catch (UniValue& objError) +>>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { try // Nice formatting for standard-format error { @@ -191,7 +195,7 @@ void RPCExecutor::request(const QString &command) } catch (const std::runtime_error&) // raised when converting to invalid type, i.e. missing code or message { // Show raw JSON object - emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false))); + emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(objError.write())); } } catch (const std::exception& e) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 79528db2fe..2f9fd5e045 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -13,7 +13,7 @@ #include -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; using namespace std; @@ -206,7 +206,13 @@ Value getrawmempool(const Array& params, bool fHelp) if (mempool.exists(txin.prevout.hash)) setDepends.insert(txin.prevout.hash.ToString()); } - Array depends(setDepends.begin(), setDepends.end()); + + UniValue depends; + BOOST_FOREACH(const string& dep, setDepends) + { + depends.push_back(dep); + } + info.push_back(Pair("depends", depends)); o.push_back(Pair(hash.ToString(), info)); } @@ -412,14 +418,14 @@ Value gettxout(const Array& params, bool fHelp) LOCK(mempool.cs); CCoinsViewMemPool view(pcoinsTip, mempool); if (!view.GetCoins(hash, coins)) - return Value::null; + return NullUniValue; mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool } else { if (!pcoinsTip->GetCoins(hash, coins)) - return Value::null; + return NullUniValue; } if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull()) - return Value::null; + return NullUniValue; BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); CBlockIndex *pindex = it->second; diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 4b576b3707..d8c4da4207 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -135,7 +135,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector& strParams); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 528d5406f4..4571269c3f 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -24,8 +24,7 @@ #include -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; using namespace std; @@ -216,7 +215,7 @@ Value setgenerate(const Array& params, bool fHelp) mapArgs ["-genproclimit"] = itostr(nGenProcLimit); GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit); - return Value::null; + return NullUniValue; } #endif @@ -382,14 +381,14 @@ Value getblocktemplate(const Array& params, bool fHelp) LOCK(cs_main); std::string strMode = "template"; - Value lpval = Value::null; + Value lpval = NullUniValue; if (params.size() > 0) { const Object& oparam = params[0].get_obj(); const Value& modeval = find_value(oparam, "mode"); - if (modeval.type() == str_type) + if (modeval.isStr()) strMode = modeval.get_str(); - else if (modeval.type() == null_type) + else if (modeval.isNull()) { /* Do nothing */ } @@ -439,14 +438,14 @@ Value getblocktemplate(const Array& params, bool fHelp) static unsigned int nTransactionsUpdatedLast; - if (lpval.type() != null_type) + if (!lpval.isNull()) { // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions uint256 hashWatchedChain; boost::system_time checktxtime; unsigned int nTransactionsUpdatedLastLP; - if (lpval.type() == str_type) + if (lpval.isStr()) { // Format: std::string lpstr = lpval.get_str(); @@ -686,7 +685,7 @@ Value estimatefee(const Array& params, bool fHelp) + HelpExampleCli("estimatefee", "6") ); - RPCTypeCheck(params, boost::assign::list_of(int_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); int nBlocks = params[0].get_int(); if (nBlocks < 1) @@ -718,7 +717,7 @@ Value estimatepriority(const Array& params, bool fHelp) + HelpExampleCli("estimatepriority", "6") ); - RPCTypeCheck(params, boost::assign::list_of(int_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); int nBlocks = params[0].get_int(); if (nBlocks < 1) diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index f5bef2a077..f7bd3e0d5a 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -20,8 +20,7 @@ #include #include -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; using namespace std; @@ -204,7 +203,7 @@ Value validateaddress(const Array& params, bool fHelp) if (mine != ISMINE_NO) { ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false)); Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); - ret.insert(ret.end(), detail.begin(), detail.end()); + ret.pushKVs(detail); } if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index bdee5b9f2e..3f46be0ccb 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -16,7 +16,7 @@ #include -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; using namespace std; @@ -59,7 +59,7 @@ Value ping(const Array& params, bool fHelp) pNode->fPingQueued = true; } - return Value::null; + return NullUniValue; } static void CopyNodeStats(std::vector& vstats) @@ -190,7 +190,7 @@ Value addnode(const Array& params, bool fHelp) { CAddress addr; OpenNetworkConnection(addr, NULL, strNode.c_str()); - return Value::null; + return NullUniValue; } LOCK(cs_vAddedNodes); @@ -212,7 +212,7 @@ Value addnode(const Array& params, bool fHelp) vAddedNodes.erase(it); } - return Value::null; + return NullUniValue; } Value getaddednodeinfo(const Array& params, bool fHelp) diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index 95d6b9e531..72a7b76343 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -23,7 +23,7 @@ #include #include #include -#include "json/json_spirit_writer_template.h" +#include "json_spirit_wrapper.h" using namespace std; using namespace json_spirit; @@ -260,14 +260,14 @@ string JSONRPCRequest(const string& strMethod, const Array& params, const Value& request.push_back(Pair("method", strMethod)); request.push_back(Pair("params", params)); request.push_back(Pair("id", id)); - return write_string(Value(request), false) + "\n"; + return request.write() + "\n"; } Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id) { Object reply; - if (error.type() != null_type) - reply.push_back(Pair("result", Value::null)); + if (!error.isNull()) + reply.push_back(Pair("result", NullUniValue)); else reply.push_back(Pair("result", result)); reply.push_back(Pair("error", error)); @@ -278,7 +278,7 @@ Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id) string JSONRPCReply(const Value& result, const Value& error, const Value& id) { Object reply = JSONRPCReplyObj(result, error, id); - return write_string(Value(reply), false) + "\n"; + return reply.write() + "\n"; } Object JSONRPCError(int code, const string& message) diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index 4f3f70fb37..496e19ed53 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -15,9 +15,7 @@ #include #include -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include "json_spirit_wrapper.h" //! HTTP status codes enum HTTPStatusCode diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 3e37b797e8..8d2b035f31 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -25,8 +25,7 @@ #include #include -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; using namespace std; @@ -343,20 +342,21 @@ Value createrawtransaction(const Array& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)); Array inputs = params[0].get_array(); Object sendTo = params[1].get_obj(); CMutableTransaction rawTx; - BOOST_FOREACH(const Value& input, inputs) { + for (unsigned int idx = 0; idx < inputs.size(); idx++) { + const Value& input = inputs[idx]; const Object& o = input.get_obj(); uint256 txid = ParseHashO(o, "txid"); const Value& vout_v = find_value(o, "vout"); - if (vout_v.type() != int_type) + if (!vout_v.isNum()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); int nOutput = vout_v.get_int(); if (nOutput < 0) @@ -367,17 +367,18 @@ Value createrawtransaction(const Array& params, bool fHelp) } set setAddress; - BOOST_FOREACH(const Pair& s, sendTo) { - CBitcoinAddress address(s.name_); + vector addrList = sendTo.getKeys(); + BOOST_FOREACH(const string& name_, addrList) { + CBitcoinAddress address(name_); if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_); if (setAddress.count(address)) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_); setAddress.insert(address); CScript scriptPubKey = GetScriptForDestination(address.Get()); - CAmount nAmount = AmountFromValue(s.value_); + CAmount nAmount = AmountFromValue(sendTo[name_]); CTxOut out(nAmount, scriptPubKey); rawTx.vout.push_back(out); @@ -438,7 +439,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(str_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); CTransaction tx; @@ -570,7 +571,7 @@ Value signrawtransaction(const Array& params, bool fHelp) #else LOCK(cs_main); #endif - RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR), true); vector txData(ParseHexV(params[0], "argument 1")); CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); @@ -613,10 +614,11 @@ Value signrawtransaction(const Array& params, bool fHelp) bool fGivenKeys = false; CBasicKeyStore tempKeystore; - if (params.size() > 2 && params[2].type() != null_type) { + if (params.size() > 2 && !params[2].isNull()) { fGivenKeys = true; Array keys = params[2].get_array(); - BOOST_FOREACH(Value k, keys) { + for (unsigned int idx = 0; idx < keys.size(); idx++) { + Value k = keys[idx]; CBitcoinSecret vchSecret; bool fGood = vchSecret.SetString(k.get_str()); if (!fGood) @@ -633,15 +635,16 @@ Value signrawtransaction(const Array& params, bool fHelp) #endif // Add previous txouts given in the RPC call: - if (params.size() > 1 && params[1].type() != null_type) { + if (params.size() > 1 && !params[1].isNull()) { Array prevTxs = params[1].get_array(); - BOOST_FOREACH(Value& p, prevTxs) { - if (p.type() != obj_type) + for (unsigned int idx = 0; idx < prevTxs.size(); idx++) { + const Value& p = prevTxs[idx]; + if (!p.isObject()) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); Object prevOut = p.get_obj(); - RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)); + RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)); uint256 txid = ParseHashO(prevOut, "txid"); @@ -669,9 +672,9 @@ Value signrawtransaction(const Array& params, bool fHelp) // if redeemScript given and not using the local wallet (private keys // given), add redeemScript to the tempKeystore so it can be signed: if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) { - RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type)); + RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR)); Value v = find_value(prevOut, "redeemScript"); - if (!(v == Value::null)) { + if (!v.isNull()) { vector rsData(ParseHexV(v, "redeemScript")); CScript redeemScript(rsData.begin(), rsData.end()); tempKeystore.AddCScript(redeemScript); @@ -687,7 +690,7 @@ Value signrawtransaction(const Array& params, bool fHelp) #endif int nHashType = SIGHASH_ALL; - if (params.size() > 3 && params[3].type() != null_type) { + if (params.size() > 3 && !params[3].isNull()) { static map mapSigHashValues = boost::assign::map_list_of (string("ALL"), int(SIGHASH_ALL)) @@ -769,7 +772,7 @@ Value sendrawtransaction(const Array& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); // parse hex string from parameter CTransaction tx; diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 3f74517a67..da0a8048b2 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -27,7 +27,8 @@ #include #include #include -#include "json/json_spirit_writer_template.h" + +#include "json_spirit_wrapper.h" using namespace boost::asio; using namespace json_spirit; @@ -89,30 +90,30 @@ void RPCTypeCheck(const Array& params, break; const Value& v = params[i]; - if (!((v.type() == t) || (fAllowNull && (v.type() == null_type)))) + if (!((v.type() == t) || (fAllowNull && (v.isNull())))) { string err = strprintf("Expected type %s, got %s", - Value_type_name[t], Value_type_name[v.type()]); + uvTypeName(t), uvTypeName(v.type())); throw JSONRPCError(RPC_TYPE_ERROR, err); } i++; } } -void RPCTypeCheck(const Object& o, - const map& typesExpected, +void RPCTypeCheckObj(const UniValue& o, + const map& typesExpected, bool fAllowNull) { BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected) { const Value& v = find_value(o, t.first); - if (!fAllowNull && v.type() == null_type) + if (!fAllowNull && v.isNull()) throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first)); - if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type)))) + if (!((v.type() == t.second) || (fAllowNull && (v.isNull())))) { string err = strprintf("Expected type %s for %s, got %s", - Value_type_name[t.second], t.first, Value_type_name[v.type()]); + uvTypeName(t.second), t.first, uvTypeName(v.type())); throw JSONRPCError(RPC_TYPE_ERROR, err); } } @@ -142,7 +143,7 @@ Value ValueFromAmount(const CAmount& amount) uint256 ParseHashV(const Value& v, string strName) { string strHex; - if (v.type() == str_type) + if (v.isStr()) strHex = v.get_str(); if (!IsHex(strHex)) // Note: IsHex("") is false throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); @@ -157,7 +158,7 @@ uint256 ParseHashO(const Object& o, string strKey) vector ParseHexV(const Value& v, string strName) { string strHex; - if (v.type() == str_type) + if (v.isStr()) strHex = v.get_str(); if (!IsHex(strHex)) throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); @@ -417,7 +418,7 @@ void ErrorReply(std::ostream& stream, const Object& objError, const Value& id) int code = find_value(objError, "code").get_int(); if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST; else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND; - string strReply = JSONRPCReply(Value::null, objError, id); + string strReply = JSONRPCReply(NullUniValue, objError, id); stream << HTTPReply(nStatus, strReply, false) << std::flush; } @@ -828,14 +829,14 @@ public: string strMethod; Array params; - JSONRequest() { id = Value::null; } + JSONRequest() { id = NullUniValue; } void parse(const Value& valRequest); }; void JSONRequest::parse(const Value& valRequest) { // Parse request - if (valRequest.type() != obj_type) + if (!valRequest.isObject()) throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object"); const Object& request = valRequest.get_obj(); @@ -844,9 +845,9 @@ void JSONRequest::parse(const Value& valRequest) // Parse method Value valMethod = find_value(request, "method"); - if (valMethod.type() == null_type) + if (valMethod.isNull()) throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method"); - if (valMethod.type() != str_type) + if (!valMethod.isStr()) throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string"); strMethod = valMethod.get_str(); if (strMethod != "getblocktemplate") @@ -854,9 +855,9 @@ void JSONRequest::parse(const Value& valRequest) // Parse params Value valParams = find_value(request, "params"); - if (valParams.type() == array_type) + if (valParams.isArray()) params = valParams.get_array(); - else if (valParams.type() == null_type) + else if (valParams.isNull()) params = Array(); else throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array"); @@ -872,15 +873,15 @@ static Object JSONRPCExecOne(const Value& req) jreq.parse(req); Value result = tableRPC.execute(jreq.strMethod, jreq.params); - rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id); + rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); } catch (const Object& objError) { - rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id); + rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id); } catch (const std::exception& e) { - rpc_result = JSONRPCReplyObj(Value::null, + rpc_result = JSONRPCReplyObj(NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); } @@ -893,7 +894,7 @@ static string JSONRPCExecBatch(const Array& vReq) for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) ret.push_back(JSONRPCExecOne(vReq[reqIdx])); - return write_string(Value(ret), false) + "\n"; + return ret.write() + "\n"; } static bool HTTPReq_JSONRPC(AcceptedConnection *conn, @@ -925,7 +926,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, { // Parse request Value valRequest; - if (!read_string(strRequest, valRequest)) + if (!valRequest.read(strRequest)) throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); // Return immediately if in warmup @@ -938,16 +939,16 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, string strReply; // singleton request - if (valRequest.type() == obj_type) { + if (valRequest.isObject()) { jreq.parse(valRequest); Value result = tableRPC.execute(jreq.strMethod, jreq.params); // Send reply - strReply = JSONRPCReply(result, Value::null, jreq.id); + strReply = JSONRPCReply(result, NullUniValue, jreq.id); // array of requests - } else if (valRequest.type() == array_type) + } else if (valRequest.isArray()) strReply = JSONRPCExecBatch(valRequest.get_array()); else throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); diff --git a/src/rpcserver.h b/src/rpcserver.h index 30a5b28db7..c9982bb8ca 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -15,9 +15,8 @@ #include #include -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include +#include "json_spirit_wrapper.h" class CRPCCommand; @@ -73,12 +72,13 @@ bool RPCIsInWarmup(std::string *statusOut); */ void RPCTypeCheck(const json_spirit::Array& params, const std::list& typesExpected, bool fAllowNull=false); -/** - * Check for expected keys/value types in an Object. - * Use like: RPCTypeCheck(object, boost::assign::map_list_of("name", str_type)("value", int_type)); - */ -void RPCTypeCheck(const json_spirit::Object& o, - const std::map& typesExpected, bool fAllowNull=false); + +/* + Check for expected keys/value types in an Object. + Use like: RPCTypeCheckObj(object, boost::assign::map_list_of("name", str_type)("value", int_type)); +*/ +void RPCTypeCheckObj(const UniValue& o, + const std::map& typesExpected, bool fAllowNull=false); /** * Run func nSeconds from now. Uses boost deadline timers. diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index f07dd7a7db..a806fe7b05 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -17,9 +17,7 @@ #include #include -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; extern Array read_json(const std::string& jsondata); @@ -30,10 +28,9 @@ BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(base58_EncodeBase58) { Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -53,10 +50,9 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58) Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); std::vector result; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -130,10 +126,9 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) CBitcoinAddress addr; SelectParams(CBaseChainParams::MAIN); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -185,10 +180,10 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) { Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); std::vector result; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -256,10 +251,9 @@ BOOST_AUTO_TEST_CASE(base58_keys_invalid) CBitcoinSecret secret; CBitcoinAddress addr; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 5899671d2f..fea826b65a 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -111,20 +111,20 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign) BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) { - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(0LL), false), "0.00000000"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(1LL), false), "0.00000001"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(17622195LL), false), "0.17622195"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(50000000LL), false), "0.50000000"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(89898989LL), false), "0.89898989"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(100000000LL), false), "1.00000000"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999990LL), false), "20999999.99999990"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999999LL), false), "20999999.99999999"); + BOOST_CHECK(ValueFromAmount(0LL).write() == "0.00000000"); + BOOST_CHECK(ValueFromAmount(1LL).write() == "0.00000001"); + BOOST_CHECK(ValueFromAmount(17622195LL).write() == "0.17622195"); + BOOST_CHECK(ValueFromAmount(50000000LL).write() == "0.50000000"); + BOOST_CHECK(ValueFromAmount(89898989LL).write() == "0.89898989"); + BOOST_CHECK(ValueFromAmount(100000000LL).write() == "1.00000000"); + BOOST_CHECK(ValueFromAmount(2099999999999990LL).write() == "20999999.99999990"); + BOOST_CHECK(ValueFromAmount(2099999999999999LL).write() == "20999999.99999999"); } static Value ValueFromString(const std::string &str) { Value value; - BOOST_CHECK(read_string(str, value)); + BOOST_CHECK(value.read(str)); return value; } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index c0614cca43..b4cab3245c 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -26,9 +26,7 @@ #include #include -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include "json_spirit_wrapper.h" using namespace std; using namespace json_spirit; @@ -46,7 +44,7 @@ read_json(const std::string& jsondata) { Value v; - if (!read_string(jsondata, v) || v.type() != array_type) + if (!v.read(jsondata) || !v.isArray()) { BOOST_ERROR("Parse error."); return Array(); @@ -636,10 +634,9 @@ BOOST_AUTO_TEST_CASE(script_valid) // scripts. Array tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + string strTest = test.write(); if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) { if (test.size() != 1) { @@ -662,11 +659,10 @@ BOOST_AUTO_TEST_CASE(script_invalid) // Scripts that should evaluate as invalid Array tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); - if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + string strTest = test.write(); + if (test.size() < 3) // Allow size > 2; extra stuff ignored (useful for comments) { if (test.size() != 1) { BOOST_ERROR("Bad test: " << strTest); diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 87be2217c4..121644ddc4 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -16,9 +16,7 @@ #include #include -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; extern Array read_json(const std::string& jsondata); @@ -170,10 +168,9 @@ BOOST_AUTO_TEST_CASE(sighash_from_data) { Array tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index d12535e438..cdd88f348d 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -22,7 +22,8 @@ #include #include #include -#include "json/json_spirit_writer_template.h" + +#include "json_spirit_wrapper.h" using namespace std; using namespace json_spirit; @@ -90,14 +91,21 @@ BOOST_AUTO_TEST_CASE(tx_valid) // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" Array tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); +<<<<<<< HEAD ScriptError err; BOOST_FOREACH(Value& tv, tests) { Array test = tv.get_array(); string strTest = write_string(tv, false); if (test[0].type() == array_type) +======= + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + string strTest = test.write(); + if (test[0].isArray()) +>>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { - if (test.size() != 3 || test[1].type() != str_type || test[2].type() != str_type) + if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { BOOST_ERROR("Bad test: " << strTest); continue; @@ -106,9 +114,9 @@ BOOST_AUTO_TEST_CASE(tx_valid) map mapprevOutScriptPubKeys; Array inputs = test[0].get_array(); bool fValid = true; - BOOST_FOREACH(Value& input, inputs) - { - if (input.type() != array_type) + for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { + const Value& input = inputs[inpIdx]; + if (!input.isArray()) { fValid = false; break; @@ -166,14 +174,21 @@ BOOST_AUTO_TEST_CASE(tx_invalid) // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" Array tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); +<<<<<<< HEAD ScriptError err; BOOST_FOREACH(Value& tv, tests) { Array test = tv.get_array(); string strTest = write_string(tv, false); if (test[0].type() == array_type) +======= + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + string strTest = test.write(); + if (test[0].isArray()) +>>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { - if (test.size() != 3 || test[1].type() != str_type || test[2].type() != str_type) + if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { BOOST_ERROR("Bad test: " << strTest); continue; @@ -182,9 +197,9 @@ BOOST_AUTO_TEST_CASE(tx_invalid) map mapprevOutScriptPubKeys; Array inputs = test[0].get_array(); bool fValid = true; - BOOST_FOREACH(Value& input, inputs) - { - if (input.type() != array_type) + for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { + const Value& input = inputs[inpIdx]; + if (!input.isArray()) { fValid = false; break; diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index afe751ed9d..28d6e3d3cd 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -11,6 +11,10 @@ #include #include +#include // .get_int64() +#include // std::pair +#include // atoi(), atof() TODO: remove + class UniValue { public: enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, }; @@ -130,8 +134,88 @@ private: int findKey(const std::string& key) const; void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; + +public: + // + // The following were added for compatibility with json_spirit. + // Most duplicate other methods, and should be removed. + // + std::vector getKeys() const { return keys; } + std::vector getValues() const { return values; } + bool get_bool() const { return getBool(); } + std::string get_str() const { return getValStr(); } + int get_int() const { return atoi(getValStr().c_str()); } + double get_real() const { return atof(getValStr().c_str()); } + const UniValue& get_obj() const { return *this; } + const UniValue& get_array() const { return *this; } + enum VType type() const { return getType(); } + bool push_back(std::pair pear) { + return pushKV(pear.first, pear.second); + } + int64_t get_int64() const { + int64_t ret; + std::istringstream(getValStr()) >> ret; + return ret; + } }; +// +// The following were added for compatibility with json_spirit. +// Most duplicate other methods, and should be removed. +// +static inline std::pair Pair(const char *cKey, const char *cVal) +{ + std::string key(cKey); + UniValue uVal(cVal); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, std::string strVal) +{ + std::string key(cKey); + UniValue uVal(strVal); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, uint64_t u64Val) +{ + std::string key(cKey); + UniValue uVal(u64Val); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, int64_t i64Val) +{ + std::string key(cKey); + UniValue uVal(i64Val); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, int iVal) +{ + std::string key(cKey); + UniValue uVal(iVal); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, double dVal) +{ + std::string key(cKey); + UniValue uVal(dVal); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, const UniValue& uVal) +{ + std::string key(cKey); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(std::string key, const UniValue& uVal) +{ + return std::make_pair(key, uVal); +} + enum jtokentype { JTOK_ERR = -1, JTOK_NONE = 0, // eof diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index ab951d1d7d..68d2a21c47 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -19,7 +19,7 @@ #include #include -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; using namespace std; @@ -126,7 +126,7 @@ Value importprivkey(const Array& params, bool fHelp) // Don't throw error in case a key is already there if (pwalletMain->HaveKey(vchAddress)) - return Value::null; + return NullUniValue; pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1; @@ -141,7 +141,7 @@ Value importprivkey(const Array& params, bool fHelp) } } - return Value::null; + return NullUniValue; } Value importaddress(const Array& params, bool fHelp) @@ -200,7 +200,7 @@ Value importaddress(const Array& params, bool fHelp) // Don't throw error in case an address is already there if (pwalletMain->HaveWatchOnly(script)) - return Value::null; + return NullUniValue; pwalletMain->MarkDirty(); @@ -214,7 +214,7 @@ Value importaddress(const Array& params, bool fHelp) } } - return Value::null; + return NullUniValue; } Value importwallet(const Array& params, bool fHelp) @@ -318,7 +318,7 @@ Value importwallet(const Array& params, bool fHelp) if (!fGood) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet"); - return Value::null; + return NullUniValue; } Value dumpprivkey(const Array& params, bool fHelp) @@ -421,5 +421,5 @@ Value dumpwallet(const Array& params, bool fHelp) file << "\n"; file << "# End of dump\n"; file.close(); - return Value::null; + return NullUniValue; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3f55b04273..e743b1fa1d 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -21,8 +21,7 @@ #include -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace std; using namespace json_spirit; @@ -275,7 +274,7 @@ Value setaccount(const Array& params, bool fHelp) else throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address"); - return Value::null; + return NullUniValue; } @@ -419,9 +418,9 @@ Value sendtoaddress(const Array& params, bool fHelp) // Wallet comments CWalletTx wtx; - if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty()) + if (params.size() > 2 && !params[2].isNull() && !params[2].get_str().empty()) wtx.mapValue["comment"] = params[2].get_str(); - if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) wtx.mapValue["to"] = params[3].get_str(); bool fSubtractFeeFromAmount = false; @@ -896,9 +895,9 @@ Value sendfrom(const Array& params, bool fHelp) CWalletTx wtx; wtx.strFromAccount = strAccount; - if (params.size() > 4 && params[4].type() != null_type && !params[4].get_str().empty()) + if (params.size() > 4 && !params[4].isNull() && !params[4].get_str().empty()) wtx.mapValue["comment"] = params[4].get_str(); - if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty()) + if (params.size() > 5 && !params[5].isNull() && !params[5].get_str().empty()) wtx.mapValue["to"] = params[5].get_str(); EnsureWalletIsUnlocked(); @@ -965,7 +964,7 @@ Value sendmany(const Array& params, bool fHelp) CWalletTx wtx; wtx.strFromAccount = strAccount; - if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) wtx.mapValue["comment"] = params[3].get_str(); Array subtractFeeFromAmount; @@ -976,18 +975,19 @@ Value sendmany(const Array& params, bool fHelp) vector vecSend; CAmount totalAmount = 0; - BOOST_FOREACH(const Pair& s, sendTo) + vector keys = sendTo.getKeys(); + BOOST_FOREACH(const string& name_, keys) { - CBitcoinAddress address(s.name_); + CBitcoinAddress address(name_); if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_); if (setAddress.count(address)) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_); setAddress.insert(address); CScript scriptPubKey = GetScriptForDestination(address.Get()); - CAmount nAmount = AmountFromValue(s.value_); + CAmount nAmount = AmountFromValue(sendTo[name_]); totalAmount += nAmount; bool fSubtractFeeFromAmount = false; @@ -1472,15 +1472,21 @@ Value listtransactions(const Array& params, bool fHelp) nFrom = ret.size(); if ((nFrom + nCount) > (int)ret.size()) nCount = ret.size() - nFrom; - Array::iterator first = ret.begin(); + + vector arrTmp = ret.getValues(); + + vector::iterator first = arrTmp.begin(); std::advance(first, nFrom); - Array::iterator last = ret.begin(); + vector::iterator last = arrTmp.begin(); std::advance(last, nFrom+nCount); - if (last != ret.end()) ret.erase(last, ret.end()); - if (first != ret.begin()) ret.erase(ret.begin(), first); + if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end()); + if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first); - std::reverse(ret.begin(), ret.end()); // Return oldest to newest + std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest + + ret.clear(); + ret.push_backV(arrTmp); return ret; } @@ -1756,7 +1762,7 @@ Value backupwallet(const Array& params, bool fHelp) if (!BackupWallet(*pwalletMain, strDest)) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!"); - return Value::null; + return NullUniValue; } @@ -1793,7 +1799,7 @@ Value keypoolrefill(const Array& params, bool fHelp) if (pwalletMain->GetKeyPoolSize() < kpSize) throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool."); - return Value::null; + return NullUniValue; } @@ -1860,7 +1866,7 @@ Value walletpassphrase(const Array& params, bool fHelp) nWalletUnlockTime = GetTime() + nSleepTime; RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime); - return Value::null; + return NullUniValue; } @@ -1906,7 +1912,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp) if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); - return Value::null; + return NullUniValue; } @@ -1945,7 +1951,7 @@ Value walletlock(const Array& params, bool fHelp) nWalletUnlockTime = 0; } - return Value::null; + return NullUniValue; } @@ -2050,9 +2056,9 @@ Value lockunspent(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); if (params.size() == 1) - RPCTypeCheck(params, boost::assign::list_of(bool_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL)); else - RPCTypeCheck(params, boost::assign::list_of(bool_type)(array_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR)); bool fUnlock = params[0].get_bool(); @@ -2063,13 +2069,13 @@ Value lockunspent(const Array& params, bool fHelp) } Array outputs = params[1].get_array(); - BOOST_FOREACH(Value& output, outputs) - { - if (output.type() != obj_type) + for (unsigned int idx = 0; idx < outputs.size(); idx++) { + const UniValue& output = outputs[idx]; + if (!output.isObject()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object"); const Object& o = output.get_obj(); - RPCTypeCheck(o, boost::assign::map_list_of("txid", str_type)("vout", int_type)); + RPCTypeCheckObj(o, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)); string txid = find_value(o, "txid").get_str(); if (!IsHex(txid)) -- cgit v1.2.3 From 53b4671a9de75f7c8e2903d510cf88867c3f6b97 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 13:35:44 +0200 Subject: extend conversion to UniValue --- src/Makefile.am | 1 + src/bitcoin-cli.cpp | 2 +- src/rest.cpp | 9 +++-- src/rpcblockchain.cpp | 4 +-- src/rpcclient.cpp | 2 +- src/rpcmining.cpp | 4 +-- src/rpcmisc.cpp | 4 +-- src/rpcprotocol.cpp | 6 ++-- src/rpcrawtransaction.cpp | 7 ++-- src/test/script_tests.cpp | 14 ++++---- src/test/transaction_tests.cpp | 1 + src/wallet/rpcdump.cpp | 10 +++--- src/wallet/rpcwallet.cpp | 81 ++++++++++++++++++++++-------------------- 13 files changed, 76 insertions(+), 69 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 63332f9acd..5041ae2f1c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -98,6 +98,7 @@ BITCOIN_CORE_H = \ ecwrapper.h \ hash.h \ init.h \ + json_spirit_wrapper.h \ key.h \ keystore.h \ leveldbwrapper.h \ diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 9950153a65..9ad5fb6b1d 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -142,7 +142,7 @@ Object CallRPC(const string& strMethod, const Array& params) throw runtime_error("no response from server"); // Parse reply - Value valReply; + Value valReply(UniValue::VSTR); if (!valReply.read(strReply)) throw runtime_error("couldn't parse reply from server"); const Object& reply = valReply.get_obj(); diff --git a/src/rest.cpp b/src/rest.cpp index 7c238d506d..5f64a0091c 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -222,7 +222,7 @@ static bool rest_block(AcceptedConnection* conn, case RF_JSON: { Object objBlock = blockToJSON(block, pblockindex, showTxDetails); - string strJSON = write_string(Value(objBlock), false) + "\n"; + string strJSON = objBlock.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } @@ -267,8 +267,7 @@ static bool rest_chaininfo(AcceptedConnection* conn, case RF_JSON: { Array rpcParams; Value chainInfoObject = getblockchaininfo(rpcParams, false); - - string strJSON = write_string(chainInfoObject, false) + "\n"; + string strJSON = chainInfoObject.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } @@ -319,7 +318,7 @@ static bool rest_tx(AcceptedConnection* conn, case RF_JSON: { Object objTx; TxToJSON(tx, hashBlock, objTx); - string strJSON = write_string(Value(objTx), false) + "\n"; + string strJSON = objTx.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } @@ -516,7 +515,7 @@ static bool rest_getutxos(AcceptedConnection* conn, objGetUTXOResponse.push_back(Pair("utxos", utxos)); // return json string - string strJSON = write_string(Value(objGetUTXOResponse), false) + "\n"; + string strJSON = objGetUTXOResponse.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 2f9fd5e045..55403c9e82 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -678,7 +678,7 @@ Value invalidateblock(const Array& params, bool fHelp) throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); } - return Value::null; + return NullUniValue; } Value reconsiderblock(const Array& params, bool fHelp) @@ -717,5 +717,5 @@ Value reconsiderblock(const Array& params, bool fHelp) throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); } - return Value::null; + return NullUniValue; } diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index d8c4da4207..8b7b9e1493 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -122,7 +122,7 @@ static CRPCConvertTable rpcCvtTable; /** Convert strings to command-specific RPC representation */ Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams) { - Array params; + UniValue params(UniValue::VARR); for (unsigned int idx = 0; idx < strParams.size(); idx++) { const std::string& strVal = strParams[idx]; diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 4571269c3f..95b788810e 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -399,7 +399,7 @@ Value getblocktemplate(const Array& params, bool fHelp) if (strMode == "proposal") { const Value& dataval = find_value(oparam, "data"); - if (dataval.type() != str_type) + if (dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); CBlock block; @@ -519,7 +519,7 @@ Value getblocktemplate(const Array& params, bool fHelp) UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nNonce = 0; - static const Array aCaps = boost::assign::list_of("proposal"); + Array aCaps; aCaps.push_back("proposal"); Array transactions; map setTxIndex; diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index f7bd3e0d5a..b06408f21e 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -389,8 +389,8 @@ Value setmocktime(const Array& params, bool fHelp) LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(int_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); SetMockTime(params[0].get_int64()); - return Value::null; + return NullUniValue; } diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index 72a7b76343..9b422894ef 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -256,7 +256,7 @@ int ReadHTTPMessage(std::basic_istream& stream, map setTxids; uint256 oneTxid; Array txids = params[0].get_array(); - BOOST_FOREACH(Value& txid, txids) { + for (unsigned int idx = 0; idx < txids.size(); idx++) { + const Value& txid = txids[idx]; if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str()); uint256 hash(uint256S(txid.get_str())); @@ -446,7 +447,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) if (!DecodeHexTx(tx, params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); - Object result; + UniValue result(UniValue::VOBJ); TxToJSON(tx, uint256(), result); return result; @@ -478,7 +479,7 @@ Value decodescript(const Array& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(str_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); Object r; CScript script; diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index b4cab3245c..989b35b9e8 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -583,11 +583,13 @@ BOOST_AUTO_TEST_CASE(script_build) Array json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); Array json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); - BOOST_FOREACH(Value& tv, json_good) { - tests_good.insert(write_string(Value(tv.get_array()), true)); + for (unsigned int idx = 0; idx < json_good.size(); idx++) { + const Value& tv = json_good[idx]; + tests_good.insert(tv.get_array().write()); } - BOOST_FOREACH(Value& tv, json_bad) { - tests_bad.insert(write_string(Value(tv.get_array()), true)); + for (unsigned int idx = 0; idx < json_bad.size(); idx++) { + const Value& tv = json_bad[idx]; + tests_bad.insert(tv.get_array().write()); } } @@ -596,7 +598,7 @@ BOOST_AUTO_TEST_CASE(script_build) BOOST_FOREACH(TestBuilder& test, good) { test.Test(true); - std::string str = write_string(Value(test.GetJSON()), true); + std::string str = test.GetJSON().write(); #ifndef UPDATE_JSON_TESTS if (tests_good.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment()); @@ -606,7 +608,7 @@ BOOST_AUTO_TEST_CASE(script_build) } BOOST_FOREACH(TestBuilder& test, bad) { test.Test(false); - std::string str = write_string(Value(test.GetJSON()), true); + std::string str = test.GetJSON().write(); #ifndef UPDATE_JSON_TESTS if (tests_bad.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_invalid test: " + test.GetComment()); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index cdd88f348d..0ddc48271b 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 68d2a21c47..e0cccef696 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -73,7 +73,7 @@ std::string DecodeDumpString(const std::string &str) { Value importprivkey(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 3) throw runtime_error( @@ -147,7 +147,7 @@ Value importprivkey(const Array& params, bool fHelp) Value importaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 3) throw runtime_error( @@ -220,7 +220,7 @@ Value importaddress(const Array& params, bool fHelp) Value importwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -324,7 +324,7 @@ Value importwallet(const Array& params, bool fHelp) Value dumpprivkey(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -362,7 +362,7 @@ Value dumpprivkey(const Array& params, bool fHelp) Value dumpwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e743b1fa1d..f24a37ae6c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -89,7 +89,7 @@ string AccountFromValue(const Value& value) Value getnewaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -168,7 +168,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) Value getaccountaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -200,7 +200,7 @@ Value getaccountaddress(const Array& params, bool fHelp) Value getrawchangeaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -235,7 +235,7 @@ Value getrawchangeaddress(const Array& params, bool fHelp) Value setaccount(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -281,7 +281,7 @@ Value setaccount(const Array& params, bool fHelp) Value getaccount(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -313,7 +313,7 @@ Value getaccount(const Array& params, bool fHelp) Value getaddressesbyaccount(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -381,7 +381,7 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr Value sendtoaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( @@ -437,7 +437,7 @@ Value sendtoaddress(const Array& params, bool fHelp) Value listaddressgroupings(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp) throw runtime_error( @@ -489,7 +489,7 @@ Value listaddressgroupings(const Array& params, bool fHelp) Value signmessage(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 2) throw runtime_error( @@ -545,7 +545,7 @@ Value signmessage(const Array& params, bool fHelp) Value getreceivedbyaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -603,7 +603,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) Value getreceivedbyaccount(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -692,7 +692,7 @@ CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminef Value getbalance(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -767,7 +767,7 @@ Value getbalance(const Array& params, bool fHelp) Value getunconfirmedbalance(const Array ¶ms, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 0) throw runtime_error( @@ -783,7 +783,7 @@ Value getunconfirmedbalance(const Array ¶ms, bool fHelp) Value movecmd(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 3 || params.size() > 5) throw runtime_error( @@ -853,7 +853,7 @@ Value movecmd(const Array& params, bool fHelp) Value sendfrom(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 3 || params.size() > 6) throw runtime_error( @@ -916,7 +916,7 @@ Value sendfrom(const Array& params, bool fHelp) Value sendmany(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( @@ -991,9 +991,11 @@ Value sendmany(const Array& params, bool fHelp) totalAmount += nAmount; bool fSubtractFeeFromAmount = false; - BOOST_FOREACH(const Value& addr, subtractFeeFromAmount) - if (addr.get_str() == s.name_) + for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) { + const Value& addr = subtractFeeFromAmount[idx]; + if (addr.get_str() == name_) fSubtractFeeFromAmount = true; + } CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount}; vecSend.push_back(recipient); @@ -1026,7 +1028,7 @@ extern CScript _createmultisig_redeemScript(const Array& params); Value addmultisigaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 2 || params.size() > 3) { @@ -1207,7 +1209,7 @@ Value ListReceived(const Array& params, bool fByAccounts) Value listreceivedbyaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -1244,7 +1246,7 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) Value listreceivedbyaccount(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -1374,7 +1376,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar Value listtransactions(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 4) throw runtime_error( @@ -1494,7 +1496,7 @@ Value listtransactions(const Array& params, bool fHelp) Value listaccounts(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 2) throw runtime_error( @@ -1574,7 +1576,7 @@ Value listaccounts(const Array& params, bool fHelp) Value listsinceblock(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp) throw runtime_error( @@ -1665,7 +1667,7 @@ Value listsinceblock(const Array& params, bool fHelp) Value gettransaction(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -1743,7 +1745,7 @@ Value gettransaction(const Array& params, bool fHelp) Value backupwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -1769,7 +1771,7 @@ Value backupwallet(const Array& params, bool fHelp) Value keypoolrefill(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -1813,7 +1815,7 @@ static void LockWallet(CWallet* pWallet) Value walletpassphrase(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( @@ -1873,7 +1875,7 @@ Value walletpassphrase(const Array& params, bool fHelp) Value walletpassphrasechange(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( @@ -1919,7 +1921,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp) Value walletlock(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) throw runtime_error( @@ -1958,7 +1960,7 @@ Value walletlock(const Array& params, bool fHelp) Value encryptwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) throw runtime_error( @@ -2015,7 +2017,7 @@ Value encryptwallet(const Array& params, bool fHelp) Value lockunspent(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -2099,7 +2101,7 @@ Value lockunspent(const Array& params, bool fHelp) Value listlockunspent(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 0) throw runtime_error( @@ -2148,7 +2150,7 @@ Value listlockunspent(const Array& params, bool fHelp) Value settxfee(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( @@ -2177,7 +2179,7 @@ Value settxfee(const Array& params, bool fHelp) Value getwalletinfo(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 0) throw runtime_error( @@ -2217,7 +2219,7 @@ Value getwalletinfo(const Array& params, bool fHelp) Value resendwallettransactions(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 0) throw runtime_error( @@ -2242,7 +2244,7 @@ Value resendwallettransactions(const Array& params, bool fHelp) Value listunspent(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -2280,7 +2282,7 @@ Value listunspent(const Array& params, bool fHelp) + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") ); - RPCTypeCheck(params, boost::assign::list_of(int_type)(int_type)(array_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VARR)); int nMinDepth = 1; if (params.size() > 0) @@ -2293,7 +2295,8 @@ Value listunspent(const Array& params, bool fHelp) set setAddress; if (params.size() > 2) { Array inputs = params[2].get_array(); - BOOST_FOREACH(Value& input, inputs) { + for (unsigned int idx = 0; idx < inputs.size(); idx++) { + const Value& input = inputs[idx]; CBitcoinAddress address(input.get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str()); -- cgit v1.2.3 From 6c7bee062437acbc078533fdcf8e53794031bf99 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 14:48:35 +0200 Subject: expicit set UniValue type to avoid empty values --- src/rest.cpp | 12 +++++------ src/rpcblockchain.cpp | 26 ++++++++++++------------ src/rpcmining.cpp | 18 ++++++++--------- src/rpcmisc.cpp | 12 +++++------ src/rpcnet.cpp | 32 ++++++++++++++--------------- src/rpcrawtransaction.cpp | 26 ++++++++++++------------ src/rpcserver.cpp | 2 +- src/test/rpc_tests.cpp | 4 ++-- src/test/script_tests.cpp | 2 +- src/wallet/rpcwallet.cpp | 51 ++++++++++++++++++++++++----------------------- 10 files changed, 93 insertions(+), 92 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index 5f64a0091c..f3195746ba 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -265,7 +265,7 @@ static bool rest_chaininfo(AcceptedConnection* conn, switch (rf) { case RF_JSON: { - Array rpcParams; + UniValue rpcParams(UniValue::VARR); Value chainInfoObject = getblockchaininfo(rpcParams, false); string strJSON = chainInfoObject.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; @@ -316,7 +316,7 @@ static bool rest_tx(AcceptedConnection* conn, } case RF_JSON: { - Object objTx; + UniValue objTx(UniValue::VOBJ); TxToJSON(tx, hashBlock, objTx); string strJSON = objTx.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; @@ -491,7 +491,7 @@ static bool rest_getutxos(AcceptedConnection* conn, } case RF_JSON: { - Object objGetUTXOResponse; + UniValue objGetUTXOResponse(UniValue::VOBJ); // pack in some essentials // use more or less the same output as mentioned in Bip64 @@ -499,15 +499,15 @@ static bool rest_getutxos(AcceptedConnection* conn, objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex())); objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation)); - Array utxos; + UniValue utxos(UniValue::VARR); BOOST_FOREACH (const CCoin& coin, outs) { - Object utxo; + UniValue utxo(UniValue::VOBJ); utxo.push_back(Pair("txvers", (int32_t)coin.nTxVer)); utxo.push_back(Pair("height", (int32_t)coin.nHeight)); utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue))); // include the script in a json output - Object o; + UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(coin.out.scriptPubKey, o, true); utxo.push_back(Pair("scriptPubKey", o)); utxos.push_back(utxo); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 55403c9e82..facc112cb4 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -55,7 +55,7 @@ double GetDifficulty(const CBlockIndex* blockindex) Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("hash", block.GetHash().GetHex())); int confirmations = -1; // Only report confirmations if the block is on the main chain @@ -66,12 +66,12 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); - Array txs; + UniValue txs(UniValue::VARR); BOOST_FOREACH(const CTransaction&tx, block.vtx) { if(txDetails) { - Object objTx; + UniValue objTx(UniValue::VOBJ); TxToJSON(tx, uint256(), objTx); txs.push_back(objTx); } @@ -187,12 +187,12 @@ Value getrawmempool(const Array& params, bool fHelp) if (fVerbose) { LOCK(mempool.cs); - Object o; + UniValue o(UniValue::VOBJ); BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx) { const uint256& hash = entry.first; const CTxMemPoolEntry& e = entry.second; - Object info; + UniValue info(UniValue::VOBJ); info.push_back(Pair("size", (int)e.GetTxSize())); info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); info.push_back(Pair("time", e.GetTime())); @@ -223,7 +223,7 @@ Value getrawmempool(const Array& params, bool fHelp) vector vtxid; mempool.queryHashes(vtxid); - Array a; + UniValue a(UniValue::VARR); BOOST_FOREACH(const uint256& hash, vtxid) a.push_back(hash.ToString()); @@ -348,7 +348,7 @@ Value gettxoutsetinfo(const Array& params, bool fHelp) LOCK(cs_main); - Object ret; + UniValue ret(UniValue::VOBJ); CCoinsStats stats; FlushStateToDisk(); @@ -404,7 +404,7 @@ Value gettxout(const Array& params, bool fHelp) LOCK(cs_main); - Object ret; + UniValue ret(UniValue::VOBJ); std::string strHash = params[0].get_str(); uint256 hash(uint256S(strHash)); @@ -435,7 +435,7 @@ Value gettxout(const Array& params, bool fHelp) else ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1)); ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue))); - Object o; + UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true); ret.push_back(Pair("scriptPubKey", o)); ret.push_back(Pair("version", coins.nVersion)); @@ -495,7 +495,7 @@ Value getblockchaininfo(const Array& params, bool fHelp) LOCK(cs_main); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("chain", Params().NetworkIDString())); obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); @@ -582,10 +582,10 @@ Value getchaintips(const Array& params, bool fHelp) setTips.insert(chainActive.Tip()); /* Construct the output array. */ - Array res; + UniValue res(UniValue::VARR); BOOST_FOREACH(const CBlockIndex* block, setTips) { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("height", block->nHeight)); obj.push_back(Pair("hash", block->phashBlock->GetHex())); @@ -636,7 +636,7 @@ Value getmempoolinfo(const Array& params, bool fHelp) + HelpExampleRpc("getmempoolinfo", "") ); - Object ret; + UniValue ret; ret.push_back(Pair("size", (int64_t) mempool.size())); ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 95b788810e..c2ad75af69 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -146,7 +146,7 @@ Value generate(const Array& params, bool fHelp) nHeightEnd = nHeightStart+nGenerate; } unsigned int nExtraNonce = 0; - Array blockHashes; + UniValue blockHashes(UniValue::VARR); while (nHeight < nHeightEnd) { auto_ptr pblocktemplate(CreateNewBlockWithKey(reservekey)); @@ -247,7 +247,7 @@ Value getmininginfo(const Array& params, bool fHelp) LOCK(cs_main); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); @@ -519,9 +519,9 @@ Value getblocktemplate(const Array& params, bool fHelp) UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nNonce = 0; - Array aCaps; aCaps.push_back("proposal"); + UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); - Array transactions; + UniValue transactions(UniValue::VARR); map setTxIndex; int i = 0; BOOST_FOREACH (CTransaction& tx, pblock->vtx) @@ -532,13 +532,13 @@ Value getblocktemplate(const Array& params, bool fHelp) if (tx.IsCoinBase()) continue; - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("data", EncodeHexTx(tx))); entry.push_back(Pair("hash", txHash.GetHex())); - Array deps; + UniValue deps(UniValue::VARR); BOOST_FOREACH (const CTxIn &in, tx.vin) { if (setTxIndex.count(in.prevout.hash)) @@ -553,12 +553,12 @@ Value getblocktemplate(const Array& params, bool fHelp) transactions.push_back(entry); } - Object aux; + UniValue aux(UniValue::VOBJ); aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); - static Array aMutable; + static UniValue aMutable(UniValue::VARR); if (aMutable.empty()) { aMutable.push_back("time"); @@ -566,7 +566,7 @@ Value getblocktemplate(const Array& params, bool fHelp) aMutable.push_back("prevblock"); } - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("capabilities", aCaps)); result.push_back(Pair("version", pblock->nVersion)); result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index b06408f21e..2d54b555b9 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -77,7 +77,7 @@ Value getinfo(const Array& params, bool fHelp) proxyType proxy; GetProxy(NET_IPV4, proxy); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); #ifdef ENABLE_WALLET @@ -118,7 +118,7 @@ public: Object operator()(const CNoDestination &dest) const { return Object(); } Object operator()(const CKeyID &keyID) const { - Object obj; + UniValue obj(UniValue::VOBJ); CPubKey vchPubKey; obj.push_back(Pair("isscript", false)); if (mine == ISMINE_SPENDABLE) { @@ -130,7 +130,7 @@ public: } Object operator()(const CScriptID &scriptID) const { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("isscript", true)); if (mine != ISMINE_NO) { CScript subscript; @@ -141,7 +141,7 @@ public: ExtractDestinations(subscript, whichType, addresses, nRequired); obj.push_back(Pair("script", GetTxnOutputType(whichType))); obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end()))); - Array a; + UniValue a(UniValue::VARR); BOOST_FOREACH(const CTxDestination& addr, addresses) a.push_back(CBitcoinAddress(addr).ToString()); obj.push_back(Pair("addresses", a)); @@ -186,7 +186,7 @@ Value validateaddress(const Array& params, bool fHelp) CBitcoinAddress address(params[0].get_str()); bool isValid = address.IsValid(); - Object ret; + UniValue ret(UniValue::VOBJ); ret.push_back(Pair("isvalid", isValid)); if (isValid) { @@ -312,7 +312,7 @@ Value createmultisig(const Array& params, bool fHelp) CScriptID innerID(inner); CBitcoinAddress address(innerID); - Object result; + UniValue result; result.push_back(Pair("address", address.ToString())); result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end()))); diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 3f46be0ccb..d8dd46e64e 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -120,10 +120,10 @@ Value getpeerinfo(const Array& params, bool fHelp) vector vstats; CopyNodeStats(vstats); - Array ret; + UniValue ret(UniValue::VARR); BOOST_FOREACH(const CNodeStats& stats, vstats) { - Object obj; + UniValue obj(UniValue::VOBJ); CNodeStateStats statestats; bool fStateStats = GetNodeStateStats(stats.nodeid, statestats); obj.push_back(Pair("id", stats.nodeid)); @@ -151,7 +151,7 @@ Value getpeerinfo(const Array& params, bool fHelp) obj.push_back(Pair("banscore", statestats.nMisbehavior)); obj.push_back(Pair("synced_headers", statestats.nSyncHeight)); obj.push_back(Pair("synced_blocks", statestats.nCommonHeight)); - Array heights; + UniValue heights(UniValue::VARR); BOOST_FOREACH(int height, statestats.vHeightInFlight) { heights.push_back(height); } @@ -271,12 +271,12 @@ Value getaddednodeinfo(const Array& params, bool fHelp) throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added."); } - Array ret; + UniValue ret(UniValue::VARR); if (!fDns) { BOOST_FOREACH(string& strAddNode, laddedNodes) { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", strAddNode)); ret.push_back(obj); } @@ -291,10 +291,10 @@ Value getaddednodeinfo(const Array& params, bool fHelp) laddedAddreses.push_back(make_pair(strAddNode, vservNode)); else { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", strAddNode)); obj.push_back(Pair("connected", false)); - Array addresses; + UniValue addresses(UniValue::VARR); obj.push_back(Pair("addresses", addresses)); } } @@ -302,15 +302,15 @@ Value getaddednodeinfo(const Array& params, bool fHelp) LOCK(cs_vNodes); for (list > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++) { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", it->first)); - Array addresses; + UniValue addresses(UniValue::VARR); bool fConnected = false; BOOST_FOREACH(CService& addrNode, it->second) { bool fFound = false; - Object node; + UniValue node(UniValue::VOBJ); node.push_back(Pair("address", addrNode.ToString())); BOOST_FOREACH(CNode* pnode, vNodes) if (pnode->addr == addrNode) @@ -350,7 +350,7 @@ Value getnettotals(const Array& params, bool fHelp) + HelpExampleRpc("getnettotals", "") ); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv())); obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent())); obj.push_back(Pair("timemillis", GetTimeMillis())); @@ -359,14 +359,14 @@ Value getnettotals(const Array& params, bool fHelp) static Array GetNetworksInfo() { - Array networks; + UniValue networks(UniValue::VARR); for(int n=0; n(n); if(network == NET_UNROUTABLE) continue; proxyType proxy; - Object obj; + UniValue obj(UniValue::VOBJ); GetProxy(network, proxy); obj.push_back(Pair("name", GetNetworkName(network))); obj.push_back(Pair("limited", IsLimited(network))); @@ -418,7 +418,7 @@ Value getnetworkinfo(const Array& params, bool fHelp) LOCK(cs_main); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("subversion", FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector()))); @@ -428,12 +428,12 @@ Value getnetworkinfo(const Array& params, bool fHelp) obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("networks", GetNetworksInfo())); obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); - Array localAddresses; + UniValue localAddresses(UniValue::VARR); { LOCK(cs_mapLocalHost); BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost) { - Object rec; + UniValue rec(UniValue::VOBJ); rec.push_back(Pair("address", item.first.ToString())); rec.push_back(Pair("port", item.second.nPort)); rec.push_back(Pair("score", item.second.nScore)); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index fe357d341f..5467f6df88 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -48,7 +48,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeH out.push_back(Pair("reqSigs", nRequired)); out.push_back(Pair("type", GetTxnOutputType(type))); - Array a; + UniValue a(UniValue::VARR); BOOST_FOREACH(const CTxDestination& addr, addresses) a.push_back(CBitcoinAddress(addr).ToString()); out.push_back(Pair("addresses", a)); @@ -59,15 +59,15 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); - Array vin; + UniValue vin(UniValue::VARR); BOOST_FOREACH(const CTxIn& txin, tx.vin) { - Object in; + UniValue in(UniValue::VOBJ); if (tx.IsCoinBase()) in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); else { in.push_back(Pair("txid", txin.prevout.hash.GetHex())); in.push_back(Pair("vout", (int64_t)txin.prevout.n)); - Object o; + UniValue o(UniValue::VOBJ); o.push_back(Pair("asm", txin.scriptSig.ToString())); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); @@ -76,13 +76,13 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) vin.push_back(in); } entry.push_back(Pair("vin", vin)); - Array vout; + UniValue vout(UniValue::VARR); for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; - Object out; + UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); out.push_back(Pair("n", (int64_t)i)); - Object o; + UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(txout.scriptPubKey, o, true); out.push_back(Pair("scriptPubKey", o)); vout.push_back(out); @@ -189,7 +189,7 @@ Value getrawtransaction(const Array& params, bool fHelp) if (!fVerbose) return strHex; - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("hex", strHex)); TxToJSON(tx, hashBlock, result); return result; @@ -293,7 +293,7 @@ Value verifytxoutproof(const Array& params, bool fHelp) CMerkleBlock merkleBlock; ssMB >> merkleBlock; - Array res; + UniValue res(UniValue::VARR); vector vMatch; if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot) @@ -481,7 +481,7 @@ Value decodescript(const Array& params, bool fHelp) LOCK(cs_main); RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); - Object r; + UniValue r(UniValue::VOBJ); CScript script; if (params[0].get_str().size() > 0){ vector scriptData(ParseHexV(params[0], "argument")); @@ -498,7 +498,7 @@ Value decodescript(const Array& params, bool fHelp) /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */ static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::string& strMessage) { - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", txin.prevout.hash.ToString())); entry.push_back(Pair("vout", (uint64_t)txin.prevout.n)); entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); @@ -711,7 +711,7 @@ Value signrawtransaction(const Array& params, bool fHelp) bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); // Script verification errors - Array vErrors; + UniValue vErrors(UniValue::VARR); // Sign what we can: for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { @@ -739,7 +739,7 @@ Value signrawtransaction(const Array& params, bool fHelp) } bool fComplete = vErrors.empty(); - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("hex", EncodeHexTx(mergedTx))); result.push_back(Pair("complete", fComplete)); if (!vErrors.empty()) { diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index da0a8048b2..3a54f1670b 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -866,7 +866,7 @@ void JSONRequest::parse(const Value& valRequest) static Object JSONRPCExecOne(const Value& req) { - Object rpc_result; + UniValue rpc_result(UniValue::VOBJ); JSONRequest jreq; try { diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index fea826b65a..cbbecf08ef 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -19,9 +19,9 @@ using namespace json_spirit; Array createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL) { - Array result; + UniValue result(UniValue::VARR); result.push_back(nRequired); - Array addresses; + UniValue addresses(UniValue::VARR); if (address1) addresses.push_back(address1); if (address2) addresses.push_back(address2); result.push_back(addresses); diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 989b35b9e8..80e5ac6b32 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -296,7 +296,7 @@ public: Array GetJSON() { DoPush(); - Array array; + UniValue array(UniValue::VARR); array.push_back(FormatScript(spendTx.vin[0].scriptSig)); array.push_back(FormatScript(creditTx.vout[0].scriptPubKey)); array.push_back(FormatScriptFlags(flags)); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f24a37ae6c..0cfd13a6b2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -68,7 +68,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry) } uint256 hash = wtx.GetHash(); entry.push_back(Pair("txid", hash.GetHex())); - Array conflicts; + UniValue conflicts(UniValue::VARR); BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts()) conflicts.push_back(conflict.GetHex()); entry.push_back(Pair("walletconflicts", conflicts)); @@ -336,7 +336,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) string strAccount = AccountFromValue(params[0]); // Find all addresses that have the given account - Array ret; + UniValue ret(UniValue::VARR); BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) { const CBitcoinAddress& address = item.first; @@ -464,14 +464,14 @@ Value listaddressgroupings(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - Array jsonGroupings; + UniValue jsonGroupings(UniValue::VARR); map balances = pwalletMain->GetAddressBalances(); BOOST_FOREACH(set grouping, pwalletMain->GetAddressGroupings()) { - Array jsonGrouping; + UniValue jsonGrouping(UniValue::VARR); BOOST_FOREACH(CTxDestination address, grouping) { - Array addressInfo; + UniValue addressInfo(UniValue::VARR); addressInfo.push_back(CBitcoinAddress(address).ToString()); addressInfo.push_back(ValueFromAmount(balances[address])); { @@ -967,7 +967,7 @@ Value sendmany(const Array& params, bool fHelp) if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) wtx.mapValue["comment"] = params[3].get_str(); - Array subtractFeeFromAmount; + UniValue subtractFeeFromAmount(UniValue::VARR); if (params.size() > 4) subtractFeeFromAmount = params[4].get_array(); @@ -1138,7 +1138,7 @@ Value ListReceived(const Array& params, bool fByAccounts) } // Reply - Array ret; + UniValue ret(UniValue::VARR); map mapAccountTally; BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) { @@ -1167,14 +1167,14 @@ Value ListReceived(const Array& params, bool fByAccounts) } else { - Object obj; + UniValue obj(UniValue::VOBJ); if(fIsWatchonly) obj.push_back(Pair("involvesWatchonly", true)); obj.push_back(Pair("address", address.ToString())); obj.push_back(Pair("account", strAccount)); obj.push_back(Pair("amount", ValueFromAmount(nAmount))); obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); - Array transactions; + UniValue transactions(UniValue::VARR); if (it != mapTally.end()) { BOOST_FOREACH(const uint256& item, (*it).second.txids) @@ -1193,7 +1193,7 @@ Value ListReceived(const Array& params, bool fByAccounts) { CAmount nAmount = (*it).second.nAmount; int nConf = (*it).second.nConf; - Object obj; + UniValue obj(UniValue::VOBJ); if((*it).second.fIsWatchonly) obj.push_back(Pair("involvesWatchonly", true)); obj.push_back(Pair("account", (*it).first)); @@ -1303,7 +1303,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe { BOOST_FOREACH(const COutputEntry& s, listSent) { - Object entry; + UniValue entry(UniValue::VOBJ); if(involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("account", strSentAccount)); @@ -1328,7 +1328,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe account = pwalletMain->mapAddressBook[r.destination].name; if (fAllAccounts || (account == strAccount)) { - Object entry; + UniValue entry(UniValue::VOBJ); if(involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("account", account)); @@ -1362,7 +1362,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar if (fAllAccounts || acentry.strAccount == strAccount) { - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("account", acentry.strAccount)); entry.push_back(Pair("category", "move")); entry.push_back(Pair("time", acentry.nTime)); @@ -1451,7 +1451,7 @@ Value listtransactions(const Array& params, bool fHelp) if (nFrom < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); - Array ret; + UniValue ret(UniValue::VARR); std::list acentries; CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount); @@ -1488,6 +1488,7 @@ Value listtransactions(const Array& params, bool fHelp) std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest ret.clear(); + ret.setArray(); ret.push_backV(arrTmp); return ret; @@ -1566,7 +1567,7 @@ Value listaccounts(const Array& params, bool fHelp) BOOST_FOREACH(const CAccountingEntry& entry, acentries) mapAccountBalances[entry.strAccount] += entry.nCreditDebit; - Object ret; + UniValue ret(UniValue::VOBJ); BOOST_FOREACH(const PAIRTYPE(string, CAmount)& accountBalance, mapAccountBalances) { ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second))); } @@ -1644,7 +1645,7 @@ Value listsinceblock(const Array& params, bool fHelp) int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1; - Array transactions; + UniValue transactions(UniValue::VARR); for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++) { @@ -1657,7 +1658,7 @@ Value listsinceblock(const Array& params, bool fHelp) CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256(); - Object ret; + UniValue ret(UniValue::VOBJ); ret.push_back(Pair("transactions", transactions)); ret.push_back(Pair("lastblock", lastblock.GetHex())); @@ -1715,7 +1716,7 @@ Value gettransaction(const Array& params, bool fHelp) if(params[1].get_bool()) filter = filter | ISMINE_WATCH_ONLY; - Object entry; + UniValue entry(UniValue::VOBJ); if (!pwalletMain->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); const CWalletTx& wtx = pwalletMain->mapWallet[hash]; @@ -1731,7 +1732,7 @@ Value gettransaction(const Array& params, bool fHelp) WalletTxToJSON(wtx, entry); - Array details; + UniValue details(UniValue::VARR); ListTransactions(wtx, "*", 0, false, details, filter); entry.push_back(Pair("details", details)); @@ -2134,10 +2135,10 @@ Value listlockunspent(const Array& params, bool fHelp) vector vOutpts; pwalletMain->ListLockedCoins(vOutpts); - Array ret; + UniValue ret(UniValue::VARR); BOOST_FOREACH(COutPoint &outpt, vOutpts) { - Object o; + UniValue o(UniValue::VOBJ); o.push_back(Pair("txid", outpt.hash.GetHex())); o.push_back(Pair("vout", (int)outpt.n)); @@ -2203,7 +2204,7 @@ Value getwalletinfo(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); @@ -2233,7 +2234,7 @@ Value resendwallettransactions(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); std::vector txids = pwalletMain->ResendWalletTransactionsBefore(GetTime()); - Array result; + UniValue result(UniValue::VARR); BOOST_FOREACH(const uint256& txid, txids) { result.push_back(txid.ToString()); @@ -2306,7 +2307,7 @@ Value listunspent(const Array& params, bool fHelp) } } - Array results; + UniValue results(UniValue::VARR); vector vecOutputs; assert(pwalletMain != NULL); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -2326,7 +2327,7 @@ Value listunspent(const Array& params, bool fHelp) CAmount nValue = out.tx->vout[out.i].nValue; const CScript& pk = out.tx->vout[out.i].scriptPubKey; - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); entry.push_back(Pair("vout", out.i)); CTxDestination address; -- cgit v1.2.3 From 21c10de8c2de17a6357dbbcea7613b41f6ab8449 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 14:49:18 +0200 Subject: special threatment for null,true,false because they are non valid json --- src/rpcclient.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 8b7b9e1493..bedf9ffbcb 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -11,6 +11,8 @@ #include #include +#include // for to_lower() + using namespace std; using namespace json_spirit; @@ -134,9 +136,19 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector Date: Sun, 10 May 2015 15:53:54 +0200 Subject: 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; -- cgit v1.2.3 From e04d9c25cf96edaf5b70baec6a21ceca624deea6 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 15:54:11 +0200 Subject: univalue: correct bool support --- src/univalue/univalue.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index efcf202bdd..c37a3829fc 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -30,6 +30,9 @@ public: UniValue(int64_t val_) { setInt(val_); } + UniValue(bool val_) { + setBool(val_); + } UniValue(int val_) { setInt(val_); } @@ -192,6 +195,13 @@ static inline std::pair Pair(const char *cKey, int64_t i64 return std::make_pair(key, uVal); } +static inline std::pair Pair(const char *cKey, bool iVal) +{ + std::string key(cKey); + UniValue uVal(iVal); + return std::make_pair(key, uVal); +} + static inline std::pair Pair(const char *cKey, int iVal) { std::string key(cKey); -- cgit v1.2.3 From 1f263c899ee0756ed9ed133f35bec18bdef20cdc Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 15:55:32 +0200 Subject: fix rpc unit test, plain numbers are not JSON compatible object UniValues read() does only read valid json. --- src/test/rpc_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index cbbecf08ef..991763abaf 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -123,8 +123,8 @@ BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) static Value ValueFromString(const std::string &str) { - Value value; - BOOST_CHECK(value.read(str)); + UniValue value; + BOOST_CHECK(value.setNumStr(str)); return value; } -- cgit v1.2.3 From 3df0411ad9fd75fb27af53e44835d41f5480fe3f Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 13 May 2015 21:29:19 +0200 Subject: remove JSON Spirit UniValue wrapper --- src/Makefile.am | 1 - src/bitcoin-cli.cpp | 9 +- src/json_spirit_wrapper.h | 17 ---- src/rest.cpp | 6 +- src/rpcblockchain.cpp | 30 +++--- src/rpcclient.cpp | 2 +- src/rpcclient.h | 4 +- src/rpcmining.cpp | 26 +++--- src/rpcmisc.cpp | 18 ++-- src/rpcnet.cpp | 16 ++-- src/rpcprotocol.cpp | 8 +- src/rpcprotocol.h | 8 +- src/rpcrawtransaction.cpp | 32 +++---- src/rpcserver.cpp | 28 +++--- src/rpcserver.h | 202 ++++++++++++++++++++--------------------- src/test/base58_tests.cpp | 26 +++--- src/test/rpc_tests.cpp | 2 +- src/test/rpc_wallet_tests.cpp | 4 +- src/test/script_tests.cpp | 14 +-- src/test/sighash_tests.cpp | 6 +- src/test/transaction_tests.cpp | 18 ++-- src/wallet/rpcdump.cpp | 10 +- src/wallet/rpcwallet.cpp | 10 +- 23 files changed, 239 insertions(+), 258 deletions(-) delete mode 100644 src/json_spirit_wrapper.h diff --git a/src/Makefile.am b/src/Makefile.am index 5041ae2f1c..63332f9acd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -98,7 +98,6 @@ BITCOIN_CORE_H = \ ecwrapper.h \ hash.h \ init.h \ - json_spirit_wrapper.h \ key.h \ keystore.h \ leveldbwrapper.h \ diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 9ad5fb6b1d..0cafd2b0b4 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -94,7 +94,7 @@ static bool AppInitRPC(int argc, char* argv[]) return true; } -Object CallRPC(const string& strMethod, const Array& params) +UniValue CallRPC(const string& strMethod, const Array& params) { if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "") throw runtime_error(strprintf( @@ -142,7 +142,7 @@ Object CallRPC(const string& strMethod, const Array& params) throw runtime_error("no response from server"); // Parse reply - Value valReply(UniValue::VSTR); + UniValue valReply(UniValue::VSTR); if (!valReply.read(strReply)) throw runtime_error("couldn't parse reply from server"); const Object& reply = valReply.get_obj(); @@ -170,14 +170,13 @@ int CommandLineRPC(int argc, char *argv[]) // Parameters default to strings std::vector strParams(&argv[2], &argv[argc]); - Array params = RPCConvertValues(strMethod, strParams); + UniValue params = RPCConvertValues(strMethod, strParams); // Execute and handle connection failures with -rpcwait const bool fWait = GetBoolArg("-rpcwait", false); do { try { - // Execute - Object reply = CallRPC(strMethod, params); + const UniValue reply = CallRPC(strMethod, params); // Parse reply const Value& result = find_value(reply, "result"); diff --git a/src/json_spirit_wrapper.h b/src/json_spirit_wrapper.h deleted file mode 100644 index 1962cf6431..0000000000 --- a/src/json_spirit_wrapper.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __JSON_SPIRIT_WRAPPER_H__ -#define __JSON_SPIRIT_WRAPPER_H__ - -#include "univalue/univalue.h" - -namespace json_spirit { - -typedef UniValue Value; -typedef UniValue Array; -typedef UniValue Object; -typedef UniValue::VType Value_type; - -} - -#define find_value(val,key) (val[key]) - -#endif // __JSON_SPIRIT_WRAPPER_H__ diff --git a/src/rest.cpp b/src/rest.cpp index f3195746ba..3142b25036 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -62,7 +62,7 @@ public: }; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); -extern Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex); static RestErr RESTERR(enum HTTPStatusCode status, string message) @@ -221,7 +221,7 @@ static bool rest_block(AcceptedConnection* conn, } case RF_JSON: { - Object objBlock = blockToJSON(block, pblockindex, showTxDetails); + UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails); string strJSON = objBlock.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; @@ -266,7 +266,7 @@ static bool rest_chaininfo(AcceptedConnection* conn, switch (rf) { case RF_JSON: { UniValue rpcParams(UniValue::VARR); - Value chainInfoObject = getblockchaininfo(rpcParams, false); + UniValue chainInfoObject = getblockchaininfo(rpcParams, false); string strJSON = chainInfoObject.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index facc112cb4..f20f9f994d 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -53,7 +53,7 @@ double GetDifficulty(const CBlockIndex* blockindex) } -Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) +UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { UniValue result(UniValue::VOBJ); result.push_back(Pair("hash", block.GetHash().GetHex())); @@ -94,7 +94,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe } -Value getblockcount(const Array& params, bool fHelp) +UniValue getblockcount(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -111,7 +111,7 @@ Value getblockcount(const Array& params, bool fHelp) return chainActive.Height(); } -Value getbestblockhash(const Array& params, bool fHelp) +UniValue getbestblockhash(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -128,7 +128,7 @@ Value getbestblockhash(const Array& params, bool fHelp) return chainActive.Tip()->GetBlockHash().GetHex(); } -Value getdifficulty(const Array& params, bool fHelp) +UniValue getdifficulty(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -146,7 +146,7 @@ Value getdifficulty(const Array& params, bool fHelp) } -Value getrawmempool(const Array& params, bool fHelp) +UniValue getrawmempool(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -231,7 +231,7 @@ Value getrawmempool(const Array& params, bool fHelp) } } -Value getblockhash(const Array& params, bool fHelp) +UniValue getblockhash(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -256,7 +256,7 @@ Value getblockhash(const Array& params, bool fHelp) return pblockindex->GetBlockHash().GetHex(); } -Value getblock(const Array& params, bool fHelp) +UniValue getblock(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -324,7 +324,7 @@ Value getblock(const Array& params, bool fHelp) return blockToJSON(block, pblockindex); } -Value gettxoutsetinfo(const Array& params, bool fHelp) +UniValue gettxoutsetinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -364,7 +364,7 @@ Value gettxoutsetinfo(const Array& params, bool fHelp) return ret; } -Value gettxout(const Array& params, bool fHelp) +UniValue gettxout(const Array& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 3) throw runtime_error( @@ -444,7 +444,7 @@ Value gettxout(const Array& params, bool fHelp) return ret; } -Value verifychain(const Array& params, bool fHelp) +UniValue verifychain(const Array& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -472,7 +472,7 @@ Value verifychain(const Array& params, bool fHelp) return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth); } -Value getblockchaininfo(const Array& params, bool fHelp) +UniValue getblockchaininfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -530,7 +530,7 @@ struct CompareBlocksByHeight } }; -Value getchaintips(const Array& params, bool fHelp) +UniValue getchaintips(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -620,7 +620,7 @@ Value getchaintips(const Array& params, bool fHelp) return res; } -Value getmempoolinfo(const Array& params, bool fHelp) +UniValue getmempoolinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -643,7 +643,7 @@ Value getmempoolinfo(const Array& params, bool fHelp) return ret; } -Value invalidateblock(const Array& params, bool fHelp) +UniValue invalidateblock(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -681,7 +681,7 @@ Value invalidateblock(const Array& params, bool fHelp) return NullUniValue; } -Value reconsiderblock(const Array& params, bool fHelp) +UniValue reconsiderblock(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index aa6d1eff59..ec098a17a7 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -122,7 +122,7 @@ CRPCConvertTable::CRPCConvertTable() static CRPCConvertTable rpcCvtTable; /** Convert strings to command-specific RPC representation */ -Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams) +UniValue RPCConvertValues(const std::string &strMethod, const std::vector &strParams) { UniValue params(UniValue::VARR); diff --git a/src/rpcclient.h b/src/rpcclient.h index 29c1260272..52270aec74 100644 --- a/src/rpcclient.h +++ b/src/rpcclient.h @@ -6,8 +6,8 @@ #ifndef BITCOIN_RPCCLIENT_H #define BITCOIN_RPCCLIENT_H -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" -json_spirit::Array RPCConvertValues(const std::string& strMethod, const std::vector& strParams); +UniValue RPCConvertValues(const std::string& strMethod, const std::vector& strParams); #endif // BITCOIN_RPCCLIENT_H diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index c2ad75af69..89e20526ed 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -34,7 +34,7 @@ using namespace std; * or from the last difficulty change if 'lookup' is nonpositive. * If 'height' is nonnegative, compute the estimate at the time when a given block was found. */ -Value GetNetworkHashPS(int lookup, int height) { +UniValue GetNetworkHashPS(int lookup, int height) { CBlockIndex *pb = chainActive.Tip(); if (height >= 0 && height < chainActive.Height()) @@ -71,7 +71,7 @@ Value GetNetworkHashPS(int lookup, int height) { return (int64_t)(workDiff.getdouble() / timeDiff); } -Value getnetworkhashps(const Array& params, bool fHelp) +UniValue getnetworkhashps(const Array& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -94,7 +94,7 @@ Value getnetworkhashps(const Array& params, bool fHelp) } #ifdef ENABLE_WALLET -Value getgenerate(const Array& params, bool fHelp) +UniValue getgenerate(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -113,7 +113,7 @@ Value getgenerate(const Array& params, bool fHelp) return GetBoolArg("-gen", false); } -Value generate(const Array& params, bool fHelp) +UniValue generate(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( @@ -172,7 +172,7 @@ Value generate(const Array& params, bool fHelp) } -Value setgenerate(const Array& params, bool fHelp) +UniValue setgenerate(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -220,7 +220,7 @@ Value setgenerate(const Array& params, bool fHelp) #endif -Value getmininginfo(const Array& params, bool fHelp) +UniValue getmininginfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -266,7 +266,7 @@ Value getmininginfo(const Array& params, bool fHelp) // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts -Value prioritisetransaction(const Array& params, bool fHelp) +UniValue prioritisetransaction(const Array& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( @@ -298,7 +298,7 @@ Value prioritisetransaction(const Array& params, bool fHelp) // NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller -static Value BIP22ValidationResult(const CValidationState& state) +static UniValue BIP22ValidationResult(const CValidationState& state) { if (state.IsValid()) return Value::null; @@ -316,7 +316,7 @@ static Value BIP22ValidationResult(const CValidationState& state) return "valid?"; } -Value getblocktemplate(const Array& params, bool fHelp) +UniValue getblocktemplate(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -381,7 +381,7 @@ Value getblocktemplate(const Array& params, bool fHelp) LOCK(cs_main); std::string strMode = "template"; - Value lpval = NullUniValue; + UniValue lpval = NullUniValue; if (params.size() > 0) { const Object& oparam = params[0].get_obj(); @@ -605,7 +605,7 @@ protected: }; }; -Value submitblock(const Array& params, bool fHelp) +UniValue submitblock(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -666,7 +666,7 @@ Value submitblock(const Array& params, bool fHelp) return BIP22ValidationResult(state); } -Value estimatefee(const Array& params, bool fHelp) +UniValue estimatefee(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -698,7 +698,7 @@ Value estimatefee(const Array& params, bool fHelp) return ValueFromAmount(feeRate.GetFeePerK()); } -Value estimatepriority(const Array& params, bool fHelp) +UniValue estimatepriority(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 2d54b555b9..15bbe90bc7 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -38,7 +38,7 @@ using namespace std; * * Or alternatively, create a specific query method for the information. **/ -Value getinfo(const Array& params, bool fHelp) +UniValue getinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -115,9 +115,9 @@ private: public: DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {} - Object operator()(const CNoDestination &dest) const { return Object(); } + UniValue operator()(const CNoDestination &dest) const { return Object(); } - Object operator()(const CKeyID &keyID) const { + UniValue operator()(const CKeyID &keyID) const { UniValue obj(UniValue::VOBJ); CPubKey vchPubKey; obj.push_back(Pair("isscript", false)); @@ -129,7 +129,7 @@ public: return obj; } - Object operator()(const CScriptID &scriptID) const { + UniValue operator()(const CScriptID &scriptID) const { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("isscript", true)); if (mine != ISMINE_NO) { @@ -153,7 +153,7 @@ public: }; #endif -Value validateaddress(const Array& params, bool fHelp) +UniValue validateaddress(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -202,7 +202,7 @@ Value validateaddress(const Array& params, bool fHelp) ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); if (mine != ISMINE_NO) { ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false)); - Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); + UniValue detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); ret.pushKVs(detail); } if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) @@ -276,7 +276,7 @@ CScript _createmultisig_redeemScript(const Array& params) return result; } -Value createmultisig(const Array& params, bool fHelp) +UniValue createmultisig(const Array& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 2) { @@ -319,7 +319,7 @@ Value createmultisig(const Array& params, bool fHelp) return result; } -Value verifymessage(const Array& params, bool fHelp) +UniValue verifymessage(const Array& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( @@ -373,7 +373,7 @@ Value verifymessage(const Array& params, bool fHelp) return (pubkey.GetID() == keyID); } -Value setmocktime(const Array& params, bool fHelp) +UniValue setmocktime(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index d8dd46e64e..17eda22451 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -21,7 +21,7 @@ using namespace json_spirit; using namespace std; -Value getconnectioncount(const Array& params, bool fHelp) +UniValue getconnectioncount(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -39,7 +39,7 @@ Value getconnectioncount(const Array& params, bool fHelp) return (int)vNodes.size(); } -Value ping(const Array& params, bool fHelp) +UniValue ping(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -75,7 +75,7 @@ static void CopyNodeStats(std::vector& vstats) } } -Value getpeerinfo(const Array& params, bool fHelp) +UniValue getpeerinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -165,7 +165,7 @@ Value getpeerinfo(const Array& params, bool fHelp) return ret; } -Value addnode(const Array& params, bool fHelp) +UniValue addnode(const Array& params, bool fHelp) { string strCommand; if (params.size() == 2) @@ -215,7 +215,7 @@ Value addnode(const Array& params, bool fHelp) return NullUniValue; } -Value getaddednodeinfo(const Array& params, bool fHelp) +UniValue getaddednodeinfo(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -332,7 +332,7 @@ Value getaddednodeinfo(const Array& params, bool fHelp) return ret; } -Value getnettotals(const Array& params, bool fHelp) +UniValue getnettotals(const Array& params, bool fHelp) { if (fHelp || params.size() > 0) throw runtime_error( @@ -357,7 +357,7 @@ Value getnettotals(const Array& params, bool fHelp) return obj; } -static Array GetNetworksInfo() +static UniValue GetNetworksInfo() { UniValue networks(UniValue::VARR); for(int n=0; n& stream, map& stream, int &proto); int ReadHTTPHeaders(std::basic_istream& stream, std::map& mapHeadersRet); int ReadHTTPMessage(std::basic_istream& stream, std::map& mapHeadersRet, std::string& strMessageRet, int nProto, size_t max_size); -std::string JSONRPCRequest(const std::string& strMethod, const json_spirit::Array& params, const json_spirit::Value& id); -json_spirit::Object JSONRPCReplyObj(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id); -std::string JSONRPCReply(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id); -json_spirit::Object JSONRPCError(int code, const std::string& message); +std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id); +UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id); +std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id); +UniValue JSONRPCError(int code, const std::string& message); #endif // BITCOIN_RPCPROTOCOL_H diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 5467f6df88..b4ddbfebf3 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -105,7 +105,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) } } -Value getrawtransaction(const Array& params, bool fHelp) +UniValue getrawtransaction(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -195,7 +195,7 @@ Value getrawtransaction(const Array& params, bool fHelp) return result; } -Value gettxoutproof(const Array& params, bool fHelp) +UniValue gettxoutproof(const Array& params, bool fHelp) { if (fHelp || (params.size() != 1 && params.size() != 2)) throw runtime_error( @@ -219,7 +219,7 @@ Value gettxoutproof(const Array& params, bool fHelp) set setTxids; uint256 oneTxid; - Array txids = params[0].get_array(); + UniValue txids = params[0].get_array(); for (unsigned int idx = 0; idx < txids.size(); idx++) { const Value& txid = txids[idx]; if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) @@ -276,7 +276,7 @@ Value gettxoutproof(const Array& params, bool fHelp) return strHex; } -Value verifytxoutproof(const Array& params, bool fHelp) +UniValue verifytxoutproof(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -309,7 +309,7 @@ Value verifytxoutproof(const Array& params, bool fHelp) return res; } -Value createrawtransaction(const Array& params, bool fHelp) +UniValue createrawtransaction(const Array& params, bool fHelp) { if (fHelp || params.size() != 2) throw runtime_error( @@ -345,8 +345,8 @@ Value createrawtransaction(const Array& params, bool fHelp) LOCK(cs_main); RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)); - Array inputs = params[0].get_array(); - Object sendTo = params[1].get_obj(); + UniValue inputs = params[0].get_array(); + UniValue sendTo = params[1].get_obj(); CMutableTransaction rawTx; @@ -388,7 +388,7 @@ Value createrawtransaction(const Array& params, bool fHelp) return EncodeHexTx(rawTx); } -Value decoderawtransaction(const Array& params, bool fHelp) +UniValue decoderawtransaction(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -453,7 +453,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) return result; } -Value decodescript(const Array& params, bool fHelp) +UniValue decodescript(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -507,7 +507,7 @@ static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::str vErrorsRet.push_back(entry); } -Value signrawtransaction(const Array& params, bool fHelp) +UniValue signrawtransaction(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 4) throw runtime_error( @@ -617,9 +617,9 @@ Value signrawtransaction(const Array& params, bool fHelp) CBasicKeyStore tempKeystore; if (params.size() > 2 && !params[2].isNull()) { fGivenKeys = true; - Array keys = params[2].get_array(); + UniValue keys = params[2].get_array(); for (unsigned int idx = 0; idx < keys.size(); idx++) { - Value k = keys[idx]; + UniValue k = keys[idx]; CBitcoinSecret vchSecret; bool fGood = vchSecret.SetString(k.get_str()); if (!fGood) @@ -637,13 +637,13 @@ Value signrawtransaction(const Array& params, bool fHelp) // Add previous txouts given in the RPC call: if (params.size() > 1 && !params[1].isNull()) { - Array prevTxs = params[1].get_array(); + UniValue prevTxs = params[1].get_array(); for (unsigned int idx = 0; idx < prevTxs.size(); idx++) { const Value& p = prevTxs[idx]; if (!p.isObject()) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); - Object prevOut = p.get_obj(); + UniValue prevOut = p.get_obj(); RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)); @@ -674,7 +674,7 @@ Value signrawtransaction(const Array& params, bool fHelp) // given), add redeemScript to the tempKeystore so it can be signed: if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) { RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR)); - Value v = find_value(prevOut, "redeemScript"); + UniValue v = find_value(prevOut, "redeemScript"); if (!v.isNull()) { vector rsData(ParseHexV(v, "redeemScript")); CScript redeemScript(rsData.begin(), rsData.end()); @@ -749,7 +749,7 @@ Value signrawtransaction(const Array& params, bool fHelp) return result; } -Value sendrawtransaction(const Array& params, bool fHelp) +UniValue sendrawtransaction(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 3a54f1670b..cb746508b1 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -135,7 +135,7 @@ CAmount AmountFromValue(const Value& value) return nAmount; } -Value ValueFromAmount(const CAmount& amount) +UniValue ValueFromAmount(const CAmount& amount) { return (double)amount / (double)COIN; } @@ -196,7 +196,7 @@ string CRPCTable::help(string strCommand) const continue; try { - Array params; + UniValue params; rpcfn_type pfn = pcmd->actor; if (setDone.insert(pfn).second) (*pfn)(params, true); @@ -229,7 +229,7 @@ string CRPCTable::help(string strCommand) const return strRet; } -Value help(const Array& params, bool fHelp) +UniValue help(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -249,7 +249,7 @@ Value help(const Array& params, bool fHelp) } -Value stop(const Array& params, bool fHelp) +UniValue stop(const Array& params, bool fHelp) { // Accept the deprecated and ignored 'detach' boolean argument if (fHelp || params.size() > 1) @@ -825,9 +825,9 @@ void RPCRunLater(const std::string& name, boost::function func, int6 class JSONRequest { public: - Value id; + UniValue id; string strMethod; - Array params; + UniValue params; JSONRequest() { id = NullUniValue; } void parse(const Value& valRequest); @@ -844,7 +844,7 @@ void JSONRequest::parse(const Value& valRequest) id = find_value(request, "id"); // Parse method - Value valMethod = find_value(request, "method"); + UniValue valMethod = find_value(request, "method"); if (valMethod.isNull()) throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method"); if (!valMethod.isStr()) @@ -854,7 +854,7 @@ void JSONRequest::parse(const Value& valRequest) LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod)); // Parse params - Value valParams = find_value(request, "params"); + UniValue valParams = find_value(request, "params"); if (valParams.isArray()) params = valParams.get_array(); else if (valParams.isNull()) @@ -864,7 +864,7 @@ void JSONRequest::parse(const Value& valRequest) } -static Object JSONRPCExecOne(const Value& req) +static UniValue JSONRPCExecOne(const Value& req) { UniValue rpc_result(UniValue::VOBJ); @@ -872,7 +872,7 @@ static Object JSONRPCExecOne(const Value& req) try { jreq.parse(req); - Value result = tableRPC.execute(jreq.strMethod, jreq.params); + UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); } catch (const Object& objError) @@ -890,7 +890,7 @@ static Object JSONRPCExecOne(const Value& req) static string JSONRPCExecBatch(const Array& vReq) { - Array ret; + UniValue ret; for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) ret.push_back(JSONRPCExecOne(vReq[reqIdx])); @@ -925,7 +925,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, try { // Parse request - Value valRequest; + UniValue valRequest; if (!valRequest.read(strRequest)) throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); @@ -942,7 +942,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, if (valRequest.isObject()) { jreq.parse(valRequest); - Value result = tableRPC.execute(jreq.strMethod, jreq.params); + UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); // Send reply strReply = JSONRPCReply(result, NullUniValue, jreq.id); @@ -1005,7 +1005,7 @@ void ServiceConnection(AcceptedConnection *conn) } } -json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const +UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms) const { // Find method const CRPCCommand *pcmd = tableRPC[strMethod]; diff --git a/src/rpcserver.h b/src/rpcserver.h index c9982bb8ca..e2bc8c0955 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -70,8 +70,8 @@ bool RPCIsInWarmup(std::string *statusOut); * the right number of arguments are passed, just that any passed are the correct type. * Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type)); */ -void RPCTypeCheck(const json_spirit::Array& params, - const std::list& typesExpected, bool fAllowNull=false); +void RPCTypeCheck(const UniValue& params, + const std::list& typesExpected, bool fAllowNull=false); /* Check for expected keys/value types in an Object. @@ -89,7 +89,7 @@ void RPCRunLater(const std::string& name, boost::function func, int6 //! Convert boost::asio address to CNetAddr extern CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address); -typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp); +typedef UniValue(*rpcfn_type)(const UniValue& params, bool fHelp); class CRPCCommand { @@ -115,11 +115,11 @@ public: /** * Execute a method. * @param method Method to execute - * @param params Array of arguments (JSON objects) + * @param params UniValue Array of arguments (JSON objects) * @returns Result of the call. - * @throws an exception (json_spirit::Value) when an error happens. + * @throws an exception (UniValue) when an error happens. */ - json_spirit::Value execute(const std::string &method, const json_spirit::Array ¶ms) const; + UniValue execute(const std::string &method, const UniValue ¶ms) const; }; extern const CRPCTable tableRPC; @@ -128,17 +128,17 @@ extern const CRPCTable tableRPC; * Utilities: convert hex-encoded Values * (throws error if not hex). */ -extern uint256 ParseHashV(const json_spirit::Value& v, std::string strName); -extern uint256 ParseHashO(const json_spirit::Object& o, std::string strKey); -extern std::vector ParseHexV(const json_spirit::Value& v, std::string strName); -extern std::vector ParseHexO(const json_spirit::Object& o, std::string strKey); +extern uint256 ParseHashV(const UniValue& v, std::string strName); +extern uint256 ParseHashO(const UniValue& o, std::string strKey); +extern std::vector ParseHexV(const UniValue& v, std::string strName); +extern std::vector ParseHexO(const UniValue& o, std::string strKey); extern void InitRPCMining(); extern void ShutdownRPCMining(); extern int64_t nWalletUnlockTime; -extern CAmount AmountFromValue(const json_spirit::Value& value); -extern json_spirit::Value ValueFromAmount(const CAmount& amount); +extern CAmount AmountFromValue(const UniValue& value); +extern UniValue ValueFromAmount(const CAmount& amount); extern double GetDifficulty(const CBlockIndex* blockindex = NULL); extern std::string HelpRequiringPassphrase(); extern std::string HelpExampleCli(std::string methodname, std::string args); @@ -146,95 +146,95 @@ extern std::string HelpExampleRpc(std::string methodname, std::string args); extern void EnsureWalletIsUnlocked(); -extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp -extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value ping(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getnettotals(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp -extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value importaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value dumpwallet(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp -extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value generate(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value estimatepriority(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getrawchangeaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value setaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaddressesbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendtoaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value signmessage(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value verifymessage(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getreceivedbyaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getreceivedbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getbalance(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getunconfirmedbalance(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value movecmd(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendfrom(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendmany(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value addmultisigaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value createmultisig(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listreceivedbyaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listreceivedbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listtransactions(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listaddressgroupings(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listaccounts(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listsinceblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value backupwallet(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value keypoolrefill(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletpassphrase(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value encryptwallet(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value validateaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getwalletinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblockchaininfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getnetworkinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value setmocktime(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value resendwallettransactions(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp -extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value lockunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listlockunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value createrawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value decodescript(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettxoutproof(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value verifytxoutproof(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp -extern json_spirit::Value getbestblockhash(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getmempoolinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool fHelp); +extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.cpp +extern UniValue getpeerinfo(const UniValue& params, bool fHelp); +extern UniValue ping(const UniValue& params, bool fHelp); +extern UniValue addnode(const UniValue& params, bool fHelp); +extern UniValue getaddednodeinfo(const UniValue& params, bool fHelp); +extern UniValue getnettotals(const UniValue& params, bool fHelp); + +extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp +extern UniValue importprivkey(const UniValue& params, bool fHelp); +extern UniValue importaddress(const UniValue& params, bool fHelp); +extern UniValue dumpwallet(const UniValue& params, bool fHelp); +extern UniValue importwallet(const UniValue& params, bool fHelp); + +extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpcmining.cpp +extern UniValue setgenerate(const UniValue& params, bool fHelp); +extern UniValue generate(const UniValue& params, bool fHelp); +extern UniValue getnetworkhashps(const UniValue& params, bool fHelp); +extern UniValue getmininginfo(const UniValue& params, bool fHelp); +extern UniValue prioritisetransaction(const UniValue& params, bool fHelp); +extern UniValue getblocktemplate(const UniValue& params, bool fHelp); +extern UniValue submitblock(const UniValue& params, bool fHelp); +extern UniValue estimatefee(const UniValue& params, bool fHelp); +extern UniValue estimatepriority(const UniValue& params, bool fHelp); + +extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue getaccountaddress(const UniValue& params, bool fHelp); +extern UniValue getrawchangeaddress(const UniValue& params, bool fHelp); +extern UniValue setaccount(const UniValue& params, bool fHelp); +extern UniValue getaccount(const UniValue& params, bool fHelp); +extern UniValue getaddressesbyaccount(const UniValue& params, bool fHelp); +extern UniValue sendtoaddress(const UniValue& params, bool fHelp); +extern UniValue signmessage(const UniValue& params, bool fHelp); +extern UniValue verifymessage(const UniValue& params, bool fHelp); +extern UniValue getreceivedbyaddress(const UniValue& params, bool fHelp); +extern UniValue getreceivedbyaccount(const UniValue& params, bool fHelp); +extern UniValue getbalance(const UniValue& params, bool fHelp); +extern UniValue getunconfirmedbalance(const UniValue& params, bool fHelp); +extern UniValue movecmd(const UniValue& params, bool fHelp); +extern UniValue sendfrom(const UniValue& params, bool fHelp); +extern UniValue sendmany(const UniValue& params, bool fHelp); +extern UniValue addmultisigaddress(const UniValue& params, bool fHelp); +extern UniValue createmultisig(const UniValue& params, bool fHelp); +extern UniValue listreceivedbyaddress(const UniValue& params, bool fHelp); +extern UniValue listreceivedbyaccount(const UniValue& params, bool fHelp); +extern UniValue listtransactions(const UniValue& params, bool fHelp); +extern UniValue listaddressgroupings(const UniValue& params, bool fHelp); +extern UniValue listaccounts(const UniValue& params, bool fHelp); +extern UniValue listsinceblock(const UniValue& params, bool fHelp); +extern UniValue gettransaction(const UniValue& params, bool fHelp); +extern UniValue backupwallet(const UniValue& params, bool fHelp); +extern UniValue keypoolrefill(const UniValue& params, bool fHelp); +extern UniValue walletpassphrase(const UniValue& params, bool fHelp); +extern UniValue walletpassphrasechange(const UniValue& params, bool fHelp); +extern UniValue walletlock(const UniValue& params, bool fHelp); +extern UniValue encryptwallet(const UniValue& params, bool fHelp); +extern UniValue validateaddress(const UniValue& params, bool fHelp); +extern UniValue getinfo(const UniValue& params, bool fHelp); +extern UniValue getwalletinfo(const UniValue& params, bool fHelp); +extern UniValue getblockchaininfo(const UniValue& params, bool fHelp); +extern UniValue getnetworkinfo(const UniValue& params, bool fHelp); +extern UniValue setmocktime(const UniValue& params, bool fHelp); +extern UniValue resendwallettransactions(const UniValue& params, bool fHelp); + +extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rcprawtransaction.cpp +extern UniValue listunspent(const UniValue& params, bool fHelp); +extern UniValue lockunspent(const UniValue& params, bool fHelp); +extern UniValue listlockunspent(const UniValue& params, bool fHelp); +extern UniValue createrawtransaction(const UniValue& params, bool fHelp); +extern UniValue decoderawtransaction(const UniValue& params, bool fHelp); +extern UniValue decodescript(const UniValue& params, bool fHelp); +extern UniValue signrawtransaction(const UniValue& params, bool fHelp); +extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); +extern UniValue gettxoutproof(const UniValue& params, bool fHelp); +extern UniValue verifytxoutproof(const UniValue& params, bool fHelp); + +extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpcblockchain.cpp +extern UniValue getbestblockhash(const UniValue& params, bool fHelp); +extern UniValue getdifficulty(const UniValue& params, bool fHelp); +extern UniValue settxfee(const UniValue& params, bool fHelp); +extern UniValue getmempoolinfo(const UniValue& params, bool fHelp); +extern UniValue getrawmempool(const UniValue& params, bool fHelp); +extern UniValue getblockhash(const UniValue& params, bool fHelp); +extern UniValue getblock(const UniValue& params, bool fHelp); +extern UniValue gettxoutsetinfo(const UniValue& params, bool fHelp); +extern UniValue gettxout(const UniValue& params, bool fHelp); +extern UniValue verifychain(const UniValue& params, bool fHelp); +extern UniValue getchaintips(const UniValue& params, bool fHelp); +extern UniValue invalidateblock(const UniValue& params, bool fHelp); +extern UniValue reconsiderblock(const UniValue& params, bool fHelp); // in rest.cpp extern bool HTTPReq_REST(AcceptedConnection *conn, diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index a806fe7b05..114bd79ea9 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -20,16 +20,16 @@ #include "json_spirit_wrapper.h" using namespace json_spirit; -extern Array read_json(const std::string& jsondata); +extern UniValue read_json(const std::string& jsondata); BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup) // Goal: test low-level base58 encoding functionality BOOST_AUTO_TEST_CASE(base58_EncodeBase58) { - Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); + UniValue tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) { @@ -47,11 +47,11 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58) // Goal: test low-level base58 decoding functionality BOOST_AUTO_TEST_CASE(base58_DecodeBase58) { - Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); + UniValue tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); std::vector result; for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) { @@ -120,14 +120,14 @@ public: // Goal: check that parsed keys match test payload BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) { - Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); + UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); std::vector result; CBitcoinSecret secret; CBitcoinAddress addr; SelectParams(CBaseChainParams::MAIN); for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) { @@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) } std::string exp_base58string = test[0].get_str(); std::vector exp_payload = ParseHex(test[1].get_str()); - const Object &metadata = test[2].get_obj(); + const UniValue &metadata = test[2].get_obj(); bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); bool isTestnet = find_value(metadata, "isTestnet").get_bool(); if (isTestnet) @@ -178,11 +178,11 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) // Goal: check that generated keys match test vectors BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) { - Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); + UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); std::vector result; for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) { @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) } std::string exp_base58string = test[0].get_str(); std::vector exp_payload = ParseHex(test[1].get_str()); - const Object &metadata = test[2].get_obj(); + const UniValue &metadata = test[2].get_obj(); bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); bool isTestnet = find_value(metadata, "isTestnet").get_bool(); if (isTestnet) @@ -246,13 +246,13 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) // Goal: check that base58 parsing code is robust against a variety of corrupted data BOOST_AUTO_TEST_CASE(base58_keys_invalid) { - Array tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases + UniValue tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases std::vector result; CBitcoinSecret secret; CBitcoinAddress addr; for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) { diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 991763abaf..a97c96be72 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -34,7 +34,7 @@ Value CallRPC(string args) boost::split(vArgs, args, boost::is_any_of(" \t")); string strMethod = vArgs[0]; vArgs.erase(vArgs.begin()); - Array params = RPCConvertValues(strMethod, vArgs); + UniValue params = RPCConvertValues(strMethod, vArgs); rpcfn_type method = tableRPC[strMethod]->actor; try { diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 4d5e92cbd4..1a897fcd54 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -17,7 +17,7 @@ using namespace std; using namespace json_spirit; -extern Array createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL); +extern UniValue createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL); extern Value CallRPC(string args); extern CWallet* pwalletMain; @@ -213,7 +213,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) *********************************/ BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error); BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount)); - Array arr = retValue.get_array(); + UniValue arr = retValue.get_array(); BOOST_CHECK(arr.size() > 0); BOOST_CHECK(CBitcoinAddress(arr[0].get_str()).Get() == demoAddress.Get()); } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 80e5ac6b32..af11c0c9d9 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -293,7 +293,7 @@ public: return *this; } - Array GetJSON() + UniValue GetJSON() { DoPush(); UniValue array(UniValue::VARR); @@ -580,8 +580,8 @@ BOOST_AUTO_TEST_CASE(script_build) std::set tests_bad; { - Array json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); - Array json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); + UniValue json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); + UniValue json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); for (unsigned int idx = 0; idx < json_good.size(); idx++) { const Value& tv = json_good[idx]; @@ -634,10 +634,10 @@ BOOST_AUTO_TEST_CASE(script_valid) // Inner arrays are [ "scriptSig", "scriptPubKey", "flags" ] // ... where scriptSig and scriptPubKey are stringified // scripts. - Array tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); + UniValue tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; string strTest = test.write(); if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) { @@ -659,10 +659,10 @@ BOOST_AUTO_TEST_CASE(script_valid) BOOST_AUTO_TEST_CASE(script_invalid) { // Scripts that should evaluate as invalid - Array tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); + UniValue tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; string strTest = test.write(); if (test.size() < 3) // Allow size > 2; extra stuff ignored (useful for comments) { diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 121644ddc4..efdb4e8043 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -19,7 +19,7 @@ #include "json_spirit_wrapper.h" using namespace json_spirit; -extern Array read_json(const std::string& jsondata); +extern UniValue read_json(const std::string& jsondata); // Old script.cpp SignatureHash function uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) @@ -166,10 +166,10 @@ BOOST_AUTO_TEST_CASE(sighash_test) // Goal: check that SignatureHash generates correct hash BOOST_AUTO_TEST_CASE(sighash_from_data) { - Array tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); + UniValue tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) { diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 0ddc48271b..afd2d74013 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -30,7 +30,7 @@ using namespace std; using namespace json_spirit; // In script_tests.cpp -extern Array read_json(const std::string& jsondata); +extern UniValue read_json(const std::string& jsondata); static std::map mapFlagNames = boost::assign::map_list_of (string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE) @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) // ... where all scripts are stringified scripts. // // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" - Array tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); + UniValue tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); <<<<<<< HEAD ScriptError err; @@ -101,7 +101,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) if (test[0].type() == array_type) ======= for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; string strTest = test.write(); if (test[0].isArray()) >>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. @@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) } map mapprevOutScriptPubKeys; - Array inputs = test[0].get_array(); + UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { const Value& input = inputs[inpIdx]; @@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) fValid = false; break; } - Array vinput = input.get_array(); + UniValue vinput = input.get_array(); if (vinput.size() != 3) { fValid = false; @@ -173,7 +173,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) // ... where all scripts are stringified scripts. // // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" - Array tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); + UniValue tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); <<<<<<< HEAD ScriptError err; @@ -184,7 +184,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) if (test[0].type() == array_type) ======= for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; string strTest = test.write(); if (test[0].isArray()) >>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. @@ -196,7 +196,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) } map mapprevOutScriptPubKeys; - Array inputs = test[0].get_array(); + UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { const Value& input = inputs[inpIdx]; @@ -205,7 +205,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) fValid = false; break; } - Array vinput = input.get_array(); + UniValue vinput = input.get_array(); if (vinput.size() != 3) { fValid = false; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index e0cccef696..9d72c45bae 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -70,7 +70,7 @@ std::string DecodeDumpString(const std::string &str) { return ret.str(); } -Value importprivkey(const Array& params, bool fHelp) +UniValue importprivkey(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -144,7 +144,7 @@ Value importprivkey(const Array& params, bool fHelp) return NullUniValue; } -Value importaddress(const Array& params, bool fHelp) +UniValue importaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -217,7 +217,7 @@ Value importaddress(const Array& params, bool fHelp) return NullUniValue; } -Value importwallet(const Array& params, bool fHelp) +UniValue importwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -321,7 +321,7 @@ Value importwallet(const Array& params, bool fHelp) return NullUniValue; } -Value dumpprivkey(const Array& params, bool fHelp) +UniValue dumpprivkey(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -359,7 +359,7 @@ Value dumpprivkey(const Array& params, bool fHelp) } -Value dumpwallet(const Array& params, bool fHelp) +UniValue dumpwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 0cfd13a6b2..d5d97604f4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -764,7 +764,7 @@ Value getbalance(const Array& params, bool fHelp) return ValueFromAmount(nBalance); } -Value getunconfirmedbalance(const Array ¶ms, bool fHelp) +Value getunconfirmedbalance(const UniValue ¶ms, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -957,7 +957,7 @@ Value sendmany(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); string strAccount = AccountFromValue(params[0]); - Object sendTo = params[1].get_obj(); + UniValue sendTo = params[1].get_obj(); int nMinDepth = 1; if (params.size() > 2) nMinDepth = params[2].get_int(); @@ -1279,7 +1279,7 @@ Value listreceivedbyaccount(const Array& params, bool fHelp) return ListReceived(params, true); } -static void MaybePushAddress(Object & entry, const CTxDestination &dest) +static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) { CBitcoinAddress addr; if (addr.Set(dest)) @@ -2071,7 +2071,7 @@ Value lockunspent(const Array& params, bool fHelp) return true; } - Array outputs = params[1].get_array(); + UniValue outputs = params[1].get_array(); for (unsigned int idx = 0; idx < outputs.size(); idx++) { const UniValue& output = outputs[idx]; if (!output.isObject()) @@ -2295,7 +2295,7 @@ Value listunspent(const Array& params, bool fHelp) set setAddress; if (params.size() > 2) { - Array inputs = params[2].get_array(); + UniValue inputs = params[2].get_array(); for (unsigned int idx = 0; idx < inputs.size(); idx++) { const Value& input = inputs[idx]; CBitcoinAddress address(input.get_str()); -- cgit v1.2.3 From 9a8897f4ac992741e153d88b54bd2cde877c713d Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 18 May 2015 14:02:18 +0200 Subject: Remove JSON Spirit wrapper, remove JSON Spirit leftovers - implement find_value() function for UniValue - replace all Array/Value/Object types with UniValues, remove JSON Spirit to UniValue wrapper - remove JSON Spirit sources --- src/Makefile.am | 12 - src/bitcoin-cli.cpp | 15 +- src/json/LICENSE.txt | 24 -- src/json/json_spirit.h | 18 - src/json/json_spirit_error_position.h | 54 --- src/json/json_spirit_reader.cpp | 137 -------- src/json/json_spirit_reader.h | 62 ---- src/json/json_spirit_reader_template.h | 612 --------------------------------- src/json/json_spirit_stream_reader.h | 70 ---- src/json/json_spirit_utils.h | 61 ---- src/json/json_spirit_value.cpp | 8 - src/json/json_spirit_value.h | 534 ---------------------------- src/json/json_spirit_writer.cpp | 95 ----- src/json/json_spirit_writer.h | 50 --- src/json/json_spirit_writer_template.h | 249 -------------- src/qt/rpcconsole.cpp | 4 - src/rest.cpp | 7 +- src/rpcblockchain.cpp | 35 +- src/rpcclient.cpp | 4 +- src/rpcmining.cpp | 31 +- src/rpcmisc.cpp | 22 +- src/rpcnet.cpp | 17 +- src/rpcprotocol.cpp | 10 +- src/rpcprotocol.h | 2 +- src/rpcrawtransaction.cpp | 36 +- src/rpcserver.cpp | 47 ++- src/rpcserver.h | 3 +- src/test/base58_tests.cpp | 4 +- src/test/rpc_tests.cpp | 17 +- src/test/rpc_wallet_tests.cpp | 11 +- src/test/script_tests.cpp | 14 +- src/test/sighash_tests.cpp | 4 +- src/test/transaction_tests.cpp | 23 +- src/univalue/univalue.cpp | 12 + src/univalue/univalue.h | 4 + src/wallet/rpcdump.cpp | 13 +- src/wallet/rpcwallet.cpp | 93 +++-- 37 files changed, 212 insertions(+), 2202 deletions(-) delete mode 100644 src/json/LICENSE.txt delete mode 100644 src/json/json_spirit.h delete mode 100644 src/json/json_spirit_error_position.h delete mode 100644 src/json/json_spirit_reader.cpp delete mode 100644 src/json/json_spirit_reader.h delete mode 100644 src/json/json_spirit_reader_template.h delete mode 100644 src/json/json_spirit_stream_reader.h delete mode 100644 src/json/json_spirit_utils.h delete mode 100644 src/json/json_spirit_value.cpp delete mode 100644 src/json/json_spirit_value.h delete mode 100644 src/json/json_spirit_writer.cpp delete mode 100644 src/json/json_spirit_writer.h delete mode 100644 src/json/json_spirit_writer_template.h diff --git a/src/Makefile.am b/src/Makefile.am index 63332f9acd..59618c4940 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -154,17 +154,6 @@ BITCOIN_CORE_H = \ wallet/wallet_ismine.h \ wallet/walletdb.h -JSON_H = \ - json/json_spirit.h \ - json/json_spirit_error_position.h \ - json/json_spirit_reader.h \ - json/json_spirit_reader_template.h \ - json/json_spirit_stream_reader.h \ - json/json_spirit_utils.h \ - json/json_spirit_value.h \ - json/json_spirit_writer.h \ - json/json_spirit_writer_template.h - obj/build.h: FORCE @$(MKDIR_P) $(builddir)/obj @$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \ @@ -200,7 +189,6 @@ libbitcoin_server_a_SOURCES = \ txdb.cpp \ txmempool.cpp \ validationinterface.cpp \ - $(JSON_H) \ $(BITCOIN_CORE_H) # wallet: shared between bitcoind and bitcoin-qt, but only linked diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 0cafd2b0b4..d451720141 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -12,8 +12,9 @@ #include +#include "univalue/univalue.h" + using namespace std; -using namespace json_spirit; std::string HelpMessageCli() { @@ -94,7 +95,7 @@ static bool AppInitRPC(int argc, char* argv[]) return true; } -UniValue CallRPC(const string& strMethod, const Array& params) +UniValue CallRPC(const string& strMethod, const UniValue& params) { if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "") throw runtime_error(strprintf( @@ -145,7 +146,7 @@ UniValue CallRPC(const string& strMethod, const Array& params) UniValue valReply(UniValue::VSTR); if (!valReply.read(strReply)) throw runtime_error("couldn't parse reply from server"); - const Object& reply = valReply.get_obj(); + const UniValue& reply = valReply.get_obj(); if (reply.empty()) throw runtime_error("expected reply to have result, error and id properties"); @@ -179,13 +180,15 @@ int CommandLineRPC(int argc, char *argv[]) const UniValue reply = CallRPC(strMethod, params); // Parse reply - const Value& result = find_value(reply, "result"); - const Value& error = find_value(reply, "error"); + const UniValue& result = find_value(reply, "result"); + const UniValue& error = find_value(reply, "error"); if (!error.isNull()) { // Error - strPrint = "error: " + error.write(); int code = error["code"].get_int(); + if (fWait && code == RPC_IN_WARMUP) + throw CConnectionFailed("server in warmup"); + strPrint = "error: " + error.write(); nRet = abs(code); } else { // Result diff --git a/src/json/LICENSE.txt b/src/json/LICENSE.txt deleted file mode 100644 index 797d5363b3..0000000000 --- a/src/json/LICENSE.txt +++ /dev/null @@ -1,24 +0,0 @@ -The MIT License - -Copyright (c) 2007 - 2009 John W. Wilkinson - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/json/json_spirit.h b/src/json/json_spirit.h deleted file mode 100644 index ac1879d5b3..0000000000 --- a/src/json/json_spirit.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef JSON_SPIRIT -#define JSON_SPIRIT - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include "json_spirit_reader.h" -#include "json_spirit_writer.h" -#include "json_spirit_utils.h" - -#endif diff --git a/src/json/json_spirit_error_position.h b/src/json/json_spirit_error_position.h deleted file mode 100644 index 17208507df..0000000000 --- a/src/json/json_spirit_error_position.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef JSON_SPIRIT_ERROR_POSITION -#define JSON_SPIRIT_ERROR_POSITION - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include - -namespace json_spirit -{ - // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error. - // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read" - // functions that return a bool. - // - struct Error_position - { - Error_position(); - Error_position( unsigned int line, unsigned int column, const std::string& reason ); - bool operator==( const Error_position& lhs ) const; - unsigned int line_; - unsigned int column_; - std::string reason_; - }; - - inline Error_position::Error_position() - : line_( 0 ) - , column_( 0 ) - { - } - - inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason ) - : line_( line ) - , column_( column ) - , reason_( reason ) - { - } - - inline bool Error_position::operator==( const Error_position& lhs ) const - { - if( this == &lhs ) return true; - - return ( reason_ == lhs.reason_ ) && - ( line_ == lhs.line_ ) && - ( column_ == lhs.column_ ); -} -} - -#endif diff --git a/src/json/json_spirit_reader.cpp b/src/json/json_spirit_reader.cpp deleted file mode 100644 index aa4f637226..0000000000 --- a/src/json/json_spirit_reader.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_reader.h" -#include "json_spirit_reader_template.h" - -using namespace json_spirit; - -bool json_spirit::read( const std::string& s, Value& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::string& s, Value& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::istream& is, Value& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::istream& is, Value& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#ifndef BOOST_NO_STD_WSTRING - -bool json_spirit::read( const std::wstring& s, wValue& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::wstring& s, wValue& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::wistream& is, wValue& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::wistream& is, wValue& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#endif - -bool json_spirit::read( const std::string& s, mValue& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::string& s, mValue& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::istream& is, mValue& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::istream& is, mValue& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#ifndef BOOST_NO_STD_WSTRING - -bool json_spirit::read( const std::wstring& s, wmValue& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::wstring& s, wmValue& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::wistream& is, wmValue& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::wistream& is, wmValue& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#endif diff --git a/src/json/json_spirit_reader.h b/src/json/json_spirit_reader.h deleted file mode 100644 index 96494a9789..0000000000 --- a/src/json/json_spirit_reader.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef JSON_SPIRIT_READER -#define JSON_SPIRIT_READER - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include "json_spirit_error_position.h" -#include - -namespace json_spirit -{ - // functions to reads a JSON values - - bool read( const std::string& s, Value& value ); - bool read( std::istream& is, Value& value ); - bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); - - void read_or_throw( const std::string& s, Value& value ); - void read_or_throw( std::istream& is, Value& value ); - void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); - -#ifndef BOOST_NO_STD_WSTRING - - bool read( const std::wstring& s, wValue& value ); - bool read( std::wistream& is, wValue& value ); - bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); - - void read_or_throw( const std::wstring& s, wValue& value ); - void read_or_throw( std::wistream& is, wValue& value ); - void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); - -#endif - - bool read( const std::string& s, mValue& value ); - bool read( std::istream& is, mValue& value ); - bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); - - void read_or_throw( const std::string& s, mValue& value ); - void read_or_throw( std::istream& is, mValue& value ); - void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); - -#ifndef BOOST_NO_STD_WSTRING - - bool read( const std::wstring& s, wmValue& value ); - bool read( std::wistream& is, wmValue& value ); - bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); - - void read_or_throw( const std::wstring& s, wmValue& value ); - void read_or_throw( std::wistream& is, wmValue& value ); - void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); - -#endif -} - -#endif diff --git a/src/json/json_spirit_reader_template.h b/src/json/json_spirit_reader_template.h deleted file mode 100644 index 47e3c1ca84..0000000000 --- a/src/json/json_spirit_reader_template.h +++ /dev/null @@ -1,612 +0,0 @@ -#ifndef JSON_SPIRIT_READER_TEMPLATE -#define JSON_SPIRIT_READER_TEMPLATE - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_value.h" -#include "json_spirit_error_position.h" - -//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread - -#include -#include -#include - -#if BOOST_VERSION >= 103800 - #include - #include - #include - #include - #include - #define spirit_namespace boost::spirit::classic -#else - #include - #include - #include - #include - #include - #define spirit_namespace boost::spirit -#endif - -namespace json_spirit -{ - const spirit_namespace::int_parser < int64_t > int64_p = spirit_namespace::int_parser < int64_t >(); - const spirit_namespace::uint_parser< uint64_t > uint64_p = spirit_namespace::uint_parser< uint64_t >(); - - template< class Iter_type > - bool is_eq( Iter_type first, Iter_type last, const char* c_str ) - { - for( Iter_type i = first; i != last; ++i, ++c_str ) - { - if( *c_str == 0 ) return false; - - if( *i != *c_str ) return false; - } - - return true; - } - - template< class Char_type > - Char_type hex_to_num( const Char_type c ) - { - if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0'; - if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10; - if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10; - return 0; - } - - template< class Char_type, class Iter_type > - Char_type hex_str_to_char( Iter_type& begin ) - { - const Char_type c1( *( ++begin ) ); - const Char_type c2( *( ++begin ) ); - - return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 ); - } - - template< class Char_type, class Iter_type > - Char_type unicode_str_to_char( Iter_type& begin ) - { - const Char_type c1( *( ++begin ) ); - const Char_type c2( *( ++begin ) ); - const Char_type c3( *( ++begin ) ); - const Char_type c4( *( ++begin ) ); - - return ( hex_to_num( c1 ) << 12 ) + - ( hex_to_num( c2 ) << 8 ) + - ( hex_to_num( c3 ) << 4 ) + - hex_to_num( c4 ); - } - - template< class String_type > - void append_esc_char_and_incr_iter( String_type& s, - typename String_type::const_iterator& begin, - typename String_type::const_iterator end ) - { - typedef typename String_type::value_type Char_type; - - const Char_type c2( *begin ); - - switch( c2 ) - { - case 't': s += '\t'; break; - case 'b': s += '\b'; break; - case 'f': s += '\f'; break; - case 'n': s += '\n'; break; - case 'r': s += '\r'; break; - case '\\': s += '\\'; break; - case '/': s += '/'; break; - case '"': s += '"'; break; - case 'x': - { - if( end - begin >= 3 ) // expecting "xHH..." - { - s += hex_str_to_char< Char_type >( begin ); - } - break; - } - case 'u': - { - if( end - begin >= 5 ) // expecting "uHHHH..." - { - s += unicode_str_to_char< Char_type >( begin ); - } - break; - } - } - } - - template< class String_type > - String_type substitute_esc_chars( typename String_type::const_iterator begin, - typename String_type::const_iterator end ) - { - typedef typename String_type::const_iterator Iter_type; - - if( end - begin < 2 ) return String_type( begin, end ); - - String_type result; - - result.reserve( end - begin ); - - const Iter_type end_minus_1( end - 1 ); - - Iter_type substr_start = begin; - Iter_type i = begin; - - for( ; i < end_minus_1; ++i ) - { - if( *i == '\\' ) - { - result.append( substr_start, i ); - - ++i; // skip the '\' - - append_esc_char_and_incr_iter( result, i, end ); - - substr_start = i + 1; - } - } - - result.append( substr_start, end ); - - return result; - } - - template< class String_type > - String_type get_str_( typename String_type::const_iterator begin, - typename String_type::const_iterator end ) - { - assert( end - begin >= 2 ); - - typedef typename String_type::const_iterator Iter_type; - - Iter_type str_without_quotes( ++begin ); - Iter_type end_without_quotes( --end ); - - return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes ); - } - - inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end ) - { - return get_str_< std::string >( begin, end ); - } - - inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end ) - { - return get_str_< std::wstring >( begin, end ); - } - - template< class String_type, class Iter_type > - String_type get_str( Iter_type begin, Iter_type end ) - { - const String_type tmp( begin, end ); // convert multipass iterators to string iterators - - return get_str( tmp.begin(), tmp.end() ); - } - - // this class's methods get called by the spirit parse resulting - // in the creation of a JSON object or array - // - // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator - // - template< class Value_type, class Iter_type > - class Semantic_actions - { - public: - - typedef typename Value_type::Config_type Config_type; - typedef typename Config_type::String_type String_type; - typedef typename Config_type::Object_type Object_type; - typedef typename Config_type::Array_type Array_type; - typedef typename String_type::value_type Char_type; - - Semantic_actions( Value_type& value ) - : value_( value ) - , current_p_( 0 ) - { - } - - void begin_obj( Char_type c ) - { - assert( c == '{' ); - - begin_compound< Object_type >(); - } - - void end_obj( Char_type c ) - { - assert( c == '}' ); - - end_compound(); - } - - void begin_array( Char_type c ) - { - assert( c == '[' ); - - begin_compound< Array_type >(); - } - - void end_array( Char_type c ) - { - assert( c == ']' ); - - end_compound(); - } - - void new_name( Iter_type begin, Iter_type end ) - { - assert( current_p_->type() == obj_type ); - - name_ = get_str< String_type >( begin, end ); - } - - void new_str( Iter_type begin, Iter_type end ) - { - add_to_current( get_str< String_type >( begin, end ) ); - } - - void new_true( Iter_type begin, Iter_type end ) - { - assert( is_eq( begin, end, "true" ) ); - - add_to_current( true ); - } - - void new_false( Iter_type begin, Iter_type end ) - { - assert( is_eq( begin, end, "false" ) ); - - add_to_current( false ); - } - - void new_null( Iter_type begin, Iter_type end ) - { - assert( is_eq( begin, end, "null" ) ); - - add_to_current( Value_type() ); - } - - void new_int( int64_t i ) - { - add_to_current( i ); - } - - void new_uint64( uint64_t ui ) - { - add_to_current( ui ); - } - - void new_real( double d ) - { - add_to_current( d ); - } - - private: - - Semantic_actions& operator=( const Semantic_actions& ); - // to prevent "assignment operator could not be generated" warning - - Value_type* add_first( const Value_type& value ) - { - assert( current_p_ == 0 ); - - value_ = value; - current_p_ = &value_; - return current_p_; - } - - template< class Array_or_obj > - void begin_compound() - { - if( current_p_ == 0 ) - { - add_first( Array_or_obj() ); - } - else - { - stack_.push_back( current_p_ ); - - Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place - - current_p_ = add_to_current( new_array_or_obj ); - } - } - - void end_compound() - { - if( current_p_ != &value_ ) - { - current_p_ = stack_.back(); - - stack_.pop_back(); - } - } - - Value_type* add_to_current( const Value_type& value ) - { - if( current_p_ == 0 ) - { - return add_first( value ); - } - else if( current_p_->type() == array_type ) - { - current_p_->get_array().push_back( value ); - - return ¤t_p_->get_array().back(); - } - - assert( current_p_->type() == obj_type ); - - return &Config_type::add( current_p_->get_obj(), name_, value ); - } - - Value_type& value_; // this is the object or array that is being created - Value_type* current_p_; // the child object or array that is currently being constructed - - std::vector< Value_type* > stack_; // previous child objects and arrays - - String_type name_; // of current name/value pair - }; - - template< typename Iter_type > - void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason ) - { - throw Error_position( i.get_position().line, i.get_position().column, reason ); - } - - template< typename Iter_type > - void throw_error( Iter_type i, const std::string& reason ) - { - throw reason; - } - - // the spirit grammer - // - template< class Value_type, class Iter_type > - class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > > - { - public: - - typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t; - - Json_grammer( Semantic_actions_t& semantic_actions ) - : actions_( semantic_actions ) - { - } - - static void throw_not_value( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not a value" ); - } - - static void throw_not_array( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not an array" ); - } - - static void throw_not_object( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not an object" ); - } - - static void throw_not_pair( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not a pair" ); - } - - static void throw_not_colon( Iter_type begin, Iter_type end ) - { - throw_error( begin, "no colon in pair" ); - } - - static void throw_not_string( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not a string" ); - } - - template< typename ScannerT > - class definition - { - public: - - definition( const Json_grammer& self ) - { - using namespace spirit_namespace; - - typedef typename Value_type::String_type::value_type Char_type; - - // first we convert the semantic action class methods to functors with the - // parameter signature expected by spirit - - typedef boost::function< void( Char_type ) > Char_action; - typedef boost::function< void( Iter_type, Iter_type ) > Str_action; - typedef boost::function< void( double ) > Real_action; - typedef boost::function< void( int64_t ) > Int_action; - typedef boost::function< void( uint64_t ) > Uint64_action; - - Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); - Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); - Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) ); - Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) ); - Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) ); - Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) ); - Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) ); - Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) ); - Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) ); - Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) ); - Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) ); - Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) ); - - // actual grammer - - json_ - = value_ | eps_p[ &throw_not_value ] - ; - - value_ - = string_[ new_str ] - | number_ - | object_ - | array_ - | str_p( "true" ) [ new_true ] - | str_p( "false" )[ new_false ] - | str_p( "null" ) [ new_null ] - ; - - object_ - = ch_p('{')[ begin_obj ] - >> !members_ - >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] ) - ; - - members_ - = pair_ >> *( ',' >> pair_ ) - ; - - pair_ - = string_[ new_name ] - >> ( ':' | eps_p[ &throw_not_colon ] ) - >> ( value_ | eps_p[ &throw_not_value ] ) - ; - - array_ - = ch_p('[')[ begin_array ] - >> !elements_ - >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] ) - ; - - elements_ - = value_ >> *( ',' >> value_ ) - ; - - string_ - = lexeme_d // this causes white space inside a string to be retained - [ - confix_p - ( - '"', - *lex_escape_ch_p, - '"' - ) - ] - ; - - number_ - = strict_real_p[ new_real ] - | int64_p [ new_int ] - | uint64_p [ new_uint64 ] - ; - } - - spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_; - - const spirit_namespace::rule< ScannerT >& start() const { return json_; } - }; - - private: - - Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning - - Semantic_actions_t& actions_; - }; - - template< class Iter_type, class Value_type > - Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) - { - Semantic_actions< Value_type, Iter_type > semantic_actions( value ); - - const spirit_namespace::parse_info< Iter_type > info = - spirit_namespace::parse( begin, end, - Json_grammer< Value_type, Iter_type >( semantic_actions ) >> spirit_namespace::end_p, - spirit_namespace::space_p ); - - if( !info.hit ) - { - throw_error( info.stop, "error" ); - } - - return info.stop; - } - - template< class Iter_type, class Value_type > - void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) - { - typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t; - - const Posn_iter_t posn_begin( begin, end ); - const Posn_iter_t posn_end( end, end ); - - read_range_or_throw( posn_begin, posn_end, value ); - } - - template< class Iter_type, class Value_type > - bool read_range( Iter_type& begin, Iter_type end, Value_type& value ) - { - try - { - begin = read_range_or_throw( begin, end, value ); - - return true; - } - catch( ... ) - { - return false; - } - } - - template< class String_type, class Value_type > - void read_string_or_throw( const String_type& s, Value_type& value ) - { - add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value ); - } - - template< class String_type, class Value_type > - bool read_string( const String_type& s, Value_type& value ) - { - typename String_type::const_iterator begin = s.begin(); - - bool success = read_range( begin, s.end(), value ); - return success && begin == s.end(); - } - - template< class Istream_type > - struct Multi_pass_iters - { - typedef typename Istream_type::char_type Char_type; - typedef std::istream_iterator< Char_type, Char_type > istream_iter; - typedef spirit_namespace::multi_pass< istream_iter > Mp_iter; - - Multi_pass_iters( Istream_type& is ) - { - is.unsetf( std::ios::skipws ); - - begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) ); - end_ = spirit_namespace::make_multi_pass( istream_iter() ); - } - - Mp_iter begin_; - Mp_iter end_; - }; - - template< class Istream_type, class Value_type > - bool read_stream( Istream_type& is, Value_type& value ) - { - Multi_pass_iters< Istream_type > mp_iters( is ); - - return read_range( mp_iters.begin_, mp_iters.end_, value ); - } - - template< class Istream_type, class Value_type > - void read_stream_or_throw( Istream_type& is, Value_type& value ) - { - const Multi_pass_iters< Istream_type > mp_iters( is ); - - add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value ); - } -} - -#endif diff --git a/src/json/json_spirit_stream_reader.h b/src/json/json_spirit_stream_reader.h deleted file mode 100644 index 7e59c9adc2..0000000000 --- a/src/json/json_spirit_stream_reader.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef JSON_SPIRIT_READ_STREAM -#define JSON_SPIRIT_READ_STREAM - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_reader_template.h" - -namespace json_spirit -{ - // these classes allows you to read multiple top level contiguous values from a stream, - // the normal stream read functions have a bug that prevent multiple top level values - // from being read unless they are separated by spaces - - template< class Istream_type, class Value_type > - class Stream_reader - { - public: - - Stream_reader( Istream_type& is ) - : iters_( is ) - { - } - - bool read_next( Value_type& value ) - { - return read_range( iters_.begin_, iters_.end_, value ); - } - - private: - - typedef Multi_pass_iters< Istream_type > Mp_iters; - - Mp_iters iters_; - }; - - template< class Istream_type, class Value_type > - class Stream_reader_thrower - { - public: - - Stream_reader_thrower( Istream_type& is ) - : iters_( is ) - , posn_begin_( iters_.begin_, iters_.end_ ) - , posn_end_( iters_.end_, iters_.end_ ) - { - } - - void read_next( Value_type& value ) - { - posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value ); - } - - private: - - typedef Multi_pass_iters< Istream_type > Mp_iters; - typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t; - - Mp_iters iters_; - Posn_iter_t posn_begin_, posn_end_; - }; -} - -#endif diff --git a/src/json/json_spirit_utils.h b/src/json/json_spirit_utils.h deleted file mode 100644 index 553e3b96a4..0000000000 --- a/src/json/json_spirit_utils.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef JSON_SPIRIT_UTILS -#define JSON_SPIRIT_UTILS - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include - -namespace json_spirit -{ - template< class Obj_t, class Map_t > - void obj_to_map( const Obj_t& obj, Map_t& mp_obj ) - { - mp_obj.clear(); - - for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) - { - mp_obj[ i->name_ ] = i->value_; - } - } - - template< class Obj_t, class Map_t > - void map_to_obj( const Map_t& mp_obj, Obj_t& obj ) - { - obj.clear(); - - for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) - { - obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); - } - } - - typedef std::map< std::string, Value > Mapped_obj; - -#ifndef BOOST_NO_STD_WSTRING - typedef std::map< std::wstring, wValue > wMapped_obj; -#endif - - template< class Object_type, class String_type > - const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name ) - { - for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i ) - { - if( i->name_ == name ) - { - return i->value_; - } - } - - return Object_type::value_type::Value_type::null; - } -} - -#endif diff --git a/src/json/json_spirit_value.cpp b/src/json/json_spirit_value.cpp deleted file mode 100644 index 44d2f06a01..0000000000 --- a/src/json/json_spirit_value.cpp +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright (c) 2007 John W Wilkinson - - This source code can be used for any purpose as long as - this comment is retained. */ - -// json spirit version 2.00 - -#include "json_spirit_value.h" diff --git a/src/json/json_spirit_value.h b/src/json/json_spirit_value.h deleted file mode 100644 index 13cc89210c..0000000000 --- a/src/json/json_spirit_value.h +++ /dev/null @@ -1,534 +0,0 @@ -#ifndef JSON_SPIRIT_VALUE -#define JSON_SPIRIT_VALUE - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace json_spirit -{ - enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; - static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"}; - - template< class Config > // Config determines whether the value uses std::string or std::wstring and - // whether JSON Objects are represented as vectors or maps - class Value_impl - { - public: - - typedef Config Config_type; - typedef typename Config::String_type String_type; - typedef typename Config::Object_type Object; - typedef typename Config::Array_type Array; - typedef typename String_type::const_pointer Const_str_ptr; // eg const char* - - Value_impl(); // creates null value - Value_impl( Const_str_ptr value ); - Value_impl( const String_type& value ); - Value_impl( const Object& value ); - Value_impl( const Array& value ); - Value_impl( bool value ); - Value_impl( int value ); - Value_impl( int64_t value ); - Value_impl( uint64_t value ); - Value_impl( double value ); - - Value_impl( const Value_impl& other ); - - bool operator==( const Value_impl& lhs ) const; - - Value_impl& operator=( const Value_impl& lhs ); - - Value_type type() const; - - bool is_uint64() const; - bool is_null() const; - - const String_type& get_str() const; - const Object& get_obj() const; - const Array& get_array() const; - bool get_bool() const; - int get_int() const; - int64_t get_int64() const; - uint64_t get_uint64() const; - double get_real() const; - - Object& get_obj(); - Array& get_array(); - - template< typename T > T get_value() const; // example usage: int i = value.get_value< int >(); - // or double d = value.get_value< double >(); - - static const Value_impl null; - - private: - - void check_type( const Value_type vtype ) const; - - typedef boost::variant< String_type, - boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, - bool, int64_t, double > Variant; - - Value_type type_; - Variant v_; - bool is_uint64_; - }; - - // vector objects - - template< class Config > - struct Pair_impl - { - typedef typename Config::String_type String_type; - typedef typename Config::Value_type Value_type; - - Pair_impl( const String_type& name, const Value_type& value ); - - bool operator==( const Pair_impl& lhs ) const; - - String_type name_; - Value_type value_; - }; - - template< class String > - struct Config_vector - { - typedef String String_type; - typedef Value_impl< Config_vector > Value_type; - typedef Pair_impl < Config_vector > Pair_type; - typedef std::vector< Value_type > Array_type; - typedef std::vector< Pair_type > Object_type; - - static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) - { - obj.push_back( Pair_type( name , value ) ); - - return obj.back().value_; - } - - static String_type get_name( const Pair_type& pair ) - { - return pair.name_; - } - - static Value_type get_value( const Pair_type& pair ) - { - return pair.value_; - } - }; - - // typedefs for ASCII - - typedef Config_vector< std::string > Config; - - typedef Config::Value_type Value; - typedef Config::Pair_type Pair; - typedef Config::Object_type Object; - typedef Config::Array_type Array; - - // typedefs for Unicode - -#ifndef BOOST_NO_STD_WSTRING - - typedef Config_vector< std::wstring > wConfig; - - typedef wConfig::Value_type wValue; - typedef wConfig::Pair_type wPair; - typedef wConfig::Object_type wObject; - typedef wConfig::Array_type wArray; -#endif - - // map objects - - template< class String > - struct Config_map - { - typedef String String_type; - typedef Value_impl< Config_map > Value_type; - typedef std::vector< Value_type > Array_type; - typedef std::map< String_type, Value_type > Object_type; - typedef typename Object_type::value_type Pair_type; - - static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) - { - return obj[ name ] = value; - } - - static String_type get_name( const Pair_type& pair ) - { - return pair.first; - } - - static Value_type get_value( const Pair_type& pair ) - { - return pair.second; - } - }; - - // typedefs for ASCII - - typedef Config_map< std::string > mConfig; - - typedef mConfig::Value_type mValue; - typedef mConfig::Object_type mObject; - typedef mConfig::Array_type mArray; - - // typedefs for Unicode - -#ifndef BOOST_NO_STD_WSTRING - - typedef Config_map< std::wstring > wmConfig; - - typedef wmConfig::Value_type wmValue; - typedef wmConfig::Object_type wmObject; - typedef wmConfig::Array_type wmArray; - -#endif - - /////////////////////////////////////////////////////////////////////////////////////////////// - // - // implementation - - template< class Config > - const Value_impl< Config > Value_impl< Config >::null; - - template< class Config > - Value_impl< Config >::Value_impl() - : type_( null_type ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Const_str_ptr value ) - : type_( str_type ) - , v_( String_type( value ) ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const String_type& value ) - : type_( str_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Object& value ) - : type_( obj_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Array& value ) - : type_( array_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( bool value ) - : type_( bool_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( int value ) - : type_( int_type ) - , v_( static_cast< int64_t >( value ) ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( int64_t value ) - : type_( int_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( uint64_t value ) - : type_( int_type ) - , v_( static_cast< int64_t >( value ) ) - , is_uint64_( true ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( double value ) - : type_( real_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) - : type_( other.type() ) - , v_( other.v_ ) - , is_uint64_( other.is_uint64_ ) - { - } - - template< class Config > - Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs ) - { - Value_impl tmp( lhs ); - - std::swap( type_, tmp.type_ ); - std::swap( v_, tmp.v_ ); - std::swap( is_uint64_, tmp.is_uint64_ ); - - return *this; - } - - template< class Config > - bool Value_impl< Config >::operator==( const Value_impl& lhs ) const - { - if( this == &lhs ) return true; - - if( type() != lhs.type() ) return false; - - return v_ == lhs.v_; - } - - template< class Config > - Value_type Value_impl< Config >::type() const - { - return type_; - } - - template< class Config > - bool Value_impl< Config >::is_uint64() const - { - return is_uint64_; - } - - template< class Config > - bool Value_impl< Config >::is_null() const - { - return type() == null_type; - } - - template< class Config > - void Value_impl< Config >::check_type( const Value_type vtype ) const - { - if( type() != vtype ) - { - std::ostringstream os; - - ///// Bitcoin: Tell the types by name instead of by number - os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype]; - - throw std::runtime_error( os.str() ); - } - } - - template< class Config > - const typename Config::String_type& Value_impl< Config >::get_str() const - { - check_type( str_type ); - - return *boost::get< String_type >( &v_ ); - } - - template< class Config > - const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const - { - check_type( obj_type ); - - return *boost::get< Object >( &v_ ); - } - - template< class Config > - const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const - { - check_type( array_type ); - - return *boost::get< Array >( &v_ ); - } - - template< class Config > - bool Value_impl< Config >::get_bool() const - { - check_type( bool_type ); - - return boost::get< bool >( v_ ); - } - - template< class Config > - int Value_impl< Config >::get_int() const - { - check_type( int_type ); - - return static_cast< int >( get_int64() ); - } - - template< class Config > - int64_t Value_impl< Config >::get_int64() const - { - check_type( int_type ); - - return boost::get< int64_t >( v_ ); - } - - template< class Config > - uint64_t Value_impl< Config >::get_uint64() const - { - check_type( int_type ); - - return static_cast< uint64_t >( get_int64() ); - } - - template< class Config > - double Value_impl< Config >::get_real() const - { - if( type() == int_type ) - { - return is_uint64() ? static_cast< double >( get_uint64() ) - : static_cast< double >( get_int64() ); - } - - check_type( real_type ); - - return boost::get< double >( v_ ); - } - - template< class Config > - typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() - { - check_type( obj_type ); - - return *boost::get< Object >( &v_ ); - } - - template< class Config > - typename Value_impl< Config >::Array& Value_impl< Config >::get_array() - { - check_type( array_type ); - - return *boost::get< Array >( &v_ ); - } - - template< class Config > - Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value ) - : name_( name ) - , value_( value ) - { - } - - template< class Config > - bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const - { - if( this == &lhs ) return true; - - return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ ); - } - - // converts a C string, ie. 8 bit char array, to a string object - // - template < class String_type > - String_type to_str( const char* c_str ) - { - String_type result; - - for( const char* p = c_str; *p != 0; ++p ) - { - result += *p; - } - - return result; - } - - // - - namespace internal_ - { - template< typename T > - struct Type_to_type - { - }; - - template< class Value > - int get_value( const Value& value, Type_to_type< int > ) - { - return value.get_int(); - } - - template< class Value > - int64_t get_value( const Value& value, Type_to_type< int64_t > ) - { - return value.get_int64(); - } - - template< class Value > - uint64_t get_value( const Value& value, Type_to_type< uint64_t > ) - { - return value.get_uint64(); - } - - template< class Value > - double get_value( const Value& value, Type_to_type< double > ) - { - return value.get_real(); - } - - template< class Value > - typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > ) - { - return value.get_str(); - } - - template< class Value > - typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > ) - { - return value.get_array(); - } - - template< class Value > - typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > ) - { - return value.get_obj(); - } - - template< class Value > - bool get_value( const Value& value, Type_to_type< bool > ) - { - return value.get_bool(); - } - } - - template< class Config > - template< typename T > - T Value_impl< Config >::get_value() const - { - return internal_::get_value( *this, internal_::Type_to_type< T >() ); - } -} - -#endif diff --git a/src/json/json_spirit_writer.cpp b/src/json/json_spirit_writer.cpp deleted file mode 100644 index d24a632cf3..0000000000 --- a/src/json/json_spirit_writer.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_writer.h" -#include "json_spirit_writer_template.h" - -void json_spirit::write( const Value& value, std::ostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const Value& value, std::ostream& os ) -{ - write_stream( value, os, true ); -} - -std::string json_spirit::write( const Value& value ) -{ - return write_string( value, false ); -} - -std::string json_spirit::write_formatted( const Value& value ) -{ - return write_string( value, true ); -} - -#ifndef BOOST_NO_STD_WSTRING - -void json_spirit::write( const wValue& value, std::wostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const wValue& value, std::wostream& os ) -{ - write_stream( value, os, true ); -} - -std::wstring json_spirit::write( const wValue& value ) -{ - return write_string( value, false ); -} - -std::wstring json_spirit::write_formatted( const wValue& value ) -{ - return write_string( value, true ); -} - -#endif - -void json_spirit::write( const mValue& value, std::ostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const mValue& value, std::ostream& os ) -{ - write_stream( value, os, true ); -} - -std::string json_spirit::write( const mValue& value ) -{ - return write_string( value, false ); -} - -std::string json_spirit::write_formatted( const mValue& value ) -{ - return write_string( value, true ); -} - -#ifndef BOOST_NO_STD_WSTRING - -void json_spirit::write( const wmValue& value, std::wostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const wmValue& value, std::wostream& os ) -{ - write_stream( value, os, true ); -} - -std::wstring json_spirit::write( const wmValue& value ) -{ - return write_string( value, false ); -} - -std::wstring json_spirit::write_formatted( const wmValue& value ) -{ - return write_string( value, true ); -} - -#endif diff --git a/src/json/json_spirit_writer.h b/src/json/json_spirit_writer.h deleted file mode 100644 index 52e14068e7..0000000000 --- a/src/json/json_spirit_writer.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef JSON_SPIRIT_WRITER -#define JSON_SPIRIT_WRITER - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include - -namespace json_spirit -{ - // functions to convert JSON Values to text, - // the "formatted" versions add whitespace to format the output nicely - - void write ( const Value& value, std::ostream& os ); - void write_formatted( const Value& value, std::ostream& os ); - std::string write ( const Value& value ); - std::string write_formatted( const Value& value ); - -#ifndef BOOST_NO_STD_WSTRING - - void write ( const wValue& value, std::wostream& os ); - void write_formatted( const wValue& value, std::wostream& os ); - std::wstring write ( const wValue& value ); - std::wstring write_formatted( const wValue& value ); - -#endif - - void write ( const mValue& value, std::ostream& os ); - void write_formatted( const mValue& value, std::ostream& os ); - std::string write ( const mValue& value ); - std::string write_formatted( const mValue& value ); - -#ifndef BOOST_NO_STD_WSTRING - - void write ( const wmValue& value, std::wostream& os ); - void write_formatted( const wmValue& value, std::wostream& os ); - std::wstring write ( const wmValue& value ); - std::wstring write_formatted( const wmValue& value ); - -#endif -} - -#endif diff --git a/src/json/json_spirit_writer_template.h b/src/json/json_spirit_writer_template.h deleted file mode 100644 index 6b4978a1ff..0000000000 --- a/src/json/json_spirit_writer_template.h +++ /dev/null @@ -1,249 +0,0 @@ -#ifndef JSON_SPIRIT_WRITER_TEMPLATE -#define JSON_SPIRIT_WRITER_TEMPLATE - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_value.h" - -#include -#include -#include - -namespace json_spirit -{ - inline char to_hex_char( unsigned int c ) - { - assert( c <= 0xF ); - - const char ch = static_cast< char >( c ); - - if( ch < 10 ) return '0' + ch; - - return 'A' - 10 + ch; - } - - template< class String_type > - String_type non_printable_to_string( unsigned int c ) - { - // Silence the warning: typedef ‘Char_type’ locally defined but not used [-Wunused-local-typedefs] - // typedef typename String_type::value_type Char_type; - - String_type result( 6, '\\' ); - - result[1] = 'u'; - - result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4; - result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4; - result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4; - result[ 2 ] = to_hex_char( c & 0x000F ); - - return result; - } - - template< typename Char_type, class String_type > - bool add_esc_char( Char_type c, String_type& s ) - { - switch( c ) - { - case '"': s += to_str< String_type >( "\\\"" ); return true; - case '\\': s += to_str< String_type >( "\\\\" ); return true; - case '\b': s += to_str< String_type >( "\\b" ); return true; - case '\f': s += to_str< String_type >( "\\f" ); return true; - case '\n': s += to_str< String_type >( "\\n" ); return true; - case '\r': s += to_str< String_type >( "\\r" ); return true; - case '\t': s += to_str< String_type >( "\\t" ); return true; - } - - return false; - } - - template< class String_type > - String_type add_esc_chars( const String_type& s ) - { - typedef typename String_type::const_iterator Iter_type; - typedef typename String_type::value_type Char_type; - - String_type result; - - const Iter_type end( s.end() ); - - for( Iter_type i = s.begin(); i != end; ++i ) - { - const Char_type c( *i ); - - if( add_esc_char( c, result ) ) continue; - - const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c ); - - if( iswprint( unsigned_c ) ) - { - result += c; - } - else - { - result += non_printable_to_string< String_type >( unsigned_c ); - } - } - - return result; - } - - // this class generates the JSON text, - // it keeps track of the indentation level etc. - // - template< class Value_type, class Ostream_type > - class Generator - { - typedef typename Value_type::Config_type Config_type; - typedef typename Config_type::String_type String_type; - typedef typename Config_type::Object_type Object_type; - typedef typename Config_type::Array_type Array_type; - typedef typename String_type::value_type Char_type; - typedef typename Object_type::value_type Obj_member_type; - - public: - - Generator( const Value_type& value, Ostream_type& os, bool pretty ) - : os_( os ) - , indentation_level_( 0 ) - , pretty_( pretty ) - { - output( value ); - } - - private: - - void output( const Value_type& value ) - { - switch( value.type() ) - { - case obj_type: output( value.get_obj() ); break; - case array_type: output( value.get_array() ); break; - case str_type: output( value.get_str() ); break; - case bool_type: output( value.get_bool() ); break; - case int_type: output_int( value ); break; - - /// Bitcoin: Added std::fixed and changed precision from 16 to 8 - case real_type: os_ << std::showpoint << std::fixed << std::setprecision(8) - << value.get_real(); break; - - case null_type: os_ << "null"; break; - default: assert( false ); - } - } - - void output( const Object_type& obj ) - { - output_array_or_obj( obj, '{', '}' ); - } - - void output( const Array_type& arr ) - { - output_array_or_obj( arr, '[', ']' ); - } - - void output( const Obj_member_type& member ) - { - output( Config_type::get_name( member ) ); space(); - os_ << ':'; space(); - output( Config_type::get_value( member ) ); - } - - void output_int( const Value_type& value ) - { - if( value.is_uint64() ) - { - os_ << value.get_uint64(); - } - else - { - os_ << value.get_int64(); - } - } - - void output( const String_type& s ) - { - os_ << '"' << add_esc_chars( s ) << '"'; - } - - void output( bool b ) - { - os_ << to_str< String_type >( b ? "true" : "false" ); - } - - template< class T > - void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char ) - { - os_ << start_char; new_line(); - - ++indentation_level_; - - for( typename T::const_iterator i = t.begin(); i != t.end(); ++i ) - { - indent(); output( *i ); - - typename T::const_iterator next = i; - - if( ++next != t.end()) - { - os_ << ','; - } - - new_line(); - } - - --indentation_level_; - - indent(); os_ << end_char; - } - - void indent() - { - if( !pretty_ ) return; - - for( int i = 0; i < indentation_level_; ++i ) - { - os_ << " "; - } - } - - void space() - { - if( pretty_ ) os_ << ' '; - } - - void new_line() - { - if( pretty_ ) os_ << '\n'; - } - - Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning - - Ostream_type& os_; - int indentation_level_; - bool pretty_; - }; - - template< class Value_type, class Ostream_type > - void write_stream( const Value_type& value, Ostream_type& os, bool pretty ) - { - Generator< Value_type, Ostream_type >( value, os, pretty ); - } - - template< class Value_type > - typename Value_type::String_type write_string( const Value_type& value, bool pretty ) - { - typedef typename Value_type::String_type::value_type Char_type; - - std::basic_ostringstream< Char_type > os; - - write_stream( value, os, pretty ); - - return os.str(); - } -} - -#endif diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 29b1e8f262..d7be531b2d 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -181,11 +181,7 @@ void RPCExecutor::request(const QString &command) emit reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); } -<<<<<<< HEAD - catch (const json_spirit::Object& objError) -======= catch (UniValue& objError) ->>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { try // Nice formatting for standard-format error { diff --git a/src/rest.cpp b/src/rest.cpp index 3142b25036..1fce7dfc9c 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -16,8 +16,9 @@ #include #include +#include "univalue/univalue.h" + using namespace std; -using namespace json_spirit; static const int MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once @@ -61,9 +62,9 @@ public: string message; }; -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); -extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex); +extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); static RestErr RESTERR(enum HTTPStatusCode status, string message) { diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index f20f9f994d..e3f17b4ae7 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -13,13 +13,12 @@ #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); -void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex); +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); double GetDifficulty(const CBlockIndex* blockindex) { @@ -94,7 +93,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx } -UniValue getblockcount(const Array& params, bool fHelp) +UniValue getblockcount(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -111,7 +110,7 @@ UniValue getblockcount(const Array& params, bool fHelp) return chainActive.Height(); } -UniValue getbestblockhash(const Array& params, bool fHelp) +UniValue getbestblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -128,7 +127,7 @@ UniValue getbestblockhash(const Array& params, bool fHelp) return chainActive.Tip()->GetBlockHash().GetHex(); } -UniValue getdifficulty(const Array& params, bool fHelp) +UniValue getdifficulty(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -146,7 +145,7 @@ UniValue getdifficulty(const Array& params, bool fHelp) } -UniValue getrawmempool(const Array& params, bool fHelp) +UniValue getrawmempool(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -231,7 +230,7 @@ UniValue getrawmempool(const Array& params, bool fHelp) } } -UniValue getblockhash(const Array& params, bool fHelp) +UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -256,7 +255,7 @@ UniValue getblockhash(const Array& params, bool fHelp) return pblockindex->GetBlockHash().GetHex(); } -UniValue getblock(const Array& params, bool fHelp) +UniValue getblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -324,7 +323,7 @@ UniValue getblock(const Array& params, bool fHelp) return blockToJSON(block, pblockindex); } -UniValue gettxoutsetinfo(const Array& params, bool fHelp) +UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -364,7 +363,7 @@ UniValue gettxoutsetinfo(const Array& params, bool fHelp) return ret; } -UniValue gettxout(const Array& params, bool fHelp) +UniValue gettxout(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 3) throw runtime_error( @@ -444,7 +443,7 @@ UniValue gettxout(const Array& params, bool fHelp) return ret; } -UniValue verifychain(const Array& params, bool fHelp) +UniValue verifychain(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -472,7 +471,7 @@ UniValue verifychain(const Array& params, bool fHelp) return CVerifyDB().VerifyDB(pcoinsTip, nCheckLevel, nCheckDepth); } -UniValue getblockchaininfo(const Array& params, bool fHelp) +UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -530,7 +529,7 @@ struct CompareBlocksByHeight } }; -UniValue getchaintips(const Array& params, bool fHelp) +UniValue getchaintips(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -620,7 +619,7 @@ UniValue getchaintips(const Array& params, bool fHelp) return res; } -UniValue getmempoolinfo(const Array& params, bool fHelp) +UniValue getmempoolinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -643,7 +642,7 @@ UniValue getmempoolinfo(const Array& params, bool fHelp) return ret; } -UniValue invalidateblock(const Array& params, bool fHelp) +UniValue invalidateblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -681,7 +680,7 @@ UniValue invalidateblock(const Array& params, bool fHelp) return NullUniValue; } -UniValue reconsiderblock(const Array& params, bool fHelp) +UniValue reconsiderblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index ec098a17a7..d175db09ee 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -12,9 +12,9 @@ #include #include // for to_lower() +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; class CRPCConvertParam { @@ -137,7 +137,7 @@ UniValue RPCConvertValues(const std::string &strMethod, const std::vector -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; /** @@ -71,7 +70,7 @@ UniValue GetNetworkHashPS(int lookup, int height) { return (int64_t)(workDiff.getdouble() / timeDiff); } -UniValue getnetworkhashps(const Array& params, bool fHelp) +UniValue getnetworkhashps(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -94,7 +93,7 @@ UniValue getnetworkhashps(const Array& params, bool fHelp) } #ifdef ENABLE_WALLET -UniValue getgenerate(const Array& params, bool fHelp) +UniValue getgenerate(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -113,7 +112,7 @@ UniValue getgenerate(const Array& params, bool fHelp) return GetBoolArg("-gen", false); } -UniValue generate(const Array& params, bool fHelp) +UniValue generate(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( @@ -172,7 +171,7 @@ UniValue generate(const Array& params, bool fHelp) } -UniValue setgenerate(const Array& params, bool fHelp) +UniValue setgenerate(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -220,7 +219,7 @@ UniValue setgenerate(const Array& params, bool fHelp) #endif -UniValue getmininginfo(const Array& params, bool fHelp) +UniValue getmininginfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -266,7 +265,7 @@ UniValue getmininginfo(const Array& params, bool fHelp) // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts -UniValue prioritisetransaction(const Array& params, bool fHelp) +UniValue prioritisetransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( @@ -301,7 +300,7 @@ UniValue prioritisetransaction(const Array& params, bool fHelp) static UniValue BIP22ValidationResult(const CValidationState& state) { if (state.IsValid()) - return Value::null; + return NullUniValue; std::string strRejectReason = state.GetRejectReason(); if (state.IsError()) @@ -316,7 +315,7 @@ static UniValue BIP22ValidationResult(const CValidationState& state) return "valid?"; } -UniValue getblocktemplate(const Array& params, bool fHelp) +UniValue getblocktemplate(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -384,8 +383,8 @@ UniValue getblocktemplate(const Array& params, bool fHelp) UniValue lpval = NullUniValue; if (params.size() > 0) { - const Object& oparam = params[0].get_obj(); - const Value& modeval = find_value(oparam, "mode"); + const UniValue& oparam = params[0].get_obj(); + const UniValue& modeval = find_value(oparam, "mode"); if (modeval.isStr()) strMode = modeval.get_str(); else if (modeval.isNull()) @@ -398,7 +397,7 @@ UniValue getblocktemplate(const Array& params, bool fHelp) if (strMode == "proposal") { - const Value& dataval = find_value(oparam, "data"); + const UniValue& dataval = find_value(oparam, "data"); if (dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); @@ -605,7 +604,7 @@ protected: }; }; -UniValue submitblock(const Array& params, bool fHelp) +UniValue submitblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -666,7 +665,7 @@ UniValue submitblock(const Array& params, bool fHelp) return BIP22ValidationResult(state); } -UniValue estimatefee(const Array& params, bool fHelp) +UniValue estimatefee(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -698,7 +697,7 @@ UniValue estimatefee(const Array& params, bool fHelp) return ValueFromAmount(feeRate.GetFeePerK()); } -UniValue estimatepriority(const Array& params, bool fHelp) +UniValue estimatepriority(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 15bbe90bc7..f5fc22aff1 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -20,9 +20,9 @@ #include #include -#include "json_spirit_wrapper.h" -using namespace json_spirit; +#include "univalue/univalue.h" + using namespace std; /** @@ -38,7 +38,7 @@ using namespace std; * * Or alternatively, create a specific query method for the information. **/ -UniValue getinfo(const Array& params, bool fHelp) +UniValue getinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -107,7 +107,7 @@ UniValue getinfo(const Array& params, bool fHelp) } #ifdef ENABLE_WALLET -class DescribeAddressVisitor : public boost::static_visitor +class DescribeAddressVisitor : public boost::static_visitor { private: isminetype mine; @@ -115,7 +115,7 @@ private: public: DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {} - UniValue operator()(const CNoDestination &dest) const { return Object(); } + UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); } UniValue operator()(const CKeyID &keyID) const { UniValue obj(UniValue::VOBJ); @@ -153,7 +153,7 @@ public: }; #endif -UniValue validateaddress(const Array& params, bool fHelp) +UniValue validateaddress(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -215,10 +215,10 @@ UniValue validateaddress(const Array& params, bool fHelp) /** * Used by addmultisigaddress / createmultisig: */ -CScript _createmultisig_redeemScript(const Array& params) +CScript _createmultisig_redeemScript(const UniValue& params) { int nRequired = params[0].get_int(); - const Array& keys = params[1].get_array(); + const UniValue& keys = params[1].get_array(); // Gather public keys if (nRequired < 1) @@ -276,7 +276,7 @@ CScript _createmultisig_redeemScript(const Array& params) return result; } -UniValue createmultisig(const Array& params, bool fHelp) +UniValue createmultisig(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 2) { @@ -319,7 +319,7 @@ UniValue createmultisig(const Array& params, bool fHelp) return result; } -UniValue verifymessage(const Array& params, bool fHelp) +UniValue verifymessage(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( @@ -373,7 +373,7 @@ UniValue verifymessage(const Array& params, bool fHelp) return (pubkey.GetID() == keyID); } -UniValue setmocktime(const Array& params, bool fHelp) +UniValue setmocktime(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 17eda22451..59253e72af 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -16,12 +16,11 @@ #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; -UniValue getconnectioncount(const Array& params, bool fHelp) +UniValue getconnectioncount(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -39,7 +38,7 @@ UniValue getconnectioncount(const Array& params, bool fHelp) return (int)vNodes.size(); } -UniValue ping(const Array& params, bool fHelp) +UniValue ping(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -75,7 +74,7 @@ static void CopyNodeStats(std::vector& vstats) } } -UniValue getpeerinfo(const Array& params, bool fHelp) +UniValue getpeerinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -165,7 +164,7 @@ UniValue getpeerinfo(const Array& params, bool fHelp) return ret; } -UniValue addnode(const Array& params, bool fHelp) +UniValue addnode(const UniValue& params, bool fHelp) { string strCommand; if (params.size() == 2) @@ -215,7 +214,7 @@ UniValue addnode(const Array& params, bool fHelp) return NullUniValue; } -UniValue getaddednodeinfo(const Array& params, bool fHelp) +UniValue getaddednodeinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -332,7 +331,7 @@ UniValue getaddednodeinfo(const Array& params, bool fHelp) return ret; } -UniValue getnettotals(const Array& params, bool fHelp) +UniValue getnettotals(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 0) throw runtime_error( @@ -378,7 +377,7 @@ static UniValue GetNetworksInfo() return networks; } -UniValue getnetworkinfo(const Array& params, bool fHelp) +UniValue getnetworkinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index 953e476022..090e5ea7f4 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -23,10 +23,10 @@ #include #include #include -#include "json_spirit_wrapper.h" + +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; //! Number of bytes to allocate and read at most at once in post data const size_t POST_READ_SIZE = 256 * 1024; @@ -254,7 +254,7 @@ int ReadHTTPMessage(std::basic_istream& stream, map #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" //! HTTP status codes enum HTTPStatusCode diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index b4ddbfebf3..20394fc2c1 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -25,12 +25,12 @@ #include #include -#include "json_spirit_wrapper.h" -using namespace json_spirit; +#include "univalue/univalue.h" + using namespace std; -void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex) +void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex) { txnouttype type; vector addresses; @@ -54,7 +54,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeH out.push_back(Pair("addresses", a)); } -void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) +void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); @@ -105,7 +105,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) } } -UniValue getrawtransaction(const Array& params, bool fHelp) +UniValue getrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -195,7 +195,7 @@ UniValue getrawtransaction(const Array& params, bool fHelp) return result; } -UniValue gettxoutproof(const Array& params, bool fHelp) +UniValue gettxoutproof(const UniValue& params, bool fHelp) { if (fHelp || (params.size() != 1 && params.size() != 2)) throw runtime_error( @@ -221,7 +221,7 @@ UniValue gettxoutproof(const Array& params, bool fHelp) uint256 oneTxid; UniValue txids = params[0].get_array(); for (unsigned int idx = 0; idx < txids.size(); idx++) { - const Value& txid = txids[idx]; + const UniValue& txid = txids[idx]; if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str()); uint256 hash(uint256S(txid.get_str())); @@ -276,7 +276,7 @@ UniValue gettxoutproof(const Array& params, bool fHelp) return strHex; } -UniValue verifytxoutproof(const Array& params, bool fHelp) +UniValue verifytxoutproof(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -309,7 +309,7 @@ UniValue verifytxoutproof(const Array& params, bool fHelp) return res; } -UniValue createrawtransaction(const Array& params, bool fHelp) +UniValue createrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 2) throw runtime_error( @@ -351,12 +351,12 @@ UniValue createrawtransaction(const Array& params, bool fHelp) CMutableTransaction rawTx; for (unsigned int idx = 0; idx < inputs.size(); idx++) { - const Value& input = inputs[idx]; - const Object& o = input.get_obj(); + const UniValue& input = inputs[idx]; + const UniValue& o = input.get_obj(); uint256 txid = ParseHashO(o, "txid"); - const Value& vout_v = find_value(o, "vout"); + const UniValue& vout_v = find_value(o, "vout"); if (!vout_v.isNum()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); int nOutput = vout_v.get_int(); @@ -388,7 +388,7 @@ UniValue createrawtransaction(const Array& params, bool fHelp) return EncodeHexTx(rawTx); } -UniValue decoderawtransaction(const Array& params, bool fHelp) +UniValue decoderawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -453,7 +453,7 @@ UniValue decoderawtransaction(const Array& params, bool fHelp) return result; } -UniValue decodescript(const Array& params, bool fHelp) +UniValue decodescript(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -496,7 +496,7 @@ UniValue decodescript(const Array& params, bool fHelp) } /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */ -static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::string& strMessage) +static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage) { UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", txin.prevout.hash.ToString())); @@ -507,7 +507,7 @@ static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::str vErrorsRet.push_back(entry); } -UniValue signrawtransaction(const Array& params, bool fHelp) +UniValue signrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 4) throw runtime_error( @@ -639,7 +639,7 @@ UniValue signrawtransaction(const Array& params, bool fHelp) if (params.size() > 1 && !params[1].isNull()) { UniValue prevTxs = params[1].get_array(); for (unsigned int idx = 0; idx < prevTxs.size(); idx++) { - const Value& p = prevTxs[idx]; + const UniValue& p = prevTxs[idx]; if (!p.isObject()) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); @@ -749,7 +749,7 @@ UniValue signrawtransaction(const Array& params, bool fHelp) return result; } -UniValue sendrawtransaction(const Array& params, bool fHelp) +UniValue sendrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index cb746508b1..18e74e03cf 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -28,10 +28,9 @@ #include #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" using namespace boost::asio; -using namespace json_spirit; using namespace RPCServer; using namespace std; @@ -79,17 +78,17 @@ void RPCServer::OnPostCommand(boost::function slot) g_rpcSignals.PostCommand.connect(boost::bind(slot, _1)); } -void RPCTypeCheck(const Array& params, - const list& typesExpected, +void RPCTypeCheck(const UniValue& params, + const list& typesExpected, bool fAllowNull) { unsigned int i = 0; - BOOST_FOREACH(Value_type t, typesExpected) + BOOST_FOREACH(UniValue::VType t, typesExpected) { if (params.size() <= i) break; - const Value& v = params[i]; + const UniValue& v = params[i]; if (!((v.type() == t) || (fAllowNull && (v.isNull())))) { string err = strprintf("Expected type %s, got %s", @@ -104,9 +103,9 @@ void RPCTypeCheckObj(const UniValue& o, const map& typesExpected, bool fAllowNull) { - BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected) + BOOST_FOREACH(const PAIRTYPE(string, UniValue::VType)& t, typesExpected) { - const Value& v = find_value(o, t.first); + const UniValue& v = find_value(o, t.first); if (!fAllowNull && v.isNull()) throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first)); @@ -124,7 +123,7 @@ static inline int64_t roundint64(double d) return (int64_t)(d > 0 ? d + 0.5 : d - 0.5); } -CAmount AmountFromValue(const Value& value) +CAmount AmountFromValue(const UniValue& value) { double dAmount = value.get_real(); if (dAmount <= 0.0 || dAmount > 21000000.0) @@ -140,7 +139,7 @@ UniValue ValueFromAmount(const CAmount& amount) return (double)amount / (double)COIN; } -uint256 ParseHashV(const Value& v, string strName) +uint256 ParseHashV(const UniValue& v, string strName) { string strHex; if (v.isStr()) @@ -151,11 +150,11 @@ uint256 ParseHashV(const Value& v, string strName) result.SetHex(strHex); return result; } -uint256 ParseHashO(const Object& o, string strKey) +uint256 ParseHashO(const UniValue& o, string strKey) { return ParseHashV(find_value(o, strKey), strKey); } -vector ParseHexV(const Value& v, string strName) +vector ParseHexV(const UniValue& v, string strName) { string strHex; if (v.isStr()) @@ -164,7 +163,7 @@ vector ParseHexV(const Value& v, string strName) throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); return ParseHex(strHex); } -vector ParseHexO(const Object& o, string strKey) +vector ParseHexO(const UniValue& o, string strKey) { return ParseHexV(find_value(o, strKey), strKey); } @@ -229,7 +228,7 @@ string CRPCTable::help(string strCommand) const return strRet; } -UniValue help(const Array& params, bool fHelp) +UniValue help(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -249,7 +248,7 @@ UniValue help(const Array& params, bool fHelp) } -UniValue stop(const Array& params, bool fHelp) +UniValue stop(const UniValue& params, bool fHelp) { // Accept the deprecated and ignored 'detach' boolean argument if (fHelp || params.size() > 1) @@ -411,7 +410,7 @@ bool HTTPAuthorized(map& mapHeaders) return TimingResistantEqual(strUserPass, strRPCUserColonPass); } -void ErrorReply(std::ostream& stream, const Object& objError, const Value& id) +void ErrorReply(std::ostream& stream, const UniValue& objError, const UniValue& id) { // Send error reply from json-rpc error object int nStatus = HTTP_INTERNAL_SERVER_ERROR; @@ -830,15 +829,15 @@ public: UniValue params; JSONRequest() { id = NullUniValue; } - void parse(const Value& valRequest); + void parse(const UniValue& valRequest); }; -void JSONRequest::parse(const Value& valRequest) +void JSONRequest::parse(const UniValue& valRequest) { // Parse request if (!valRequest.isObject()) throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object"); - const Object& request = valRequest.get_obj(); + const UniValue& request = valRequest.get_obj(); // Parse id now so errors from here on will have the id id = find_value(request, "id"); @@ -858,13 +857,13 @@ void JSONRequest::parse(const Value& valRequest) if (valParams.isArray()) params = valParams.get_array(); else if (valParams.isNull()) - params = Array(); + params = UniValue(UniValue::VARR); else throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array"); } -static UniValue JSONRPCExecOne(const Value& req) +static UniValue JSONRPCExecOne(const UniValue& req) { UniValue rpc_result(UniValue::VOBJ); @@ -875,7 +874,7 @@ static UniValue JSONRPCExecOne(const Value& req) UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); } - catch (const Object& objError) + catch (const UniValue& objError) { rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id); } @@ -888,7 +887,7 @@ static UniValue JSONRPCExecOne(const Value& req) return rpc_result; } -static string JSONRPCExecBatch(const Array& vReq) +static string JSONRPCExecBatch(const UniValue& vReq) { UniValue ret; for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) @@ -955,7 +954,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush; } - catch (const Object& objError) + catch (const UniValue& objError) { ErrorReply(conn->stream(), objError, jreq.id); return false; diff --git a/src/rpcserver.h b/src/rpcserver.h index e2bc8c0955..3f623651cc 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -16,7 +16,8 @@ #include #include -#include "json_spirit_wrapper.h" + +#include "univalue/univalue.h" class CRPCCommand; diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 114bd79ea9..9e74f5f427 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -17,9 +17,9 @@ #include #include -#include "json_spirit_wrapper.h" -using namespace json_spirit; +#include "univalue/univalue.h" + extern UniValue read_json(const std::string& jsondata); BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup) diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index a97c96be72..8dbe377626 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -13,10 +13,11 @@ #include #include +#include "univalue/univalue.h" + using namespace std; -using namespace json_spirit; -Array +UniValue createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL) { UniValue result(UniValue::VARR); @@ -28,7 +29,7 @@ createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL) return result; } -Value CallRPC(string args) +UniValue CallRPC(string args) { vector vArgs; boost::split(vArgs, args, boost::is_any_of(" \t")); @@ -38,10 +39,10 @@ Value CallRPC(string args) rpcfn_type method = tableRPC[strMethod]->actor; try { - Value result = (*method)(params, false); + UniValue result = (*method)(params, false); return result; } - catch (const Object& objError) { + catch (const UniValue& objError) { throw runtime_error(find_value(objError, "message").get_str()); } } @@ -52,7 +53,7 @@ BOOST_FIXTURE_TEST_SUITE(rpc_tests, TestingSetup) BOOST_AUTO_TEST_CASE(rpc_rawparams) { // Test raw transaction API argument handling - Value r; + UniValue r; BOOST_CHECK_THROW(CallRPC("getrawtransaction"), runtime_error); BOOST_CHECK_THROW(CallRPC("getrawtransaction not_hex"), runtime_error); @@ -92,7 +93,7 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams) BOOST_AUTO_TEST_CASE(rpc_rawsign) { - Value r; + UniValue r; // input is a 1-of-2 multisig (so is output): string prevout = "[{\"txid\":\"b4cc287e58f87cdae59417329f710f3ecd75a4ee1d2872b7248f50977c8493f3\"," @@ -121,7 +122,7 @@ BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) BOOST_CHECK(ValueFromAmount(2099999999999999LL).write() == "20999999.99999999"); } -static Value ValueFromString(const std::string &str) +static UniValue ValueFromString(const std::string &str) { UniValue value; BOOST_CHECK(value.setNumStr(str)); diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 1a897fcd54..a72b656100 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -14,11 +14,12 @@ #include #include +#include "univalue/univalue.h" + using namespace std; -using namespace json_spirit; extern UniValue createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL); -extern Value CallRPC(string args); +extern UniValue CallRPC(string args); extern CWallet* pwalletMain; @@ -35,7 +36,7 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig) // new, compressed: const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4"; - Value v; + UniValue v; CBitcoinAddress address; BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false)); address.SetString(v.get_str()); @@ -66,13 +67,13 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig) BOOST_AUTO_TEST_CASE(rpc_wallet) { // Test RPC calls for various wallet statistics - Value r; + UniValue r; LOCK2(cs_main, pwalletMain->cs_wallet); CPubKey demoPubkey = pwalletMain->GenerateNewKey(); CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID())); - Value retValue; + UniValue retValue; string strAccount = "walletDemoAccount"; string strPurpose = "receive"; BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */ diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index af11c0c9d9..3733425699 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -26,10 +26,10 @@ #include #include -#include "json_spirit_wrapper.h" + +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; // Uncomment if you want to output updated JSON tests. // #define UPDATE_JSON_TESTS @@ -39,15 +39,15 @@ static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; unsigned int ParseScriptFlags(string strFlags); string FormatScriptFlags(unsigned int flags); -Array +UniValue read_json(const std::string& jsondata) { - Value v; + UniValue v; if (!v.read(jsondata) || !v.isArray()) { BOOST_ERROR("Parse error."); - return Array(); + return UniValue(UniValue::VARR); } return v.get_array(); } @@ -584,11 +584,11 @@ BOOST_AUTO_TEST_CASE(script_build) UniValue json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); for (unsigned int idx = 0; idx < json_good.size(); idx++) { - const Value& tv = json_good[idx]; + const UniValue& tv = json_good[idx]; tests_good.insert(tv.get_array().write()); } for (unsigned int idx = 0; idx < json_bad.size(); idx++) { - const Value& tv = json_bad[idx]; + const UniValue& tv = json_bad[idx]; tests_bad.insert(tv.get_array().write()); } } diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index efdb4e8043..a0797d5f3f 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -16,9 +16,9 @@ #include #include -#include "json_spirit_wrapper.h" -using namespace json_spirit; +#include "univalue/univalue.h" + extern UniValue read_json(const std::string& jsondata); // Old script.cpp SignatureHash function diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index afd2d74013..4cfdec1267 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -24,10 +24,9 @@ #include #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; // In script_tests.cpp extern UniValue read_json(const std::string& jsondata); @@ -92,19 +91,11 @@ BOOST_AUTO_TEST_CASE(tx_valid) // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" UniValue tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); -<<<<<<< HEAD ScriptError err; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); - if (test[0].type() == array_type) -======= for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); if (test[0].isArray()) ->>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { @@ -116,7 +107,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { - const Value& input = inputs[inpIdx]; + const UniValue& input = inputs[inpIdx]; if (!input.isArray()) { fValid = false; @@ -175,19 +166,11 @@ BOOST_AUTO_TEST_CASE(tx_invalid) // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" UniValue tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); -<<<<<<< HEAD ScriptError err; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); - if (test[0].type() == array_type) -======= for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); if (test[0].isArray()) ->>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { @@ -199,7 +182,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { - const Value& input = inputs[inpIdx]; + const UniValue& input = inputs[inpIdx]; if (!input.isArray()) { fValid = false; diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index 994d93113a..e8fc513433 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -213,3 +213,15 @@ const char *uvTypeName(UniValue::VType t) return NULL; } +const UniValue& find_value( const UniValue& obj, const std::string& name) +{ + for (unsigned int i = 0; i < obj.keys.size(); i++) + { + if( obj.keys[i] == name ) + { + return obj.values[i]; + } + } + + return NullUniValue; +} \ No newline at end of file diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index c37a3829fc..57a96abe26 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -161,6 +161,7 @@ public: std::istringstream(getValStr()) >> ret; return ret; } + friend const UniValue& find_value( const UniValue& obj, const std::string& name); }; // @@ -248,5 +249,8 @@ extern enum jtokentype getJsonToken(std::string& tokenVal, extern const char *uvTypeName(UniValue::VType t); extern const UniValue NullUniValue; + +const UniValue& find_value( const UniValue& obj, const std::string& name); + #endif // BITCOIN_UNIVALUE_UNIVALUE_H diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 9d72c45bae..b682a42e23 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -19,9 +19,8 @@ #include #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; void EnsureWalletIsUnlocked(); @@ -70,7 +69,7 @@ std::string DecodeDumpString(const std::string &str) { return ret.str(); } -UniValue importprivkey(const Array& params, bool fHelp) +UniValue importprivkey(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -144,7 +143,7 @@ UniValue importprivkey(const Array& params, bool fHelp) return NullUniValue; } -UniValue importaddress(const Array& params, bool fHelp) +UniValue importaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -217,7 +216,7 @@ UniValue importaddress(const Array& params, bool fHelp) return NullUniValue; } -UniValue importwallet(const Array& params, bool fHelp) +UniValue importwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -321,7 +320,7 @@ UniValue importwallet(const Array& params, bool fHelp) return NullUniValue; } -UniValue dumpprivkey(const Array& params, bool fHelp) +UniValue dumpprivkey(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -359,7 +358,7 @@ UniValue dumpprivkey(const Array& params, bool fHelp) } -UniValue dumpwallet(const Array& params, bool fHelp) +UniValue dumpwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index d5d97604f4..e44940993e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -21,10 +21,9 @@ #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; @@ -54,7 +53,7 @@ void EnsureWalletIsUnlocked() throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); } -void WalletTxToJSON(const CWalletTx& wtx, Object& entry) +void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) { int confirms = wtx.GetDepthInMainChain(); entry.push_back(Pair("confirmations", confirms)); @@ -78,7 +77,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry) entry.push_back(Pair(item.first, item.second)); } -string AccountFromValue(const Value& value) +string AccountFromValue(const UniValue& value) { string strAccount = value.get_str(); if (strAccount == "*") @@ -86,7 +85,7 @@ string AccountFromValue(const Value& value) return strAccount; } -Value getnewaddress(const Array& params, bool fHelp) +UniValue getnewaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -165,7 +164,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) return CBitcoinAddress(account.vchPubKey.GetID()); } -Value getaccountaddress(const Array& params, bool fHelp) +UniValue getaccountaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -190,14 +189,14 @@ Value getaccountaddress(const Array& params, bool fHelp) // Parse the account first so we don't generate a key if there's an error string strAccount = AccountFromValue(params[0]); - Value ret; + UniValue ret(UniValue::VSTR); ret = GetAccountAddress(strAccount).ToString(); return ret; } -Value getrawchangeaddress(const Array& params, bool fHelp) +UniValue getrawchangeaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -232,7 +231,7 @@ Value getrawchangeaddress(const Array& params, bool fHelp) } -Value setaccount(const Array& params, bool fHelp) +UniValue setaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -278,7 +277,7 @@ Value setaccount(const Array& params, bool fHelp) } -Value getaccount(const Array& params, bool fHelp) +UniValue getaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -310,7 +309,7 @@ Value getaccount(const Array& params, bool fHelp) } -Value getaddressesbyaccount(const Array& params, bool fHelp) +UniValue getaddressesbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -378,7 +377,7 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); } -Value sendtoaddress(const Array& params, bool fHelp) +UniValue sendtoaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -434,7 +433,7 @@ Value sendtoaddress(const Array& params, bool fHelp) return wtx.GetHash().GetHex(); } -Value listaddressgroupings(const Array& params, bool fHelp) +UniValue listaddressgroupings(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -486,7 +485,7 @@ Value listaddressgroupings(const Array& params, bool fHelp) return jsonGroupings; } -Value signmessage(const Array& params, bool fHelp) +UniValue signmessage(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -542,7 +541,7 @@ Value signmessage(const Array& params, bool fHelp) return EncodeBase64(&vchSig[0], vchSig.size()); } -Value getreceivedbyaddress(const Array& params, bool fHelp) +UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -600,7 +599,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) } -Value getreceivedbyaccount(const Array& params, bool fHelp) +UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -689,7 +688,7 @@ CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminef } -Value getbalance(const Array& params, bool fHelp) +UniValue getbalance(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -764,7 +763,7 @@ Value getbalance(const Array& params, bool fHelp) return ValueFromAmount(nBalance); } -Value getunconfirmedbalance(const UniValue ¶ms, bool fHelp) +UniValue getunconfirmedbalance(const UniValue ¶ms, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -780,7 +779,7 @@ Value getunconfirmedbalance(const UniValue ¶ms, bool fHelp) } -Value movecmd(const Array& params, bool fHelp) +UniValue movecmd(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -850,7 +849,7 @@ Value movecmd(const Array& params, bool fHelp) } -Value sendfrom(const Array& params, bool fHelp) +UniValue sendfrom(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -913,7 +912,7 @@ Value sendfrom(const Array& params, bool fHelp) } -Value sendmany(const Array& params, bool fHelp) +UniValue sendmany(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -992,7 +991,7 @@ Value sendmany(const Array& params, bool fHelp) bool fSubtractFeeFromAmount = false; for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) { - const Value& addr = subtractFeeFromAmount[idx]; + const UniValue& addr = subtractFeeFromAmount[idx]; if (addr.get_str() == name_) fSubtractFeeFromAmount = true; } @@ -1023,9 +1022,9 @@ Value sendmany(const Array& params, bool fHelp) } // Defined in rpcmisc.cpp -extern CScript _createmultisig_redeemScript(const Array& params); +extern CScript _createmultisig_redeemScript(const UniValue& params); -Value addmultisigaddress(const Array& params, bool fHelp) +UniValue addmultisigaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1088,7 +1087,7 @@ struct tallyitem } }; -Value ListReceived(const Array& params, bool fByAccounts) +UniValue ListReceived(const UniValue& params, bool fByAccounts) { // Minimum confirmations int nMinDepth = 1; @@ -1206,7 +1205,7 @@ Value ListReceived(const Array& params, bool fByAccounts) return ret; } -Value listreceivedbyaddress(const Array& params, bool fHelp) +UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1243,7 +1242,7 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) return ListReceived(params, false); } -Value listreceivedbyaccount(const Array& params, bool fHelp) +UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1286,7 +1285,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) entry.push_back(Pair("address", addr.ToString())); } -void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter) +void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) { CAmount nFee; string strSentAccount; @@ -1356,7 +1355,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe } } -void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret) +void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, UniValue& ret) { bool fAllAccounts = (strAccount == string("*")); @@ -1373,7 +1372,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar } } -Value listtransactions(const Array& params, bool fHelp) +UniValue listtransactions(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1494,7 +1493,7 @@ Value listtransactions(const Array& params, bool fHelp) return ret; } -Value listaccounts(const Array& params, bool fHelp) +UniValue listaccounts(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1574,7 +1573,7 @@ Value listaccounts(const Array& params, bool fHelp) return ret; } -Value listsinceblock(const Array& params, bool fHelp) +UniValue listsinceblock(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1665,7 +1664,7 @@ Value listsinceblock(const Array& params, bool fHelp) return ret; } -Value gettransaction(const Array& params, bool fHelp) +UniValue gettransaction(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1743,7 +1742,7 @@ Value gettransaction(const Array& params, bool fHelp) } -Value backupwallet(const Array& params, bool fHelp) +UniValue backupwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1769,7 +1768,7 @@ Value backupwallet(const Array& params, bool fHelp) } -Value keypoolrefill(const Array& params, bool fHelp) +UniValue keypoolrefill(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1813,7 +1812,7 @@ static void LockWallet(CWallet* pWallet) pWallet->Lock(); } -Value walletpassphrase(const Array& params, bool fHelp) +UniValue walletpassphrase(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1873,7 +1872,7 @@ Value walletpassphrase(const Array& params, bool fHelp) } -Value walletpassphrasechange(const Array& params, bool fHelp) +UniValue walletpassphrasechange(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1919,7 +1918,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp) } -Value walletlock(const Array& params, bool fHelp) +UniValue walletlock(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1958,7 +1957,7 @@ Value walletlock(const Array& params, bool fHelp) } -Value encryptwallet(const Array& params, bool fHelp) +UniValue encryptwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2015,7 +2014,7 @@ Value encryptwallet(const Array& params, bool fHelp) return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup."; } -Value lockunspent(const Array& params, bool fHelp) +UniValue lockunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2076,7 +2075,7 @@ Value lockunspent(const Array& params, bool fHelp) const UniValue& output = outputs[idx]; if (!output.isObject()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object"); - const Object& o = output.get_obj(); + const UniValue& o = output.get_obj(); RPCTypeCheckObj(o, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)); @@ -2099,7 +2098,7 @@ Value lockunspent(const Array& params, bool fHelp) return true; } -Value listlockunspent(const Array& params, bool fHelp) +UniValue listlockunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2148,7 +2147,7 @@ Value listlockunspent(const Array& params, bool fHelp) return ret; } -Value settxfee(const Array& params, bool fHelp) +UniValue settxfee(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2177,7 +2176,7 @@ Value settxfee(const Array& params, bool fHelp) return true; } -Value getwalletinfo(const Array& params, bool fHelp) +UniValue getwalletinfo(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2217,7 +2216,7 @@ Value getwalletinfo(const Array& params, bool fHelp) return obj; } -Value resendwallettransactions(const Array& params, bool fHelp) +UniValue resendwallettransactions(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2242,7 +2241,7 @@ Value resendwallettransactions(const Array& params, bool fHelp) return result; } -Value listunspent(const Array& params, bool fHelp) +UniValue listunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2297,7 +2296,7 @@ Value listunspent(const Array& params, bool fHelp) if (params.size() > 2) { UniValue inputs = params[2].get_array(); for (unsigned int idx = 0; idx < inputs.size(); idx++) { - const Value& input = inputs[idx]; + const UniValue& input = inputs[idx]; CBitcoinAddress address(input.get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str()); -- cgit v1.2.3 From 8f7e4abbe6d6c814f5f3c069e5b3067920689dbe Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 2 Jun 2015 11:41:00 +0200 Subject: fix rpc batching univalue issue --- src/rpcserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 18e74e03cf..a92ec0b29b 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -889,7 +889,7 @@ static UniValue JSONRPCExecOne(const UniValue& req) static string JSONRPCExecBatch(const UniValue& vReq) { - UniValue ret; + UniValue ret(UniValue::VARR); for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) ret.push_back(JSONRPCExecOne(vReq[reqIdx])); -- cgit v1.2.3 From c7fbbc7e1d7b076f68f0b2d87f7e86faba5d3a26 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 2 Jun 2015 12:28:54 +0200 Subject: fix missing univalue types during constructing --- src/rpcblockchain.cpp | 4 ++-- src/rpcmisc.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index e3f17b4ae7..e45368cb97 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -206,7 +206,7 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) setDepends.insert(txin.prevout.hash.ToString()); } - UniValue depends; + UniValue depends(UniValue::VARR); BOOST_FOREACH(const string& dep, setDepends) { depends.push_back(dep); @@ -635,7 +635,7 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp) + HelpExampleRpc("getmempoolinfo", "") ); - UniValue ret; + UniValue ret(UniValue::VOBJ); ret.push_back(Pair("size", (int64_t) mempool.size())); ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index f5fc22aff1..fe6eb81b84 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -312,7 +312,7 @@ UniValue createmultisig(const UniValue& params, bool fHelp) CScriptID innerID(inner); CBitcoinAddress address(innerID); - UniValue result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("address", address.ToString())); result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end()))); -- cgit v1.2.3 From 519eedeba76a2192bbded69b3c7e7e96bfc549a2 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 4 Jun 2015 10:35:36 +0200 Subject: fix univalue json parse tests --- src/test/rpc_tests.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 8dbe377626..576e62a0bb 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -143,20 +143,23 @@ BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) BOOST_AUTO_TEST_CASE(json_parse_errors) { - Value value; + UniValue value; // Valid - BOOST_CHECK_EQUAL(read_string(std::string("1.0"), value), true); + BOOST_CHECK_EQUAL(value.read(std::string("1.0")), false); + BOOST_CHECK_EQUAL(value.read(std::string("[1.0]")), true); // Valid, with trailing whitespace - BOOST_CHECK_EQUAL(read_string(std::string("1.0 "), value), true); + BOOST_CHECK_EQUAL(value.read(std::string("1.0 ")), false); + BOOST_CHECK_EQUAL(value.read(std::string("[1.0 ] ")), true); // Invalid, initial garbage - BOOST_CHECK_EQUAL(read_string(std::string("[1.0"), value), false); - BOOST_CHECK_EQUAL(read_string(std::string("a1.0"), value), false); + BOOST_CHECK_EQUAL(value.read(std::string("[1.0")), false); + BOOST_CHECK_EQUAL(value.read(std::string("[a1.0]")), false); + BOOST_CHECK_EQUAL(value.read(std::string("[\"a1.0\"]")), true); // Invalid, trailing garbage - BOOST_CHECK_EQUAL(read_string(std::string("1.0sds"), value), false); - BOOST_CHECK_EQUAL(read_string(std::string("1.0]"), value), false); + BOOST_CHECK_EQUAL(value.read(std::string("1.0sds")), false); + BOOST_CHECK_EQUAL(value.read(std::string("1.0]")), false); // BTC addresses should fail parsing - BOOST_CHECK_EQUAL(read_string(std::string("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"), value), false); - BOOST_CHECK_EQUAL(read_string(std::string("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), value), false); + BOOST_CHECK_EQUAL(value.read(std::string("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")), false); + BOOST_CHECK_EQUAL(value.read(std::string("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL")), false); } BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr) -- cgit v1.2.3 From 043df2b56831bef4c4b726ae4fc761d4710b99be Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 4 Jun 2015 10:31:22 +0200 Subject: Simplify RPCclient, adapt json_parse_error test # Conflicts: # src/test/rpc_tests.cpp --- src/rpcclient.cpp | 36 ++++++++++++++++-------------------- src/rpcclient.h | 4 ++++ src/test/rpc_tests.cpp | 23 ++++++++++------------- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index d175db09ee..f254da5de0 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -121,6 +121,18 @@ CRPCConvertTable::CRPCConvertTable() static CRPCConvertTable rpcCvtTable; +/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null) + * as well as objects and arrays. + */ +UniValue ParseNonRFCJSONValue(const std::string& strVal) +{ + UniValue jVal; + if (!jVal.read(std::string("[")+strVal+std::string("]")) || + !jVal.isArray() || jVal.size()!=1) + throw runtime_error(string("Error parsing JSON:")+strVal); + return jVal[0]; +} + /** Convert strings to command-specific RPC representation */ UniValue RPCConvertValues(const std::string &strMethod, const std::vector &strParams) { @@ -129,28 +141,12 @@ UniValue 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); + } else { + // parse string as JSON, insert bool/number/object/etc. value + params.push_back(ParseNonRFCJSONValue(strVal)); } } diff --git a/src/rpcclient.h b/src/rpcclient.h index 52270aec74..d68b4ed6ae 100644 --- a/src/rpcclient.h +++ b/src/rpcclient.h @@ -9,5 +9,9 @@ #include "univalue/univalue.h" UniValue RPCConvertValues(const std::string& strMethod, const std::vector& strParams); +/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null) + * as well as objects and arrays. + */ +UniValue ParseNonRFCJSONValue(const std::string& strVal); #endif // BITCOIN_RPCCLIENT_H diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 576e62a0bb..0b33ddb086 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -143,23 +143,20 @@ BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) BOOST_AUTO_TEST_CASE(json_parse_errors) { - UniValue value; // Valid - BOOST_CHECK_EQUAL(value.read(std::string("1.0")), false); - BOOST_CHECK_EQUAL(value.read(std::string("[1.0]")), true); - // Valid, with trailing whitespace - BOOST_CHECK_EQUAL(value.read(std::string("1.0 ")), false); - BOOST_CHECK_EQUAL(value.read(std::string("[1.0 ] ")), true); + BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0").get_real(), 1.0); + // Valid, with leading or trailing whitespace + BOOST_CHECK_EQUAL(ParseNonRFCJSONValue(" 1.0").get_real(), 1.0); + BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0 ").get_real(), 1.0); // Invalid, initial garbage - BOOST_CHECK_EQUAL(value.read(std::string("[1.0")), false); - BOOST_CHECK_EQUAL(value.read(std::string("[a1.0]")), false); - BOOST_CHECK_EQUAL(value.read(std::string("[\"a1.0\"]")), true); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("[1.0"), std::runtime_error); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("a1.0"), std::runtime_error); // Invalid, trailing garbage - BOOST_CHECK_EQUAL(value.read(std::string("1.0sds")), false); - BOOST_CHECK_EQUAL(value.read(std::string("1.0]")), false); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0sds"), std::runtime_error); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0]"), std::runtime_error); // BTC addresses should fail parsing - BOOST_CHECK_EQUAL(value.read(std::string("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")), false); - BOOST_CHECK_EQUAL(value.read(std::string("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL")), false); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"), std::runtime_error); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), std::runtime_error); } BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr) -- cgit v1.2.3 From 7e98a3c642222edc0813ced945d4b6e548cb8ca8 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 4 Jun 2015 12:03:09 +0200 Subject: util: Add ParseInt64 and ParseDouble functions Strict parsing functions for other numeric types. - ParseInt64 analogous to ParseInt32, but for 64-bit values. - ParseDouble for doubles. - Make all three Parse* functions more strict (e.g. reject whitespace on the inside) Also add tests. --- src/test/util_tests.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ src/utilstrencodings.cpp | 43 +++++++++++++++++++++++++++++++- src/utilstrencodings.h | 14 +++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 3309e2e387..1779bcdd95 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -322,9 +322,16 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32) BOOST_CHECK(ParseInt32("-2147483648", &n) && n == -2147483648); BOOST_CHECK(ParseInt32("-1234", &n) && n == -1234); // Invalid values + BOOST_CHECK(!ParseInt32("", &n)); + BOOST_CHECK(!ParseInt32(" 1", &n)); // no padding inside + BOOST_CHECK(!ParseInt32("1 ", &n)); BOOST_CHECK(!ParseInt32("1a", &n)); BOOST_CHECK(!ParseInt32("aap", &n)); BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex + BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex + const char test_bytes[] = {'1', 0, '1'}; + std::string teststr(test_bytes, sizeof(test_bytes)); + BOOST_CHECK(!ParseInt32(teststr, &n)); // no embedded NULs // Overflow and underflow BOOST_CHECK(!ParseInt32("-2147483649", NULL)); BOOST_CHECK(!ParseInt32("2147483648", NULL)); @@ -332,6 +339,64 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32) BOOST_CHECK(!ParseInt32("32482348723847471234", NULL)); } +BOOST_AUTO_TEST_CASE(test_ParseInt64) +{ + int64_t n; + // Valid values + BOOST_CHECK(ParseInt64("1234", NULL)); + BOOST_CHECK(ParseInt64("0", &n) && n == 0LL); + BOOST_CHECK(ParseInt64("1234", &n) && n == 1234LL); + BOOST_CHECK(ParseInt64("01234", &n) && n == 1234LL); // no octal + BOOST_CHECK(ParseInt64("2147483647", &n) && n == 2147483647LL); + BOOST_CHECK(ParseInt64("-2147483648", &n) && n == -2147483648LL); + BOOST_CHECK(ParseInt64("9223372036854775807", &n) && n == 9223372036854775807LL); + BOOST_CHECK(ParseInt64("-9223372036854775808", &n) && n == 9223372036854775808LL); + BOOST_CHECK(ParseInt64("-1234", &n) && n == -1234LL); + // Invalid values + BOOST_CHECK(!ParseInt64("", &n)); + BOOST_CHECK(!ParseInt64(" 1", &n)); // no padding inside + BOOST_CHECK(!ParseInt64("1 ", &n)); + BOOST_CHECK(!ParseInt64("1a", &n)); + BOOST_CHECK(!ParseInt64("aap", &n)); + BOOST_CHECK(!ParseInt64("0x1", &n)); // no hex + const char test_bytes[] = {'1', 0, '1'}; + std::string teststr(test_bytes, sizeof(test_bytes)); + BOOST_CHECK(!ParseInt64(teststr, &n)); // no embedded NULs + // Overflow and underflow + BOOST_CHECK(!ParseInt64("-9223372036854775809", NULL)); + BOOST_CHECK(!ParseInt64("9223372036854775808", NULL)); + BOOST_CHECK(!ParseInt64("-32482348723847471234", NULL)); + BOOST_CHECK(!ParseInt64("32482348723847471234", NULL)); +} + +BOOST_AUTO_TEST_CASE(test_ParseDouble) +{ + double n; + // Valid values + BOOST_CHECK(ParseDouble("1234", NULL)); + BOOST_CHECK(ParseDouble("0", &n) && n == 0.0); + BOOST_CHECK(ParseDouble("1234", &n) && n == 1234.0); + BOOST_CHECK(ParseDouble("01234", &n) && n == 1234.0); // no octal + BOOST_CHECK(ParseDouble("2147483647", &n) && n == 2147483647.0); + BOOST_CHECK(ParseDouble("-2147483648", &n) && n == -2147483648.0); + BOOST_CHECK(ParseDouble("-1234", &n) && n == -1234.0); + BOOST_CHECK(ParseDouble("1e6", &n) && n == 1e6); + BOOST_CHECK(ParseDouble("-1e6", &n) && n == -1e6); + // Invalid values + BOOST_CHECK(!ParseDouble("", &n)); + BOOST_CHECK(!ParseDouble(" 1", &n)); // no padding inside + BOOST_CHECK(!ParseDouble("1 ", &n)); + BOOST_CHECK(!ParseDouble("1a", &n)); + BOOST_CHECK(!ParseDouble("aap", &n)); + BOOST_CHECK(!ParseDouble("0x1", &n)); // no hex + const char test_bytes[] = {'1', 0, '1'}; + std::string teststr(test_bytes, sizeof(test_bytes)); + BOOST_CHECK(!ParseDouble(teststr, &n)); // no embedded NULs + // Overflow and underflow + BOOST_CHECK(!ParseDouble("-1e10000", NULL)); + BOOST_CHECK(!ParseDouble("1e10000", NULL)); +} + BOOST_AUTO_TEST_CASE(test_FormatParagraph) { BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), ""); diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index c15bddc6fb..b10f3c5903 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -416,12 +416,25 @@ string DecodeBase32(const string& str) return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size()); } +static bool ParsePrechecks(const std::string& str) +{ + if (str.empty()) // No empty string allowed + return false; + if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed + return false; + if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed + return false; + return true; +} + bool ParseInt32(const std::string& str, int32_t *out) { + if (!ParsePrechecks(str)) + return false; char *endp = NULL; errno = 0; // strtol will not set errno if valid long int n = strtol(str.c_str(), &endp, 10); - if(out) *out = (int)n; + if(out) *out = (int32_t)n; // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit // platforms the size of these types may be different. @@ -430,6 +443,34 @@ bool ParseInt32(const std::string& str, int32_t *out) n <= std::numeric_limits::max(); } +bool ParseInt64(const std::string& str, int64_t *out) +{ + if (!ParsePrechecks(str)) + return false; + char *endp = NULL; + errno = 0; // strtoll will not set errno if valid + long long int n = strtoll(str.c_str(), &endp, 10); + if(out) *out = (int64_t)n; + // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow + // we still have to check that the returned value is within the range of an *int64_t*. + return endp && *endp == 0 && !errno && + n >= std::numeric_limits::min() && + n <= std::numeric_limits::max(); +} + +bool ParseDouble(const std::string& str, double *out) +{ + if (!ParsePrechecks(str)) + return false; + if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed + return false; + char *endp = NULL; + errno = 0; // strtod will not set errno if valid + double n = strtod(str.c_str(), &endp); + if(out) *out = n; + return endp && *endp == 0 && !errno; +} + std::string FormatParagraph(const std::string in, size_t width, size_t indent) { std::stringstream out; diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index b0edd8b542..fb3ef04281 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -49,6 +49,20 @@ int atoi(const std::string& str); */ bool ParseInt32(const std::string& str, int32_t *out); +/** + * Convert string to signed 64-bit integer with strict parse error feedback. + * @returns true if the entire string could be parsed as valid integer, + * false if not the entire string could be parsed or when overflow or underflow occurred. + */ +bool ParseInt64(const std::string& str, int64_t *out); + +/** + * Convert string to double with strict parse error feedback. + * @returns true if the entire string could be parsed as valid double, + * false if not the entire string could be parsed or when overflow or underflow occurred. + */ +bool ParseDouble(const std::string& str, double *out); + template std::string HexStr(const T itbegin, const T itend, bool fSpaces=false) { -- cgit v1.2.3 From c02309204b8195476945f7066e8d96c60246db08 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 4 Jun 2015 11:40:03 +0200 Subject: univalue: add strict type checking --- src/univalue/univalue.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++- src/univalue/univalue.h | 32 ++++++++----------- 2 files changed, 91 insertions(+), 20 deletions(-) diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index e8fc513433..6920c44c96 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -6,8 +6,12 @@ #include #include #include +#include // std::runtime_error + #include "univalue.h" +#include "utilstrencodings.h" // ParseXX + using namespace std; const UniValue NullUniValue; @@ -224,4 +228,77 @@ const UniValue& find_value( const UniValue& obj, const std::string& name) } return NullUniValue; -} \ No newline at end of file +} + +std::vector UniValue::getKeys() const +{ + if (typ != VOBJ) + throw std::runtime_error("JSON value is not an object as expected"); + return keys; +} + +std::vector UniValue::getValues() const +{ + if (typ != VOBJ && typ != VARR) + throw std::runtime_error("JSON value is not an object or array as expected"); + return values; +} + +bool UniValue::get_bool() const +{ + if (typ != VBOOL) + throw std::runtime_error("JSON value is not a boolean as expected"); + return getBool(); +} + +std::string UniValue::get_str() const +{ + if (typ != VSTR) + throw std::runtime_error("JSON value is not a string as expected"); + return getValStr(); +} + +int UniValue::get_int() const +{ + if (typ != VNUM) + throw std::runtime_error("JSON value is not an integer as expected"); + int32_t retval; + if (!ParseInt32(getValStr(), &retval)) + throw std::runtime_error("JSON integer out of range"); + return retval; +} + +int64_t UniValue::get_int64() const +{ + if (typ != VNUM) + throw std::runtime_error("JSON value is not an integer as expected"); + int64_t retval; + if (!ParseInt64(getValStr(), &retval)) + throw std::runtime_error("JSON integer out of range"); + return retval; +} + +double UniValue::get_real() const +{ + if (typ != VREAL && typ != VNUM) + throw std::runtime_error("JSON value is not a number as expected"); + double retval; + if (!ParseDouble(getValStr(), &retval)) + throw std::runtime_error("JSON double out of range"); + return retval; +} + +const UniValue& UniValue::get_obj() const +{ + if (typ != VOBJ) + throw std::runtime_error("JSON value is not an object as expected"); + return *this; +} + +const UniValue& UniValue::get_array() const +{ + if (typ != VARR) + throw std::runtime_error("JSON value is not an array as expected"); + return *this; +} + diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index 57a96abe26..79018bb787 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -13,7 +13,6 @@ #include // .get_int64() #include // std::pair -#include // atoi(), atof() TODO: remove class UniValue { public: @@ -75,7 +74,7 @@ public: bool isNull() const { return (typ == VNULL); } bool isTrue() const { return (typ == VBOOL) && (val == "1"); } - bool isFalse() const { return (!isTrue()); } + bool isFalse() const { return (typ == VBOOL) && (val != "1"); } bool isBool() const { return (typ == VBOOL); } bool isStr() const { return (typ == VSTR); } bool isNum() const { return (typ == VNUM); } @@ -140,27 +139,22 @@ private: void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; public: - // - // The following were added for compatibility with json_spirit. - // Most duplicate other methods, and should be removed. - // - std::vector getKeys() const { return keys; } - std::vector getValues() const { return values; } - bool get_bool() const { return getBool(); } - std::string get_str() const { return getValStr(); } - int get_int() const { return atoi(getValStr().c_str()); } - double get_real() const { return atof(getValStr().c_str()); } - const UniValue& get_obj() const { return *this; } - const UniValue& get_array() const { return *this; } + // Strict type-specific getters, these throw std::runtime_error if the + // value is of unexpected type + std::vector getKeys() const; + std::vector getValues() const; + bool get_bool() const; + std::string get_str() const; + int get_int() const; + int64_t get_int64() const; + double get_real() const; + const UniValue& get_obj() const; + const UniValue& get_array() const; + enum VType type() const { return getType(); } bool push_back(std::pair pear) { return pushKV(pear.first, pear.second); } - int64_t get_int64() const { - int64_t ret; - std::istringstream(getValStr()) >> ret; - return ret; - } friend const UniValue& find_value( const UniValue& obj, const std::string& name); }; -- cgit v1.2.3 From 44c7474446d5a020bc06bf2f2b87572f42e54e9e Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 4 Jun 2015 13:58:14 +0200 Subject: univalue: add type check unit tests --- src/test/univalue_tests.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 87186cac44..de84faca23 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -63,6 +63,48 @@ BOOST_AUTO_TEST_CASE(univalue_constructor) BOOST_CHECK_EQUAL(v9.getValStr(), "zappa"); } +BOOST_AUTO_TEST_CASE(univalue_typecheck) +{ + UniValue v1; + BOOST_CHECK(v1.setNumStr("1")); + BOOST_CHECK(v1.isNum()); + BOOST_CHECK_THROW(v1.get_bool(), runtime_error); + + UniValue v2; + BOOST_CHECK(v2.setBool(true)); + BOOST_CHECK_EQUAL(v2.get_bool(), true); + BOOST_CHECK_THROW(v2.get_int(), runtime_error); + + UniValue v3; + BOOST_CHECK(v3.setNumStr("32482348723847471234")); + BOOST_CHECK_THROW(v3.get_int64(), runtime_error); + BOOST_CHECK(v3.setNumStr("1000")); + BOOST_CHECK_EQUAL(v3.get_int64(), 1000); + + UniValue v4; + BOOST_CHECK(v4.setNumStr("2147483648")); + BOOST_CHECK_EQUAL(v4.get_int64(), 2147483648); + BOOST_CHECK_THROW(v4.get_int(), runtime_error); + BOOST_CHECK(v4.setNumStr("1000")); + BOOST_CHECK_EQUAL(v4.get_int(), 1000); + BOOST_CHECK_THROW(v4.get_str(), runtime_error); + BOOST_CHECK_EQUAL(v4.get_real(), 1000); + BOOST_CHECK_THROW(v4.get_array(), runtime_error); + BOOST_CHECK_THROW(v4.getKeys(), runtime_error); + BOOST_CHECK_THROW(v4.getValues(), runtime_error); + BOOST_CHECK_THROW(v4.get_obj(), runtime_error); + + UniValue v5; + BOOST_CHECK(v5.read("[true, 10]")); + BOOST_CHECK_NO_THROW(v5.get_array()); + std::vector vals = v5.getValues(); + BOOST_CHECK_THROW(vals[0].get_int(), runtime_error); + BOOST_CHECK_EQUAL(vals[0].get_bool(), true); + + BOOST_CHECK_EQUAL(vals[1].get_int(), 10); + BOOST_CHECK_THROW(vals[1].get_bool(), runtime_error); +} + BOOST_AUTO_TEST_CASE(univalue_set) { UniValue v(UniValue::VSTR, "foo"); -- cgit v1.2.3