/ src / univalue / lib / univalue_get.cpp
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  }