Bitcoin ABC  0.26.3
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 namespace {
22 struct UniValueStreamWriter;
23 }
24 
25 class UniValue {
26  friend struct ::UniValueStreamWriter;
27 
28 public:
29  enum VType {
36  };
37 
38  class type_error : public std::runtime_error {
39  using std::runtime_error::runtime_error;
40  };
41 
42  UniValue() : typ(VNULL) {}
43  UniValue(UniValue::VType type, std::string str = {})
44  : typ(type), val(std::move(str)) {}
45  template <typename Ref,
46  typename T = std::remove_cv_t<std::remove_reference_t<Ref>>,
47  std::enable_if_t<
48  std::is_floating_point_v<T> || // setFloat
49  std::is_same_v<bool, T> || // setBool
50  std::is_signed_v<T> || std::is_unsigned_v<T> || // setInt
51  std::is_constructible_v<std::string, T>, // setStr
52  bool> = true>
53  UniValue(Ref &&val) {
54  if constexpr (std::is_floating_point_v<T>) {
55  setFloat(val);
56  } else if constexpr (std::is_same_v<bool, T>) {
57  setBool(val);
58  } else if constexpr (std::is_signed_v<T>) {
59  setInt(int64_t{val});
60  } else if constexpr (std::is_unsigned_v<T>) {
61  setInt(uint64_t{val});
62  } else {
63  setStr(std::string{std::forward<Ref>(val)});
64  }
65  }
66 
67  void clear();
68  void reserve(size_t n) {
69  if (typ == VOBJ || typ == VARR) {
70  if (typ == VOBJ) keys.reserve(n);
71  values.reserve(n);
72  } else if (typ != VNULL) {
73  val.reserve(n);
74  }
75  }
76 
77  void setNull();
78  void setBool(bool val);
79  void setNumStr(std::string str);
80  void setInt(uint64_t val);
81  void setInt(int64_t val);
82  void setInt(int val_) { return setInt(int64_t{val_}); }
83  void setFloat(double val);
84  void setStr(std::string str);
85  void setArray();
86  void setObject();
87 
88  enum VType getType() const { return typ; }
89  const std::string &getValStr() const { return val; }
90  bool empty() const { return (values.size() == 0); }
91 
92  size_t size() const { return values.size(); }
93 
94  void getObjMap(std::map<std::string, UniValue> &kv) const;
95  bool checkObject(
96  const std::map<std::string, UniValue::VType> &memberTypes) const;
97  const UniValue &operator[](const std::string &key) const;
98  const UniValue &operator[](size_t index) const;
99  bool exists(const std::string &key) const {
100  size_t i;
101  return findKey(key, i);
102  }
103 
104  bool isNull() const { return (typ == VNULL); }
105  bool isTrue() const { return (typ == VBOOL) && (val == "1"); }
106  bool isFalse() const { return (typ == VBOOL) && (val != "1"); }
107  bool isBool() const { return (typ == VBOOL); }
108  bool isStr() const { return (typ == VSTR); }
109  bool isNum() const { return (typ == VNUM); }
110  bool isArray() const { return (typ == VARR); }
111  bool isObject() const { return (typ == VOBJ); }
112 
113  void push_back(UniValue val);
114  void push_backV(const std::vector<UniValue> &vec);
115  template <class It> void push_backV(It first, It last);
116 
117  void pushKVEnd(std::string key, UniValue val);
118  void pushKV(std::string key, UniValue val);
119  void pushKVs(UniValue obj);
120 
121  std::string write(unsigned int prettyIndent = 0,
122  unsigned int indentLevel = 0) const;
123 
124  bool read(std::string_view raw);
125 
126 private:
128  std::string val; // numbers are stored as C++ strings
129  std::vector<std::string> keys;
130  std::vector<UniValue> values;
131 
132  void checkType(const VType &expected) const;
133  bool findKey(const std::string &key, size_t &retIdx) const;
134 
135 public:
136  // Strict type-specific getters, these throw std::runtime_error if the
137  // value is of unexpected type
138  const std::vector<std::string> &getKeys() const;
139  const std::vector<UniValue> &getValues() const;
140  template <typename Int> Int getInt() const;
141  bool get_bool() const;
142  const std::string &get_str() const;
143  double get_real() const;
144  const UniValue &get_obj() const;
145  const UniValue &get_array() const;
146 
147  enum VType type() const { return getType(); }
148 
149  const UniValue &find_value(std::string_view key) const;
150 };
151 
152 template <class It> void UniValue::push_backV(It first, It last) {
153  checkType(VARR);
154  values.insert(values.end(), first, last);
155 }
156 
157 template <typename Int> Int UniValue::getInt() const {
158  static_assert(std::is_integral<Int>::value);
159  checkType(VNUM);
160  Int result;
161  const auto [first_nonmatching, error_condition] =
162  std::from_chars(val.data(), val.data() + val.size(), result);
163  if (first_nonmatching != val.data() + val.size() ||
164  error_condition != std::errc{}) {
165  throw std::runtime_error("JSON integer out of range");
166  }
167  return result;
168 }
169 
171  JTOK_ERR = -1,
172  JTOK_NONE = 0, // eof
184 };
185 
186 extern enum jtokentype getJsonToken(std::string &tokenVal,
187  unsigned int &consumed, const char *raw,
188  const char *end);
189 extern const char *uvTypeName(UniValue::VType t);
190 
191 static inline bool jsonTokenIsValue(enum jtokentype jtt) {
192  switch (jtt) {
193  case JTOK_KW_NULL:
194  case JTOK_KW_TRUE:
195  case JTOK_KW_FALSE:
196  case JTOK_NUMBER:
197  case JTOK_STRING:
198  return true;
199 
200  default:
201  return false;
202  }
203 
204  // not reached
205 }
206 
207 static inline bool json_isspace(int ch) {
208  switch (ch) {
209  case 0x20:
210  case 0x09:
211  case 0x0a:
212  case 0x0d:
213  return true;
214 
215  default:
216  return false;
217  }
218 
219  // not reached
220 }
221 
222 extern const UniValue NullUniValue;
223 
224 #endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
void push_back(UniValue val)
Definition: univalue.cpp:96
UniValue::VType typ
Definition: univalue.h:127
const std::string & get_str() const
UniValue(UniValue::VType type, std::string str={})
Definition: univalue.h:43
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes) const
Definition: univalue.cpp:157
bool isTrue() const
Definition: univalue.h:105
bool isArray() const
Definition: univalue.h:110
const UniValue & find_value(std::string_view key) const
Definition: univalue.cpp:229
enum VType getType() const
Definition: univalue.h:88
@ VNULL
Definition: univalue.h:30
@ VOBJ
Definition: univalue.h:31
@ VSTR
Definition: univalue.h:33
@ VARR
Definition: univalue.h:32
@ VNUM
Definition: univalue.h:34
@ VBOOL
Definition: univalue.h:35
void setArray()
Definition: univalue.cpp:86
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
bool isNull() const
Definition: univalue.h:104
void clear()
Definition: univalue.cpp:18
const UniValue & get_obj() const
void setNull()
Definition: univalue.cpp:25
const std::string & getValStr() const
Definition: univalue.h:89
size_t size() const
Definition: univalue.h:92
UniValue(Ref &&val)
Definition: univalue.h:53
enum VType type() const
Definition: univalue.h:147
const std::vector< UniValue > & getValues() const
void pushKVs(UniValue obj)
Definition: univalue.cpp:126
const std::vector< std::string > & getKeys() const
bool empty() const
Definition: univalue.h:90
void setInt(uint64_t val)
Definition: univalue.cpp:56
void setBool(bool val)
Definition: univalue.cpp:29
void setInt(int val_)
Definition: univalue.h:82
void pushKVEnd(std::string key, UniValue val)
Definition: univalue.cpp:108
std::vector< UniValue > values
Definition: univalue.h:130
std::vector< std::string > keys
Definition: univalue.h:129
void checkType(const VType &expected) const
Definition: univalue.cpp:201
bool findKey(const std::string &key, size_t &retIdx) const
Definition: univalue.cpp:146
bool read(std::string_view raw)
bool isStr() const
Definition: univalue.h:108
void setObject()
Definition: univalue.cpp:91
bool isBool() const
Definition: univalue.h:107
const UniValue & operator[](const std::string &key) const
Definition: univalue.cpp:177
UniValue()
Definition: univalue.h:42
Int getInt() const
Definition: univalue.h:157
const UniValue & get_array() const
bool exists(const std::string &key) const
Definition: univalue.h:99
void setFloat(double val)
Definition: univalue.cpp:72
std::string val
Definition: univalue.h:128
void reserve(size_t n)
Definition: univalue.h:68
bool isNum() const
Definition: univalue.h:109
void setStr(std::string str)
Definition: univalue.cpp:80
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:115
void setNumStr(std::string str)
Definition: univalue.cpp:45
void getObjMap(std::map< std::string, UniValue > &kv) const
Definition: univalue.cpp:135
double get_real() const
bool isFalse() const
Definition: univalue.h:106
bool get_bool() const
void push_backV(const std::vector< UniValue > &vec)
Definition: univalue.cpp:102
bool isObject() const
Definition: univalue.h:111
enum jtokentype getJsonToken(std::string &tokenVal, unsigned int &consumed, const char *raw, const char *end)
static bool jsonTokenIsValue(enum jtokentype jtt)
Definition: univalue.h:191
static bool json_isspace(int ch)
Definition: univalue.h:207
jtokentype
Definition: univalue.h:170
@ JTOK_OBJ_CLOSE
Definition: univalue.h:174
@ JTOK_STRING
Definition: univalue.h:183
@ JTOK_COLON
Definition: univalue.h:177
@ JTOK_OBJ_OPEN
Definition: univalue.h:173
@ JTOK_NUMBER
Definition: univalue.h:182
@ JTOK_KW_NULL
Definition: univalue.h:179
@ JTOK_COMMA
Definition: univalue.h:178
@ JTOK_ARR_CLOSE
Definition: univalue.h:176
@ JTOK_KW_TRUE
Definition: univalue.h:180
@ JTOK_ARR_OPEN
Definition: univalue.h:175
@ JTOK_KW_FALSE
Definition: univalue.h:181
@ JTOK_ERR
Definition: univalue.h:171
@ JTOK_NONE
Definition: univalue.h:172
const char * uvTypeName(UniValue::VType t)
Definition: univalue.cpp:209
const UniValue NullUniValue
Definition: univalue.cpp:16