aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcontrib/devtools/github-merge.sh4
-rw-r--r--doc/build-unix.md2
-rw-r--r--src/Makefile.test.include1
-rw-r--r--src/alert.cpp5
-rw-r--r--src/alert.h1
-rw-r--r--src/core.cpp40
-rw-r--r--src/core.h6
-rw-r--r--src/init.cpp3
-rw-r--r--src/main.cpp1
-rw-r--r--src/main.h10
-rw-r--r--src/miner.cpp10
-rw-r--r--src/netbase.cpp10
-rw-r--r--src/netbase.h2
-rw-r--r--src/protocol.cpp6
-rw-r--r--src/protocol.h3
-rw-r--r--src/serialize.h10
-rw-r--r--src/test/rpc_tests.cpp32
-rw-r--r--src/test/univalue_tests.cpp275
-rw-r--r--src/tinyformat.h2
-rw-r--r--src/univalue/univalue.cpp2
-rw-r--r--src/univalue/univalue_write.cpp11
-rw-r--r--src/util.h1
-rw-r--r--src/wallet.h5
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());
- }
};