univalue_get.cpp
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 #include <univalue.h> 7 8 #include <cstring> 9 #include <locale> 10 #include <optional> 11 #include <sstream> 12 #include <stdexcept> 13 #include <string> 14 #include <vector> 15 16 namespace 17 { 18 static bool ParsePrechecks(const std::string& str) 19 { 20 if (str.empty()) // No empty string allowed 21 return false; 22 if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed 23 return false; 24 if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed 25 return false; 26 return true; 27 } 28 29 std::optional<double> ParseDouble(const std::string& str) 30 { 31 if (!ParsePrechecks(str)) 32 return std::nullopt; 33 if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed 34 return std::nullopt; 35 std::istringstream text(str); 36 text.imbue(std::locale::classic()); 37 double result; 38 text >> result; 39 if (!text.eof() || text.fail()) { 40 return std::nullopt; 41 } 42 return result; 43 } 44 } 45 46 const std::vector<std::string>& UniValue::getKeys() const 47 { 48 checkType(VOBJ); 49 return keys; 50 } 51 52 const std::vector<UniValue>& UniValue::getValues() const 53 { 54 if (typ != VOBJ && typ != VARR) 55 throw std::runtime_error("JSON value is not an object or array as expected"); 56 return values; 57 } 58 59 bool UniValue::get_bool() const 60 { 61 checkType(VBOOL); 62 return isTrue(); 63 } 64 65 const std::string& UniValue::get_str() const 66 { 67 checkType(VSTR); 68 return getValStr(); 69 } 70 71 double UniValue::get_real() const 72 { 73 checkType(VNUM); 74 if (const auto retval{ParseDouble(getValStr())}) { 75 return *retval; 76 } 77 throw std::runtime_error("JSON double out of range"); 78 } 79 80 const UniValue& UniValue::get_obj() const 81 { 82 checkType(VOBJ); 83 return *this; 84 } 85 86 const UniValue& UniValue::get_array() const 87 { 88 checkType(VARR); 89 return *this; 90 }