LCOV - code coverage report
Current view: top level - src/univalue/include - univalue.h (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 22 45 48.9 %
Date: 2023-09-26 12:08:55 Functions: 29 88 33.0 %

          Line data    Source code
       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             : #ifndef BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
       7             : #define BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H
       8             : 
       9             : #include <charconv>
      10             : #include <cstddef>
      11             : #include <cstdint>
      12             : #include <map>
      13             : #include <stdexcept>
      14             : #include <string>
      15             : #include <string_view>
      16             : #include <system_error>
      17             : #include <type_traits>
      18             : #include <utility>
      19             : #include <vector>
      20             : 
      21         141 : class UniValue {
      22             : public:
      23             :     enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
      24             : 
      25             :     class type_error : public std::runtime_error
      26             :     {
      27             :         using std::runtime_error::runtime_error;
      28             :     };
      29             : 
      30       79252 :     UniValue() { typ = VNULL; }
      31           2 :     UniValue(UniValue::VType type, std::string str = {}) : typ{type}, val{std::move(str)} {}
      32             :     template <typename Ref, typename T = std::remove_cv_t<std::remove_reference_t<Ref>>,
      33             :               std::enable_if_t<std::is_floating_point_v<T> ||                      // setFloat
      34             :                                    std::is_same_v<bool, T> ||                      // setBool
      35             :                                    std::is_signed_v<T> || std::is_unsigned_v<T> || // setInt
      36             :                                    std::is_constructible_v<std::string, T>,        // setStr
      37             :                                bool> = true>
      38         661 :     UniValue(Ref&& val)
      39             :     {
      40             :         if constexpr (std::is_floating_point_v<T>) {
      41           2 :             setFloat(val);
      42             :         } else if constexpr (std::is_same_v<bool, T>) {
      43          45 :             setBool(val);
      44             :         } else if constexpr (std::is_signed_v<T>) {
      45          30 :             setInt(int64_t{val});
      46             :         } else if constexpr (std::is_unsigned_v<T>) {
      47           4 :             setInt(uint64_t{val});
      48             :         } else {
      49         580 :             setStr(std::string{std::forward<Ref>(val)});
      50             :         }
      51         661 :     }
      52             : 
      53             :     void clear();
      54             : 
      55             :     void setNull();
      56             :     void setBool(bool val);
      57             :     void setNumStr(std::string str);
      58             :     void setInt(uint64_t val);
      59             :     void setInt(int64_t val);
      60             :     void setInt(int val_) { return setInt(int64_t{val_}); }
      61             :     void setFloat(double val);
      62             :     void setStr(std::string str);
      63             :     void setArray();
      64             :     void setObject();
      65             : 
      66       54691 :     enum VType getType() const { return typ; }
      67          11 :     const std::string& getValStr() const { return val; }
      68           0 :     bool empty() const { return (values.size() == 0); }
      69             : 
      70           0 :     size_t size() const { return values.size(); }
      71             : 
      72             :     void getObjMap(std::map<std::string,UniValue>& kv) const;
      73             :     bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes) const;
      74             :     const UniValue& operator[](const std::string& key) const;
      75             :     const UniValue& operator[](size_t index) const;
      76           0 :     bool exists(const std::string& key) const { size_t i; return findKey(key, i); }
      77             : 
      78       79242 :     bool isNull() const { return (typ == VNULL); }
      79       10976 :     bool isTrue() const { return (typ == VBOOL) && (val == "1"); }
      80        9117 :     bool isFalse() const { return (typ == VBOOL) && (val != "1"); }
      81           4 :     bool isBool() const { return (typ == VBOOL); }
      82           0 :     bool isStr() const { return (typ == VSTR); }
      83           4 :     bool isNum() const { return (typ == VNUM); }
      84           3 :     bool isArray() const { return (typ == VARR); }
      85           0 :     bool isObject() const { return (typ == VOBJ); }
      86             : 
      87             :     void push_back(UniValue val);
      88             :     void push_backV(const std::vector<UniValue>& vec);
      89             :     template <class It>
      90             :     void push_backV(It first, It last);
      91             : 
      92             :     void pushKVEnd(std::string key, UniValue val);
      93             :     void pushKV(std::string key, UniValue val);
      94             :     void pushKVs(UniValue obj);
      95             : 
      96             :     std::string write(unsigned int prettyIndent = 0,
      97             :                       unsigned int indentLevel = 0) const;
      98             : 
      99             :     bool read(std::string_view raw);
     100             : 
     101             : private:
     102             :     UniValue::VType typ;
     103             :     std::string val;                       // numbers are stored as C++ strings
     104             :     std::vector<std::string> keys;
     105             :     std::vector<UniValue> values;
     106             : 
     107             :     void checkType(const VType& expected) const;
     108             :     bool findKey(const std::string& key, size_t& retIdx) const;
     109             :     void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
     110             :     void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const;
     111             : 
     112             : public:
     113             :     // Strict type-specific getters, these throw std::runtime_error if the
     114             :     // value is of unexpected type
     115             :     const std::vector<std::string>& getKeys() const;
     116             :     const std::vector<UniValue>& getValues() const;
     117             :     template <typename Int>
     118             :     Int getInt() const;
     119             :     bool get_bool() const;
     120             :     const std::string& get_str() const;
     121             :     double get_real() const;
     122             :     const UniValue& get_obj() const;
     123             :     const UniValue& get_array() const;
     124             : 
     125           0 :     enum VType type() const { return getType(); }
     126             :     const UniValue& find_value(std::string_view key) const;
     127             : };
     128             : 
     129             : template <class It>
     130           0 : void UniValue::push_backV(It first, It last)
     131             : {
     132           0 :     checkType(VARR);
     133           0 :     values.insert(values.end(), first, last);
     134           0 : }
     135             : 
     136             : template <typename Int>
     137           0 : Int UniValue::getInt() const
     138             : {
     139             :     static_assert(std::is_integral<Int>::value);
     140           0 :     checkType(VNUM);
     141             :     Int result;
     142           0 :     const auto [first_nonmatching, error_condition] = std::from_chars(val.data(), val.data() + val.size(), result);
     143           0 :     if (first_nonmatching != val.data() + val.size() || error_condition != std::errc{}) {
     144           0 :         throw std::runtime_error("JSON integer out of range");
     145             :     }
     146           0 :     return result;
     147           0 : }
     148             : 
     149             : enum jtokentype {
     150             :     JTOK_ERR        = -1,
     151             :     JTOK_NONE       = 0,                           // eof
     152             :     JTOK_OBJ_OPEN,
     153             :     JTOK_OBJ_CLOSE,
     154             :     JTOK_ARR_OPEN,
     155             :     JTOK_ARR_CLOSE,
     156             :     JTOK_COLON,
     157             :     JTOK_COMMA,
     158             :     JTOK_KW_NULL,
     159             :     JTOK_KW_TRUE,
     160             :     JTOK_KW_FALSE,
     161             :     JTOK_NUMBER,
     162             :     JTOK_STRING,
     163             : };
     164             : 
     165             : extern enum jtokentype getJsonToken(std::string& tokenVal,
     166             :                                     unsigned int& consumed, const char *raw, const char *end);
     167             : extern const char *uvTypeName(UniValue::VType t);
     168             : 
     169           0 : static inline bool jsonTokenIsValue(enum jtokentype jtt)
     170             : {
     171           0 :     switch (jtt) {
     172             :     case JTOK_KW_NULL:
     173             :     case JTOK_KW_TRUE:
     174             :     case JTOK_KW_FALSE:
     175             :     case JTOK_NUMBER:
     176             :     case JTOK_STRING:
     177           0 :         return true;
     178             : 
     179             :     default:
     180           0 :         return false;
     181             :     }
     182             : 
     183             :     // not reached
     184           0 : }
     185             : 
     186          36 : static inline bool json_isspace(int ch)
     187             : {
     188          36 :     switch (ch) {
     189             :     case 0x20:
     190             :     case 0x09:
     191             :     case 0x0a:
     192             :     case 0x0d:
     193           0 :         return true;
     194             : 
     195             :     default:
     196          36 :         return false;
     197             :     }
     198             : 
     199             :     // not reached
     200          36 : }
     201             : 
     202             : extern const UniValue NullUniValue;
     203             : 
     204             : #endif // BITCOIN_UNIVALUE_INCLUDE_UNIVALUE_H

Generated by: LCOV version 1.14