diff options
-rwxr-xr-x | contrib/devtools/github-merge.sh | 4 | ||||
-rw-r--r-- | doc/build-unix.md | 2 | ||||
-rw-r--r-- | src/Makefile.test.include | 1 | ||||
-rw-r--r-- | src/alert.cpp | 5 | ||||
-rw-r--r-- | src/alert.h | 1 | ||||
-rw-r--r-- | src/core.cpp | 40 | ||||
-rw-r--r-- | src/core.h | 6 | ||||
-rw-r--r-- | src/init.cpp | 3 | ||||
-rw-r--r-- | src/main.cpp | 1 | ||||
-rw-r--r-- | src/main.h | 10 | ||||
-rw-r--r-- | src/miner.cpp | 10 | ||||
-rw-r--r-- | src/netbase.cpp | 10 | ||||
-rw-r--r-- | src/netbase.h | 2 | ||||
-rw-r--r-- | src/protocol.cpp | 6 | ||||
-rw-r--r-- | src/protocol.h | 3 | ||||
-rw-r--r-- | src/serialize.h | 10 | ||||
-rw-r--r-- | src/test/rpc_tests.cpp | 32 | ||||
-rw-r--r-- | src/test/univalue_tests.cpp | 275 | ||||
-rw-r--r-- | src/tinyformat.h | 2 | ||||
-rw-r--r-- | src/univalue/univalue.cpp | 2 | ||||
-rw-r--r-- | src/univalue/univalue_write.cpp | 11 | ||||
-rw-r--r-- | src/util.h | 1 | ||||
-rw-r--r-- | src/wallet.h | 5 |
23 files changed, 323 insertions, 119 deletions
diff --git a/contrib/devtools/github-merge.sh b/contrib/devtools/github-merge.sh index e42b71a54a..3217a06195 100755 --- a/contrib/devtools/github-merge.sh +++ b/contrib/devtools/github-merge.sh @@ -49,11 +49,11 @@ fi # Initialize source branches. git checkout -q "$BRANCH" if git fetch -q "$HOST":"$REPO" "+refs/pull/$PULL/*:refs/heads/pull/$PULL/*"; then - if ! git log -1q "refs/heads/pull/$PULL/head" >/dev/null 2>&1; then + if ! git log -q -1 "refs/heads/pull/$PULL/head" >/dev/null 2>&1; then echo "ERROR: Cannot find head of pull request #$PULL on $HOST:$REPO." >&2 exit 3 fi - if ! git log -1q "refs/heads/pull/$PULL/merge" >/dev/null 2>&1; then + if ! git log -q -1 "refs/heads/pull/$PULL/merge" >/dev/null 2>&1; then echo "ERROR: Cannot find merge of pull request #$PULL on $HOST:$REPO." >&2 exit 3 fi diff --git a/doc/build-unix.md b/doc/build-unix.md index 56054456a3..8a76a8b2cd 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -109,7 +109,7 @@ To build with Qt 4 you need the following: For Qt 5 you need the following: - sudo apt-get install libqt5gui5 libqt5core5 libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev + sudo apt-get install libqt5gui5 libqt5core5 libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler libqrencode (optional) can be installed with: diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 7e25430e3e..bf6534cf39 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -58,6 +58,7 @@ BITCOIN_TESTS =\ test/test_bitcoin.cpp \ test/transaction_tests.cpp \ test/uint256_tests.cpp \ + test/univalue_tests.cpp \ test/util_tests.cpp \ test/scriptnum_tests.cpp \ test/sighash_tests.cpp diff --git a/src/alert.cpp b/src/alert.cpp index 258a2b52c4..2cd684cc4c 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -80,11 +80,6 @@ std::string CUnsignedAlert::ToString() const strStatusBar); } -void CUnsignedAlert::print() const -{ - LogPrintf("%s", ToString()); -} - void CAlert::SetNull() { CUnsignedAlert::SetNull(); diff --git a/src/alert.h b/src/alert.h index 296d48891a..b9d850b565 100644 --- a/src/alert.h +++ b/src/alert.h @@ -68,7 +68,6 @@ public: void SetNull(); std::string ToString() const; - void print() const; }; /** An alert is a combination of a serialized CUnsignedAlert and a signature. */ diff --git a/src/core.cpp b/src/core.cpp index 149b3532a1..71d6fea610 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -5,18 +5,13 @@ #include "core.h" -#include "util.h" +#include "tinyformat.h" std::string COutPoint::ToString() const { return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n); } -void COutPoint::print() const -{ - LogPrintf("%s\n", ToString()); -} - CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, unsigned int nSequenceIn) { prevout = prevoutIn; @@ -46,11 +41,6 @@ std::string CTxIn::ToString() const return str; } -void CTxIn::print() const -{ - LogPrintf("%s\n", ToString()); -} - CTxOut::CTxOut(int64_t nValueIn, CScript scriptPubKeyIn) { nValue = nValueIn; @@ -67,11 +57,6 @@ std::string CTxOut::ToString() const return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30)); } -void CTxOut::print() const -{ - LogPrintf("%s\n", ToString()); -} - CFeeRate::CFeeRate(int64_t nFeePaid, size_t nSize) { if (nSize > 0) @@ -92,8 +77,7 @@ int64_t CFeeRate::GetFee(size_t nSize) const std::string CFeeRate::ToString() const { - std::string result = FormatMoney(nSatoshisPerK) + " BTC/kB"; - return result; + return strprintf("%d.%08d BTC/kB", nSatoshisPerK / COIN, nSatoshisPerK % COIN); } CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {} @@ -171,11 +155,6 @@ std::string CTransaction::ToString() const return str; } -void CTransaction::print() const -{ - LogPrintf("%s", ToString()); -} - // Amount compression: // * If the amount is 0, output 0 // * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9) @@ -285,9 +264,10 @@ uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMer return hash; } -void CBlock::print() const +std::string CBlock::ToString() const { - LogPrintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n", + std::stringstream s; + s << strprintf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n", GetHash().ToString(), nVersion, hashPrevBlock.ToString(), @@ -296,11 +276,11 @@ void CBlock::print() const vtx.size()); for (unsigned int i = 0; i < vtx.size(); i++) { - LogPrintf(" "); - vtx[i].print(); + s << " " << vtx[i].ToString() << "\n"; } - LogPrintf(" vMerkleTree: "); + s << " vMerkleTree: "; for (unsigned int i = 0; i < vMerkleTree.size(); i++) - LogPrintf("%s ", vMerkleTree[i].ToString()); - LogPrintf("\n"); + s << " " << vMerkleTree[i].ToString(); + s << "\n"; + return s.str(); } diff --git a/src/core.h b/src/core.h index fb64e6c08e..9552f70254 100644 --- a/src/core.h +++ b/src/core.h @@ -47,7 +47,6 @@ public: } std::string ToString() const; - void print() const; }; /** An inpoint - a combination of a transaction and an index n into its vin */ @@ -107,7 +106,6 @@ public: } std::string ToString() const; - void print() const; }; @@ -200,7 +198,6 @@ public: } std::string ToString() const; - void print() const; }; @@ -279,7 +276,6 @@ public: } std::string ToString() const; - void print() const; }; /** A mutable version of CTransaction. */ @@ -497,7 +493,7 @@ public: std::vector<uint256> GetMerkleBranch(int nIndex) const; static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex); - void print() const; + std::string ToString() const; }; diff --git a/src/init.cpp b/src/init.cpp index 42956a8d69..708e6386aa 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1029,8 +1029,7 @@ bool AppInit2(boost::thread_group& threadGroup) CBlock block; ReadBlockFromDisk(block, pindex); block.BuildMerkleTree(); - block.print(); - LogPrintf("\n"); + LogPrintf("%s\n", block.ToString()); nFound++; } } diff --git a/src/main.cpp b/src/main.cpp index 09b10c8e55..d7543e3f13 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3968,7 +3968,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vRecv >> block; LogPrint("net", "received block %s peer=%d\n", block.GetHash().ToString(), pfrom->id); - // block.print(); CInv inv(MSG_BLOCK, block.GetHash()); pfrom->AddInventoryKnown(inv); diff --git a/src/main.h b/src/main.h index 01d3f119e1..886cac1507 100644 --- a/src/main.h +++ b/src/main.h @@ -839,11 +839,6 @@ public: GetBlockHash().ToString()); } - void print() const - { - LogPrintf("%s\n", ToString()); - } - // Check whether this block index entry is valid up to the passed validity level. bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const { @@ -935,11 +930,6 @@ public: hashPrev.ToString()); return str; } - - void print() const - { - LogPrintf("%s\n", ToString()); - } }; /** Capture information about block/transaction validation */ diff --git a/src/miner.cpp b/src/miner.cpp index 9408d2c5aa..06acff1c33 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -42,14 +42,6 @@ public: COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0) { } - - void print() const - { - LogPrintf("COrphan(hash=%s, dPriority=%.1f, fee=%s)\n", - ptx->GetHash().ToString(), dPriority, feeRate.ToString()); - BOOST_FOREACH(uint256 hash, setDependsOn) - LogPrintf(" setDependsOn %s\n", hash.ToString()); - } }; uint64_t nLastBlockTx = 0; @@ -404,7 +396,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) { - pblock->print(); + LogPrintf("%s\n", pblock->ToString()); LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue)); // Found a solution diff --git a/src/netbase.cpp b/src/netbase.cpp index e1637cd404..e9207da330 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -874,11 +874,6 @@ uint64_t CNetAddr::GetHash() const return nRet; } -void CNetAddr::print() const -{ - LogPrintf("CNetAddr(%s)\n", ToString()); -} - // private extensions to enum Network, only returned by GetExtNetwork, // and only used in GetReachabilityFrom static const int NET_UNKNOWN = NET_MAX + 0; @@ -1107,11 +1102,6 @@ std::string CService::ToString() const return ToStringIPPort(); } -void CService::print() const -{ - LogPrintf("CService(%s)\n", ToString()); -} - void CService::SetPort(unsigned short portIn) { port = portIn; diff --git a/src/netbase.h b/src/netbase.h index bd8dbf9695..2df3c4474d 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -80,7 +80,6 @@ class CNetAddr bool GetInAddr(struct in_addr* pipv4Addr) const; std::vector<unsigned char> GetGroup() const; int GetReachabilityFrom(const CNetAddr *paddrPartner = NULL) const; - void print() const; CNetAddr(const struct in6_addr& pipv6Addr); bool GetIn6Addr(struct in6_addr* pipv6Addr) const; @@ -145,7 +144,6 @@ class CService : public CNetAddr std::string ToString() const; std::string ToStringPort() const; std::string ToStringIPPort() const; - void print() const; CService(const struct in6_addr& ipv6Addr, unsigned short port); CService(const struct sockaddr_in6& addr); diff --git a/src/protocol.cpp b/src/protocol.cpp index 87b2f23873..341de0602a 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -144,9 +144,3 @@ std::string CInv::ToString() const { return strprintf("%s %s", GetCommand(), hash.ToString()); } - -void CInv::print() const -{ - LogPrintf("CInv(%s)\n", ToString()); -} - diff --git a/src/protocol.h b/src/protocol.h index 1f23274299..d7565584af 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -98,8 +98,6 @@ class CAddress : public CService READWRITE(*pip); ) - void print() const; - // TODO: make private (improves encapsulation) public: uint64_t nServices; @@ -130,7 +128,6 @@ class CInv bool IsKnownType() const; const char* GetCommand() const; std::string ToString() const; - void print() const; // TODO: make private (improves encapsulation) public: diff --git a/src/serialize.h b/src/serialize.h index 2eb69b3ec0..3e5eff469d 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -68,7 +68,7 @@ inline const T* end_ptr(const std::vector<T,TAl>& v) ///////////////////////////////////////////////////////////////// // // Templates for serializing to anything that looks like a stream, -// i.e. anything that supports .read(char*, int) and .write(char*, int) +// i.e. anything that supports .read(char*, size_t) and .write(char*, size_t) // enum @@ -876,7 +876,7 @@ public: CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {} - CSizeComputer& write(const char *psz, int nSize) + CSizeComputer& write(const char *psz, size_t nSize) { this->nSize += nSize; return *this; @@ -1105,10 +1105,9 @@ public: void ReadVersion() { *this >> nVersion; } void WriteVersion() { *this << nVersion; } - CDataStream& read(char* pch, int nSize) + CDataStream& read(char* pch, size_t nSize) { // Read from the beginning of the buffer - assert(nSize >= 0); unsigned int nReadPosNext = nReadPos + nSize; if (nReadPosNext >= vch.size()) { @@ -1145,10 +1144,9 @@ public: return (*this); } - CDataStream& write(const char* pch, int nSize) + CDataStream& write(const char* pch, size_t nSize) { // Write to the end of the buffer - assert(nSize >= 0); vch.insert(vch.end(), pch, pch + nSize); return (*this); } diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 107c0f06e7..d5475a92bf 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -110,14 +110,14 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign) BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) { - BOOST_CHECK(write_string(ValueFromAmount(0LL), false) == "0.00000000"); - BOOST_CHECK(write_string(ValueFromAmount(1LL), false) == "0.00000001"); - BOOST_CHECK(write_string(ValueFromAmount(17622195LL), false) == "0.17622195"); - BOOST_CHECK(write_string(ValueFromAmount(50000000LL), false) == "0.50000000"); - BOOST_CHECK(write_string(ValueFromAmount(89898989LL), false) == "0.89898989"); - BOOST_CHECK(write_string(ValueFromAmount(100000000LL), false) == "1.00000000"); - BOOST_CHECK(write_string(ValueFromAmount(2099999999999990LL), false) == "20999999.99999990"); - BOOST_CHECK(write_string(ValueFromAmount(2099999999999999LL), false) == "20999999.99999999"); + 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"); } static Value ValueFromString(const std::string &str) @@ -129,14 +129,14 @@ static Value ValueFromString(const std::string &str) BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) { - BOOST_CHECK(AmountFromValue(ValueFromString("0.00000001")) == 1LL); - BOOST_CHECK(AmountFromValue(ValueFromString("0.17622195")) == 17622195LL); - BOOST_CHECK(AmountFromValue(ValueFromString("0.5")) == 50000000LL); - BOOST_CHECK(AmountFromValue(ValueFromString("0.50000000")) == 50000000LL); - BOOST_CHECK(AmountFromValue(ValueFromString("0.89898989")) == 89898989LL); - BOOST_CHECK(AmountFromValue(ValueFromString("1.00000000")) == 100000000LL); - BOOST_CHECK(AmountFromValue(ValueFromString("20999999.9999999")) == 2099999999999990LL); - BOOST_CHECK(AmountFromValue(ValueFromString("20999999.99999999")) == 2099999999999999LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000001")), 1LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.17622195")), 17622195LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.5")), 50000000LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.50000000")), 50000000LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.89898989")), 89898989LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("1.00000000")), 100000000LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.9999999")), 2099999999999990LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("20999999.99999999")), 2099999999999999LL); } BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr) diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp new file mode 100644 index 0000000000..23bc5f6b12 --- /dev/null +++ b/src/test/univalue_tests.cpp @@ -0,0 +1,275 @@ +// Copyright 2014 BitPay, Inc. +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <stdint.h> +#include <vector> +#include <string> +#include <map> +#include "univalue/univalue.h" + +#include <boost/test/unit_test.hpp> + +using namespace std; + +BOOST_AUTO_TEST_SUITE(univalue_tests) + +BOOST_AUTO_TEST_CASE(univalue_constructor) +{ + UniValue v1; + BOOST_CHECK(v1.isNull()); + + UniValue v2(UniValue::VSTR); + BOOST_CHECK(v2.isStr()); + + UniValue v3(UniValue::VSTR, "foo"); + BOOST_CHECK(v3.isStr()); + BOOST_CHECK_EQUAL(v3.getValStr(), "foo"); + + UniValue numTest; + BOOST_CHECK(numTest.setNumStr("82")); + BOOST_CHECK(numTest.isNum()); + BOOST_CHECK_EQUAL(numTest.getValStr(), "82"); + + uint64_t vu64 = 82; + UniValue v4(vu64); + BOOST_CHECK(v4.isNum()); + BOOST_CHECK_EQUAL(v4.getValStr(), "82"); + + int64_t vi64 = -82; + UniValue v5(vi64); + BOOST_CHECK(v5.isNum()); + BOOST_CHECK_EQUAL(v5.getValStr(), "-82"); + + int vi = -688; + UniValue v6(vi); + BOOST_CHECK(v6.isNum()); + BOOST_CHECK_EQUAL(v6.getValStr(), "-688"); + + double vd = -7.21; + UniValue v7(vd); + BOOST_CHECK(v7.isNum()); + BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21"); + + string vs("yawn"); + UniValue v8(vs); + BOOST_CHECK(v8.isStr()); + BOOST_CHECK_EQUAL(v8.getValStr(), "yawn"); + + const char *vcs = "zappa"; + UniValue v9(vcs); + BOOST_CHECK(v9.isStr()); + BOOST_CHECK_EQUAL(v9.getValStr(), "zappa"); +} + +BOOST_AUTO_TEST_CASE(univalue_set) +{ + UniValue v(UniValue::VSTR, "foo"); + v.clear(); + BOOST_CHECK(v.isNull()); + BOOST_CHECK_EQUAL(v.getValStr(), ""); + + BOOST_CHECK(v.setObject()); + BOOST_CHECK(v.isObject()); + BOOST_CHECK_EQUAL(v.count(), 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(v.setStr("zum")); + BOOST_CHECK(v.isStr()); + BOOST_CHECK_EQUAL(v.getValStr(), "zum"); + + BOOST_CHECK(v.setFloat(-1.01)); + BOOST_CHECK(v.isNum()); + BOOST_CHECK_EQUAL(v.getValStr(), "-1.01"); + + BOOST_CHECK(v.setInt((int)1023)); + BOOST_CHECK(v.isNum()); + BOOST_CHECK_EQUAL(v.getValStr(), "1023"); + + BOOST_CHECK(v.setInt((int64_t)-1023LL)); + BOOST_CHECK(v.isNum()); + BOOST_CHECK_EQUAL(v.getValStr(), "-1023"); + + BOOST_CHECK(v.setInt((uint64_t)1023ULL)); + BOOST_CHECK(v.isNum()); + BOOST_CHECK_EQUAL(v.getValStr(), "1023"); + + BOOST_CHECK(v.setNumStr("-688")); + BOOST_CHECK(v.isNum()); + BOOST_CHECK_EQUAL(v.getValStr(), "-688"); + + BOOST_CHECK(v.setBool(false)); + BOOST_CHECK_EQUAL(v.isBool(), true); + BOOST_CHECK_EQUAL(v.isTrue(), false); + BOOST_CHECK_EQUAL(v.isFalse(), true); + BOOST_CHECK_EQUAL(v.getBool(), false); + + BOOST_CHECK(v.setBool(true)); + BOOST_CHECK_EQUAL(v.isBool(), true); + BOOST_CHECK_EQUAL(v.isTrue(), true); + BOOST_CHECK_EQUAL(v.isFalse(), false); + BOOST_CHECK_EQUAL(v.getBool(), true); + + BOOST_CHECK(!v.setNumStr("zombocom")); + + BOOST_CHECK(v.setNull()); + BOOST_CHECK(v.isNull()); +} + +BOOST_AUTO_TEST_CASE(univalue_array) +{ + UniValue arr(UniValue::VARR); + + UniValue v((int64_t)1023LL); + BOOST_CHECK(arr.push_back(v)); + + string vStr("zippy"); + BOOST_CHECK(arr.push_back(vStr)); + + const char *s = "pippy"; + BOOST_CHECK(arr.push_back(s)); + + vector<UniValue> vec; + v.setStr("boing"); + vec.push_back(v); + + v.setStr("going"); + vec.push_back(v); + + BOOST_CHECK(arr.push_backV(vec)); + + BOOST_CHECK_EQUAL(arr.empty(), false); + BOOST_CHECK_EQUAL(arr.count(), 5); + + BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023"); + BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy"); + BOOST_CHECK_EQUAL(arr[2].getValStr(), "pippy"); + BOOST_CHECK_EQUAL(arr[3].getValStr(), "boing"); + BOOST_CHECK_EQUAL(arr[4].getValStr(), "going"); + + BOOST_CHECK_EQUAL(arr[999].getValStr(), ""); + + arr.clear(); + BOOST_CHECK(arr.empty()); + BOOST_CHECK_EQUAL(arr.count(), 0); +} + +BOOST_AUTO_TEST_CASE(univalue_object) +{ + UniValue obj(UniValue::VOBJ); + string strKey, strVal; + UniValue v; + + strKey = "age"; + v.setInt(100); + BOOST_CHECK(obj.pushKV(strKey, v)); + + strKey = "first"; + strVal = "John"; + BOOST_CHECK(obj.pushKV(strKey, strVal)); + + strKey = "last"; + const char *cVal = "Smith"; + BOOST_CHECK(obj.pushKV(strKey, cVal)); + + strKey = "distance"; + BOOST_CHECK(obj.pushKV(strKey, (int64_t) 25)); + + strKey = "time"; + BOOST_CHECK(obj.pushKV(strKey, (uint64_t) 3600)); + + strKey = "calories"; + BOOST_CHECK(obj.pushKV(strKey, (int) 12)); + + strKey = "temperature"; + BOOST_CHECK(obj.pushKV(strKey, (double) 90.012)); + + UniValue obj2(UniValue::VOBJ); + BOOST_CHECK(obj2.pushKV("cat1", 9000)); + BOOST_CHECK(obj2.pushKV("cat2", 12345)); + + BOOST_CHECK(obj.pushKVs(obj2)); + + BOOST_CHECK_EQUAL(obj.empty(), false); + BOOST_CHECK_EQUAL(obj.count(), 9); + + BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100"); + BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John"); + BOOST_CHECK_EQUAL(obj["last"].getValStr(), "Smith"); + BOOST_CHECK_EQUAL(obj["distance"].getValStr(), "25"); + BOOST_CHECK_EQUAL(obj["time"].getValStr(), "3600"); + BOOST_CHECK_EQUAL(obj["calories"].getValStr(), "12"); + BOOST_CHECK_EQUAL(obj["temperature"].getValStr(), "90.012"); + BOOST_CHECK_EQUAL(obj["cat1"].getValStr(), "9000"); + BOOST_CHECK_EQUAL(obj["cat2"].getValStr(), "12345"); + + BOOST_CHECK_EQUAL(obj["nyuknyuknyuk"].getValStr(), ""); + + BOOST_CHECK(obj.exists("age")); + BOOST_CHECK(obj.exists("first")); + BOOST_CHECK(obj.exists("last")); + BOOST_CHECK(obj.exists("distance")); + BOOST_CHECK(obj.exists("time")); + BOOST_CHECK(obj.exists("calories")); + BOOST_CHECK(obj.exists("temperature")); + BOOST_CHECK(obj.exists("cat1")); + BOOST_CHECK(obj.exists("cat2")); + + BOOST_CHECK(!obj.exists("nyuknyuknyuk")); + + map<string, UniValue::VType> objTypes; + objTypes["age"] = UniValue::VNUM; + objTypes["first"] = UniValue::VSTR; + objTypes["last"] = UniValue::VSTR; + objTypes["distance"] = UniValue::VNUM; + objTypes["time"] = UniValue::VNUM; + objTypes["calories"] = UniValue::VNUM; + objTypes["temperature"] = UniValue::VNUM; + objTypes["cat1"] = UniValue::VNUM; + objTypes["cat2"] = UniValue::VNUM; + BOOST_CHECK(obj.checkObject(objTypes)); + + objTypes["cat2"] = UniValue::VSTR; + BOOST_CHECK(!obj.checkObject(objTypes)); + + obj.clear(); + BOOST_CHECK(obj.empty()); + BOOST_CHECK_EQUAL(obj.count(), 0); +} + +static const char *json1 = +"[1.1,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]"; + +BOOST_AUTO_TEST_CASE(univalue_readwrite) +{ + UniValue v; + BOOST_CHECK(v.read(json1)); + + string strJson1(json1); + BOOST_CHECK(v.read(strJson1)); + + BOOST_CHECK(v.isArray()); + BOOST_CHECK_EQUAL(v.count(), 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(obj["key1"].isStr()); + BOOST_CHECK_EQUAL(obj["key1"].getValStr(), "str"); + BOOST_CHECK(obj["key2"].isNum()); + BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800"); + BOOST_CHECK(obj["key3"].isObject()); + + BOOST_CHECK_EQUAL(strJson1, v.write()); +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/tinyformat.h b/src/tinyformat.h index b6113029f5..929cb66e4d 100644 --- a/src/tinyformat.h +++ b/src/tinyformat.h @@ -1007,4 +1007,6 @@ TINYFORMAT_WRAP_FORMAT_N(16, returnType, funcName, funcDeclSuffix, bodyPrefix, s } // namespace tinyformat +#define strprintf tfm::format + #endif // TINYFORMAT_H_INCLUDED diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index afc208bffb..b0171e48c4 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -44,7 +44,7 @@ static bool validNumStr(const string& s) bool UniValue::setNumStr(const string& val_) { - if (!validNumStr(val)) + if (!validNumStr(val_)) return false; clear(); diff --git a/src/univalue/univalue_write.cpp b/src/univalue/univalue_write.cpp index 70762a1ef1..042091a827 100644 --- a/src/univalue/univalue_write.cpp +++ b/src/univalue/univalue_write.cpp @@ -91,8 +91,11 @@ void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, s if (prettyIndent) s += indentStr(prettyIndent, indentLevel); s += values[i].write(prettyIndent, indentLevel + 1); - if (i != (values.size() - 1)) - s += ", "; + if (i != (values.size() - 1)) { + s += ","; + if (prettyIndent) + s += " "; + } if (prettyIndent) s += "\n"; } @@ -111,7 +114,9 @@ void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, for (unsigned int i = 0; i < keys.size(); i++) { if (prettyIndent) s += indentStr(prettyIndent, indentLevel); - s += "\"" + json_escape(keys[i]) + "\": "; + s += "\"" + json_escape(keys[i]) + "\":"; + if (prettyIndent) + s += " "; s += values[i].write(prettyIndent, indentLevel + 1); if (i != (values.size() - 1)) s += ","; diff --git a/src/util.h b/src/util.h index db2005337b..1fb42a7b7e 100644 --- a/src/util.h +++ b/src/util.h @@ -108,7 +108,6 @@ bool LogAcceptCategory(const char* category); /* Send a string to the log output */ int LogPrintStr(const std::string &str); -#define strprintf tfm::format #define LogPrintf(...) LogPrint(NULL, __VA_ARGS__) /* When we switch to C++11, this can be switched to variadic templates instead diff --git a/src/wallet.h b/src/wallet.h index 864a635ec7..34c699e979 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -824,11 +824,6 @@ public: { return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue).c_str()); } - - void print() const - { - LogPrintf("%s\n", ToString()); - } }; |