Bitcoin Core  31.0.0
P2P Digital Currency
univalue.h
Go to the documentation of this file.
1 // Copyright 2014 BitPay Inc.
2 // Copyright 2015 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)
22 class UniValue {
23 public:
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 
31  UniValue() { typ = VNULL; }
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>
39  UniValue(Ref&& val)
40  {
41  if constexpr (std::is_floating_point_v<T>) {
42  setFloat(val);
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 
90  void push_back(UniValue val);
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 
102  bool read(std::string_view raw);
103 
104 private:
106  std::string val; // numbers are stored as C++ strings
107  std::vector<std::string> keys;
108  std::vector<UniValue> values;
109 
110  void checkType(const VType& expected) const;
111  bool findKey(const std::string& key, size_t& retIdx) const;
112  void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
113  void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
114 
115 public:
116  // Strict type-specific getters, these throw std::runtime_error if the
117  // value is of unexpected type
118  const std::vector<std::string>& getKeys() const;
119  const std::vector<UniValue>& getValues() const;
120  template <typename Int>
121  Int getInt() const;
122  bool get_bool() const;
123  const std::string& get_str() const;
124  double get_real() const;
125  const UniValue& get_obj() const;
126  const UniValue& get_array() const;
127 
128  enum VType type() const { return getType(); }
129  const UniValue& find_value(std::string_view key) const;
130 };
131 
132 template <class It>
133 void UniValue::push_backV(It first, It last)
134 {
135  checkType(VARR);
136  values.insert(values.end(), first, last);
137 }
138 
139 template <typename Int>
140 Int UniValue::getInt() const
141 {
142  static_assert(std::is_integral_v<Int>);
143  checkType(VNUM);
144  Int result;
145  const auto [first_nonmatching, error_condition] = std::from_chars(val.data(), val.data() + val.size(), result);
146  if (first_nonmatching != val.data() + val.size() || error_condition != std::errc{}) {
147  throw std::runtime_error("JSON integer out of range");
148  }
149  return result;
150 }
151 
153  JTOK_ERR = -1,
154  JTOK_NONE = 0, // eof
166 };
167 
168 extern enum jtokentype getJsonToken(std::string& tokenVal,
169  unsigned int& consumed, const char *raw, const char *end);
170 extern const char *uvTypeName(UniValue::VType t);
171 
172 static inline bool jsonTokenIsValue(enum jtokentype jtt)
173 {
174  switch (jtt) {
175  case JTOK_KW_NULL:
176  case JTOK_KW_TRUE:
177  case JTOK_KW_FALSE:
178  case JTOK_NUMBER:
179  case JTOK_STRING:
180  return true;
181 
182  default:
183  return false;
184  }
185 
186  // not reached
187 }
188 
189 static inline bool json_isspace(int ch)
190 {
191  switch (ch) {
192  case 0x20:
193  case 0x09:
194  case 0x0a:
195  case 0x0d:
196  return true;
197 
198  default:
199  return false;
200  }
201 
202  // not reached
203 }
204 
205 extern const UniValue NullUniValue;
206 
207 #endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
bool isObject() const
Definition: univalue.h:88
void push_back(UniValue val)
Definition: univalue.cpp:103
static bool jsonTokenIsValue(enum jtokentype jtt)
Definition: univalue.h:172
bool isBool() const
Definition: univalue.h:84
const std::vector< UniValue > & getValues() const
void setBool(bool val)
Definition: univalue.cpp:30
bool get_bool() const
void setNull()
Definition: univalue.cpp:25
void pushKVs(UniValue obj)
Definition: univalue.cpp:136
bool read(std::string_view raw)
double get_real() const
bool findKey(const std::string &key, size_t &retIdx) const
Definition: univalue.cpp:155
const std::string & get_str() const
void pushKVEnd(std::string key, UniValue val)
Definition: univalue.cpp:117
enum VType getType() const
Definition: univalue.h:67
bool isNum() const
Definition: univalue.h:86
const UniValue & get_array() const
bool isStr() const
Definition: univalue.h:85
std::vector< UniValue > values
Definition: univalue.h:108
const std::vector< std::string > & getKeys() const
Int getInt() const
Definition: univalue.h:140
const std::string & getValStr() const
Definition: univalue.h:68
void setInt(int val_)
Definition: univalue.h:61
void reserve(size_t new_cap)
Definition: univalue.cpp:242
static bool json_isspace(int ch)
Definition: univalue.h:189
const UniValue & operator[](const std::string &key) const
Definition: univalue.cpp:187
const UniValue & find_value(std::string_view key) const
Definition: univalue.cpp:232
enum jtokentype getJsonToken(std::string &tokenVal, unsigned int &consumed, const char *raw, const char *end)
const char * uvTypeName(UniValue::VType t)
Definition: univalue.cpp:217
UniValue(UniValue::VType type, std::string str={})
Definition: univalue.h:32
UniValue(Ref &&val)
Definition: univalue.h:39
bool isFalse() const
Definition: univalue.h:83
void getObjMap(std::map< std::string, UniValue > &kv) const
Definition: univalue.cpp:145
bool exists(const std::string &key) const
Definition: univalue.h:79
UniValue()
Definition: univalue.h:31
bool empty() const
Definition: univalue.h:69
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
jtokentype
Definition: univalue.h:152
void push_backV(const std::vector< UniValue > &vec)
Definition: univalue.cpp:110
void setObject()
Definition: univalue.cpp:97
bool isNull() const
Definition: univalue.h:81
bool isTrue() const
Definition: univalue.h:82
std::string val
Definition: univalue.h:106
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes) const
Definition: univalue.cpp:167
UniValue::VType typ
Definition: univalue.h:105
enum VType type() const
Definition: univalue.h:128
void setNumStr(std::string str)
Definition: univalue.cpp:46
auto result
Definition: common-types.h:74
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:125
const UniValue & get_obj() const
void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string &s) const
std::vector< std::string > keys
Definition: univalue.h:107
const UniValue NullUniValue
Definition: univalue.cpp:15
void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string &s) const
void clear()
Definition: univalue.cpp:17
size_t size() const
Definition: univalue.h:71
void setArray()
Definition: univalue.cpp:91
void setFloat(double val)
Definition: univalue.cpp:75
void setInt(uint64_t val)
Definition: univalue.cpp:57
bool isArray() const
Definition: univalue.h:87
void setStr(std::string str)
Definition: univalue.cpp:84
void checkType(const VType &expected) const
Definition: univalue.cpp:209