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 http://www.opensource.org/licenses/mit-license.php.
19 static bool ParsePrechecks(const std::string
& str
)
21 if (str
.empty()) // No empty string allowed
23 if (str
.size() >= 1 && (json_isspace(str
[0]) || json_isspace(str
[str
.size()-1]))) // No padding allowed
25 if (str
.size() != strlen(str
.c_str())) // No embedded NUL characters allowed
30 bool ParseInt32(const std::string
& str
, int32_t *out
)
32 if (!ParsePrechecks(str
))
35 errno
= 0; // strtol will not set errno if valid
36 long int n
= strtol(str
.c_str(), &endp
, 10);
37 if(out
) *out
= (int32_t)n
;
38 // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
39 // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
40 // platforms the size of these types may be different.
41 return endp
&& *endp
== 0 && !errno
&&
42 n
>= std::numeric_limits
<int32_t>::min() &&
43 n
<= std::numeric_limits
<int32_t>::max();
46 bool ParseInt64(const std::string
& str
, int64_t *out
)
48 if (!ParsePrechecks(str
))
51 errno
= 0; // strtoll will not set errno if valid
52 long long int n
= strtoll(str
.c_str(), &endp
, 10);
53 if(out
) *out
= (int64_t)n
;
54 // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
55 // we still have to check that the returned value is within the range of an *int64_t*.
56 return endp
&& *endp
== 0 && !errno
&&
57 n
>= std::numeric_limits
<int64_t>::min() &&
58 n
<= std::numeric_limits
<int64_t>::max();
61 bool ParseDouble(const std::string
& str
, double *out
)
63 if (!ParsePrechecks(str
))
65 if (str
.size() >= 2 && str
[0] == '0' && str
[1] == 'x') // No hexadecimal floats allowed
67 std::istringstream
text(str
);
68 text
.imbue(std::locale::classic());
71 if(out
) *out
= result
;
72 return text
.eof() && !text
.fail();
78 const UniValue NullUniValue
;
80 void UniValue::clear()
88 bool UniValue::setNull()
94 bool UniValue::setBool(bool val_
)
103 static bool validNumStr(const string
& s
)
106 unsigned int consumed
;
107 enum jtokentype tt
= getJsonToken(tokenVal
, consumed
, s
.c_str());
108 return (tt
== JTOK_NUMBER
);
111 bool UniValue::setNumStr(const string
& val_
)
113 if (!validNumStr(val_
))
122 bool UniValue::setInt(uint64_t val_
)
128 return setNumStr(oss
.str());
131 bool UniValue::setInt(int64_t val_
)
137 return setNumStr(oss
.str());
140 bool UniValue::setFloat(double val_
)
144 oss
<< std::setprecision(16) << val_
;
146 bool ret
= setNumStr(oss
.str());
151 bool UniValue::setStr(const string
& val_
)
159 bool UniValue::setArray()
166 bool UniValue::setObject()
173 bool UniValue::push_back(const UniValue
& val_
)
178 values
.push_back(val_
);
182 bool UniValue::push_backV(const std::vector
<UniValue
>& vec
)
187 values
.insert(values
.end(), vec
.begin(), vec
.end());
192 bool UniValue::pushKV(const std::string
& key
, const UniValue
& val_
)
198 values
.push_back(val_
);
202 bool UniValue::pushKVs(const UniValue
& obj
)
204 if (typ
!= VOBJ
|| obj
.typ
!= VOBJ
)
207 for (unsigned int i
= 0; i
< obj
.keys
.size(); i
++) {
208 keys
.push_back(obj
.keys
[i
]);
209 values
.push_back(obj
.values
.at(i
));
215 int UniValue::findKey(const std::string
& key
) const
217 for (unsigned int i
= 0; i
< keys
.size(); i
++) {
225 bool UniValue::checkObject(const std::map
<std::string
,UniValue::VType
>& t
)
227 for (std::map
<std::string
,UniValue::VType
>::const_iterator it
= t
.begin();
228 it
!= t
.end(); ++it
) {
229 int idx
= findKey(it
->first
);
233 if (values
.at(idx
).getType() != it
->second
)
240 const UniValue
& UniValue::operator[](const std::string
& key
) const
245 int index
= findKey(key
);
249 return values
.at(index
);
252 const UniValue
& UniValue::operator[](unsigned int index
) const
254 if (typ
!= VOBJ
&& typ
!= VARR
)
256 if (index
>= values
.size())
259 return values
.at(index
);
262 const char *uvTypeName(UniValue::VType t
)
265 case UniValue::VNULL
: return "null";
266 case UniValue::VBOOL
: return "bool";
267 case UniValue::VOBJ
: return "object";
268 case UniValue::VARR
: return "array";
269 case UniValue::VSTR
: return "string";
270 case UniValue::VNUM
: return "number";
277 const UniValue
& find_value(const UniValue
& obj
, const std::string
& name
)
279 for (unsigned int i
= 0; i
< obj
.keys
.size(); i
++)
280 if (obj
.keys
[i
] == name
)
281 return obj
.values
.at(i
);
286 const std::vector
<std::string
>& UniValue::getKeys() const
289 throw std::runtime_error("JSON value is not an object as expected");
293 const std::vector
<UniValue
>& UniValue::getValues() const
295 if (typ
!= VOBJ
&& typ
!= VARR
)
296 throw std::runtime_error("JSON value is not an object or array as expected");
300 bool UniValue::get_bool() const
303 throw std::runtime_error("JSON value is not a boolean as expected");
307 const std::string
& UniValue::get_str() const
310 throw std::runtime_error("JSON value is not a string as expected");
314 int UniValue::get_int() const
317 throw std::runtime_error("JSON value is not an integer as expected");
319 if (!ParseInt32(getValStr(), &retval
))
320 throw std::runtime_error("JSON integer out of range");
324 int64_t UniValue::get_int64() const
327 throw std::runtime_error("JSON value is not an integer as expected");
329 if (!ParseInt64(getValStr(), &retval
))
330 throw std::runtime_error("JSON integer out of range");
334 double UniValue::get_real() const
337 throw std::runtime_error("JSON value is not a number as expected");
339 if (!ParseDouble(getValStr(), &retval
))
340 throw std::runtime_error("JSON double out of range");
344 const UniValue
& UniValue::get_obj() const
347 throw std::runtime_error("JSON value is not an object as expected");
351 const UniValue
& UniValue::get_array() const
354 throw std::runtime_error("JSON value is not an array as expected");