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 https://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
class UniValue {
18
public:
19
    enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
20

            
21
1
    UniValue() { typ = VNULL; }
22
    UniValue(UniValue::VType initialType, const std::string& initialStr = "") {
23
        typ = initialType;
24
        val = initialStr;
25
    }
26
    UniValue(uint64_t val_) {
27
        setInt(val_);
28
    }
29
    UniValue(int64_t val_) {
30
        setInt(val_);
31
    }
32
    UniValue(bool val_) {
33
        setBool(val_);
34
    }
35
    UniValue(int val_) {
36
        setInt(val_);
37
    }
38
    UniValue(double val_) {
39
        setFloat(val_);
40
    }
41
    UniValue(const std::string& val_) {
42
        setStr(val_);
43
    }
44
    UniValue(const char *val_) {
45
        std::string s(val_);
46
        setStr(s);
47
    }
48

            
49
    void clear();
50

            
51
    bool setNull();
52
    bool setBool(bool val);
53
    bool setNumStr(const std::string& val);
54
    bool setInt(uint64_t val);
55
    bool setInt(int64_t val);
56
    bool setInt(int val_) { return setInt((int64_t)val_); }
57
    bool setFloat(double val);
58
    bool setStr(const std::string& val);
59
    bool setArray();
60
    bool setObject();
61

            
62
    enum VType getType() const { return typ; }
63
    const std::string& getValStr() const { return val; }
64
    bool empty() const { return (values.size() == 0); }
65

            
66
    size_t size() const { return values.size(); }
67

            
68
    bool getBool() const { return isTrue(); }
69
    void getObjMap(std::map<std::string,UniValue>& kv) const;
70
    bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes) const;
71
    const UniValue& operator[](const std::string& key) const;
72
    const UniValue& operator[](size_t index) const;
73
    bool exists(const std::string& key) const { size_t i; return findKey(key, i); }
74

            
75
    bool isNull() const { return (typ == VNULL); }
76
    bool isTrue() const { return (typ == VBOOL) && (val == "1"); }
77
    bool isFalse() const { return (typ == VBOOL) && (val != "1"); }
78
    bool isBool() const { return (typ == VBOOL); }
79
    bool isStr() const { return (typ == VSTR); }
80
    bool isNum() const { return (typ == VNUM); }
81
    bool isArray() const { return (typ == VARR); }
82
    bool isObject() const { return (typ == VOBJ); }
83

            
84
    bool push_back(const UniValue& val);
85
    bool push_back(const std::string& val_) {
86
        UniValue tmpVal(VSTR, val_);
87
        return push_back(tmpVal);
88
    }
89
    bool push_back(const char *val_) {
90
        std::string s(val_);
91
        return push_back(s);
92
    }
93
    bool push_back(uint64_t val_) {
94
        UniValue tmpVal(val_);
95
        return push_back(tmpVal);
96
    }
97
    bool push_back(int64_t val_) {
98
        UniValue tmpVal(val_);
99
        return push_back(tmpVal);
100
    }
101
    bool push_back(bool val_) {
102
        UniValue tmpVal(val_);
103
        return push_back(tmpVal);
104
    }
105
    bool push_back(int val_) {
106
        UniValue tmpVal(val_);
107
        return push_back(tmpVal);
108
    }
109
    bool push_back(double val_) {
110
        UniValue tmpVal(val_);
111
        return push_back(tmpVal);
112
    }
113
    bool push_backV(const std::vector<UniValue>& vec);
114

            
115
    void __pushKV(const std::string& key, const UniValue& val);
116
    bool pushKV(const std::string& key, const UniValue& val);
117
    bool pushKV(const std::string& key, const std::string& val_) {
118
        UniValue tmpVal(VSTR, val_);
119
        return pushKV(key, tmpVal);
120
    }
121
    bool pushKV(const std::string& key, const char *val_) {
122
        std::string _val(val_);
123
        return pushKV(key, _val);
124
    }
