Bitcoin Core  31.0.0
P2P Digital Currency
univalue.cpp
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 #include <univalue.h>
7 
8 #include <iomanip>
9 #include <map>
10 #include <sstream>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
16 
18 {
19  typ = VNULL;
20  val.clear();
21  keys.clear();
22  values.clear();
23 }
24 
26 {
27  clear();
28 }
29 
30 void UniValue::setBool(bool val_)
31 {
32  clear();
33  typ = VBOOL;
34  if (val_)
35  val = "1";
36 }
37 
38 static bool validNumStr(const std::string& s)
39 {
40  std::string tokenVal;
41  unsigned int consumed;
42  enum jtokentype tt = getJsonToken(tokenVal, consumed, s.data(), s.data() + s.size());
43  return (tt == JTOK_NUMBER);
44 }
45 
46 void UniValue::setNumStr(std::string str)
47 {
48  if (!validNumStr(str)) {
49  throw std::runtime_error{"The string '" + str + "' is not a valid JSON number"};
50  }
51 
52  clear();
53  typ = VNUM;
54  val = std::move(str);
55 }
56 
57 void UniValue::setInt(uint64_t val_)
58 {
59  std::ostringstream oss;
60 
61  oss << val_;
62 
63  return setNumStr(oss.str());
64 }
65 
66 void UniValue::setInt(int64_t val_)
67 {
68  std::ostringstream oss;
69 
70  oss << val_;
71 
72  return setNumStr(oss.str());
73 }
74 
75 void UniValue::setFloat(double val_)
76 {
77  std::ostringstream oss;
78 
79  oss << std::setprecision(16) << val_;
80 
81  return setNumStr(oss.str());
82 }
83 
84 void UniValue::setStr(std::string str)
85 {
86  clear();
87  typ = VSTR;
88  val = std::move(str);
89 }
90 
92 {
93  clear();
94  typ = VARR;
95 }
96 
98 {
99  clear();
100  typ = VOBJ;
101 }
102 
104 {
105  checkType(VARR);
106 
107  values.push_back(std::move(val));
108 }
109 
110 void UniValue::push_backV(const std::vector<UniValue>& vec)
111 {
112  checkType(VARR);
113 
114  values.insert(values.end(), vec.begin(), vec.end());
115 }
116 
117 void UniValue::pushKVEnd(std::string key, UniValue val)
118 {
119  checkType(VOBJ);
120 
121  keys.push_back(std::move(key));
122  values.push_back(std::move(val));
123 }
124 
125 void UniValue::pushKV(std::string key, UniValue val)
126 {
127  checkType(VOBJ);
128 
129  size_t idx;
130  if (findKey(key, idx))
131  values[idx] = std::move(val);
132  else
133  pushKVEnd(std::move(key), std::move(val));
134 }
135 
137 {
138  checkType(VOBJ);
139  obj.checkType(VOBJ);
140 
141  for (size_t i = 0; i < obj.keys.size(); i++)
142  pushKVEnd(std::move(obj.keys.at(i)), std::move(obj.values.at(i)));
143 }
144 
145 void UniValue::getObjMap(std::map<std::string,UniValue>& kv) const
146 {
147  if (typ != VOBJ)
148  return;
149 
150  kv.clear();
151  for (size_t i = 0; i < keys.size(); i++)
152  kv[keys[i]] = values[i];
153 }
154 
155 bool UniValue::findKey(const std::string& key, size_t& retIdx) const
156 {
157  for (size_t i = 0; i < keys.size(); i++) {
158  if (keys[i] == key) {
159  retIdx = i;
160  return true;
161  }
162  }
163 
164  return false;
165 }
166 
167 bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t) const
168 {
169  if (typ != VOBJ) {
170  return false;
171  }
172 
173  for (const auto& object: t) {
174  size_t idx = 0;
175  if (!findKey(object.first, idx)) {
176  return false;
177  }
178 
179  if (values.at(idx).getType() != object.second) {
180  return false;
181  }
182  }
183 
184  return true;
185 }
186 
187 const UniValue& UniValue::operator[](const std::string& key) const
188 {
189  if (typ != VOBJ)
190  return NullUniValue;
191 
192  size_t index = 0;
193  if (!findKey(key, index))
194  return NullUniValue;
195 
196  return values.at(index);
197 }
198 
199 const UniValue& UniValue::operator[](size_t index) const
200 {
201  if (typ != VOBJ && typ != VARR)
202  return NullUniValue;
203  if (index >= values.size())
204  return NullUniValue;
205 
206  return values.at(index);
207 }
208 
209 void UniValue::checkType(const VType& expected) const
210 {
211  if (typ != expected) {
212  throw type_error{"JSON value of type " + std::string{uvTypeName(typ)} + " is not of expected type " +
213  std::string{uvTypeName(expected)}};
214  }
215 }
216 
218 {
219  switch (t) {
220  case UniValue::VNULL: return "null";
221  case UniValue::VBOOL: return "bool";
222  case UniValue::VOBJ: return "object";
223  case UniValue::VARR: return "array";
224  case UniValue::VSTR: return "string";
225  case UniValue::VNUM: return "number";
226  }
227 
228  // not reached
229  return nullptr;
230 }
231 
232 const UniValue& UniValue::find_value(std::string_view key) const
233 {
234  for (unsigned int i = 0; i < keys.size(); ++i) {
235  if (keys[i] == key) {
236  return values.at(i);
237  }
238  }
239  return NullUniValue;
240 }
241 
242 void UniValue::reserve(size_t new_cap)
243 {
244  values.reserve(new_cap);
245  if (typ == VOBJ) {
246  keys.reserve(new_cap);
247  }
248 }
void push_back(UniValue val)
Definition: univalue.cpp:103
void setBool(bool val)
Definition: univalue.cpp:30
void setNull()
Definition: univalue.cpp:25
void pushKVs(UniValue obj)
Definition: univalue.cpp:136
const char * uvTypeName(UniValue::VType t)
Definition: univalue.cpp:217
bool findKey(const std::string &key, size_t &retIdx) const
Definition: univalue.cpp:155
void pushKVEnd(std::string key, UniValue val)
Definition: univalue.cpp:117
std::vector< UniValue > values
Definition: univalue.h:108
void reserve(size_t new_cap)
Definition: univalue.cpp:242
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)
void getObjMap(std::map< std::string, UniValue > &kv) const
Definition: univalue.cpp:145
jtokentype
Definition: univalue.h:152
void push_backV(const std::vector< UniValue > &vec)
Definition: univalue.cpp:110
void setObject()
Definition: univalue.cpp:97
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
void setNumStr(std::string str)
Definition: univalue.cpp:46
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:125
std::vector< std::string > keys
Definition: univalue.h:107
void clear()
Definition: univalue.cpp:17
void setArray()
Definition: univalue.cpp:91
void setFloat(double val)
Definition: univalue.cpp:75
void setInt(uint64_t val)
Definition: univalue.cpp:57
static bool validNumStr(const std::string &s)
Definition: univalue.cpp:38
const UniValue NullUniValue
Definition: univalue.cpp:15
void setStr(std::string str)
Definition: univalue.cpp:84
void checkType(const VType &expected) const
Definition: univalue.cpp:209