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