aboutsummaryrefslogtreecommitdiff
path: root/src/univalue/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/univalue/lib')
-rw-r--r--src/univalue/lib/univalue.cpp81
-rw-r--r--src/univalue/lib/univalue_escapes.h262
-rw-r--r--src/univalue/lib/univalue_get.cpp89
-rw-r--r--src/univalue/lib/univalue_read.cpp13
-rw-r--r--src/univalue/lib/univalue_utffilter.h119
-rw-r--r--src/univalue/lib/univalue_write.cpp10
6 files changed, 69 insertions, 505 deletions
diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp
index c4e59fae74..55e777b8ae 100644
--- a/src/univalue/lib/univalue.cpp
+++ b/src/univalue/lib/univalue.cpp
@@ -3,12 +3,15 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
-#include <stdint.h>
+#include <univalue.h>
+
#include <iomanip>
+#include <map>
+#include <memory>
#include <sstream>
-#include <stdlib.h>
-
-#include "univalue.h"
+#include <string>
+#include <utility>
+#include <vector>
const UniValue NullUniValue;
@@ -20,19 +23,17 @@ void UniValue::clear()
values.clear();
}
-bool UniValue::setNull()
+void UniValue::setNull()
{
clear();
- return true;
}
-bool UniValue::setBool(bool val_)
+void UniValue::setBool(bool val_)
{
clear();
typ = VBOOL;
if (val_)
val = "1";
- return true;
}
static bool validNumStr(const std::string& s)
@@ -43,18 +44,18 @@ static bool validNumStr(const std::string& s)
return (tt == JTOK_NUMBER);
}
-bool UniValue::setNumStr(const std::string& val_)
+void UniValue::setNumStr(const std::string& val_)
{
- if (!validNumStr(val_))
- return false;
+ if (!validNumStr(val_)) {
+ throw std::runtime_error{"The string '" + val_ + "' is not a valid JSON number"};
+ }
clear();
typ = VNUM;
val = val_;
- return true;
}
-bool UniValue::setInt(uint64_t val_)
+void UniValue::setInt(uint64_t val_)
{
std::ostringstream oss;
@@ -63,7 +64,7 @@ bool UniValue::setInt(uint64_t val_)
return setNumStr(oss.str());
}
-bool UniValue::setInt(int64_t val_)
+void UniValue::setInt(int64_t val_)
{
std::ostringstream oss;
@@ -72,86 +73,74 @@ bool UniValue::setInt(int64_t val_)
return setNumStr(oss.str());
}
-bool UniValue::setFloat(double val_)
+void UniValue::setFloat(double val_)
{
std::ostringstream oss;
oss << std::setprecision(16) << val_;
- bool ret = setNumStr(oss.str());
- typ = VNUM;
- return ret;
+ return setNumStr(oss.str());
}
-bool UniValue::setStr(const std::string& val_)
+void UniValue::setStr(const std::string& val_)
{
clear();
typ = VSTR;
val = val_;
- return true;
}
-bool UniValue::setArray()
+void UniValue::setArray()
{
clear();
typ = VARR;
- return true;
}
-bool UniValue::setObject()
+void UniValue::setObject()
{
clear();
typ = VOBJ;
- return true;
}
-bool UniValue::push_back(const UniValue& val_)
+void UniValue::push_back(const UniValue& val_)
{
- if (typ != VARR)
- return false;
+ checkType(VARR);
values.push_back(val_);
- return true;
}
-bool UniValue::push_backV(const std::vector<UniValue>& vec)
+void UniValue::push_backV(const std::vector<UniValue>& vec)
{
- if (typ != VARR)
- return false;
+ checkType(VARR);
values.insert(values.end(), vec.begin(), vec.end());
-
- return true;
}
void UniValue::__pushKV(const std::string& key, const UniValue& val_)
{
+ checkType(VOBJ);
+
keys.push_back(key);
values.push_back(val_);
}
-bool UniValue::pushKV(const std::string& key, const UniValue& val_)
+void UniValue::pushKV(const std::string& key, const UniValue& val_)
{
- if (typ != VOBJ)
- return false;
+ checkType(VOBJ);
size_t idx;
if (findKey(key, idx))
values[idx] = val_;
else
__pushKV(key, val_);
- return true;
}
-bool UniValue::pushKVs(const UniValue& obj)
+void UniValue::pushKVs(const UniValue& obj)
{
- if (typ != VOBJ || obj.typ != VOBJ)
- return false;
+ checkType(VOBJ);
+ obj.checkType(VOBJ);
for (size_t i = 0; i < obj.keys.size(); i++)
__pushKV(obj.keys[i], obj.values.at(i));
-
- return true;
}
void UniValue::getObjMap(std::map<std::string,UniValue>& kv) const
@@ -218,6 +207,14 @@ const UniValue& UniValue::operator[](size_t index) const
return values.at(index);
}
+void UniValue::checkType(const VType& expected) const
+{
+ if (typ != expected) {
+ throw std::runtime_error{"JSON value of type " + std::string{uvTypeName(typ)} + " is not of expected type " +
+ std::string{uvTypeName(expected)}};
+ }
+}
+
const char *uvTypeName(UniValue::VType t)
{
switch (t) {
diff --git a/src/univalue/lib/univalue_escapes.h b/src/univalue/lib/univalue_escapes.h
deleted file mode 100644
index 3f714f8e5b..0000000000
--- a/src/univalue/lib/univalue_escapes.h
+++ /dev/null
@@ -1,262 +0,0 @@
-// Automatically generated file. Do not modify.
-#ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H
-#define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H
-static const char *escapes[256] = {
- "\\u0000",
- "\\u0001",
- "\\u0002",
- "\\u0003",
- "\\u0004",
- "\\u0005",
- "\\u0006",
- "\\u0007",
- "\\b",
- "\\t",
- "\\n",
- "\\u000b",
- "\\f",
- "\\r",
- "\\u000e",
- "\\u000f",
- "\\u0010",
- "\\u0011",
- "\\u0012",
- "\\u0013",
- "\\u0014",
- "\\u0015",
- "\\u0016",
- "\\u0017",
- "\\u0018",
- "\\u0019",
- "\\u001a",
- "\\u001b",
- "\\u001c",
- "\\u001d",
- "\\u001e",
- "\\u001f",
- nullptr,
- nullptr,
- "\\\"",
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- "\\\\",
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- "\\u007f",
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
-};
-#endif // BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H
diff --git a/src/univalue/lib/univalue_get.cpp b/src/univalue/lib/univalue_get.cpp
index 5af89a3561..5c58f388dd 100644
--- a/src/univalue/lib/univalue_get.cpp
+++ b/src/univalue/lib/univalue_get.cpp
@@ -3,17 +3,18 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
-#include <stdint.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdexcept>
-#include <vector>
+#include <univalue.h>
+
+#include <cerrno>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
#include <limits>
-#include <string>
+#include <locale>
#include <sstream>
-
-#include "univalue.h"
+#include <stdexcept>
+#include <string>
+#include <vector>
namespace
{
@@ -28,37 +29,6 @@ static bool ParsePrechecks(const std::string& str)
return true;
}
-bool ParseInt32(const std::string& str, int32_t *out)
-{
- if (!ParsePrechecks(str))
- return false;
- char *endp = nullptr;
- errno = 0; // strtol will not set errno if valid
- long int n = strtol(str.c_str(), &endp, 10);
- if(out) *out = (int32_t)n;
- // 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
- // platforms the size of these types may be different.
- return endp && *endp == 0 && !errno &&
- n >= std::numeric_limits<int32_t>::min() &&
- n <= std::numeric_limits<int32_t>::max();
-}
-
-bool ParseInt64(const std::string& str, int64_t *out)
-{
- if (!ParsePrechecks(str))
- return false;
- char *endp = nullptr;
- 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<int64_t>::min() &&
- n <= std::numeric_limits<int64_t>::max();
-}
-
bool ParseDouble(const std::string& str, double *out)
{
if (!ParsePrechecks(str))
@@ -76,8 +46,7 @@ bool ParseDouble(const std::string& str, double *out)
const std::vector<std::string>& UniValue::getKeys() const
{
- if (typ != VOBJ)
- throw std::runtime_error("JSON value is not an object as expected");
+ checkType(VOBJ);
return keys;
}
@@ -90,42 +59,19 @@ const std::vector<UniValue>& UniValue::getValues() const
bool UniValue::get_bool() const
{
- if (typ != VBOOL)
- throw std::runtime_error("JSON value is not a boolean as expected");
+ checkType(VBOOL);
return getBool();
}
const std::string& UniValue::get_str() const
{
- if (typ != VSTR)
- throw std::runtime_error("JSON value is not a string as expected");
+ checkType(VSTR);
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 != VNUM)
- throw std::runtime_error("JSON value is not a number as expected");
+ checkType(VNUM);
double retval;
if (!ParseDouble(getValStr(), &retval))
throw std::runtime_error("JSON double out of range");
@@ -134,15 +80,12 @@ double UniValue::get_real() const
const UniValue& UniValue::get_obj() const
{
- if (typ != VOBJ)
- throw std::runtime_error("JSON value is not an object as expected");
+ checkType(VOBJ);
return *this;
}
const UniValue& UniValue::get_array() const
{
- if (typ != VARR)
- throw std::runtime_error("JSON value is not an array as expected");
+ checkType(VARR);
return *this;
}
-
diff --git a/src/univalue/lib/univalue_read.cpp b/src/univalue/lib/univalue_read.cpp
index be39bfe57a..2f2385383c 100644
--- a/src/univalue/lib/univalue_read.cpp
+++ b/src/univalue/lib/univalue_read.cpp
@@ -2,11 +2,14 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
-#include <string.h>
+#include <univalue.h>
+#include <univalue_utffilter.h>
+
+#include <cstdio>
+#include <cstdint>
+#include <cstring>
+#include <string>
#include <vector>
-#include <stdio.h>
-#include "univalue.h"
-#include "univalue_utffilter.h"
/*
* According to stackexchange, the original json test suite wanted
@@ -14,7 +17,7 @@
* so we will follow PHP's lead, which should be more than sufficient
* (further stackexchange comments indicate depth > 32 rarely occurs).
*/
-static const size_t MAX_JSON_DEPTH = 512;
+static constexpr size_t MAX_JSON_DEPTH = 512;
static bool json_isdigit(int ch)
{
diff --git a/src/univalue/lib/univalue_utffilter.h b/src/univalue/lib/univalue_utffilter.h
deleted file mode 100644
index c24ac58eaf..0000000000
--- a/src/univalue/lib/univalue_utffilter.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2016 Wladimir J. van der Laan
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or https://opensource.org/licenses/mit-license.php.
-#ifndef UNIVALUE_UTFFILTER_H
-#define UNIVALUE_UTFFILTER_H
-
-#include <string>
-
-/**
- * Filter that generates and validates UTF-8, as well as collates UTF-16
- * surrogate pairs as specified in RFC4627.
- */
-class JSONUTF8StringFilter
-{
-public:
- explicit JSONUTF8StringFilter(std::string &s):
- str(s), is_valid(true), codepoint(0), state(0), surpair(0)
- {
- }
- // Write single 8-bit char (may be part of UTF-8 sequence)
- void push_back(unsigned char ch)
- {
- if (state == 0) {
- if (ch < 0x80) // 7-bit ASCII, fast direct pass-through
- str.push_back(ch);
- else if (ch < 0xc0) // Mid-sequence character, invalid in this state
- is_valid = false;
- else if (ch < 0xe0) { // Start of 2-byte sequence
- codepoint = (ch & 0x1f) << 6;
- state = 6;
- } else if (ch < 0xf0) { // Start of 3-byte sequence
- codepoint = (ch & 0x0f) << 12;
- state = 12;
- } else if (ch < 0xf8) { // Start of 4-byte sequence
- codepoint = (ch & 0x07) << 18;
- state = 18;
- } else // Reserved, invalid
- is_valid = false;
- } else {
- if ((ch & 0xc0) != 0x80) // Not a continuation, invalid
- is_valid = false;
- state -= 6;
- codepoint |= (ch & 0x3f) << state;
- if (state == 0)
- push_back_u(codepoint);
- }
- }
- // Write codepoint directly, possibly collating surrogate pairs
- void push_back_u(unsigned int codepoint_)
- {
- if (state) // Only accept full codepoints in open state
- is_valid = false;
- if (codepoint_ >= 0xD800 && codepoint_ < 0xDC00) { // First half of surrogate pair
- if (surpair) // Two subsequent surrogate pair openers - fail
- is_valid = false;
- else
- surpair = codepoint_;
- } else if (codepoint_ >= 0xDC00 && codepoint_ < 0xE000) { // Second half of surrogate pair
- if (surpair) { // Open surrogate pair, expect second half
- // Compute code point from UTF-16 surrogate pair
- append_codepoint(0x10000 | ((surpair - 0xD800)<<10) | (codepoint_ - 0xDC00));
- surpair = 0;
- } else // Second half doesn't follow a first half - fail
- is_valid = false;
- } else {
- if (surpair) // First half of surrogate pair not followed by second - fail
- is_valid = false;
- else
- append_codepoint(codepoint_);
- }
- }
- // Check that we're in a state where the string can be ended
- // No open sequences, no open surrogate pairs, etc
- bool finalize()
- {
- if (state || surpair)
- is_valid = false;
- return is_valid;
- }
-private:
- std::string &str;
- bool is_valid;
- // Current UTF-8 decoding state
- unsigned int codepoint;
- int state; // Top bit to be filled in for next UTF-8 byte, or 0
-
- // Keep track of the following state to handle the following section of
- // RFC4627:
- //
- // To escape an extended character that is not in the Basic Multilingual
- // Plane, the character is represented as a twelve-character sequence,
- // encoding the UTF-16 surrogate pair. So, for example, a string
- // containing only the G clef character (U+1D11E) may be represented as
- // "\uD834\uDD1E".
- //
- // Two subsequent \u.... may have to be replaced with one actual codepoint.
- unsigned int surpair; // First half of open UTF-16 surrogate pair, or 0
-
- void append_codepoint(unsigned int codepoint_)
- {
- if (codepoint_ <= 0x7f)
- str.push_back((char)codepoint_);
- else if (codepoint_ <= 0x7FF) {
- str.push_back((char)(0xC0 | (codepoint_ >> 6)));
- str.push_back((char)(0x80 | (codepoint_ & 0x3F)));
- } else if (codepoint_ <= 0xFFFF) {
- str.push_back((char)(0xE0 | (codepoint_ >> 12)));
- str.push_back((char)(0x80 | ((codepoint_ >> 6) & 0x3F)));
- str.push_back((char)(0x80 | (codepoint_ & 0x3F)));
- } else if (codepoint_ <= 0x1FFFFF) {
- str.push_back((char)(0xF0 | (codepoint_ >> 18)));
- str.push_back((char)(0x80 | ((codepoint_ >> 12) & 0x3F)));
- str.push_back((char)(0x80 | ((codepoint_ >> 6) & 0x3F)));
- str.push_back((char)(0x80 | (codepoint_ & 0x3F)));
- }
- }
-};
-
-#endif
diff --git a/src/univalue/lib/univalue_write.cpp b/src/univalue/lib/univalue_write.cpp
index 3a2c580c7f..4a3cbba20f 100644
--- a/src/univalue/lib/univalue_write.cpp
+++ b/src/univalue/lib/univalue_write.cpp
@@ -2,10 +2,12 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://opensource.org/licenses/mit-license.php.
-#include <iomanip>
-#include <stdio.h>
-#include "univalue.h"
-#include "univalue_escapes.h"
+#include <univalue.h>
+#include <univalue_escapes.h>
+
+#include <memory>
+#include <string>
+#include <vector>
static std::string json_escape(const std::string& inS)
{