Ethereum  PoC-8
The C++ Implementation of Ethereum
CommonData.h
Go to the documentation of this file.
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 */
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 
37 // String conversion functions, mainly to/from hex/nibble/byte representations.
38 
39 enum class WhenError
40 {
41  DontThrow = 0,
42  Throw = 1,
43 };
44 
45 template <class Iterator>
46 std::string toHex(Iterator _it, Iterator _end, std::string const& _prefix)
47 {
48  typedef std::iterator_traits<Iterator> traits;
49  static_assert(sizeof(typename traits::value_type) == 1, "toHex needs byte-sized element type");
50 
51  static char const* hexdigits = "0123456789abcdef";
52  size_t off = _prefix.size();
53  std::string hex(std::distance(_it, _end)*2 + off, '0');
54  hex.replace(0, off, _prefix);
55  for (; _it != _end; _it++)
56  {
57  hex[off++] = hexdigits[(*_it >> 4) & 0x0f];
58  hex[off++] = hexdigits[*_it & 0x0f];
59  }
60  return hex;
61 }
62 
65 template <class T> std::string toHex(T const& _data)
66 {
67  return toHex(_data.begin(), _data.end(), "");
68 }
69 
72 template <class T> std::string toHexPrefixed(T const& _data)
73 {
74  return toHex(_data.begin(), _data.end(), "0x");
75 }
76 
80 bytes fromHex(std::string const& _s, WhenError _throw = WhenError::DontThrow);
81 
83 bool isHex(std::string const& _s) noexcept;
84 
86 template <class T> static bool isHash(std::string const& _hash)
87 {
88  return (_hash.size() == T::size * 2 || (_hash.size() == T::size * 2 + 2 && _hash.substr(0, 2) == "0x")) && isHex(_hash);
89 }
90 
93 inline std::string asString(bytes const& _b)
94 {
95  return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size()));
96 }
97 
100 inline std::string asString(bytesConstRef _b)
101 {
102  return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size()));
103 }
104 
106 inline bytes asBytes(std::string const& _b)
107 {
108  return bytes((byte const*)_b.data(), (byte const*)(_b.data() + _b.size()));
109 }
110 
113 bytes asNibbles(bytesConstRef const& _s);
114 
115 
116 // Big-endian to/from host endian conversion functions.
117 
123 template <class T, class Out>
124 inline void toBigEndian(T _val, Out& o_out)
125 {
126  static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift
127  for (auto i = o_out.size(); i != 0; _val >>= 8, i--)
128  {
129  T v = _val & (T)0xff;
130  o_out[i - 1] = (typename Out::value_type)(uint8_t)v;
131  }
132 }
133 
137 template <class T, class _In>
138 inline T fromBigEndian(_In const& _bytes)
139 {
140  T ret = (T)0;
141  for (auto i: _bytes)
142  ret = (T)((ret << 8) | (byte)(typename std::make_unsigned<decltype(i)>::type)i);
143  return ret;
144 }
145 
147 inline std::string toBigEndianString(u256 _val) { std::string ret(32, '\0'); toBigEndian(_val, ret); return ret; }
148 inline std::string toBigEndianString(u160 _val) { std::string ret(20, '\0'); toBigEndian(_val, ret); return ret; }
149 inline bytes toBigEndian(u256 _val) { bytes ret(32); toBigEndian(_val, ret); return ret; }
150 inline bytes toBigEndian(u160 _val) { bytes ret(20); toBigEndian(_val, ret); return ret; }
151 
154 template <class T>
155 inline bytes toCompactBigEndian(T _val, unsigned _min = 0)
156 {
157  static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift
158  int i = 0;
159  for (T v = _val; v; ++i, v >>= 8) {}
160  bytes ret(std::max<unsigned>(_min, i), 0);
161  toBigEndian(_val, ret);
162  return ret;
163 }
164 inline bytes toCompactBigEndian(byte _val, unsigned _min = 0)
165 {
166  return (_min || _val) ? bytes{ _val } : bytes{};
167 }
168 
171 template <class T>
172 inline std::string toCompactBigEndianString(T _val, unsigned _min = 0)
173 {
174  static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift
175  int i = 0;
176  for (T v = _val; v; ++i, v >>= 8) {}
177  std::string ret(std::max<unsigned>(_min, i), '\0');
178  toBigEndian(_val, ret);
179  return ret;
180 }
181 
182 inline std::string toCompactHex(u256 _val, unsigned _min = 0)
183 {
184  return toHex(toCompactBigEndian(_val, _min));
185 }
186 
187 inline std::string toCompactHexPrefixed(u256 _val, unsigned _min = 0)
188 {
189  return toHexPrefixed(toCompactBigEndian(_val, _min));
190 }
191 
192 // Algorithms for string and string-like collections.
193 
196 std::string escaped(std::string const& _s, bool _all = true);
197 
201 template <class T, class _U>
202 unsigned commonPrefix(T const& _t, _U const& _u)
203 {
204  unsigned s = std::min<unsigned>(_t.size(), _u.size());
205  for (unsigned i = 0;; ++i)
206  if (i == s || _t[i] != _u[i])
207  return i;
208  return s;
209 }
210 
212 template <class T>
213 inline unsigned bytesRequired(T _i)
214 {
215  static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, "only unsigned types or bigint supported"); //bigint does not carry sign bit on shift
216  unsigned i = 0;
217  for (; _i != 0; ++i, _i >>= 8) {}
218  return i;
219 }
220 
223 template <class T>
224 void trimFront(T& _t, unsigned _elements)
225 {
226  static_assert(std::is_pod<typename T::value_type>::value, "");
227  memmove(_t.data(), _t.data() + _elements, (_t.size() - _elements) * sizeof(_t[0]));
228  _t.resize(_t.size() - _elements);
229 }
230 
233 template <class T, class _U>
234 void pushFront(T& _t, _U _e)
235 {
236  static_assert(std::is_pod<typename T::value_type>::value, "");
237  _t.push_back(_e);
238  memmove(_t.data() + 1, _t.data(), (_t.size() - 1) * sizeof(_e));
239  _t[0] = _e;
240 }
241 
243 template <class T, class U>
244 inline std::vector<T>& operator+=(std::vector<T>& _a, U const& _b)
245 {
246  _a.insert(_a.end(), std::begin(_b), std::end(_b));
247  return _a;
248 }
249 
251 template <class T, class U>
252 std::set<T>& operator+=(std::set<T>& _a, U const& _b)
253 {
254  _a.insert(std::begin(_b), std::end(_b));
255  return _a;
256 }
257 
259 template <class T, class U>
260 std::unordered_set<T>& operator+=(std::unordered_set<T>& _a, U const& _b)
261 {
262  _a.insert(std::begin(_b), std::end(_b));
263  return _a;
264 }
265 
267 template <class T, class U> std::set<T> operator+(std::set<T> _a, U const& _b)
268 {
269  return _a += _b;
270 }
271 
273 template <class T, class U> std::unordered_set<T> operator+(std::unordered_set<T> _a, U const& _b)
274 {
275  return _a += _b;
276 }
277 
279 template <class T, class U> std::vector<T> operator+(std::vector<T> _a, U const& _b)
280 {
281  return _a += _b;
282 }
283 
284 
285 template<class T, class U>
286 std::vector<T> keysOf(std::map<T, U> const& _m)
287 {
288  std::vector<T> ret;
289  for (auto const& i: _m)
290  ret.push_back(i.first);
291  return ret;
292 }
293 
294 template<class T, class U>
295 std::vector<T> keysOf(std::unordered_map<T, U> const& _m)
296 {
297  std::vector<T> ret;
298  for (auto const& i: _m)
299  ret.push_back(i.first);
300  return ret;
301 }
302 
303 template<class T, class U>
304 std::vector<U> valuesOf(std::map<T, U> const& _m)
305 {
306  std::vector<U> ret;
307  ret.reserve(_m.size());
308  for (auto const& i: _m)
309  ret.push_back(i.second);
310  return ret;
311 }
312 
313 template<class T, class U>
314 std::vector<U> valuesOf(std::unordered_map<T, U> const& _m)
315 {
316  std::vector<U> ret;
317  ret.reserve(_m.size());
318  for (auto const& i: _m)
319  ret.push_back(i.second);
320  return ret;
321 }
322 
323 template <class T, class V>
324 bool contains(T const& _t, V const& _v)
325 {
326  return std::end(_t) != std::find(std::begin(_t), std::end(_t), _v);
327 }
328 
329 template <class V>
330 bool contains(std::unordered_set<V> const& _set, V const& _v)
331 {
332  return _set.find(_v) != _set.end();
333 }
334 
335 template <class K, class V>
336 bool contains(std::unordered_map<K, V> const& _map, K const& _k)
337 {
338  return _map.find(_k) != _map.end();
339 }
340 
341 template <class V>
342 bool contains(std::set<V> const& _set, V const& _v)
343 {
344  return _set.find(_v) != _set.end();
345 }
346 }
dev::asNibbles
bytes asNibbles(bytesConstRef const &_s)
Definition: CommonData.cpp:111
dev::toBigEndian
void toBigEndian(T _val, Out &o_out)
Definition: CommonData.h:124
dev::vector_ref< byte const >
byte
uint8_t byte
Definition: Common.h:57
dev::toHexPrefixed
std::string toHexPrefixed(T const &_data)
Definition: CommonData.h:72
dev::pushFront
void pushFront(T &_t, _U _e)
Definition: CommonData.h:234
Common.h
dev::toCompactHexPrefixed
std::string toCompactHexPrefixed(u256 _val, unsigned _min=0)
Definition: CommonData.h:187
dev::toCompactHex
std::string toCompactHex(u256 _val, unsigned _min=0)
Definition: CommonData.h:182
dev::bytesRequired
unsigned bytesRequired(T _i)
Determine bytes required to encode the given integer value.
Definition: CommonData.h:213
dev::valuesOf
std::vector< U > valuesOf(std::map< T, U > const &_m)
Definition: CommonData.h:304
dev::toCompactBigEndian
bytes toCompactBigEndian(T _val, unsigned _min=0)
Definition: CommonData.h:155
dev::bytes
std::vector< byte > bytes
Definition: Common.h:72
dev::vector_ref::data
_T * data() const
Definition: vector_ref.h:49
dev::bytesConstRef
vector_ref< byte const > bytesConstRef
Definition: Common.h:74
dev::operator+=
std::vector< T > & operator+=(std::vector< T > &_a, U const &_b)
Concatenate the contents of a container onto a vector.
Definition: CommonData.h:244
dev::u160
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u160
Definition: Common.h:123
dev::vector_ref::size
size_t size() const
Definition: vector_ref.h:53
dev::escaped
std::string escaped(std::string const &_s, bool _all=true)
Definition: CommonData.cpp:52
dev::WhenError::Throw
@ Throw
dev::toBigEndianString
std::string toBigEndianString(u256 _val)
Convenience functions for toBigEndian.
Definition: CommonData.h:147
dev::keysOf
std::vector< T > keysOf(std::map< T, U > const &_m)
Definition: CommonData.h:286
dev::contains
bool contains(T const &_t, V const &_v)
Definition: CommonData.h:324
dev::asBytes
bytes asBytes(std::string const &_b)
Converts a string to a byte array containing the string's (byte) data.
Definition: CommonData.h:106
dev::commonPrefix
unsigned commonPrefix(T const &_t, _U const &_u)
Definition: CommonData.h:202
dev::asString
std::string asString(bytes const &_b)
Definition: CommonData.h:93
dev::u256
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
Definition: Common.h:121
dev::operator+
std::set< T > operator+(std::set< T > _a, U const &_b)
Insert the contents of a container into a set.
Definition: CommonData.h:267
dev
Definition: Address.cpp:21
dev::trimFront
void trimFront(T &_t, unsigned _elements)
Definition: CommonData.h:224
dev::fromBigEndian
T fromBigEndian(_In const &_bytes)
Definition: CommonData.h:138
dev::toHex
std::string toHex(Iterator _it, Iterator _end, std::string const &_prefix)
Definition: CommonData.h:46
dev::fromHex
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
Definition: CommonData.cpp:81
dev::WhenError::DontThrow
@ DontThrow
dev::toCompactBigEndianString
std::string toCompactBigEndianString(T _val, unsigned _min=0)
Definition: CommonData.h:172
dev::WhenError
WhenError
Definition: CommonData.h:40
dev::isHex
bool isHex(std::string const &_s) noexcept