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