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