Auto merge of #4964 - str4d:univalue-update, r=nuttycom

Update UniValue subtree

This brings us up-to-date with upstream Bitcoin's version of the library.

Includes a commit cherry-picked from bitcoin/bitcoin#12193.
This commit is contained in:
Homu 2021-01-28 18:06:37 +00:00
commit 090e284f57
9 changed files with 107 additions and 145 deletions

View File

@ -1139,12 +1139,12 @@ static UniValue RPCLockedMemoryInfo()
{ {
LockedPool::Stats stats = LockedPoolManager::Instance().stats(); LockedPool::Stats stats = LockedPoolManager::Instance().stats();
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("used", uint64_t(stats.used))); obj.pushKV("used", uint64_t(stats.used));
obj.push_back(Pair("free", uint64_t(stats.free))); obj.pushKV("free", uint64_t(stats.free));
obj.push_back(Pair("total", uint64_t(stats.total))); obj.pushKV("total", uint64_t(stats.total));
obj.push_back(Pair("locked", uint64_t(stats.locked))); obj.pushKV("locked", uint64_t(stats.locked));
obj.push_back(Pair("chunks_used", uint64_t(stats.chunks_used))); obj.pushKV("chunks_used", uint64_t(stats.chunks_used));
obj.push_back(Pair("chunks_free", uint64_t(stats.chunks_free))); obj.pushKV("chunks_free", uint64_t(stats.chunks_free));
return obj; return obj;
} }
@ -1173,7 +1173,7 @@ UniValue getmemoryinfo(const UniValue& params, bool fHelp)
+ HelpExampleRpc("getmemoryinfo", "") + HelpExampleRpc("getmemoryinfo", "")
); );
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("locked", RPCLockedMemoryInfo())); obj.pushKV("locked", RPCLockedMemoryInfo());
return obj; return obj;
} }

View File

@ -25,7 +25,6 @@ addons:
- pkg-config - pkg-config
before_script: before_script:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew uninstall libtool; brew install libtool; fi
- if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi
- test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh

View File

