Browse Source

univalue: add strict type checking

0.13
Wladimir J. van der Laan 10 years ago committed by Jonas Schnelli
parent
commit
c02309204b
  1. 79
      src/univalue/univalue.cpp
  2. 32
      src/univalue/univalue.h

79
src/univalue/univalue.cpp

@ -6,8 +6,12 @@
#include <ctype.h> #include <ctype.h>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include <stdexcept> // std::runtime_error
#include "univalue.h" #include "univalue.h"
#include "utilstrencodings.h" // ParseXX
using namespace std; using namespace std;
const UniValue NullUniValue; const UniValue NullUniValue;
@ -224,4 +228,77 @@ const UniValue& find_value( const UniValue& obj, const std::string& name)
} }
return NullUniValue; 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 != VREAL && 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;
}

32
src/univalue/univalue.h

@ -13,7 +13,6 @@
#include <sstream> // .get_int64() #include <sstream> // .get_int64()
#include <utility> // std::pair #include <utility> // std::pair
#include <stdlib.h> // atoi(), atof() TODO: remove
class UniValue { class UniValue {
public: public:
@ -75,7 +74,7 @@ public:
bool isNull() const { return (typ == VNULL); } bool isNull() const { return (typ == VNULL); }
bool isTrue() const { return (typ == VBOOL) && (val == "1"); } bool isTrue() const { return (typ == VBOOL) && (val == "1"); }
bool isFalse() const { return (!isTrue()); } bool isFalse() const { return (typ == VBOOL) && (val != "1"); }
bool isBool() const { return (typ == VBOOL); } bool isBool() const { return (typ == VBOOL); }
bool isStr() const { return (typ == VSTR); } bool isStr() const { return (typ == VSTR); }
bool isNum() const { return (typ == VNUM); } bool isNum() const { return (typ == VNUM); }
@ -140,27 +139,22 @@ private:
void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
public: public:
// // Strict type-specific getters, these throw std::runtime_error if the
// The following were added for compatibility with json_spirit. // value is of unexpected type
// Most duplicate other methods, and should be removed. std::vector<std::string> getKeys() const;
// std::vector<UniValue> getValues() const;
std::vector<std::string> getKeys() const { return keys; } bool get_bool() const;
std::vector<UniValue> getValues() const { return values; } std::string get_str() const;
bool get_bool() const { return getBool(); } int get_int() const;
std::string get_str() const { return getValStr(); } int64_t get_int64() const;
int get_int() const { return atoi(getValStr().c_str()); } double get_real() const;
double get_real() const { return atof(getValStr().c_str()); } const UniValue& get_obj() const;
const UniValue& get_obj() const { return *this; } const UniValue& get_array() const;
const UniValue& get_array() const { return *this; }
enum VType type() const { return getType(); } enum VType type() const { return getType(); }
bool push_back(std::pair<std::string,UniValue> pear) { bool push_back(std::pair<std::string,UniValue> pear) {
return pushKV(pear.first, pear.second); return pushKV(pear.first, pear.second);
} }
int64_t get_int64() const {
int64_t ret;
std::istringstream(getValStr()) >> ret;
return ret;
}
friend const UniValue& find_value( const UniValue& obj, const std::string& name); friend const UniValue& find_value( const UniValue& obj, const std::string& name);
}; };

Loading…
Cancel
Save