PRCYCoin  2.0.0.7rc1
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 http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <stdint.h>
7 #include <errno.h>
8 #include <iomanip>
9 #include <limits>
10 #include <sstream>
11 #include <stdexcept>
12 #include <stdlib.h>
13 #include <string.h>
14 
15 #include "univalue.h"
16 
17 namespace
18 {
19 static bool ParsePrechecks(const std::string& str)
20 {
21  if (str.empty()) // No empty string allowed
22  return false;
23  if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed
24  return false;
25  if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
26  return false;
27  return true;
28 }
29 
30 bool ParseInt32(const std::string& str, int32_t *out)
31 {
32  if (!ParsePrechecks(str))
33  return false;
34  char *endp = NULL;
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();
44 }
45 
46 bool ParseInt64(const std::string& str, int64_t *out)
47 {
48  if (!ParsePrechecks(str))
49  return false;
50  char *endp = NULL;
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();
59 }
60 
61 bool ParseDouble(const std::string& str, double *out)
62 {
63  if (!ParsePrechecks(str))
64  return false;
65  if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
66  return false;
67  std::istringstream text(str);
68  text.imbue(std::locale::classic());
69  double result;
70  text >> result;
71  if(out) *out = result;
72  return text.eof() && !text.fail();
73 }
74 }
75 
76 using namespace std;
77 
79 
81 {
82  typ = VNULL;
83  val.clear();
84  keys.clear();
85  values.clear();
86 }
87 
89 {
90  clear();
91  return true;
92 }
93 
94 bool UniValue::setBool(bool val_)
95 {
96  clear();
97  typ = VBOOL;
98  if (val_)
99  val = "1";
100  return true;
101 }
102 
103 static bool validNumStr(const string& s)
104 {
105  string tokenVal;
106  unsigned int consumed;
107  enum jtokentype tt = getJsonToken(tokenVal, consumed, s.data(), s.data() + s.size());
108  return (tt == JTOK_NUMBER);
109 }
110 
111 bool UniValue::setNumStr(const string& val_)
112 {
113  if (!validNumStr(val_))
114  return false;
115 
116  clear();
117  typ = VNUM;
118  val = val_;
119  return true;
120 }
121 
122 bool UniValue::setInt(uint64_t val_)
123 {
124  ostringstream oss;
125 
126  oss << val_;
127 
128  return setNumStr(oss.str());
129 }
130 
131 bool UniValue::setInt(int64_t val_)
132 {
133  ostringstream oss;
134 
135  oss << val_;
136 
137  return setNumStr(oss.str());
138 }
139 
140 bool UniValue::setFloat(double val_)
141 {
142  ostringstream oss;
143 
144  oss << std::setprecision(16) << val_;
145 
146  bool ret = setNumStr(oss.str());
147  typ = VNUM;
148  return ret;
149 }
150 
151 bool UniValue::setStr(const string& val_)
152 {
153  clear();
154  typ = VSTR;
155  val = val_;
156  return true;
157 }
158 
160 {
161  clear();
162  typ = VARR;
163  return true;
164 }
165 
167 {
168  clear();
169  typ = VOBJ;
170  return true;
171 }
172 
173 bool UniValue::push_back(const UniValue& val_)
174 {
175  if (typ != VARR)
176  return false;
177 
178  values.push_back(val_);
179  return true;
180 }
181 
182 bool UniValue::push_backV(const std::vector<UniValue>& vec)
183 {
184  if (typ != VARR)
185  return false;
186 
187  values.insert(values.end(), vec.begin(), vec.end());
188 
189  return true;
190 }
191 
192 bool UniValue::pushKV(const std::string& key, const UniValue& val_)
193 {
194  if (typ != VOBJ)
195  return false;
196 
197  keys.push_back(key);
198  values.push_back(val_);
199  return true;
200 }
201 
202 bool UniValue::pushKVs(const UniValue& obj)
203 {
204  if (typ != VOBJ || obj.typ != VOBJ)
205  return false;
206 
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));
210  }
211 
212  return true;
213 }
214 
215 bool UniValue::findKey(const std::string& key, size_t& retIdx) const
216 {
217  for (size_t i = 0; i < keys.size(); i++) {
218  if (keys[i] == key) {
219  retIdx = i;
220  return true;
221  }
222  }
223 
224  return false;
225 }
226 
227 bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t)
228 {
229  for (std::map<std::string,UniValue::VType>::const_iterator it = t.begin();
230  it != t.end(); ++it) {
231  size_t idx = 0;
232  if (!findKey(it->first, idx))
233  return false;
234 
235  if (values.at(idx).getType() != it->second)
236  return false;
237  }
238 
239  return true;
240 }
241 
242 const UniValue& UniValue::operator[](const std::string& key) const
243 {
244  if (typ != VOBJ)
245  return NullUniValue;
246 
247  size_t index = 0;
248  if (!findKey(key, index))
249  return NullUniValue;
250 
251  return values.at(index);
252 }
253 
254 const UniValue& UniValue::operator[](size_t index) const
255 {
256  if (typ != VOBJ && typ != VARR)
257  return NullUniValue;
258  if (index >= values.size())
259  return NullUniValue;
260 
261  return values.at(index);
262 }
263 
265 {
266  switch (t) {
267  case UniValue::VNULL: return "null";
268  case UniValue::VBOOL: return "bool";
269  case UniValue::VOBJ: return "object";
270  case UniValue::VARR: return "array";
271  case UniValue::VSTR: return "string";
272  case UniValue::VNUM: return "number";
273  }
274 
275  // not reached
276  return NULL;
277 }
278 
279 const UniValue& find_value(const UniValue& obj, const std::string& name)
280 {
281  for (unsigned int i = 0; i < obj.keys.size(); i++)
282  if (obj.keys[i] == name)
283  return obj.values.at(i);
284 
285  return NullUniValue;
286 }
287 
288 const std::vector<std::string>& UniValue::getKeys() const
289 {
290  if (typ != VOBJ)
291  throw std::runtime_error("JSON value is not an object as expected");
292  return keys;
293 }
294 
295 const std::vector<UniValue>& UniValue::getValues() const
296 {
297  if (typ != VOBJ && typ != VARR)
298  throw std::runtime_error("JSON value is not an object or array as expected");
299  return values;
300 }
301 
302 bool UniValue::get_bool() const
303 {
304  if (typ != VBOOL)
305  throw std::runtime_error("JSON value is not a boolean as expected");
306  return getBool();
307 }
308 
309 const std::string& UniValue::get_str() const
310 {
311  if (typ != VSTR)
312  throw std::runtime_error("JSON value is not a string as expected");
313  return getValStr();
314 }
315 
316 int UniValue::get_int() const
317 {
318  if (typ != VNUM)
319  throw std::runtime_error("JSON value is not an integer as expected");
320  int32_t retval;
321  if (!ParseInt32(getValStr(), &retval))
322  throw std::runtime_error("JSON integer out of range");
323  return retval;
324 }
325 
326 int64_t UniValue::get_int64() const
327 {
328  if (typ != VNUM)
329  throw std::runtime_error("JSON value is not an integer as expected");
330  int64_t retval;
331  if (!ParseInt64(getValStr(), &retval))
332  throw std::runtime_error("JSON integer out of range");
333  return retval;
334 }
335 
336 double UniValue::get_real() const
337 {
338  if (typ != VNUM)
339  throw std::runtime_error("JSON value is not a number as expected");
340  double retval;
341  if (!ParseDouble(getValStr(), &retval))
342  throw std::runtime_error("JSON double out of range");
343  return retval;
344 }
345 
347 {
348  if (typ != VOBJ)
349  throw std::runtime_error("JSON value is not an object as expected");
350  return *this;
351 }
352 
354 {
355  if (typ != VARR)
356  throw std::runtime_error("JSON value is not an array as expected");
357  return *this;
358 }
359 
NullUniValue
const UniValue NullUniValue
Definition: univalue.cpp:78
getJsonToken
enum jtokentype getJsonToken(std::string &tokenVal, unsigned int &consumed, const char *raw, const char *end)
UniValue::checkObject
bool checkObject(const std::map< std::string, UniValue::VType > &memberTypes)
Definition: univalue.cpp:227
UniValue::typ
UniValue::VType typ
Definition: univalue.h:146
UniValue::VOBJ
@ VOBJ
Definition: univalue.h:21
UniValue::get_bool
bool get_bool() const
Definition: univalue.cpp:302
UniValue::clear
void clear()
Definition: univalue.cpp:80
UniValue::VType
VType
Definition: univalue.h:21
UniValue::values
std::vector< UniValue > values
Definition: univalue.h:149
UniValue::operator[]
const UniValue & operator[](const std::string &key) const
Definition: univalue.cpp:242
ParseInt64
bool ParseInt64(const std::string &str, int64_t *out)
Convert string to signed 64-bit integer with strict parse error feedback.
Definition: utilstrencodings.cpp:498
UniValue::pushKV
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:192
UniValue
Definition: univalue.h:19
UniValue::setNull
bool setNull()
Definition: univalue.cpp:88
UniValue::get_str
const std::string & get_str() const
Definition: univalue.cpp:309
UniValue::get_int64
int64_t get_int64() const
Definition: univalue.cpp:326
JTOK_NUMBER
@ JTOK_NUMBER
Definition: univalue.h:251
UniValue::get_obj
const UniValue & get_obj() const
Definition: univalue.cpp:346
UniValue::pushKVs
bool pushKVs(const UniValue &obj)
Definition: univalue.cpp:202
UniValue::setInt
bool setInt(uint64_t val)
Definition: univalue.cpp:122
UniValue::VBOOL
@ VBOOL
Definition: univalue.h:21
univalue.h
UniValue::push_backV
bool push_backV(const std::vector< UniValue > &vec)
Definition: univalue.cpp:182
UniValue::getKeys
const std::vector< std::string > & getKeys() const
Definition: univalue.cpp:288
UniValue::VNUM
@ VNUM
Definition: univalue.h:21
name
const char * name
Definition: rest.cpp:34
ParseDouble
bool ParseDouble(const std::string &str, double *out)
Convert string to double with strict parse error feedback.
Definition: utilstrencodings.cpp:513
UniValue::setNumStr
bool setNumStr(const std::string &val)
Definition: univalue.cpp:111
UniValue::get_int
int get_int() const
Definition: univalue.cpp:316
key
CKey key
Definition: bip38tooldialog.cpp:173
std
Definition: adjacency_graphs.hpp:25
UniValue::keys
std::vector< std::string > keys
Definition: univalue.h:148
UniValue::push_back
bool push_back(const UniValue &val)
Definition: univalue.cpp:173
UniValue::getValues
const std::vector< UniValue > & getValues() const
Definition: univalue.cpp:295
UniValue::get_real
double get_real() const
Definition: univalue.cpp:336
UniValue::setBool
bool setBool(bool val)
Definition: univalue.cpp:94
UniValue::findKey
bool findKey(const std::string &key, size_t &retIdx) const
Definition: univalue.cpp:215
ParseInt32
bool ParseInt32(const std::string &str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
Definition: utilstrencodings.cpp:482
jtokentype
jtokentype
Definition: univalue.h:239
UniValue::get_array
const UniValue & get_array() const
Definition: univalue.cpp:353
UniValue::VARR
@ VARR
Definition: univalue.h:21
UniValue::VNULL
@ VNULL
Definition: univalue.h:21
UniValue::VSTR
@ VSTR
Definition: univalue.h:21
UniValue::setObject
bool setObject()
Definition: univalue.cpp:166
UniValue::setFloat
bool setFloat(double val)
Definition: univalue.cpp:140
UniValue::setStr
bool setStr(const std::string &val)
Definition: univalue.cpp:151
find_value
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:279
UniValue::setArray
bool setArray()
Definition: univalue.cpp:159
uvTypeName
const char * uvTypeName(UniValue::VType t)
Definition: univalue.cpp:264