LCOV - code coverage report
Current view: top level - src/jamidht/eth/libdevcore - CommonData.h (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 10 13 76.9 %
Date: 2024-03-18 07:59:09 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /*
       2             :     This file is part of cpp-ethereum.
       3             : 
       4             :     cpp-ethereum is free software: you can redistribute it and/or modify
       5             :     it under the terms of the GNU General Public License as published by
       6             :     the Free Software Foundation, either version 3 of the License, or
       7             :     (at your option) any later version.
       8             : 
       9             :     cpp-ethereum is distributed in the hope that it will be useful,
      10             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :     GNU General Public License for more details.
      13             : 
      14             :     You should have received a copy of the GNU General Public License
      15             :     along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
      16             : */
      17             : /** @file CommonData.h
      18             :  * @author Gav Wood <i@gavwood.com>
      19             :  * @date 2014
      20             :  *
      21             :  * Shared algorithms and data types.
      22             :  */
      23             : 
      24             : #pragma once
      25             : 
      26             : #include <vector>
      27             : #include <algorithm>
      28             : #include <unordered_set>
      29             : #include <type_traits>
      30             : #include <cstring>
      31             : #include <string>
      32             : #include "Common.h"
      33             : 
      34             : namespace dev {
      35             : 
      36             : // String conversion functions, mainly to/from hex/nibble/byte representations.
      37             : 
      38             : enum class WhenError {
      39             :     DontThrow = 0,
      40             :     Throw = 1,
      41             : };
      42             : 
      43             : template<class Iterator>
      44             : std::string
      45         775 : toHex(Iterator _it, Iterator _end, std::string _prefix)
      46             : {
      47             :     typedef std::iterator_traits<Iterator> traits;
      48             :     static_assert(sizeof(typename traits::value_type) == 1, "toHex needs byte-sized element type");
      49             : 
      50             :     static char const* hexdigits = "0123456789abcdef";
      51         775 :     size_t off = _prefix.size();
      52         775 :     std::string hex(std::distance(_it, _end) * 2 + off, '0');
      53         775 :     hex.replace(0, off, _prefix);
      54       16275 :     for (; _it != _end; _it++) {
      55       15500 :         hex[off++] = hexdigits[(*_it >> 4) & 0x0f];
      56       15500 :         hex[off++] = hexdigits[*_it & 0x0f];
      57             :     }
      58         775 :     return hex;
      59           0 : }
      60             : 
      61             : /// Convert a series of bytes to the corresponding hex string.
      62             : /// @example toHex("A\x69") == "4169"
      63             : template<class T>
      64             : std::string
      65         775 : toHex(T const& _data)
      66             : {
      67         775 :     return toHex(_data.begin(), _data.end(), "");
      68             : }
      69             : 
      70             : /// Convert a series of bytes to the corresponding hex string with 0x prefix.
      71             : /// @example toHexPrefixed("A\x69") == "0x4169"
      72             : template<class T>
      73             : std::string
      74             : toHexPrefixed(T const& _data)
      75             : {
      76             :     return toHex(_data.begin(), _data.end(), "0x");
      77             : }
      78             : 
      79             : /// Converts a (printable) ASCII hex string into the corresponding byte stream.
      80             : /// @example fromHex("41626261") == asBytes("Abba")
      81             : /// If _throw = ThrowType::DontThrow, it replaces bad hex characters with 0's, otherwise it will
      82             : /// throw an exception.
      83             : bytes fromHex(std::string const& _s, WhenError _throw = WhenError::DontThrow);
      84             : 
      85             : /// @returns true if @a _s is a hex string.
      86             : bool isHex(std::string const& _s) noexcept;
      87             : 
      88             : /// @returns true if @a _hash is a hash conforming to FixedHash type @a T.
      89             : template<class T>
      90             : static bool
      91             : isHash(std::string const& _hash)
      92             : {
      93             :     return (_hash.size() == T::size * 2
      94             :             || (_hash.size() == T::size * 2 + 2 && _hash.substr(0, 2) == "0x"))
      95             :            && isHex(_hash);
      96             : }
      97             : 
      98             : /// Converts byte array to a string containing the same (binary) data. Unless
      99             : /// the byte array happens to contain ASCII data, this won't be printable.
     100             : inline std::string
     101             : asString(bytes const& _b)
     102             : {
     103             :     return std::string((char const*) _b.data(), (char const*) (_b.data() + _b.size()));
     104             : }
     105             : 
     106             : /// Converts byte array ref to a string containing the same (binary) data. Unless
     107             : /// the byte array happens to contain ASCII data, this won't be printable.
     108             : inline std::string
     109             : asString(bytesConstRef _b)
     110             : {
     111             :     return std::string((char const*) _b.data(), (char const*) (_b.data() + _b.size()));
     112             : }
     113             : 
     114             : /// Converts a string to a byte array containing the string's (byte) data.
     115             : inline bytes
     116           0 : asBytes(std::string const& _b)
     117             : {
     118           0 :     return bytes((uint8_t const*) _b.data(), (uint8_t const*) (_b.data() + _b.size()));
     119             : }
     120             : 
     121             : /// Converts a string into the big-endian base-16 stream of integers (NOT ASCII).
     122             : /// @example asNibbles("A")[0] == 4 && asNibbles("A")[1] == 1
     123             : bytes asNibbles(bytesConstRef const& _s);
     124             : 
     125             : // Big-endian to/from host endian conversion functions.
     126             : 
     127             : /// Converts a big-endian byte-stream represented on a templated collection to a templated integer
     128             : /// value.
     129             : /// @a _In will typically be either std::string or bytes.
     130             : /// @a T will typically by unsigned, u160, u256 or bigint.
     131             : template<class T, class _In>
     132             : inline T
     133             : fromBigEndian(_In const& _bytes)
     134             : {
     135             :     T ret = (T) 0;
     136             :     for (auto i : _bytes)
     137             :         ret = (T)((ret << 8) | (uint8_t)(typename std::make_unsigned<decltype(i)>::type) i);
     138             :     return ret;
     139             : }
     140             : 
     141             : inline bytes
     142             : toCompactBigEndian(uint8_t _val, unsigned _min = 0)
     143             : {
     144             :     return (_min || _val) ? bytes {_val} : bytes {};
     145             : }
     146             : 
     147             : // Algorithms for string and string-like collections.
     148             : 
     149             : /// Determines the length of the common prefix of the two collections given.
     150             : /// @returns the number of elements both @a _t and @a _u share, in order, at the beginning.
     151             : /// @example commonPrefix("Hello world!", "Hello, world!") == 5
     152             : template<class T, class _U>
     153             : unsigned
     154             : commonPrefix(T const& _t, _U const& _u)
     155             : {
     156             :     unsigned s = std::min<unsigned>(_t.size(), _u.size());
     157             :     for (unsigned i = 0;; ++i)
     158             :         if (i == s || _t[i] != _u[i])
     159             :             return i;
     160             :     return s;
     161             : }
     162             : 
     163             : /// Trims a given number of elements from the front of a collection.
     164             : /// Only works for POD element types.
     165             : template<class T>
     166             : void
     167             : trimFront(T& _t, unsigned _elements)
     168             : {
     169             :     static_assert(std::is_pod<typename T::value_type>::value, "");
     170             :     memmove(_t.data(), _t.data() + _elements, (_t.size() - _elements) * sizeof(_t[0]));
     171             :     _t.resize(_t.size() - _elements);
     172             : }
     173             : 
     174             : /// Pushes an element on to the front of a collection.
     175             : /// Only works for POD element types.
     176             : template<class T, class _U>
     177             : void
     178             : pushFront(T& _t, _U _e)
     179             : {
     180             :     static_assert(std::is_pod<typename T::value_type>::value, "");
     181             :     _t.push_back(_e);
     182             :     memmove(_t.data() + 1, _t.data(), (_t.size() - 1) * sizeof(_e));
     183             :     _t[0] = _e;
     184             : }
     185             : 
     186             : /// Concatenate two vectors of elements of POD types.
     187             : template<class T>
     188             : inline std::vector<T>&
     189             : operator+=(std::vector<typename std::enable_if<std::is_pod<T>::value, T>::type>& _a,
     190             :            std::vector<T> const& _b)
     191             : {
     192             :     auto s = _a.size();
     193             :     _a.resize(_a.size() + _b.size());
     194             :     memcpy(_a.data() + s, _b.data(), _b.size() * sizeof(T));
     195             :     return _a;
     196             : }
     197             : 
     198             : /// Concatenate two vectors of elements.
     199             : template<class T>
     200             : inline std::vector<T>&
     201             : operator+=(std::vector<typename std::enable_if<!std::is_pod<T>::value, T>::type>& _a,
     202             :            std::vector<T> const& _b)
     203             : {
     204             :     _a.reserve(_a.size() + _b.size());
     205             :     for (auto& i : _b)
     206             :         _a.push_back(i);
     207             :     return _a;
     208             : }
     209             : 
     210             : /// Insert the contents of a container into a set
     211             : template<class T, class U>
     212             : std::set<T>&
     213             : operator+=(std::set<T>& _a, U const& _b)
     214             : {
     215             :     for (auto const& i : _b)
     216             :         _a.insert(i);
     217             :     return _a;
     218             : }
     219             : 
     220             : /// Insert the contents of a container into an unordered_set
     221             : template<class T, class U>
     222             : std::unordered_set<T>&
     223             : operator+=(std::unordered_set<T>& _a, U const& _b)
     224             : {
     225             :     for (auto const& i : _b)
     226             :         _a.insert(i);
     227             :     return _a;
     228             : }
     229             : 
     230             : /// Concatenate the contents of a container onto a vector
     231             : template<class T, class U>
     232             : std::vector<T>&
     233             : operator+=(std::vector<T>& _a, U const& _b)
     234             : {
     235             :     for (auto const& i : _b)
     236             :         _a.push_back(i);
     237             :     return _a;
     238             : }
     239             : 
     240             : /// Insert the contents of a container into a set
     241             : template<class T, class U>
     242             : std::set<T>
     243             : operator+(std::set<T> _a, U const& _b)
     244             : {
     245             :     return _a += _b;
     246             : }
     247             : 
     248             : /// Insert the contents of a container into an unordered_set
     249             : template<class T, class U>
     250             : std::unordered_set<T>
     251             : operator+(std::unordered_set<T> _a, U const& _b)
     252             : {
     253             :     return _a += _b;
     254             : }
     255             : 
     256             : /// Concatenate the contents of a container onto a vector
     257             : template<class T, class U>
     258             : std::vector<T>
     259             : operator+(std::vector<T> _a, U const& _b)
     260             : {
     261             :     return _a += _b;
     262             : }
     263             : 
     264             : /// Concatenate two vectors of elements.
     265             : template<class T>
     266             : inline std::vector<T>
     267             : operator+(std::vector<T> const& _a, std::vector<T> const& _b)
     268             : {
     269             :     std::vector<T> ret(_a);
     270             :     return ret += _b;
     271             : }
     272             : 
     273             : template<class T, class U>
     274             : std::vector<T>
     275             : keysOf(std::map<T, U> const& _m)
     276             : {
     277             :     std::vector<T> ret;
     278             :     for (auto const& i : _m)
     279             :         ret.push_back(i.first);
     280             :     return ret;
     281             : }
     282             : 
     283             : template<class T, class U>
     284             : std::vector<T>
     285             : keysOf(std::unordered_map<T, U> const& _m)
     286             : {
     287             :     std::vector<T> ret;
     288             :     for (auto const& i : _m)
     289             :         ret.push_back(i.first);
     290             :     return ret;
     291             : }
     292             : 
     293             : template<class T, class U>
     294             : std::vector<U>
     295             : valuesOf(std::map<T, U> const& _m)
     296             : {
     297             :     std::vector<U> ret;
     298             :     ret.reserve(_m.size());
     299             :     for (auto const& i : _m)
     300             :         ret.push_back(i.second);
     301             :     return ret;
     302             : }
     303             : 
     304             : template<class T, class U>
     305             : std::vector<U>
     306             : valuesOf(std::unordered_map<T, U> const& _m)
     307             : {
     308             :     std::vector<U> ret;
     309             :     ret.reserve(_m.size());
     310             :     for (auto const& i : _m)
     311             :         ret.push_back(i.second);
     312             :     return ret;
     313             : }
     314             : 
     315             : template<class T, class V>
     316             : bool
     317             : contains(T const& _t, V const& _v)
     318             : {
     319             :     return std::end(_t) != std::find(std::begin(_t), std::end(_t), _v);
     320             : }
     321             : 
     322             : } // namespace dev

Generated by: LCOV version 1.14