You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
303 lines
8.3 KiB
303 lines
8.3 KiB
// Copyright 2014 BitPay Inc. |
|
// Copyright 2015 Bitcoin Core Developers |
|
// Distributed under the MIT software license, see the accompanying |
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php. |
|
|
|
#ifndef __UNIVALUE_H__ |
|
#define __UNIVALUE_H__ |
|
|
|
#include <stdint.h> |
|
#include <string.h> |
|
|
|
#include <string> |
|
#include <vector> |
|
#include <map> |
|
#include <cassert> |
|
|
|
#include <sstream> // .get_int64() |
|
#include <utility> // std::pair |
|
|
|
class UniValue { |
|
public: |
|
enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, }; |
|
|
|
UniValue() { typ = VNULL; } |
|
UniValue(UniValue::VType initialType, const std::string& initialStr = "") { |
|
typ = initialType; |
|
val = initialStr; |
|
} |
|
UniValue(uint64_t val_) { |
|
setInt(val_); |
|
} |
|
UniValue(int64_t val_) { |
|
setInt(val_); |
|
} |
|
UniValue(bool val_) { |
|
setBool(val_); |
|
} |
|
UniValue(int val_) { |
|
setInt(val_); |
|
} |
|
UniValue(double val_) { |
|
setFloat(val_); |
|
} |
|
UniValue(const std::string& val_) { |
|
setStr(val_); |
|
} |
|
UniValue(const char *val_) { |
|
std::string s(val_); |
|
setStr(s); |
|
} |
|
~UniValue() {} |
|
|
|
void clear(); |
|
|
|
bool setNull(); |
|
bool setBool(bool val); |
|
bool setNumStr(const std::string& val); |
|
bool setInt(uint64_t val); |
|
bool setInt(int64_t val); |
|
bool setInt(int val_) { return setInt((int64_t)val_); } |
|
bool setFloat(double val); |
|
bool setStr(const std::string& val); |
|
bool setArray(); |
|
bool setObject(); |
|
|
|
enum VType getType() const { return typ; } |
|
const std::string& getValStr() const { return val; } |
|
bool empty() const { return (values.size() == 0); } |
|
|
|
size_t size() const { return values.size(); } |
|
|
|
bool getBool() const { return isTrue(); } |
|
void getObjMap(std::map<std::string,UniValue>& kv) const; |
|
bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes) const; |
|
const UniValue& operator[](const std::string& key) const; |
|
const UniValue& operator[](size_t index) const; |
|
bool exists(const std::string& key) const { size_t i; return findKey(key, i); } |
|
|
|
bool isNull() const { return (typ == VNULL); } |
|
bool isTrue() const { return (typ == VBOOL) && (val == "1"); } |
|
bool isFalse() const { return (typ == VBOOL) && (val != "1"); } |
|
bool isBool() const { return (typ == VBOOL); } |
|
bool isStr() const { return (typ == VSTR); } |
|
bool isNum() const { return (typ == VNUM); } |
|
bool isArray() const { return (typ == VARR); } |
|
bool isObject() const { return (typ == VOBJ); } |
|
|
|
bool push_back(const UniValue& val); |
|
bool push_back(const std::string& val_) { |
|
UniValue tmpVal(VSTR, val_); |
|
return push_back(tmpVal); |
|
} |
|
bool push_back(const char *val_) { |
|
std::string s(val_); |
|
return push_back(s); |
|
} |
|
bool push_back(uint64_t val_) { |
|
UniValue tmpVal(val_); |
|
return push_back(tmpVal); |
|
} |
|
bool push_back(int64_t val_) { |
|
UniValue tmpVal(val_); |
|
return push_back(tmpVal); |
|
} |
|
bool push_back(int val_) { |
|
UniValue tmpVal(val_); |
|
return push_back(tmpVal); |
|
} |
|
bool push_back(double val_) { |
|
UniValue tmpVal(val_); |
|
return push_back(tmpVal); |
|
} |
|
bool push_backV(const std::vector<UniValue>& vec); |
|
|
|
void __pushKV(const std::string& key, const UniValue& val); |
|
bool pushKV(const std::string& key, const UniValue& val); |
|
bool pushKV(const std::string& key, const std::string& val_) { |
|
UniValue tmpVal(VSTR, val_); |
|
return pushKV(key, tmpVal); |
|
} |
|
bool pushKV(const std::string& key, const char *val_) { |
|
std::string _val(val_); |
|
return pushKV(key, _val); |
|
} |
|
bool pushKV(const std::string& key, int64_t val_) { |
|
UniValue tmpVal(val_); |
|
return pushKV(key, tmpVal); |
|
} |
|
bool pushKV(const std::string& key, uint64_t val_) { |
|
UniValue tmpVal(val_); |
|
return pushKV(key, tmpVal); |
|
} |
|
bool pushKV(const std::string& key, int val_) { |
|
UniValue tmpVal((int64_t)val_); |
|
return pushKV(key, tmpVal); |
|
} |
|
bool pushKV(const std::string& key, double val_) { |
|
UniValue tmpVal(val_); |
|
return pushKV(key, tmpVal); |
|
} |
|
bool pushKVs(const UniValue& obj); |
|
|
|
std::string write(unsigned int prettyIndent = 0, |
|
unsigned int indentLevel = 0) const; |
|
|
|
bool read(const char *raw, size_t len); |
|
bool read(const char *raw) { return read(raw, strlen(raw)); } |
|
bool read(const std::string& rawStr) { |
|
return read(rawStr.data(), rawStr.size()); |
|
} |
|
|
|
private: |
|
UniValue::VType typ; |
|
std::string val; // numbers are stored as C++ strings |
|
std::vector<std::string> keys; |
|
std::vector<UniValue> values; |
|
|
|
bool findKey(const std::string& key, size_t& retIdx) const; |
|
void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; |
|
void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; |
|
|
|
public: |
|
// Strict type-specific getters, these throw std::runtime_error if the |
|
// value is of unexpected type |
|
const std::vector<std::string>& getKeys() const; |
|
const std::vector<UniValue>& getValues() const; |
|
bool get_bool() const; |
|
const std::string& get_str() const; |
|
int get_int() const; |
|
int64_t get_int64() const; |
|
double get_real() const; |
|
const UniValue& get_obj() const; |
|
const UniValue& get_array() const; |
|
|
|
enum VType type() const { return getType(); } |
|
bool push_back(std::pair<std::string,UniValue> pear) { |
|
return pushKV(pear.first, pear.second); |
|
} |
|
friend const UniValue& find_value( const UniValue& obj, const std::string& name); |
|
}; |
|
|
|
// |
|
// The following were added for compatibility with json_spirit. |
|
// Most duplicate other methods, and should be removed. |
|
// |
|
static inline std::pair<std::string,UniValue> Pair(const char *cKey, const char *cVal) |
|
{ |
|
std::string key(cKey); |
|
UniValue uVal(cVal); |
|
return std::make_pair(key, uVal); |
|
} |
|
|
|
static inline std::pair<std::string,UniValue> Pair(const char *cKey, std::string strVal) |
|
{ |
|
std::string key(cKey); |
|
UniValue uVal(strVal); |
|
return std::make_pair(key, uVal); |
|
} |
|
|
|
static inline std::pair<std::string,UniValue> Pair(const char *cKey, uint64_t u64Val) |
|
{ |
|
std::string key(cKey); |
|
UniValue uVal(u64Val); |
|
return std::make_pair(key, uVal); |
|
} |
|
|
|
static inline std::pair<std::string,UniValue> Pair(const char *cKey, int64_t i64Val) |
|
{ |
|
std::string key(cKey); |
|
UniValue uVal(i64Val); |
|
return std::make_pair(key, uVal); |
|
} |
|
|
|
static inline std::pair<std::string,UniValue> Pair(const char *cKey, bool iVal) |
|
{ |
|
std::string key(cKey); |
|
UniValue uVal(iVal); |
|
return std::make_pair(key, uVal); |
|
} |
|
|
|
static inline std::pair<std::string,UniValue> Pair(const char *cKey, int iVal) |
|
{ |
|
std::string key(cKey); |
|
UniValue uVal(iVal); |
|
return std::make_pair(key, uVal); |
|
} |
|
|
|
static inline std::pair<std::string,UniValue> Pair(const char *cKey, double dVal) |
|
{ |
|
std::string key(cKey); |
|
UniValue uVal(dVal); |
|
return std::make_pair(key, uVal); |
|
} |
|
|
|
static inline std::pair<std::string,UniValue> Pair(const char *cKey, const UniValue& uVal) |
|
{ |
|
std::string key(cKey); |
|
return std::make_pair(key, uVal); |
|
} |
|
|
|
static inline std::pair<std::string,UniValue> Pair(std::string key, const UniValue& uVal) |
|
{ |
|
return std::make_pair(key, uVal); |
|
} |
|
|
|
enum jtokentype { |
|
JTOK_ERR = -1, |
|
JTOK_NONE = 0, // eof |
|
JTOK_OBJ_OPEN, |
|
JTOK_OBJ_CLOSE, |
|
JTOK_ARR_OPEN, |
|
JTOK_ARR_CLOSE, |
|
JTOK_COLON, |
|
JTOK_COMMA, |
|
JTOK_KW_NULL, |
|
JTOK_KW_TRUE, |
|
JTOK_KW_FALSE, |
|
JTOK_NUMBER, |
|
JTOK_STRING, |
|
}; |
|
|
|
extern enum jtokentype getJsonToken(std::string& tokenVal, |
|
unsigned int& consumed, const char *raw, const char *end); |
|
extern const char *uvTypeName(UniValue::VType t); |
|
|
|
static inline bool jsonTokenIsValue(enum jtokentype jtt) |
|
{ |
|
switch (jtt) { |
|
case JTOK_KW_NULL: |
|
case JTOK_KW_TRUE: |
|
case JTOK_KW_FALSE: |
|
case JTOK_NUMBER: |
|
case JTOK_STRING: |
|
return true; |
|
|
|
default: |
|
return false; |
|
} |
|
|
|
// not reached |
|
} |
|
|
|
static inline bool json_isspace(int ch) |
|
{ |
|
switch (ch) { |
|
case 0x20: |
|
case 0x09: |
|
case 0x0a: |
|
case 0x0d: |
|
return true; |
|
|
|
default: |
|
return false; |
|
} |
|
|
|
// not reached |
|
} |
|
|
|
extern const UniValue NullUniValue; |
|
|
|
const UniValue& find_value( const UniValue& obj, const std::string& name); |
|
|
|
#endif // __UNIVALUE_H__
|
|
|