diff options
author | Jonas Schnelli <jonas.schnelli@include7.ch> | 2015-09-04 16:59:04 +0200 |
---|---|---|
committer | Jonas Schnelli <dev@jonasschnelli.ch> | 2015-10-01 10:36:50 +0200 |
commit | 0917306fdf39b12556b95fe91be2e7b44d34bb9f (patch) | |
tree | 49e89d23481cb667edae981c01a12a35069d9990 /src/univalue | |
parent | 1119cc3f5918575ca397518c9fd31a64704c7e4f (diff) |
remove univalue, prepare for subtree
Diffstat (limited to 'src/univalue')
-rw-r--r-- | src/univalue/gen.cpp | 77 | ||||
-rw-r--r-- | src/univalue/univalue.cpp | 303 | ||||
-rw-r--r-- | src/univalue/univalue.h | 248 | ||||
-rw-r--r-- | src/univalue/univalue_escapes.h | 262 | ||||
-rw-r--r-- | src/univalue/univalue_read.cpp | 389 | ||||
-rw-r--r-- | src/univalue/univalue_write.cpp | 127 |
6 files changed, 0 insertions, 1406 deletions
diff --git a/src/univalue/gen.cpp b/src/univalue/gen.cpp deleted file mode 100644 index 5e5a4d4aed..0000000000 --- a/src/univalue/gen.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2014 BitPay Inc. -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -// -// To re-create univalue_escapes.h: -// $ g++ -o gen gen.cpp -// $ ./gen > univalue_escapes.h -// - -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include "univalue.h" - -using namespace std; - -static bool initEscapes; -static const char *escapes[256]; - -static void initJsonEscape() -{ - escapes[(int)'"'] = "\\\""; - escapes[(int)'\\'] = "\\\\"; - escapes[(int)'\b'] = "\\b"; - escapes[(int)'\f'] = "\\f"; - escapes[(int)'\n'] = "\\n"; - escapes[(int)'\r'] = "\\r"; - escapes[(int)'\t'] = "\\t"; - - initEscapes = true; -} - -static void outputEscape() -{ - printf( "// Automatically generated file. Do not modify.\n" - "#ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n" - "#define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n" - "static const char *escapes[256] = {\n"); - - for (unsigned int i = 0; i < 256; i++) { - if (!escapes[i]) { - printf("\tNULL,\n"); - } else { - printf("\t\""); - - unsigned int si; - for (si = 0; si < strlen(escapes[i]); si++) { - char ch = escapes[i][si]; - switch (ch) { - case '"': - printf("\\\""); - break; - case '\\': - printf("\\\\"); - break; - default: - printf("%c", escapes[i][si]); - break; - } - } - - printf("\",\n"); - } - } - - printf( "};\n" - "#endif // BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H\n"); -} - -int main (int argc, char *argv[]) -{ - initJsonEscape(); - outputEscape(); - return 0; -} - diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp deleted file mode 100644 index 1d49a2cfc9..0000000000 --- a/src/univalue/univalue.cpp +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright 2014 BitPay Inc. -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include <stdint.h> -#include <ctype.h> -#include <iomanip> -#include <sstream> -#include <stdexcept> // std::runtime_error - -#include "univalue.h" - -#include "utilstrencodings.h" // ParseXX - -using namespace std; - -const UniValue NullUniValue; - -void UniValue::clear() -{ - typ = VNULL; - val.clear(); - keys.clear(); - values.clear(); -} - -bool UniValue::setNull() -{ - clear(); - return true; -} - -bool UniValue::setBool(bool val_) -{ - clear(); - typ = VBOOL; - if (val_) - val = "1"; - return true; -} - -static bool validNumStr(const string& s) -{ - string tokenVal; - unsigned int consumed; - enum jtokentype tt = getJsonToken(tokenVal, consumed, s.c_str()); - return (tt == JTOK_NUMBER); -} - -bool UniValue::setNumStr(const string& val_) -{ - if (!validNumStr(val_)) - return false; - - clear(); - typ = VNUM; - val = val_; - return true; -} - -bool UniValue::setInt(uint64_t val) -{ - string s; - ostringstream oss; - - oss << val; - - return setNumStr(oss.str()); -} - -bool UniValue::setInt(int64_t val) -{ - string s; - ostringstream oss; - - oss << val; - - return setNumStr(oss.str()); -} - -bool UniValue::setFloat(double val) -{ - string s; - ostringstream oss; - - oss << std::setprecision(16) << val; - - bool ret = setNumStr(oss.str()); - typ = VNUM; - return ret; -} - -bool UniValue::setStr(const string& val_) -{ - clear(); - typ = VSTR; - val = val_; - return true; -} - -bool UniValue::setArray() -{ - clear(); - typ = VARR; - return true; -} - -bool UniValue::setObject() -{ - clear(); - typ = VOBJ; - return true; -} - -bool UniValue::push_back(const UniValue& val) -{ - if (typ != VARR) - return false; - - values.push_back(val); - return true; -} - -bool UniValue::push_backV(const std::vector<UniValue>& vec) -{ - if (typ != VARR) - return false; - - values.insert(values.end(), vec.begin(), vec.end()); - - return true; -} - -bool UniValue::pushKV(const std::string& key, const UniValue& val) -{ - if (typ != VOBJ) - return false; - - keys.push_back(key); - values.push_back(val); - return true; -} - -bool UniValue::pushKVs(const UniValue& obj) -{ - if (typ != VOBJ || obj.typ != VOBJ) - return false; - - for (unsigned int i = 0; i < obj.keys.size(); i++) { - keys.push_back(obj.keys[i]); - values.push_back(obj.values[i]); - } - - return true; -} - -int UniValue::findKey(const std::string& key) const -{ - for (unsigned int i = 0; i < keys.size(); i++) { - if (keys[i] == key) - return (int) i; - } - - return -1; -} - -bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t) -{ - for (std::map<std::string,UniValue::VType>::const_iterator it = t.begin(); - it != t.end(); it++) { - int idx = findKey(it->first); - if (idx < 0) - return false; - - if (values[idx].getType() != it->second) - return false; - } - - return true; -} - -const UniValue& UniValue::operator[](const std::string& key) const -{ - if (typ != VOBJ) - return NullUniValue; - - int index = findKey(key); - if (index < 0) - return NullUniValue; - - return values[index]; -} - -const UniValue& UniValue::operator[](unsigned int index) const -{ - if (typ != VOBJ && typ != VARR) - return NullUniValue; - if (index >= values.size()) - return NullUniValue; - - return values[index]; -} - -const char *uvTypeName(UniValue::VType t) -{ - switch (t) { - case UniValue::VNULL: return "null"; - case UniValue::VBOOL: return "bool"; - case UniValue::VOBJ: return "object"; - case UniValue::VARR: return "array"; - case UniValue::VSTR: return "string"; - case UniValue::VNUM: return "number"; - } - - // not reached - return NULL; -} - -const UniValue& find_value( const UniValue& obj, const std::string& name) -{ - for (unsigned int i = 0; i < obj.keys.size(); i++) - { - if( obj.keys[i] == name ) - { - return obj.values[i]; - } - } - - return NullUniValue; -} - -std::vector<std::string> UniValue::getKeys() const -{ - if (typ != VOBJ) - throw std::runtime_error("JSON value is not an object as expected"); - return keys; -} - -std::vector<UniValue> UniValue::getValues() const -{ - if (typ != VOBJ && typ != VARR) - throw std::runtime_error("JSON value is not an object or array as expected"); - return values; -} - -bool UniValue::get_bool() const -{ - if (typ != VBOOL) - throw std::runtime_error("JSON value is not a boolean as expected"); - return getBool(); -} - -std::string UniValue::get_str() const -{ - if (typ != VSTR) - throw std::runtime_error("JSON value is not a string as expected"); - return getValStr(); -} - -int UniValue::get_int() const -{ - if (typ != VNUM) - throw std::runtime_error("JSON value is not an integer as expected"); - int32_t retval; - if (!ParseInt32(getValStr(), &retval)) - throw std::runtime_error("JSON integer out of range"); - return retval; -} - -int64_t UniValue::get_int64() const -{ - if (typ != VNUM) - throw std::runtime_error("JSON value is not an integer as expected"); - int64_t retval; - if (!ParseInt64(getValStr(), &retval)) - throw std::runtime_error("JSON integer out of range"); - return retval; -} - -double UniValue::get_real() const -{ - if (typ != VNUM) - throw std::runtime_error("JSON value is not a number as expected"); - double retval; - if (!ParseDouble(getValStr(), &retval)) - throw std::runtime_error("JSON double out of range"); - return retval; -} - -const UniValue& UniValue::get_obj() const -{ - if (typ != VOBJ) - throw std::runtime_error("JSON value is not an object as expected"); - return *this; -} - -const UniValue& UniValue::get_array() const -{ - if (typ != VARR) - throw std::runtime_error("JSON value is not an array as expected"); - return *this; -} - diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h deleted file mode 100644 index 4742b56f3d..0000000000 --- a/src/univalue/univalue.h +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright 2014 BitPay Inc. -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_UNIVALUE_UNIVALUE_H -#define BITCOIN_UNIVALUE_UNIVALUE_H - -#include <stdint.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(); } - bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes); - const UniValue& operator[](const std::string& key) const; - const UniValue& operator[](unsigned int index) const; - bool exists(const std::string& key) const { return (findKey(key) >= 0); } - - 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_backV(const std::vector<UniValue>& vec); - - 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); - bool read(const std::string& rawStr) { - return read(rawStr.c_str()); - } - -private: - UniValue::VType typ; - std::string val; // numbers are stored as C++ strings - std::vector<std::string> keys; - std::vector<UniValue> values; - - int findKey(const std::string& key) 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 - std::vector<std::string> getKeys() const; - std::vector<UniValue> getValues() const; - bool get_bool() 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); -extern const char *uvTypeName(UniValue::VType t); - -extern const UniValue NullUniValue; - -const UniValue& find_value( const UniValue& obj, const std::string& name); - -#endif // BITCOIN_UNIVALUE_UNIVALUE_H diff --git a/src/univalue/univalue_escapes.h b/src/univalue/univalue_escapes.h deleted file mode 100644 index 4133b24ca1..0000000000 --- a/src/univalue/univalue_escapes.h +++ /dev/null @@ -1,262 +0,0 @@ -// Automatically generated file. Do not modify. -#ifndef BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H -#define BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H -static const char *escapes[256] = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "\\b", - "\\t", - "\\n", - NULL, - "\\f", - "\\r", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "\\\"", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - "\\\\", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -}; -#endif // BITCOIN_UNIVALUE_UNIVALUE_ESCAPES_H diff --git a/src/univalue/univalue_read.cpp b/src/univalue/univalue_read.cpp deleted file mode 100644 index 64591234cb..0000000000 --- a/src/univalue/univalue_read.cpp +++ /dev/null @@ -1,389 +0,0 @@ -// Copyright 2014 BitPay Inc. -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include <string.h> -#include <vector> -#include <stdio.h> -#include "univalue.h" - -using namespace std; - -// convert hexadecimal string to unsigned integer -static const char *hatoui(const char *first, const char *last, - unsigned int& out) -{ - unsigned int result = 0; - for (; first != last; ++first) - { - int digit; - if (isdigit(*first)) - digit = *first - '0'; - - else if (*first >= 'a' && *first <= 'f') - digit = *first - 'a' + 10; - - else if (*first >= 'A' && *first <= 'F') - digit = *first - 'A' + 10; - - else - break; - - result = 16 * result + digit; - } - out = result; - - return first; -} - -enum jtokentype getJsonToken(string& tokenVal, unsigned int& consumed, - const char *raw) -{ - tokenVal.clear(); - consumed = 0; - - const char *rawStart = raw; - - while ((*raw) && (isspace(*raw))) // skip whitespace - raw++; - - switch (*raw) { - - case 0: - return JTOK_NONE; - - case '{': - raw++; - consumed = (raw - rawStart); - return JTOK_OBJ_OPEN; - case '}': - raw++; - consumed = (raw - rawStart); - return JTOK_OBJ_CLOSE; - case '[': - raw++; - consumed = (raw - rawStart); - return JTOK_ARR_OPEN; - case ']': - raw++; - consumed = (raw - rawStart); - return JTOK_ARR_CLOSE; - - case ':': - raw++; - consumed = (raw - rawStart); - return JTOK_COLON; - case ',': - raw++; - consumed = (raw - rawStart); - return JTOK_COMMA; - - case 'n': - case 't': - case 'f': - if (!strncmp(raw, "null", 4)) { - raw += 4; - consumed = (raw - rawStart); - return JTOK_KW_NULL; - } else if (!strncmp(raw, "true", 4)) { - raw += 4; - consumed = (raw - rawStart); - return JTOK_KW_TRUE; - } else if (!strncmp(raw, "false", 5)) { - raw += 5; - consumed = (raw - rawStart); - return JTOK_KW_FALSE; - } else - return JTOK_ERR; - - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { - // part 1: int - string numStr; - - const char *first = raw; - - const char *firstDigit = first; - if (!isdigit(*firstDigit)) - firstDigit++; - if ((*firstDigit == '0') && isdigit(firstDigit[1])) - return JTOK_ERR; - - numStr += *raw; // copy first char - raw++; - - if ((*first == '-') && (!isdigit(*raw))) - return JTOK_ERR; - - while ((*raw) && isdigit(*raw)) { // copy digits - numStr += *raw; - raw++; - } - - // part 2: frac - if (*raw == '.') { - numStr += *raw; // copy . - raw++; - - if (!isdigit(*raw)) - return JTOK_ERR; - while ((*raw) && isdigit(*raw)) { // copy digits - numStr += *raw; - raw++; - } - } - - // part 3: exp - if (*raw == 'e' || *raw == 'E') { - numStr += *raw; // copy E - raw++; - - if (*raw == '-' || *raw == '+') { // copy +/- - numStr += *raw; - raw++; - } - - if (!isdigit(*raw)) - return JTOK_ERR; - while ((*raw) && isdigit(*raw)) { // copy digits - numStr += *raw; - raw++; - } - } - - tokenVal = numStr; - consumed = (raw - rawStart); - return JTOK_NUMBER; - } - - case '"': { - raw++; // skip " - - string valStr; - - while (*raw) { - if (*raw < 0x20) - return JTOK_ERR; - - else if (*raw == '\\') { - raw++; // skip backslash - - switch (*raw) { - case '"': valStr += "\""; break; - case '\\': valStr += "\\"; break; - case '/': valStr += "/"; break; - case 'b': valStr += "\b"; break; - case 'f': valStr += "\f"; break; - case 'n': valStr += "\n"; break; - case 'r': valStr += "\r"; break; - case 't': valStr += "\t"; break; - - case 'u': { - unsigned int codepoint; - if (hatoui(raw + 1, raw + 1 + 4, codepoint) != - raw + 1 + 4) - return JTOK_ERR; - - if (codepoint <= 0x7f) - valStr.push_back((char)codepoint); - else if (codepoint <= 0x7FF) { - valStr.push_back((char)(0xC0 | (codepoint >> 6))); - valStr.push_back((char)(0x80 | (codepoint & 0x3F))); - } else if (codepoint <= 0xFFFF) { - valStr.push_back((char)(0xE0 | (codepoint >> 12))); - valStr.push_back((char)(0x80 | ((codepoint >> 6) & 0x3F))); - valStr.push_back((char)(0x80 | (codepoint & 0x3F))); - } - - raw += 4; - break; - } - default: - return JTOK_ERR; - - } - - raw++; // skip esc'd char - } - - else if (*raw == '"') { - raw++; // skip " - break; // stop scanning - } - - else { - valStr += *raw; - raw++; - } - } - - tokenVal = valStr; - consumed = (raw - rawStart); - return JTOK_STRING; - } - - default: - return JTOK_ERR; - } -} - -bool UniValue::read(const char *raw) -{ - clear(); - - bool expectName = false; - bool expectColon = false; - vector<UniValue*> stack; - - string tokenVal; - unsigned int consumed; - enum jtokentype tok = JTOK_NONE; - enum jtokentype last_tok = JTOK_NONE; - do { - last_tok = tok; - - tok = getJsonToken(tokenVal, consumed, raw); - if (tok == JTOK_NONE || tok == JTOK_ERR) - return false; - raw += consumed; - - switch (tok) { - - case JTOK_OBJ_OPEN: - case JTOK_ARR_OPEN: { - VType utyp = (tok == JTOK_OBJ_OPEN ? VOBJ : VARR); - if (!stack.size()) { - if (utyp == VOBJ) - setObject(); - else - setArray(); - stack.push_back(this); - } else { - UniValue tmpVal(utyp); - UniValue *top = stack.back(); - top->values.push_back(tmpVal); - - UniValue *newTop = &(top->values.back()); - stack.push_back(newTop); - } - - if (utyp == VOBJ) - expectName = true; - break; - } - - case JTOK_OBJ_CLOSE: - case JTOK_ARR_CLOSE: { - if (!stack.size() || expectColon || (last_tok == JTOK_COMMA)) - return false; - - VType utyp = (tok == JTOK_OBJ_CLOSE ? VOBJ : VARR); - UniValue *top = stack.back(); - if (utyp != top->getType()) - return false; - - stack.pop_back(); - expectName = false; - break; - } - - case JTOK_COLON: { - if (!stack.size() || expectName || !expectColon) - return false; - - UniValue *top = stack.back(); - if (top->getType() != VOBJ) - return false; - - expectColon = false; - break; - } - - case JTOK_COMMA: { - if (!stack.size() || expectName || expectColon || - (last_tok == JTOK_COMMA) || (last_tok == JTOK_ARR_OPEN)) - return false; - - UniValue *top = stack.back(); - if (top->getType() == VOBJ) - expectName = true; - break; - } - - case JTOK_KW_NULL: - case JTOK_KW_TRUE: - case JTOK_KW_FALSE: { - if (!stack.size() || expectName || expectColon) - return false; - - UniValue tmpVal; - switch (tok) { - case JTOK_KW_NULL: - // do nothing more - break; - case JTOK_KW_TRUE: - tmpVal.setBool(true); - break; - case JTOK_KW_FALSE: - tmpVal.setBool(false); - break; - default: /* impossible */ break; - } - - UniValue *top = stack.back(); - top->values.push_back(tmpVal); - - break; - } - - case JTOK_NUMBER: { - if (!stack.size() || expectName || expectColon) - return false; - - UniValue tmpVal(VNUM, tokenVal); - UniValue *top = stack.back(); - top->values.push_back(tmpVal); - - break; - } - - case JTOK_STRING: { - if (!stack.size()) - return false; - - UniValue *top = stack.back(); - - if (expectName) { - top->keys.push_back(tokenVal); - expectName = false; - expectColon = true; - } else { - UniValue tmpVal(VSTR, tokenVal); - top->values.push_back(tmpVal); - } - - break; - } - - default: - return false; - } - } while (!stack.empty ()); - - /* Check that nothing follows the initial construct (parsed above). */ - tok = getJsonToken(tokenVal, consumed, raw); - if (tok != JTOK_NONE) - return false; - - return true; -} - diff --git a/src/univalue/univalue_write.cpp b/src/univalue/univalue_write.cpp deleted file mode 100644 index bce3997af7..0000000000 --- a/src/univalue/univalue_write.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2014 BitPay Inc. -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include <ctype.h> -#include <iomanip> -#include <sstream> -#include <stdio.h> -#include "univalue.h" -#include "univalue_escapes.h" - -// TODO: Using UTF8 - -using namespace std; - -static string json_escape(const string& inS) -{ - string outS; - outS.reserve(inS.size() * 2); - - for (unsigned int i = 0; i < inS.size(); i++) { - unsigned char ch = inS[i]; - const char *escStr = escapes[ch]; - - if (escStr) - outS += escStr; - - else if (isprint(ch)) - outS += ch; - - else { - char tmpesc[16]; - sprintf(tmpesc, "\\u%04x", ch); - outS += tmpesc; - } - } - - return outS; -} - -string UniValue::write(unsigned int prettyIndent, - unsigned int indentLevel) const -{ - string s; - s.reserve(1024); - - unsigned int modIndent = indentLevel; - if (modIndent == 0) - modIndent = 1; - - switch (typ) { - case VNULL: - s += "null"; - break; - case VOBJ: - writeObject(prettyIndent, modIndent, s); - break; - case VARR: - writeArray(prettyIndent, modIndent, s); - break; - case VSTR: - s += "\"" + json_escape(val) + "\""; - break; - case VNUM: - s += val; - break; - case VBOOL: - s += (val == "1" ? "true" : "false"); - break; - } - - return s; -} - -static void indentStr(unsigned int prettyIndent, unsigned int indentLevel, string& s) -{ - s.append(prettyIndent * indentLevel, ' '); -} - -void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, string& s) const -{ - s += "["; - if (prettyIndent) - s += "\n"; - - for (unsigned int i = 0; i < values.size(); i++) { - if (prettyIndent) - indentStr(prettyIndent, indentLevel, s); - s += values[i].write(prettyIndent, indentLevel + 1); - if (i != (values.size() - 1)) { - s += ","; - if (prettyIndent) - s += " "; - } - if (prettyIndent) - s += "\n"; - } - - if (prettyIndent) - indentStr(prettyIndent, indentLevel - 1, s); - s += "]"; -} - -void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, string& s) const -{ - s += "{"; - if (prettyIndent) - s += "\n"; - - for (unsigned int i = 0; i < keys.size(); i++) { - if (prettyIndent) - indentStr(prettyIndent, indentLevel, s); - s += "\"" + json_escape(keys[i]) + "\":"; - if (prettyIndent) - s += " "; - s += values[i].write(prettyIndent, indentLevel + 1); - if (i != (values.size() - 1)) - s += ","; - if (prettyIndent) - s += "\n"; - } - - if (prettyIndent) - indentStr(prettyIndent, indentLevel - 1, s); - s += "}"; -} - |