Bitcoin Core 28.99.0
P2P Digital Currency
object.cpp
Go to the documentation of this file.
1// Copyright (c) 2014 BitPay Inc.
2// Copyright (c) 2014-2022 The 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 <cassert>
9#include <cstdint>
10#include <map>
11#include <memory>
12#include <stdexcept>
13#include <string>
14#include <string_view>
15#include <vector>
16
17#define BOOST_CHECK(expr) assert(expr)
18#define BOOST_CHECK_EQUAL(v1, v2) assert((v1) == (v2))
19#define BOOST_CHECK_THROW(stmt, excMatch) { \
20 try { \
21 (stmt); \
22 assert(0 && "No exception caught"); \
23 } catch (excMatch&) { \
24 } catch (...) { \
25 assert(0 && "Wrong exception caught"); \
26 } \
27 }
28#define BOOST_CHECK_NO_THROW(stmt) { \
29 try { \
30 (stmt); \
31 } catch (...) { \
32 assert(0); \
33 } \
34 }
35
37{
38 UniValue v1;
39 BOOST_CHECK(v1.isNull());
40
42 BOOST_CHECK(v2.isStr());
43
44 UniValue v3(UniValue::VSTR, "foo");
45 BOOST_CHECK(v3.isStr());
46 BOOST_CHECK_EQUAL(v3.getValStr(), "foo");
47
48 UniValue numTest;
49 numTest.setNumStr("82");
50 BOOST_CHECK(numTest.isNum());
51 BOOST_CHECK_EQUAL(numTest.getValStr(), "82");
52
53 uint64_t vu64 = 82;
54 UniValue v4(vu64);
55 BOOST_CHECK(v4.isNum());
56 BOOST_CHECK_EQUAL(v4.getValStr(), "82");
57
58 int64_t vi64 = -82;
59 UniValue v5(vi64);
60 BOOST_CHECK(v5.isNum());
61 BOOST_CHECK_EQUAL(v5.getValStr(), "-82");
62
63 int vi = -688;
64 UniValue v6(vi);
65 BOOST_CHECK(v6.isNum());
66 BOOST_CHECK_EQUAL(v6.getValStr(), "-688");
67
68 double vd = -7.21;
69 UniValue v7(vd);
70 BOOST_CHECK(v7.isNum());
71 BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21");
72
73 std::string vs("yawn");
74 UniValue v8(vs);
75 BOOST_CHECK(v8.isStr());
76 BOOST_CHECK_EQUAL(v8.getValStr(), "yawn");
77
78 const char *vcs = "zappa";
79 UniValue v9(vcs);
80 BOOST_CHECK(v9.isStr());
81 BOOST_CHECK_EQUAL(v9.getValStr(), "zappa");
82}
83
85{
86 UniValue j;
87 BOOST_CHECK_THROW(j.push_back(1), std::runtime_error);
88 BOOST_CHECK_THROW(j.push_backV({1}), std::runtime_error);
89 BOOST_CHECK_THROW(j.pushKVEnd("k", 1), std::runtime_error);
90 BOOST_CHECK_THROW(j.pushKV("k", 1), std::runtime_error);
91 BOOST_CHECK_THROW(j.pushKVs({}), std::runtime_error);
92}
93
95{
96 UniValue v1;
97 v1.setNumStr("1");
98 BOOST_CHECK(v1.isNum());
99 BOOST_CHECK_THROW(v1.get_bool(), std::runtime_error);
100
101 {
102 UniValue v_negative;
103 v_negative.setNumStr("-1");
104 BOOST_CHECK_THROW(v_negative.getInt<uint8_t>(), std::runtime_error);
105 BOOST_CHECK_EQUAL(v_negative.getInt<int8_t>(), -1);
106 }
107
108 UniValue v2;
109 v2.setBool(true);
110 BOOST_CHECK_EQUAL(v2.get_bool(), true);
111 BOOST_CHECK_THROW(v2.getInt<int>(), std::runtime_error);
112
113 UniValue v3;
114 v3.setNumStr("32482348723847471234");
115 BOOST_CHECK_THROW(v3.getInt<int64_t>(), std::runtime_error);
116 v3.setNumStr("1000");
117 BOOST_CHECK_EQUAL(v3.getInt<int64_t>(), 1000);
118
119 UniValue v4;
120 v4.setNumStr("2147483648");
121 BOOST_CHECK_EQUAL(v4.getInt<int64_t>(), 2147483648);
122 BOOST_CHECK_THROW(v4.getInt<int>(), std::runtime_error);
123 v4.setNumStr("1000");
124 BOOST_CHECK_EQUAL(v4.getInt<int>(), 1000);
125 BOOST_CHECK_THROW(v4.get_str(), std::runtime_error);
126 BOOST_CHECK_EQUAL(v4.get_real(), 1000);
127 BOOST_CHECK_THROW(v4.get_array(), std::runtime_error);
128 BOOST_CHECK_THROW(v4.getKeys(), std::runtime_error);
129 BOOST_CHECK_THROW(v4.getValues(), std::runtime_error);
130 BOOST_CHECK_THROW(v4.get_obj(), std::runtime_error);
131
132 UniValue v5;
133 BOOST_CHECK(v5.read("[true, 10]"));
135 std::vector<UniValue> vals = v5.getValues();
136 BOOST_CHECK_THROW(vals[0].getInt<int>(), std::runtime_error);
137 BOOST_CHECK_EQUAL(vals[0].get_bool(), true);
138
139 BOOST_CHECK_EQUAL(vals[1].getInt<int>(), 10);
140 BOOST_CHECK_THROW(vals[1].get_bool(), std::runtime_error);
141}
142
144{
145 UniValue v(UniValue::VSTR, "foo");
146 v.clear();
147 BOOST_CHECK(v.isNull());
149
150 v.setObject();
152 BOOST_CHECK_EQUAL(v.size(), 0);
154 BOOST_CHECK(v.empty());
155
156 v.setArray();
157 BOOST_CHECK(v.isArray());
158 BOOST_CHECK_EQUAL(v.size(), 0);
159
160 v.setStr("zum");
161 BOOST_CHECK(v.isStr());
162 BOOST_CHECK_EQUAL(v.getValStr(), "zum");
163
164 {
165 std::string_view sv{"ab\0c", 4};
166 UniValue j{sv};
167 BOOST_CHECK(j.isStr());
168 BOOST_CHECK_EQUAL(j.getValStr(), sv);
169 BOOST_CHECK_EQUAL(j.write(), "\"ab\\u0000c\"");
170 }
171
172 v.setFloat(-1.01);
173 BOOST_CHECK(v.isNum());
174 BOOST_CHECK_EQUAL(v.getValStr(), "-1.01");
175
176 v.setInt(int{1023});
177 BOOST_CHECK(v.isNum());
178 BOOST_CHECK_EQUAL(v.getValStr(), "1023");
179
180 v.setInt(int64_t{-1023LL});
181 BOOST_CHECK(v.isNum());
182 BOOST_CHECK_EQUAL(v.getValStr(), "-1023");
183
184 v.setInt(uint64_t{1023ULL});
185 BOOST_CHECK(v.isNum());
186 BOOST_CHECK_EQUAL(v.getValStr(), "1023");
187
188 v.setNumStr("-688");
189 BOOST_CHECK(v.isNum());
190 BOOST_CHECK_EQUAL(v.getValStr(), "-688");
191
192 v.setBool(false);
193 BOOST_CHECK_EQUAL(v.isBool(), true);
194 BOOST_CHECK_EQUAL(v.isTrue(), false);
195 BOOST_CHECK_EQUAL(v.isFalse(), true);
196 BOOST_CHECK_EQUAL(v.get_bool(), false);
197
198 v.setBool(true);
199 BOOST_CHECK_EQUAL(v.isBool(), true);
200 BOOST_CHECK_EQUAL(v.isTrue(), true);
201 BOOST_CHECK_EQUAL(v.isFalse(), false);
202 BOOST_CHECK_EQUAL(v.get_bool(), true);
203
204 BOOST_CHECK_THROW(v.setNumStr("zombocom"), std::runtime_error);
205
206 v.setNull();
207 BOOST_CHECK(v.isNull());
208}
209
211{
213
214 UniValue v((int64_t)1023LL);
215 arr.push_back(v);
216
217 std::string vStr("zippy");
218 arr.push_back(vStr);
219
220 const char *s = "pippy";
221 arr.push_back(s);
222
223 std::vector<UniValue> vec;
224 v.setStr("boing");
225 vec.push_back(v);
226
227 v.setStr("going");
228 vec.push_back(v);
229
230 arr.push_backV(vec);
231
232 arr.push_back(uint64_t{400ULL});
233 arr.push_back(int64_t{-400LL});
234 arr.push_back(int{-401});
235 arr.push_back(-40.1);
236 arr.push_back(true);
237
238 BOOST_CHECK_EQUAL(arr.empty(), false);
239 BOOST_CHECK_EQUAL(arr.size(), 10);
240
241 BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023");
242 BOOST_CHECK_EQUAL(arr[0].getType(), UniValue::VNUM);
243 BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy");
244 BOOST_CHECK_EQUAL(arr[1].getType(), UniValue::VSTR);
245 BOOST_CHECK_EQUAL(arr[2].getValStr(), "pippy");
246 BOOST_CHECK_EQUAL(arr[2].getType(), UniValue::VSTR);
247 BOOST_CHECK_EQUAL(arr[3].getValStr(), "boing");
248 BOOST_CHECK_EQUAL(arr[3].getType(), UniValue::VSTR);
249 BOOST_CHECK_EQUAL(arr[4].getValStr(), "going");
250 BOOST_CHECK_EQUAL(arr[4].getType(), UniValue::VSTR);
251 BOOST_CHECK_EQUAL(arr[5].getValStr(), "400");
252 BOOST_CHECK_EQUAL(arr[5].getType(), UniValue::VNUM);
253 BOOST_CHECK_EQUAL(arr[6].getValStr(), "-400");
254 BOOST_CHECK_EQUAL(arr[6].getType(), UniValue::VNUM);
255 BOOST_CHECK_EQUAL(arr[7].getValStr(), "-401");
256 BOOST_CHECK_EQUAL(arr[7].getType(), UniValue::VNUM);
257 BOOST_CHECK_EQUAL(arr[8].getValStr(), "-40.1");
258 BOOST_CHECK_EQUAL(arr[8].getType(), UniValue::VNUM);
259 BOOST_CHECK_EQUAL(arr[9].getValStr(), "1");
260 BOOST_CHECK_EQUAL(arr[9].getType(), UniValue::VBOOL);
261
262 BOOST_CHECK_EQUAL(arr[999].getValStr(), "");
263
264 arr.clear();
265 BOOST_CHECK(arr.empty());
266 BOOST_CHECK_EQUAL(arr.size(), 0);
267}
268
270{
272 std::string strKey, strVal;
273 UniValue v;
274
275 strKey = "age";
276 v.setInt(100);
277 obj.pushKV(strKey, v);
278
279 strKey = "first";
280 strVal = "John";
281 obj.pushKV(strKey, strVal);
282
283 strKey = "last";
284 const char* cVal = "Smith";
285 obj.pushKV(strKey, cVal);
286
287 strKey = "distance";
288 obj.pushKV(strKey, int64_t{25});
289
290 strKey = "time";
291 obj.pushKV(strKey, uint64_t{3600});
292
293 strKey = "calories";
294 obj.pushKV(strKey, int{12});
295
296 strKey = "temperature";
297 obj.pushKV(strKey, double{90.012});
298
299 strKey = "moon";
300 obj.pushKV(strKey, true);
301
302 strKey = "spoon";
303 obj.pushKV(strKey, false);
304
306 obj2.pushKV("cat1", 9000);
307 obj2.pushKV("cat2", 12345);
308
309 obj.pushKVs(obj2);
310
311 BOOST_CHECK_EQUAL(obj.empty(), false);
312 BOOST_CHECK_EQUAL(obj.size(), 11);
313
314 BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100");
315 BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John");
316 BOOST_CHECK_EQUAL(obj["last"].getValStr(), "Smith");
317 BOOST_CHECK_EQUAL(obj["distance"].getValStr(), "25");
318 BOOST_CHECK_EQUAL(obj["time"].getValStr(), "3600");
319 BOOST_CHECK_EQUAL(obj["calories"].getValStr(), "12");
320 BOOST_CHECK_EQUAL(obj["temperature"].getValStr(), "90.012");
321 BOOST_CHECK_EQUAL(obj["moon"].getValStr(), "1");
322 BOOST_CHECK_EQUAL(obj["spoon"].getValStr(), "");
323 BOOST_CHECK_EQUAL(obj["cat1"].getValStr(), "9000");
324 BOOST_CHECK_EQUAL(obj["cat2"].getValStr(), "12345");
325
326 BOOST_CHECK_EQUAL(obj["nyuknyuknyuk"].getValStr(), "");
327
328 BOOST_CHECK(obj.exists("age"));
329 BOOST_CHECK(obj.exists("first"));
330 BOOST_CHECK(obj.exists("last"));
331 BOOST_CHECK(obj.exists("distance"));
332 BOOST_CHECK(obj.exists("time"));
333 BOOST_CHECK(obj.exists("calories"));
334 BOOST_CHECK(obj.exists("temperature"));
335 BOOST_CHECK(obj.exists("moon"));
336 BOOST_CHECK(obj.exists("spoon"));
337 BOOST_CHECK(obj.exists("cat1"));
338 BOOST_CHECK(obj.exists("cat2"));
339
340 BOOST_CHECK(!obj.exists("nyuknyuknyuk"));
341
342 std::map<std::string, UniValue::VType> objTypes;
343 objTypes["age"] = UniValue::VNUM;
344 objTypes["first"] = UniValue::VSTR;
345 objTypes["last"] = UniValue::VSTR;
346 objTypes["distance"] = UniValue::VNUM;
347 objTypes["time"] = UniValue::VNUM;
348 objTypes["calories"] = UniValue::VNUM;
349 objTypes["temperature"] = UniValue::VNUM;
350 objTypes["moon"] = UniValue::VBOOL;
351 objTypes["spoon"] = UniValue::VBOOL;
352 objTypes["cat1"] = UniValue::VNUM;
353 objTypes["cat2"] = UniValue::VNUM;
354 BOOST_CHECK(obj.checkObject(objTypes));
355
356 objTypes["cat2"] = UniValue::VSTR;
357 BOOST_CHECK(!obj.checkObject(objTypes));
358
359 obj.clear();
360 BOOST_CHECK(obj.empty());
361 BOOST_CHECK_EQUAL(obj.size(), 0);
363
364 obj.setObject();
365 UniValue uv;
366 uv.setInt(42);
367 obj.pushKVEnd("age", uv);
368 BOOST_CHECK_EQUAL(obj.size(), 1);
369 BOOST_CHECK_EQUAL(obj["age"].getValStr(), "42");
370
371 uv.setInt(43);
372 obj.pushKV("age", uv);
373 BOOST_CHECK_EQUAL(obj.size(), 1);
374 BOOST_CHECK_EQUAL(obj["age"].getValStr(), "43");
375
376 obj.pushKV("name", "foo bar");
377
378 std::map<std::string,UniValue> kv;
379 obj.getObjMap(kv);
380 BOOST_CHECK_EQUAL(kv["age"].getValStr(), "43");
381 BOOST_CHECK_EQUAL(kv["name"].getValStr(), "foo bar");
382
383}
384
385static const char *json1 =
386"[1.10000000,{\"key1\":\"str\\u0000\",\"key2\":800,\"key3\":{\"name\":\"martian http://test.com\"}}]";
387
389{
390 UniValue v;
392
393 std::string strJson1(json1);
394 BOOST_CHECK(v.read(strJson1));
395
396 BOOST_CHECK(v.isArray());
397 BOOST_CHECK_EQUAL(v.size(), 2);
398
399 BOOST_CHECK_EQUAL(v[0].getValStr(), "1.10000000");
400
401 UniValue obj = v[1];
402 BOOST_CHECK(obj.isObject());
403 BOOST_CHECK_EQUAL(obj.size(), 3);
404
405 BOOST_CHECK(obj["key1"].isStr());
406 std::string correctValue("str");
407 correctValue.push_back('\0');
408 BOOST_CHECK_EQUAL(obj["key1"].getValStr(), correctValue);
409 BOOST_CHECK(obj["key2"].isNum());
410 BOOST_CHECK_EQUAL(obj["key2"].getValStr(), "800");
411 BOOST_CHECK(obj["key3"].isObject());
412
413 BOOST_CHECK_EQUAL(strJson1, v.write());
414
415 // Valid
416 BOOST_CHECK(v.read("1.0") && (v.get_real() == 1.0));
417 BOOST_CHECK(v.read("true") && v.get_bool());
418 BOOST_CHECK(v.read("[false]") && !v[0].get_bool());
419 BOOST_CHECK(v.read("{\"a\": true}") && v["a"].get_bool());
420 BOOST_CHECK(v.read("{\"1\": \"true\"}") && (v["1"].get_str() == "true"));
421 // Valid, with leading or trailing whitespace
422 BOOST_CHECK(v.read(" 1.0") && (v.get_real() == 1.0));
423 BOOST_CHECK(v.read("1.0 ") && (v.get_real() == 1.0));
424 BOOST_CHECK(v.read("0.00000000000000000000000000000000000001e+30 "));
425
426 BOOST_CHECK(!v.read(".19e-6")); //should fail, missing leading 0, therefore invalid JSON
427 // Invalid, initial garbage
428 BOOST_CHECK(!v.read("[1.0"));
429 BOOST_CHECK(!v.read("a1.0"));
430 // Invalid, trailing garbage
431 BOOST_CHECK(!v.read("1.0sds"));
432 BOOST_CHECK(!v.read("1.0]"));
433 // Invalid, keys have to be names
434 BOOST_CHECK(!v.read("{1: \"true\"}"));
435 BOOST_CHECK(!v.read("{true: 1}"));
436 BOOST_CHECK(!v.read("{[1]: 1}"));
437 BOOST_CHECK(!v.read("{{\"a\": \"a\"}: 1}"));
438 // BTC addresses should fail parsing
439 BOOST_CHECK(!v.read("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
440 BOOST_CHECK(!v.read("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"));
441
442 /* Check for (correctly reporting) a parsing error if the initial
443 JSON construct is followed by more stuff. Note that whitespace
444 is, of course, exempt. */
445
446 BOOST_CHECK(v.read(" {}\n "));
448 BOOST_CHECK(v.read(" []\n "));
449 BOOST_CHECK(v.isArray());
450
451 BOOST_CHECK(!v.read("@{}"));
452 BOOST_CHECK(!v.read("{} garbage"));
453 BOOST_CHECK(!v.read("[]{}"));
454 BOOST_CHECK(!v.read("{}[]"));
455 BOOST_CHECK(!v.read("{} 42"));
456}
457
458int main(int argc, char* argv[])
459{
463 univalue_set();
467 return 0;
468}
void push_back(UniValue val)
Definition: univalue.cpp:104
const std::string & get_str() const
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes) const
Definition: univalue.cpp:168
bool isTrue() const
Definition: univalue.h:80
bool isArray() const
Definition: univalue.h:85
enum VType getType() const
Definition: univalue.h:67
@ VNULL
Definition: univalue.h:24
@ VOBJ
Definition: univalue.h:24
@ VSTR
Definition: univalue.h:24
@ VARR
Definition: univalue.h:24
@ VNUM
Definition: univalue.h:24
@ VBOOL
Definition: univalue.h:24
void setArray()
Definition: univalue.cpp:92
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
bool isNull() const
Definition: univalue.h:79
void clear()
Definition: univalue.cpp:18
const std::string & getValStr() const
Definition: univalue.h:68
const UniValue & get_obj() const
void setNull()
Definition: univalue.cpp:26
size_t size() const
Definition: univalue.h:71
const std::vector< UniValue > & getValues() const
void pushKVs(UniValue obj)
Definition: univalue.cpp:137
const std::vector< std::string > & getKeys() const
bool empty() const
Definition: univalue.h:69
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
bool read(std::string_view raw)
bool isStr() const
Definition: univalue.h:83
void setObject()
Definition: univalue.cpp:98
bool isBool() const
Definition: univalue.h:82
Int getInt() const
Definition: univalue.h:138
const UniValue & get_array() const
bool exists(const std::string &key) const
Definition: univalue.h:77
void setFloat(double val)
Definition: univalue.cpp:76
bool isNum() const
Definition: univalue.h:84
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
double get_real() const
bool isFalse() const
Definition: univalue.h:81
bool get_bool() const
void push_backV(const std::vector< UniValue > &vec)
Definition: univalue.cpp:111
bool isObject() const
Definition: univalue.h:86
int main(int argc, char *argv[])
Definition: object.cpp:458
#define BOOST_CHECK_THROW(stmt, excMatch)
Definition: object.cpp:19
void univalue_array()
Definition: object.cpp:210
static const char * json1
Definition: object.cpp:385
void univalue_readwrite()
Definition: object.cpp:388
void univalue_object()
Definition: object.cpp:269
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK_NO_THROW(stmt)
Definition: object.cpp:28
void univalue_typecheck()
Definition: object.cpp:94
void univalue_set()
Definition: object.cpp:143
#define BOOST_CHECK(expr)
Definition: object.cpp:17
void univalue_constructor()
Definition: object.cpp:36
void univalue_push_throw()
Definition: object.cpp:84