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 #ifndef __UNIVALUE_H__
7 #define __UNIVALUE_H__
8
9 #include <stdint.h>
10 #include <string.h>
11
12 #include <string>
13 #include <vector>
14 #include <map>
15 #include <cassert>
16
17 #include <sstream> // .get_int64()
18
19 class UniValue {
20 public:
21 enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
22
UniValue()23 UniValue() { typ = VNULL; }
24 UniValue(UniValue::VType initialType, const std::string& initialStr = "") {
25 typ = initialType;
26 val = initialStr;
27 }
UniValue(uint64_t val_)28 UniValue(uint64_t val_) {
29 setInt(val_);
30 }
UniValue(int64_t val_)31 UniValue(int64_t val_) {
32 setInt(val_);
33 }
UniValue(bool val_)34 UniValue(bool val_) {
35 setBool(val_);
36 }
UniValue(int val_)37 UniValue(int val_) {
38 setInt(val_);
39 }
UniValue(double val_)40 UniValue(double val_) {
41 setFloat(val_);
42 }
UniValue(const std::string & val_)43 UniValue(const std::string& val_) {
44 setStr(val_);
45 }
UniValue(const char * val_)46 UniValue(const char *val_) {
47 std::string s(val_);
48 setStr(s);
49 }
~UniValue()50 ~UniValue() {}
51
52 void clear();
53
54 bool setNull();
55 bool setBool(bool val);
56 bool setNumStr(const std::string& val);
57 bool setInt(uint64_t val);
58 bool setInt(int64_t val);
setInt(int val_)59 bool setInt(int val_) { return setInt((int64_t)val_); }
60 bool setFloat(double val);
61 bool setStr(const std::string& val);
62 bool setArray();
63 bool setObject();
64
getType()65 enum VType getType() const { return typ; }
getValStr()66 const std::string& getValStr() const { return val; }
empty()67 bool empty() const { return (values.size() == 0); }
68
size()69 size_t size() const { return values.size(); }
70
getBool()71 bool getBool() const { return isTrue(); }
72 void getObjMap(std::map<std::string,UniValue>& kv) const;
73 bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes) const;
74 const UniValue& operator[](const std::string& key) const;
75 const UniValue& operator[](size_t index) const;
exists(const std::string & key)76 bool exists(const std::string& key) const { size_t i; return findKey(key, i); }
77
isNull()78 bool isNull() const { return (typ == VNULL); }
isTrue()79 bool isTrue() const { return (typ == VBOOL) && (val == "1"); }
isFalse()80 bool isFalse() const { return (typ == VBOOL) && (val != "1"); }
isBool()81 bool isBool() const { return (typ == VBOOL); }
isStr()82 bool isStr() const { return (typ == VSTR); }
isNum()83 bool isNum() const { return (typ == VNUM); }
isArray()84 bool isArray() const { return (typ == VARR); }
isObject()85 bool isObject() const { return (typ == VOBJ); }
86
87 bool push_back(const UniValue& val);
push_back(const std::string & val_)88 bool push_back(const std::string& val_) {
89 UniValue tmpVal(VSTR, val_);
90 return push_back(tmpVal);
91 }
push_back(const char * val_)92 bool push_back(const char *val_) {
93 std::string s(val_);
94 return push_back(s);
95 }
push_back(uint64_t val_)96 bool push_back(uint64_t val_) {
97 UniValue tmpVal(val_);
98 return push_back(tmpVal);
99 }
push_back(int64_t val_)100 bool push_back(int64_t val_) {
101 UniValue tmpVal(val_);
102 return push_back(tmpVal);
103 }
push_back(int val_)104 bool push_back(int val_) {
105 UniValue tmpVal(val_);
106 return push_back(tmpVal);
107 }
push_back(double val_)108 bool push_back(double val_) {
109 UniValue tmpVal(val_);
110 return push_back(tmpVal);
111 }
112 bool push_backV(const std::vector<UniValue>& vec);
113
114 void __pushKV(const std::string& key, const UniValue& val);
115 bool pushKV(const std::string& key, const UniValue& val);
pushKV(const std::string & key,const std::string & val_)116 bool pushKV(const std::string& key, const std::string& val_) {
117 UniValue tmpVal(VSTR, val_);
118 return pushKV(key, tmpVal);
119 }
pushKV(const std::string & key,const char * val_)120 bool pushKV(const std::string& key, const char *val_) {
121 std::string _val(val_);
122 return pushKV(key, _val);
123 }
pushKV(const std::string & key,int64_t val_)124 bool pushKV(const std::string& key, int64_t val_) {
125 UniValue tmpVal(val_);
126 return pushKV(key, tmpVal);
127 }
pushKV(const std::string & key,uint64_t val_)128 bool pushKV(const std::string& key, uint64_t val_) {
129 UniValue tmpVal(val_);
130 return pushKV(key, tmpVal);
131 }
pushKV(const std::string & key,bool val_)132 bool pushKV(const std::string& key, bool val_) {
133 UniValue tmpVal((bool)val_);
134 return pushKV(key, tmpVal);
135 }
pushKV(const std::string & key,int val_)136 bool pushKV(const std::string& key, int val_) {
137 UniValue tmpVal((int64_t)val_);
138 return pushKV(key, tmpVal);
139 }
pushKV(const std::string & key,double val_)140 bool pushKV(const std::string& key, double val_) {
141 UniValue tmpVal(val_);
142 return pushKV(key, tmpVal);
143 }
144 bool pushKVs(const UniValue& obj);
145
146 std::string write(unsigned int prettyIndent = 0,
147 unsigned int indentLevel = 0) const;
148
149 bool read(const char *raw, size_t len);
read(const char * raw)150 bool read(const char *raw) { return read(raw, strlen(raw)); }
read(const std::string & rawStr)151 bool read(const std::string& rawStr) {
152 return read(rawStr.data(), rawStr.size());
153 }
154
155 private:
156 UniValue::VType typ;
157 std::string val; // numbers are stored as C++ strings
158 std::vector<std::string> keys;
159 std::vector<UniValue> values;
160
161 bool findKey(const std::string& key, size_t& retIdx) const;
162 void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
163 void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
164
165 public:
166 // Strict type-specific getters, these throw std::runtime_error if the
167 // value is of unexpected type
168 const std::vector<std::string>& getKeys() const;
169 const std::vector<UniValue>& getValues() const;
170 bool get_bool() const;
171 const std::string& get_str() const;
172 int get_int() const;
173 int64_t get_int64() const;
174 double get_real() const;
175 const UniValue& get_obj() const;
176 const UniValue& get_array() const;
177
type()178 enum VType type() const { return getType(); }
179 friend const UniValue& find_value( const UniValue& obj, const std::string& name);
180 };
181
182 enum jtokentype {
183 JTOK_ERR = -1,
184 JTOK_NONE = 0, // eof
185 JTOK_OBJ_OPEN,
186 JTOK_OBJ_CLOSE,
187 JTOK_ARR_OPEN,
188 JTOK_ARR_CLOSE,
189 JTOK_COLON,
190 JTOK_COMMA,
191 JTOK_KW_NULL,
192 JTOK_KW_TRUE,
193 JTOK_KW_FALSE,
194 JTOK_NUMBER,
195 JTOK_STRING,
196 };
197
198 extern enum jtokentype getJsonToken(std::string& tokenVal,
199 unsigned int& consumed, const char *raw, const char *end);
200 extern const char *uvTypeName(UniValue::VType t);
201
jsonTokenIsValue(enum jtokentype jtt)202 static inline bool jsonTokenIsValue(enum jtokentype jtt)
203 {
204 switch (jtt) {
205 case JTOK_KW_NULL:
206 case JTOK_KW_TRUE:
207 case JTOK_KW_FALSE:
208 case JTOK_NUMBER:
209 case JTOK_STRING:
210 return true;
211
212 default:
213 return false;
214 }
215
216 // not reached
217 }
218
json_isspace(int ch)219 static inline bool json_isspace(int ch)
220 {
221 switch (ch) {
222 case 0x20:
223 case 0x09:
224 case 0x0a:
225 case 0x0d:
226 return true;
227
228 default:
229 return false;
230 }
231
232 // not reached
233 }
234
235 extern const UniValue NullUniValue;
236
237 const UniValue& find_value( const UniValue& obj, const std::string& name);
238
239 #endif // __UNIVALUE_H__
240