@ -12,33 +12,10 @@ an arbitrary depth.
This class is aligned with the JSON standard, [RFC This class is aligned with the JSON standard, [RFC
7159](https://tools.ietf.org/html/rfc7159.html). 7159](https://tools.ietf.org/html/rfc7159.html).
## Motivation ## Library usage
UniValue is a reaction to json_spirit, seeking to minimize template This is a fork of univalue used by Bitcoin Core. It is not maintained for usage
and memory use, providing a straightforward RAII class compatible with by other projects. Notably, the API may break in non-backward-compatible ways.
link-time optimization and embedded uses.
## Status
The current production version is available from the [stable-1.0.x branch](https://github.com/jgarzik/univalue/tree/stable-1.0.x).
The current development series is 1.1.x, and is pushed to the `master` branch.
The next stable version will be 1.2.0, to be released immediately
following the conclusion of the 1.1.x series, similar to [this
variant](https://en.wikipedia.org/wiki/Software_versioning#Odd-numbered_versions_for_development_releases)
of semver.
## Installation
This project is a standard GNU
[autotools](https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html)
project. Build and install instructions are available in the `INSTALL`
file provided with GNU autotools.
```
$ ./autogen.sh
$ ./configure
$ make
```
Other projects looking for a maintained library should use the upstream
univalue at https://github.com/jgarzik/univalue.

View File

@ -1,7 +1,7 @@
m4_define([libunivalue_major_version], [1]) m4_define([libunivalue_major_version], [1])
m4_define([libunivalue_minor_version], [1]) m4_define([libunivalue_minor_version], [1])
m4_define([libunivalue_micro_version], [4]) m4_define([libunivalue_micro_version], [3])
m4_define([libunivalue_interface_age], [4]) m4_define([libunivalue_interface_age], [3])
# If you need a modifier for the version number. # If you need a modifier for the version number.
# Normally empty, but can be used to make "fixup" releases. # Normally empty, but can be used to make "fixup" releases.
m4_define([libunivalue_extraversion], []) m4_define([libunivalue_extraversion], [])
@ -14,7 +14,7 @@ m4_define([libunivalue_age], [m4_eval(libunivalue_binary_age - libunivalue_inter
m4_define([libunivalue_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()]) m4_define([libunivalue_version], [libunivalue_major_version().libunivalue_minor_version().libunivalue_micro_version()libunivalue_extraversion()])
AC_INIT([univalue], [1.1.1], AC_INIT([univalue], [1.0.3],
[https://github.com/jgarzik/univalue/]) [https://github.com/jgarzik/univalue/])
dnl make the compilation flags quiet unless V=1 is used dnl make the compilation flags quiet unless V=1 is used

View File

@ -14,14 +14,17 @@
#include <map> #include <map>
#include <cassert> #include <cassert>
#include <utility> // std::pair #include <sstream> // .get_int64()
class UniValue { class UniValue {
public: public:
enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, }; enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
UniValue() : typ(VNULL) {} UniValue() { typ = VNULL; }
UniValue(UniValue::VType type, const std::string& value = std::string()) : typ(type), val(value) {} UniValue(UniValue::VType initialType, const std::string& initialStr = "") {
typ = initialType;
val = initialStr;
}
UniValue(uint64_t val_) { UniValue(uint64_t val_) {
setInt(val_); setInt(val_);
} }
@ -46,15 +49,6 @@ public:
} }
void clear(); void clear();
void reserve(size_t n) {
if (typ == VOBJ || typ == VARR) {
if (typ == VOBJ)
keys.reserve(n);
values.reserve(n);
} else if (typ != VNULL) {
val.reserve(n);
}
}
bool setNull(); bool setNull();
bool setBool(bool val); bool setBool(bool val);
@ -90,10 +84,66 @@ public:
bool isObject() const { return (typ == VOBJ); } bool isObject() const { return (typ == VOBJ); }
bool push_back(const UniValue& val); bool push_back(const UniValue& val);
bool push_back(const std::string& val_) {
UniValue tmpVal(VSTR, val_);
return push_back(tmpVal);
}
bool push_back(const char *val_) {
std::string s(val_);
return push_back(s);
}
bool push_back(uint64_t val_) {
UniValue tmpVal(val_);
return push_back(tmpVal);
}
bool push_back(int64_t val_) {
UniValue tmpVal(val_);
return push_back(tmpVal);
}
bool push_back(bool val_) {
UniValue tmpVal(val_);
return push_back(tmpVal);
}
bool push_back(int val_) {
UniValue tmpVal(val_);
return push_back(tmpVal);
}
bool push_back(double val_) {
UniValue tmpVal(val_);
return push_back(tmpVal);
}
bool push_backV(const std::vector<UniValue>& vec); bool push_backV(const std::vector<UniValue>& vec);
void _pushKV(const std::string& key, const UniValue& val); void _pushKV(const std::string& key, const UniValue& val);
bool pushKV(const std::string& key, const UniValue& val); bool pushKV(const std::string& key, const UniValue& val);
bool pushKV(const std::string& key, const std::string& val_) {
UniValue tmpVal(VSTR, val_);
return pushKV(key, tmpVal);
}
bool pushKV(const std::string& key, const char *val_) {
std::string _val(val_);
return pushKV(key, _val);
}
bool pushKV(const std::string& key, int64_t val_) {
UniValue tmpVal(val_);
return pushKV(key, tmpVal);
}
bool pushKV(const std::string& key, uint64_t val_) {
UniValue tmpVal(val_);
return pushKV(key, tmpVal);
}
bool pushKV(const std::string& key, bool val_) {
UniValue tmpVal(val_);
return pushKV(key, tmpVal);
}
bool pushKV(const std::string& key, int val_) {
UniValue tmpVal((int64_t)val_);
return pushKV(key, tmpVal);
}
bool pushKV(const std::string& key, double val_) {
UniValue tmpVal(val_);
return pushKV(key, tmpVal);
}
bool pushKVs(const UniValue& obj); bool pushKVs(const UniValue& obj);
std::string write(unsigned int prettyIndent = 0, std::string write(unsigned int prettyIndent = 0,
@ -129,76 +179,9 @@ public:
const UniValue& get_array() const; const UniValue& get_array() const;
enum VType type() const { return getType(); } enum VType type() const { return getType(); }
bool push_back(std::pair<std::string,UniValue> pear) {
return pushKV(pear.first, pear.second);
}
friend const UniValue& find_value( const UniValue& obj, const std::string& name); friend const UniValue& find_value( const UniValue& obj, const std::string& name);
}; };
//
// The following were added for compatibility with json_spirit.
// Most duplicate other methods, and should be removed.
//
static inline std::pair<std::string,UniValue> Pair(const char *cKey, const char *cVal)
{
std::string key(cKey);
UniValue uVal(cVal);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, std::string strVal)
{
std::string key(cKey);
UniValue uVal(strVal);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, uint64_t u64Val)
{
std::string key(cKey);
UniValue uVal(u64Val);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, int64_t i64Val)
{
std::string key(cKey);
UniValue uVal(i64Val);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, bool iVal)
{
std::string key(cKey);
UniValue uVal(iVal);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, int iVal)
{
std::string key(cKey);
UniValue uVal(iVal);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, double dVal)
{
std::string key(cKey);
UniValue uVal(dVal);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(const char *cKey, const UniValue& uVal)
{
std::string key(cKey);
return std::make_pair(key, uVal);
}
static inline std::pair<std::string,UniValue> Pair(std::string key, const UniValue& uVal)
{
return std::make_pair(key, uVal);
}
enum jtokentype { enum jtokentype {
JTOK_ERR = -1, JTOK_ERR = -1,
JTOK_NONE = 0, // eof JTOK_NONE = 0, // eof

View File

@ -11,7 +11,6 @@
#include <vector> #include <vector>
#include <limits> #include <limits>
#include <string> #include <string>
#include <sstream>
#include "univalue.h" #include "univalue.h"
@ -36,7 +35,7 @@ bool ParseInt32(const std::string& str, int32_t *out)
errno = 0; // strtol will not set errno if valid errno = 0; // strtol will not set errno if valid
long int n = strtol(str.c_str(), &endp, 10); long int n = strtol(str.c_str(), &endp, 10);
if(out) *out = (int32_t)n; if(out) *out = (int32_t)n;
// Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow // Note that strtol returns a *long int*, so even if strtol doesn't report an over/underflow
// we still have to check that the returned value is within the range of an *int32_t*. On 64-bit // 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. // platforms the size of these types may be different.
return endp && *endp == 0 && !errno && return endp && *endp == 0 && !errno &&

View File

@ -273,7 +273,7 @@ bool UniValue::read(const char *raw, size_t size)
tok = getJsonToken(tokenVal, consumed, raw, end); tok = getJsonToken(tokenVal, consumed, raw, end);
if (tok == JTOK_NONE || tok == JTOK_ERR) if (tok == JTOK_NONE || tok == JTOK_ERR)
goto return_fail; return false;
raw += consumed; raw += consumed;
bool isValueOpen = jsonTokenIsValue(tok) || bool isValueOpen = jsonTokenIsValue(tok) ||
@ -281,33 +281,33 @@ bool UniValue::read(const char *raw, size_t size)
if (expect(VALUE)) { if (expect(VALUE)) {
if (!isValueOpen) if (!isValueOpen)
goto return_fail; return false;
clearExpect(VALUE); clearExpect(VALUE);
} else if (expect(ARR_VALUE)) { } else if (expect(ARR_VALUE)) {
bool isArrValue = isValueOpen || (tok == JTOK_ARR_CLOSE); bool isArrValue = isValueOpen || (tok == JTOK_ARR_CLOSE);
if (!isArrValue) if (!isArrValue)
goto return_fail; return false;
clearExpect(ARR_VALUE); clearExpect(ARR_VALUE);
} else if (expect(OBJ_NAME)) { } else if (expect(OBJ_NAME)) {
bool isObjName = (tok == JTOK_OBJ_CLOSE || tok == JTOK_STRING); bool isObjName = (tok == JTOK_OBJ_CLOSE || tok == JTOK_STRING);
if (!isObjName) if (!isObjName)
goto return_fail; return false;
} else if (expect(COLON)) { } else if (expect(COLON)) {
if (tok != JTOK_COLON) if (tok != JTOK_COLON)
goto return_fail; return false;
clearExpect(COLON); clearExpect(COLON);
} else if (!expect(COLON) && (tok == JTOK_COLON)) { } else if (!expect(COLON) && (tok == JTOK_COLON)) {
goto return_fail; return false;
} }
if (expect(NOT_VALUE)) { if (expect(NOT_VALUE)) {
if (isValueOpen) if (isValueOpen)
goto return_fail; return false;
clearExpect(NOT_VALUE); clearExpect(NOT_VALUE);
} }
@ -332,7 +332,7 @@ bool UniValue::read(const char *raw, size_t size)
} }
if (stack.size() > MAX_JSON_DEPTH) if (stack.size() > MAX_JSON_DEPTH)
goto return_fail; return false;
if (utyp == VOBJ) if (utyp == VOBJ)
setExpect(OBJ_NAME); setExpect(OBJ_NAME);
@ -344,12 +344,12 @@ bool UniValue::read(const char *raw, size_t size)
case JTOK_OBJ_CLOSE: case JTOK_OBJ_CLOSE:
case JTOK_ARR_CLOSE: { case JTOK_ARR_CLOSE: {
if (!stack.size() || (last_tok == JTOK_COMMA)) if (!stack.size() || (last_tok == JTOK_COMMA))
goto return_fail; return false;
VType utyp = (tok == JTOK_OBJ_CLOSE ? VOBJ : VARR); VType utyp = (tok == JTOK_OBJ_CLOSE ? VOBJ : VARR);
UniValue *top = stack.back(); UniValue *top = stack.back();
if (utyp != top->getType()) if (utyp != top->getType())
goto return_fail; return false;
stack.pop_back(); stack.pop_back();
clearExpect(OBJ_NAME); clearExpect(OBJ_NAME);
@ -359,11 +359,11 @@ bool UniValue::read(const char *raw, size_t size)
case JTOK_COLON: { case JTOK_COLON: {
if (!stack.size()) if (!stack.size())
goto return_fail; return false;
UniValue *top = stack.back(); UniValue *top = stack.back();
if (top->getType() != VOBJ) if (top->getType() != VOBJ)
goto return_fail; return false;
setExpect(VALUE); setExpect(VALUE);
break; break;
@ -372,7 +372,7 @@ bool UniValue::read(const char *raw, size_t size)
case JTOK_COMMA: { case JTOK_COMMA: {
if (!stack.size() || if (!stack.size() ||
(last_tok == JTOK_COMMA) || (last_tok == JTOK_ARR_OPEN)) (last_tok == JTOK_COMMA) || (last_tok == JTOK_ARR_OPEN))
goto return_fail; return false;
UniValue *top = stack.back(); UniValue *top = stack.back();
if (top->getType() == VOBJ) if (top->getType() == VOBJ)
@ -446,19 +446,15 @@ bool UniValue::read(const char *raw, size_t size)
} }
default: default:
goto return_fail; return false;
} }
} while (!stack.empty ()); } while (!stack.empty ());
/* Check that nothing follows the initial construct (parsed above). */ /* Check that nothing follows the initial construct (parsed above). */
tok = getJsonToken(tokenVal, consumed, raw, end); tok = getJsonToken(tokenVal, consumed, raw, end);
if (tok != JTOK_NONE) if (tok != JTOK_NONE)
goto return_fail; return false;
return true; return true;
return_fail:
clear();
return false;
} }

View File

@ -3,6 +3,7 @@
// file COPYING or https://opensource.org/licenses/mit-license.php. // file COPYING or https://opensource.org/licenses/mit-license.php.
#include <iomanip> #include <iomanip>
#include <sstream>
#include <stdio.h> #include <stdio.h>
#include "univalue.h" #include "univalue.h"
#include "univalue_escapes.h" #include "univalue_escapes.h"

View File

@ -142,8 +142,6 @@ BOOST_AUTO_TEST_CASE(univalue_set)
BOOST_CHECK(v.isArray()); BOOST_CHECK(v.isArray());
BOOST_CHECK_EQUAL(v.size(), 0); BOOST_CHECK_EQUAL(v.size(), 0);
BOOST_CHECK(v.setStr(""));
v.reserve(3);
BOOST_CHECK(v.setStr("zum")); BOOST_CHECK(v.setStr("zum"));
BOOST_CHECK(v.isStr()); BOOST_CHECK(v.isStr());
BOOST_CHECK_EQUAL(v.getValStr(), "zum"); BOOST_CHECK_EQUAL(v.getValStr(), "zum");
@ -189,7 +187,6 @@ BOOST_AUTO_TEST_CASE(univalue_set)
BOOST_AUTO_TEST_CASE(univalue_array) BOOST_AUTO_TEST_CASE(univalue_array)
{ {
UniValue arr(UniValue::VARR); UniValue arr(UniValue::VARR);
arr.reserve(9);
UniValue v((int64_t)1023LL); UniValue v((int64_t)1023LL);
BOOST_CHECK(arr.push_back(v)); BOOST_CHECK(arr.push_back(v));
@ -213,19 +210,31 @@ BOOST_AUTO_TEST_CASE(univalue_array)
BOOST_CHECK(arr.push_back((int64_t) -400LL)); BOOST_CHECK(arr.push_back((int64_t) -400LL));
BOOST_CHECK(arr.push_back((int) -401)); BOOST_CHECK(arr.push_back((int) -401));
BOOST_CHECK(arr.push_back(-40.1)); BOOST_CHECK(arr.push_back(-40.1));
BOOST_CHECK(arr.push_back(true));
BOOST_CHECK_EQUAL(arr.empty(), false); BOOST_CHECK_EQUAL(arr.empty(), false);
BOOST_CHECK_EQUAL(arr.size(), 9); BOOST_CHECK_EQUAL(arr.size(), 10);
BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023"); BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023");
BOOST_CHECK_EQUAL(arr[0].getType(), UniValue::VNUM);
BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy"); BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy");
BOOST_CHECK_EQUAL(arr[1].getType(), UniValue::VSTR);
BOOST_CHECK_EQUAL(arr[2].getValStr(), "pippy"); BOOST_CHECK_EQUAL(arr[2].getValStr(), "pippy");
BOOST_CHECK_EQUAL(arr[2].getType(), UniValue::VSTR);
BOOST_CHECK_EQUAL(arr[3].getValStr(), "boing"); BOOST_CHECK_EQUAL(arr[3].getValStr(), "boing");
BOOST_CHECK_EQUAL(arr[3].getType(), UniValue::VSTR);
BOOST_CHECK_EQUAL(arr[4].getValStr(), "going"); BOOST_CHECK_EQUAL(arr[4].getValStr(), "going");
BOOST_CHECK_EQUAL(arr[4].getType(), UniValue::VSTR);
BOOST_CHECK_EQUAL(arr[5].getValStr(), "400"); BOOST_CHECK_EQUAL(arr[5].getValStr(), "400");
BOOST_CHECK_EQUAL(arr[5].getType(), UniValue::VNUM);
BOOST_CHECK_EQUAL(arr[6].getValStr(), "-400"); BOOST_CHECK_EQUAL(arr[6].getValStr(), "-400");
BOOST_CHECK_EQUAL(arr[6].getType(), UniValue::VNUM);
BOOST_CHECK_EQUAL(arr[7].getValStr(), "-401"); BOOST_CHECK_EQUAL(arr[7].getValStr(), "-401");
BOOST_CHECK_EQUAL(arr[7].getType(), UniValue::VNUM);
BOOST_CHECK_EQUAL(arr[8].getValStr(), "-40.1"); BOOST_CHECK_EQUAL(arr[8].getValStr(), "-40.1");
BOOST_CHECK_EQUAL(arr[8].getType(), UniValue::VNUM);
BOOST_CHECK_EQUAL(arr[9].getValStr(), "1");
BOOST_CHECK_EQUAL(arr[9].getType(), UniValue::VBOOL);
BOOST_CHECK_EQUAL(arr[999].getValStr(), ""); BOOST_CHECK_EQUAL(arr[999].getValStr(), "");
@ -240,8 +249,6 @@ BOOST_AUTO_TEST_CASE(univalue_object)
std::string strKey, strVal; std::string strKey, strVal;
UniValue v; UniValue v;
obj.reserve(11);
strKey = "age"; strKey = "age";
v.setInt(100); v.setInt(100);
BOOST_CHECK(obj.pushKV(strKey, v)); BOOST_CHECK(obj.pushKV(strKey, v));