125
    bool pushKV(const std::string& key, int64_t val_) {
126
        UniValue tmpVal(val_);
127
        return pushKV(key, tmpVal);
128
    }
129
    bool pushKV(const std::string& key, uint64_t val_) {
130
        UniValue tmpVal(val_);
131
        return pushKV(key, tmpVal);
132
    }
133
    bool pushKV(const std::string& key, bool val_) {
134
        UniValue tmpVal(val_);
135
        return pushKV(key, tmpVal);
136
    }
137
    bool pushKV(const std::string& key, int val_) {
138
        UniValue tmpVal((int64_t)val_);
139
        return pushKV(key, tmpVal);
140
    }
141
    bool pushKV(const std::string& key, double val_) {
142
        UniValue tmpVal(val_);
143
        return pushKV(key, tmpVal);
144
    }
145
    bool pushKVs(const UniValue& obj);
146

            
147
    std::string write(unsigned int prettyIndent = 0,
148
                      unsigned int indentLevel = 0) const;
149

            
150
    bool read(const char *raw, size_t len);
151
    bool read(const char *raw) { return read(raw, strlen(raw)); }
152
    bool read(const std::string& rawStr) {
153
        return read(rawStr.data(), rawStr.size());
154
    }
155

            
156
private:
157
    UniValue::VType typ;
158
    std::string val;                       // numbers are stored as C++ strings
159
    std::vector<std::string> keys;
160
    std::vector<UniValue> values;
161

            
162
    bool findKey(const std::string& key, size_t& retIdx) const;
163
    void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
164
    void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
165

            
166
public:
167
    // Strict type-specific getters, these throw std::runtime_error if the
168
    // value is of unexpected type
169
    const std::vector<std::string>& getKeys() const;
170
    const std::vector<UniValue>& getValues() const;
171
    bool get_bool() const;
172
    const std::string& get_str() const;
173
    int get_int() const;
174
    int64_t get_int64() const;
175
    double get_real() const;
176
    const UniValue& get_obj() const;
177
    const UniValue& get_array() const;
178

            
179
    enum VType type() const { return getType(); }
180
    friend const UniValue& find_value( const UniValue& obj, const std::string& name);
181
};
182

            
183
enum jtokentype {
184
    JTOK_ERR        = -1,
185
    JTOK_NONE       = 0,                           // eof
186
    JTOK_OBJ_OPEN,
187
    JTOK_OBJ_CLOSE,
188
    JTOK_ARR_OPEN,
189
    JTOK_ARR_CLOSE,
190
    JTOK_COLON,
191
    JTOK_COMMA,
192
    JTOK_KW_NULL,
193
    JTOK_KW_TRUE,
194
    JTOK_KW_FALSE,
195
    JTOK_NUMBER,
196
    JTOK_STRING,
197
};
198

            
199
extern enum jtokentype getJsonToken(std::string& tokenVal,
200
                                    unsigned int& consumed, const char *raw, const char *end);
201
extern const char *uvTypeName(UniValue::VType t);
202

            
203
static inline bool jsonTokenIsValue(enum jtokentype jtt)
204
{
205
    switch (jtt) {
206
    case JTOK_KW_NULL:
207
    case JTOK_KW_TRUE:
208
    case JTOK_KW_FALSE:
209
    case JTOK_NUMBER:
210
    case JTOK_STRING:
211
        return true;
212

            
213
    default:
214
        return false;
215
    }
216

            
217
    // not reached
218
}
219

            
220
static inline bool json_isspace(int ch)
221
{
222
    switch (ch) {
223
    case 0x20:
224
    case 0x09:
225
    case 0x0a:
226
    case 0x0d:
227
        return true;
228

            
229
    default:
230
        return false;
231
    }
232

            
233
    // not reached
234
}
235

            
236
extern const UniValue NullUniValue;
237

            
238
const UniValue& find_value( const UniValue& obj, const std::string& name);
239

            
240
#endif // __UNIVALUE_H__