Skip to content
This repository was archived by the owner on Jun 17, 2022. It is now read-only.

Commit 6c19d05

Browse files
committed
Merge #33: Add getInt<Integral>() helper
09e4a93 Add getInt helper (MarcoFalke) Pull request description: It is confusing to offer a sanitizing `int` and `int64` getter, but leave out all other int types. Top commit has no ACKs. Tree-SHA512: 50a51442549d2c366a05d03b4b8bf9a8866bd2b253a8f9ed5e72d0f6570538a5c07d16df9300d9ccd490143493607631286df20ae07c82863b33f2814812f16b
2 parents 10619e0 + 09e4a93 commit 6c19d05

File tree

3 files changed

+21
-55
lines changed

3 files changed

+21
-55
lines changed

configure.ac

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ AC_SUBST(LIBUNIVALUE_AGE)
4545
LT_INIT
4646
LT_LANG([C++])
4747

48-
dnl Require C++11 compiler (no GNU extensions)
49-
AX_CXX_COMPILE_STDCXX([11], [noext], [mandatory], [nodefault])
48+
dnl Require C++17 compiler (no GNU extensions)
49+
AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory], [nodefault])
5050

5151
case $host in
5252
*mingw*)

include/univalue.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
#ifndef __UNIVALUE_H__
77
#define __UNIVALUE_H__
88

9+
#include <charconv>
910
#include <cstdint>
1011
#include <cstring>
1112
#include <map>
13+
#include <stdexcept>
1214
#include <string>
15+
#include <type_traits>
1316
#include <vector>
1417

1518
class UniValue {
@@ -166,10 +169,24 @@ class UniValue {
166169
// value is of unexpected type
167170
const std::vector<std::string>& getKeys() const;
168171
const std::vector<UniValue>& getValues() const;
172+
template <typename Int>
173+
auto getInt() const
174+
{
175+
static_assert(std::is_integral<Int>::value);
176+
if (typ != VNUM) {
177+
throw std::runtime_error("JSON value is not an integer as expected");
178+
}
179+
Int result;
180+
const auto [first_nonmatching, error_condition] = std::from_chars(val.data(), val.data() + val.size(), result);
181+
if (first_nonmatching != val.data() + val.size() || error_condition != std::errc{}) {
182+
throw std::runtime_error("JSON integer out of range");
183+
}
184+
return result;
185+
}
169186
bool get_bool() const;
170187
const std::string& get_str() const;
171-
int get_int() const;
172-
int64_t get_int64() const;
188+
auto get_int() const { return getInt<int>(); };
189+
auto get_int64() const { return getInt<int64_t>(); };
173190
double get_real() const;
174191
const UniValue& get_obj() const;
175192
const UniValue& get_array() const;

lib/univalue_get.cpp

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -29,37 +29,6 @@ static bool ParsePrechecks(const std::string& str)
2929
return true;
3030
}
3131

32-
bool ParseInt32(const std::string& str, int32_t *out)
33-
{
34-
if (!ParsePrechecks(str))
35-
return false;
36-
char *endp = nullptr;
37-
errno = 0; // strtol will not set errno if valid
38-
long int n = strtol(str.c_str(), &endp, 10);
39-
if(out) *out = (int32_t)n;
40-
// Note that strtol returns a *long int*, so even if strtol doesn't report an over/underflow
41-
// we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
42-
// platforms the size of these types may be different.
43-
return endp && *endp == 0 && !errno &&
44-
n >= std::numeric_limits<int32_t>::min() &&
45-
n <= std::numeric_limits<int32_t>::max();
46-
}
47-
48-
bool ParseInt64(const std::string& str, int64_t *out)
49-
{
50-
if (!ParsePrechecks(str))
51-
return false;
52-
char *endp = nullptr;
53-
errno = 0; // strtoll will not set errno if valid
54-
long long int n = strtoll(str.c_str(), &endp, 10);
55-
if(out) *out = (int64_t)n;
56-
// Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
57-
// we still have to check that the returned value is within the range of an *int64_t*.
58-
return endp && *endp == 0 && !errno &&
59-
n >= std::numeric_limits<int64_t>::min() &&
60-
n <= std::numeric_limits<int64_t>::max();
61-
}
62-
6332
bool ParseDouble(const std::string& str, double *out)
6433
{
6534
if (!ParsePrechecks(str))
@@ -103,26 +72,6 @@ const std::string& UniValue::get_str() const
10372
return getValStr();
10473
}
10574

106-
int UniValue::get_int() const
107-
{
108-
if (typ != VNUM)
109-
throw std::runtime_error("JSON value is not an integer as expected");
110-
int32_t retval;
111-
if (!ParseInt32(getValStr(), &retval))
112-
throw std::runtime_error("JSON integer out of range");
113-
return retval;
114-
}
115-
116-
int64_t UniValue::get_int64() const
117-
{
118-
if (typ != VNUM)
119-
throw std::runtime_error("JSON value is not an integer as expected");
120-
int64_t retval;
121-
if (!ParseInt64(getValStr(), &retval))
122-
throw std::runtime_error("JSON integer out of range");
123-
return retval;
124-
}
125-
12675
double UniValue::get_real() const
12776
{
12877
if (typ != VNUM)

0 commit comments

Comments
 (0)