aboutsummaryrefslogtreecommitdiff
path: root/src/univalue
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2015-06-04 11:40:03 +0200
committerJonas Schnelli <jonas.schnelli@include7.ch>2015-06-04 13:18:57 +0200
commitc02309204b8195476945f7066e8d96c60246db08 (patch)
tree3a550d0ff86d1bd557c793441b23df0d7725c68f /src/univalue
parent7e98a3c642222edc0813ced945d4b6e548cb8ca8 (diff)
downloadbitcoin-c02309204b8195476945f7066e8d96c60246db08.tar.xz
univalue: add strict type checking
Diffstat (limited to 'src/univalue')
-rw-r--r--src/univalue/univalue.cpp79
-rw-r--r--src/univalue/univalue.h32
2 files changed, 91 insertions, 20 deletions
diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp
index e8fc513433..6920c44c96 100644
--- a/src/univalue/univalue.cpp
+++ b/src/univalue/univalue.cpp
@@ -6,8 +6,12 @@
#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;
@@ -224,4 +228,77 @@ const UniValue& find_value( const UniValue& obj, const std::string& name)
}
return NullUniValue;
-} \ No newline at end of file
+}
+
+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;
+}
+
diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h
index 57a96abe26..79018bb787 100644
--- a/src/univalue/univalue.h
+++ b/src/univalue/univalue.h
@@ -13,7 +13,6 @@
#include <sstream> // .get_int64()
#include <utility> // std::pair
-#include <stdlib.h> // atoi(), atof() TODO: remove
class UniValue {
public:
@@ -75,7 +74,7 @@ public:
bool isNull() const { return (typ == VNULL); }
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 isStr() const { return (typ == VSTR); }
bool isNum() const { return (typ == VNUM); }
@@ -140,27 +139,22 @@ private:
void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
public:
- //
- // The following were added for compatibility with json_spirit.
- // Most duplicate other methods, and should be removed.
- //
- std::vector<std::string> getKeys() const { return keys; }
- std::vector<UniValue> getValues() const { return values; }
- bool get_bool() const { return getBool(); }
- std::string get_str() const { return getValStr(); }
- int get_int() const { return atoi(getValStr().c_str()); }
- double get_real() const { return atof(getValStr().c_str()); }
- const UniValue& get_obj() const { return *this; }
- const UniValue& get_array() const { return *this; }
+ // 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);
}
- 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);
};