Bitcoin Core 31.99.0
P2P Digital Currency
univalue.h
Go to the documentation of this file.
1// Copyright 2014 BitPay Inc.
2// Copyright (c) 2015-present The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or https://opensource.org/licenses/mit-license.php.
5
6#ifndef BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
7#define BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
8
9#include <charconv>
10#include <cstddef>
11#include <cstdint>
12#include <map>
13#include <stdexcept>
14#include <string>
15#include <string_view>
16#include <system_error>
17#include <type_traits>
18#include <utility>
19#include <vector>
20
21// NOLINTNEXTLINE(misc-no-recursion)
22class UniValue {
23public:
24 enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
25
26 class type_error : public std::runtime_error
27 {
28 using std::runtime_error::runtime_error;
29 };
30
32 UniValue(UniValue::VType type, std::string str = {}) : typ{type}, val{std::move(str)} {}
33 template <typename Ref, typename T = std::remove_cv_t<std::remove_reference_t<Ref>>,
34 std::enable_if_t<std::is_floating_point_v<T> || // setFloat
35 std::is_same_v<bool, T> || // setBool
36 std::is_signed_v<T> || std::is_unsigned_v<T> || // setInt
37 std::is_constructible_v<std::string, T>, // setStr
38 bool> = true>
40 {
41 if constexpr (std::is_floating_point_v<T>) {
43 } else if constexpr (std::is_same_v<bool, T>) {
44 setBool(val);
45 } else if constexpr (std::is_signed_v<T>) {
46 setInt(int64_t{val});
47 } else if constexpr (std::is_unsigned_v<T>) {
48 setInt(uint64_t{val});
49 } else {
50 setStr(std::string{std::forward<Ref>(val)});
51 }
52 }
53
54 void clear();
55
56 void setNull();
57 void setBool(bool val);
58 void setNumStr(std::string str);
59 void setInt(uint64_t val);
60 void setInt(int64_t val);
61 void setInt(int val_) { return setInt(int64_t{val_}); }
62 void setFloat(double val);
63 void setStr(std::string str);
64 void setArray();
65 void setObject();
66
67 enum VType getType() const { return typ; }
68 const std::string& getValStr() const { return val; }
69 bool empty() const { return (values.size() == 0); }
70
71 size_t size() const { return values.size(); }
72
73 void reserve(size_t new_cap);
74
75 void getObjMap(std::map<std::string,UniValue>& kv) const;
76 bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes) const;
77 const UniValue& operator[](const std::string& key) const;
78 const UniValue& operator[](size_t index) const;
79 bool exists(const std::string& key) const { size_t i; return findKey(key, i); }
80
81 bool isNull() const { return (typ == VNULL); }
82 bool isTrue() const { return (typ == VBOOL) && (val == "1"); }
83 bool isFalse() const { return (typ == VBOOL) && (val != "1"); }
84 bool isBool() const { return (typ == VBOOL); }
85 bool isStr() const { return (typ == VSTR); }
86 bool isNum() const { return (typ == VNUM); }
87 bool isArray() const { return (typ == VARR); }
88 bool isObject() const { return (typ == VOBJ); }
89
91 void push_backV(const std::vector<UniValue>& vec);
92 template <class It>
93 void push_backV(It first, It last);
94
95 void pushKVEnd(std::string key, UniValue val);
96 void pushKV(std::string key, UniValue val);
97 void pushKVs(UniValue obj);
98
99 std::string write(unsigned int prettyIndent = 0,
100 unsigned int indentLevel = 0) const;
101
103 [[nodiscard]] bool read(std::string_view json);
104
105private:
107 std::string val; // numbers are stored as C++ strings
108 std::vector<std::string> keys;
109 std::vector<UniValue> values;
110
111 void checkType(const VType& expected) const;
112 bool findKey(const std::string& key, size_t& retIdx) const;
113 void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
114 void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
116 [[nodiscard]] bool read_impl(std::string_view str_in);
117
118public:
119 // Strict type-specific getters, these throw std::runtime_error if the
120 // value is of unexpected type
121 const std::vector<std::string>& getKeys() const;
122 const std::vector<UniValue>& getValues() const;
123 template <typename Int>
124 Int getInt() const;
125 bool get_bool() const;
126 const std::string& get_str() const;
127 double get_real() const;
128 const UniValue& get_obj() const;
129 const UniValue& get_array() const;
130
131 enum VType type() const { return getType(); }
132 const UniValue& find_value(std::string_view key) const;
133};
134
135template <class It>
136void UniValue::push_backV(It first, It last)
137{
139 values.insert(values.end(), first, last);
140}
141
142template <typename Int>
144{
145 static_assert(std::is_integral_v<Int>);
147 Int result;
148 const auto [first_nonmatching, error_condition] = std::from_chars(val.data(), val.data() + val.size(), result);
149 if (first_nonmatching != val.data() + val.size() || error_condition != std::errc{}) {
150 throw std::runtime_error("JSON integer out of range");
151 }
152 return result;
153}
154
157 JTOK_NONE = 0, // eof
169};
170
171extern enum jtokentype getJsonToken(std::string& tokenVal,
172 unsigned int& consumed, const char *raw, const char *end);
173extern const char *uvTypeName(UniValue::VType t);
174
175static inline bool jsonTokenIsValue(enum jtokentype jtt)
176{
177 switch (jtt) {
178 case JTOK_KW_NULL:
179 case JTOK_KW_TRUE:
180 case JTOK_KW_FALSE:
181 case JTOK_NUMBER:
182 case JTOK_STRING:
183 return true;
184
185 default:
186 return false;
187 }
188
189 // not reached
190}
191
192static inline bool json_isspace(int ch)
193{
194 switch (ch) {
195 case 0x20:
196 case 0x09:
197 case 0x0a:
198 case 0x0d:
199 return true;
200
201 default:
202 return false;
203 }
204
205 // not reached
206}
207
208extern const UniValue NullUniValue;
209
210#endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
void push_back(UniValue val)
Definition: univalue.cpp:103
UniValue::VType typ
Definition: univalue.h:106
const std::string & get_str() const
UniValue(UniValue::VType type, std::string str={})
Definition: univalue.h:32
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes) const
Definition: univalue.cpp:167
bool isTrue() const
Definition: univalue.h:82
bool isArray() const
Definition: univalue.h:87
const UniValue & find_value(std::string_view key) const
Definition: univalue.cpp:232
void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string &s) const
enum VType getType() const
Definition: univalue.h:67
@ VNULL
Definition: univalue.h:24
@ VOBJ
Definition: univalue.h:24
@ VSTR
Definition: univalue.h:24
@ VARR
Definition: univalue.h:24
@ VNUM
Definition: univalue.h:24
@ VBOOL
Definition: univalue.h:24
void setArray()
Definition: univalue.cpp:91
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
bool isNull() const
Definition: univalue.h:81
void clear()
Definition: univalue.cpp:17
const std::string & getValStr() const
Definition: univalue.h:68
const UniValue & get_obj() const
void setNull()
Definition: univalue.cpp:25
size_t size() const
Definition: univalue.h:71
UniValue(Ref &&val)
Definition: univalue.h:39
enum VType type() const
Definition: univalue.h:131
const std::vector< UniValue > & getValues() const
void pushKVs(UniValue obj)
Definition: univalue.cpp:136
bool read_impl(std::string_view str_in)
Internal parser: May leave this value in an invalid state on failure.
const std::vector< std::string > & getKeys() const
bool empty() const
Definition: univalue.h:69
void setInt(uint64_t val)
Definition: univalue.cpp:57
void setBool(bool val)
Definition: univalue.cpp:30
void setInt(int val_)
Definition: univalue.h:61
void pushKVEnd(std::string key, UniValue val)
Definition: univalue.cpp:117
std::vector< UniValue > values
Definition: univalue.h:109
std::vector< std::string > keys
Definition: univalue.h:108
void checkType(const VType &expected) const
Definition: univalue.cpp:209
bool findKey(const std::string &key, size_t &retIdx) const
Definition: univalue.cpp:155
bool isStr() const
Definition: univalue.h:85
void setObject()
Definition: univalue.cpp:97
bool read(std::string_view json)
Parse JSON; set value to null on failure.
bool isBool() const
Definition: univalue.h:84
const UniValue & operator[](const std::string &key) const
Definition: univalue.cpp:187
UniValue()
Definition: univalue.h:31
Int getInt() const
Definition: univalue.h:143
const UniValue & get_array() const
bool exists(const std::string &key) const
Definition: univalue.h:79
void setFloat(double val)
Definition: univalue.cpp:75
void reserve(size_t new_cap)
Definition: univalue.cpp:242
std::string val
Definition: univalue.h:107
bool isNum() const
Definition: univalue.h:86
void setStr(std::string str)
Definition: univalue.cpp:84
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:125
void setNumStr(std::string str)
Definition: univalue.cpp:46
void getObjMap(std::map< std::string, UniValue > &kv) const
Definition: univalue.cpp:145
void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string &s) const
double get_real() const
bool isFalse() const
Definition: univalue.h:83
bool get_bool() const
void push_backV(const std::vector< UniValue > &vec)
Definition: univalue.cpp:110
bool isObject() const
Definition: univalue.h:88
char const * json() noexcept
Template to generate JSON data.
enum jtokentype getJsonToken(std::string &tokenVal, unsigned int &consumed, const char *raw, const char *end)
static bool jsonTokenIsValue(enum jtokentype jtt)
Definition: univalue.h:175
static bool json_isspace(int ch)
Definition: univalue.h:192
jtokentype
Definition: univalue.h:155
@ JTOK_OBJ_CLOSE
Definition: univalue.h:159
@ JTOK_STRING
Definition: univalue.h:168
@ JTOK_COLON
Definition: univalue.h:162
@ JTOK_OBJ_OPEN
Definition: univalue.h:158
@ JTOK_NUMBER
Definition: univalue.h:167
@ JTOK_KW_NULL
Definition: univalue.h:164
@ JTOK_COMMA
Definition: univalue.h:163
@ JTOK_ARR_CLOSE
Definition: univalue.h:161
@ JTOK_KW_TRUE
Definition: univalue.h:165
@ JTOK_ARR_OPEN
Definition: univalue.h:160
@ JTOK_KW_FALSE
Definition: univalue.h:166
@ JTOK_ERR
Definition: univalue.h:156
@ JTOK_NONE
Definition: univalue.h:157
const UniValue NullUniValue
Definition: univalue.cpp:15
const char * uvTypeName(UniValue::VType t)
Definition: univalue.cpp:217