Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
fixed_bytes.hpp
Go to the documentation of this file.
1
5#pragma once
6
8
9#include <array>
10#include <algorithm>
11#include <functional>
12#include <type_traits>
13
14namespace sysio {
15
17
18 using chain::uint128_t;
19
20 template<size_t Size>
21 class fixed_bytes;
22
23 template<size_t Size>
24 bool operator ==(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
25
26 template<size_t Size>
27 bool operator !=(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
28
29 template<size_t Size>
30 bool operator >(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
31
32 template<size_t Size>
33 bool operator <(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
34
35 template<size_t Size>
36 bool operator >=(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
37
38 template<size_t Size>
39 bool operator <=(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
40
42
56 template<size_t Size>
58 private:
59
60 template<bool...> struct bool_pack;
61 template<bool... bs>
62 using all_true = std::is_same< bool_pack<bs..., true>, bool_pack<true, bs...> >;
63
64 template<typename Word, size_t NumWords>
65 static void set_from_word_sequence(const Word* arr_begin, const Word* arr_end, fixed_bytes<Size>& key)
66 {
67 auto itr = key._data.begin();
68 word_t temp_word = 0;
69 const size_t sub_word_shift = 8 * sizeof(Word);
70 const size_t num_sub_words = sizeof(word_t) / sizeof(Word);
71 auto sub_words_left = num_sub_words;
72 for( auto w_itr = arr_begin; w_itr != arr_end; ++w_itr ) {
73 if( sub_words_left > 1 ) {
74 temp_word |= static_cast<word_t>(*w_itr);
75 temp_word <<= sub_word_shift;
76 --sub_words_left;
77 continue;
78 }
79
80 FC_ASSERT( sub_words_left == 1, "unexpected error in fixed_bytes constructor" );
81 temp_word |= static_cast<word_t>(*w_itr);
82 sub_words_left = num_sub_words;
83
84 *itr = temp_word;
85 temp_word = 0;
86 ++itr;
87 }
88 if( sub_words_left != num_sub_words ) {
89 if( sub_words_left > 1 )
90 temp_word <<= 8 * (sub_words_left-1);
91 *itr = temp_word;
92 }
93 }
94
95 public:
97
102 static constexpr size_t num_words() { return (Size + sizeof(word_t) - 1) / sizeof(word_t); }
103
108 static constexpr size_t padded_bytes() { return num_words() * sizeof(word_t) - Size; }
109
113 constexpr fixed_bytes() : _data() {}
114
120 fixed_bytes(const std::array<word_t, num_words()>& arr)
121 {
122 std::copy(arr.begin(), arr.end(), _data.begin());
123 }
124
130 template<typename Word, size_t NumWords,
131 typename Enable = typename std::enable_if<std::is_integral<Word>::value &&
132 std::is_unsigned<Word>::value &&
133 !std::is_same<Word, bool>::value &&
134 std::less<size_t>{}(sizeof(Word), sizeof(word_t))>::type >
135 fixed_bytes(const std::array<Word, NumWords>& arr)
136 {
137 static_assert( sizeof(word_t) == (sizeof(word_t)/sizeof(Word)) * sizeof(Word),
138 "size of the backing word size is not divisible by the size of the array element" );
139 static_assert( sizeof(Word) * NumWords <= Size, "too many words supplied to fixed_bytes constructor" );
140
141 set_from_word_sequence<Word, NumWords>(arr.data(), arr.data() + arr.size(), *this);
142 }
143
149 template<typename Word, size_t NumWords,
150 typename Enable = typename std::enable_if<std::is_integral<Word>::value &&
151 std::is_unsigned<Word>::value &&
152 !std::is_same<Word, bool>::value &&
153 std::less<size_t>{}(sizeof(Word), sizeof(word_t))>::type >
154 fixed_bytes(const Word(&arr)[NumWords])
155 {
156 static_assert( sizeof(word_t) == (sizeof(word_t)/sizeof(Word)) * sizeof(Word),
157 "size of the backing word size is not divisible by the size of the array element" );
158 static_assert( sizeof(Word) * NumWords <= Size, "too many words supplied to fixed_bytes constructor" );
159
160 set_from_word_sequence<Word, NumWords>(arr, arr + NumWords, *this);
161 }
162
171 template<typename FirstWord, typename... Rest>
172 static
174 make_from_word_sequence(typename std::enable_if<std::is_integral<FirstWord>::value &&
175 std::is_unsigned<FirstWord>::value &&
176 !std::is_same<FirstWord, bool>::value &&
177 sizeof(FirstWord) <= sizeof(word_t) &&
178 all_true<(std::is_same<FirstWord, Rest>::value)...>::value,
179 FirstWord>::type first_word,
180 Rest... rest)
181 {
182 static_assert( sizeof(word_t) == (sizeof(word_t)/sizeof(FirstWord)) * sizeof(FirstWord),
183 "size of the backing word size is not divisible by the size of the words supplied as arguments" );
184 static_assert( sizeof(FirstWord) * (1 + sizeof...(Rest)) <= Size, "too many words supplied to make_from_word_sequence" );
185
187 std::array<FirstWord, 1+sizeof...(Rest)> arr{{ first_word, rest... }};
188 set_from_word_sequence<FirstWord, 1+sizeof...(Rest)>(arr.data(), arr.data() + arr.size(), key);
189 return key;
190 }
191
195 const auto& get_array()const { return _data; }
196
200 auto data() { return _data.data(); }
201
203
207 auto data()const { return _data.data(); }
208
210
214 auto size()const { return _data.size(); }
215
216
222 std::array<uint8_t, Size> extract_as_byte_array()const {
223 std::array<uint8_t, Size> arr;
224
225 const size_t num_sub_words = sizeof(word_t);
226
227 auto arr_itr = arr.begin();
228 auto data_itr = _data.begin();
229
230 for( size_t counter = _data.size(); counter > 0; --counter, ++data_itr ) {
231 size_t sub_words_left = num_sub_words;
232
233 auto temp_word = *data_itr;
234 if( counter == 1 ) { // If last word in _data array...
235 sub_words_left -= padded_bytes();
236 temp_word >>= 8*padded_bytes();
237 }
238 for( ; sub_words_left > 0; --sub_words_left ) {
239 *(arr_itr + sub_words_left - 1) = static_cast<uint8_t>(temp_word & 0xFF);
240 temp_word >>= 8;
241 }
242 arr_itr += num_sub_words;
243 }
244
245 return arr;
246 }
247
253 inline void print()const {
254 auto arr = extract_as_byte_array();
255 printhex(static_cast<const void*>(arr.data()), arr.size());
256 }
257
259
260 friend bool operator == <>(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
261
262 friend bool operator != <>(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
263
264 friend bool operator > <>(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
265
266 friend bool operator < <>(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
267
268 friend bool operator >= <>(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
269
270 friend bool operator <= <>(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2);
271
273
274 private:
275
276 std::array<word_t, num_words()> _data;
277 };
278
280
288 template<size_t Size>
289 bool operator ==(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2) {
290 return c1._data == c2._data;
291 }
292
300 template<size_t Size>
301 bool operator !=(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2) {
302 return c1._data != c2._data;
303 }
304
312 template<size_t Size>
313 bool operator >(const fixed_bytes<Size>& c1, const fixed_bytes<Size>& c2) {
314 return c1._data > c2._data;
315 }
316
324 template<size_t Size>
325 bool operator <(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2) {
326 return c1._data < c2._data;
327 }
328
336 template<size_t Size>
337 bool operator >=(const fixed_bytes<Size>& c1, const fixed_bytes<Size>& c2) {
338 return c1._data >= c2._data;
339 }
340
348 template<size_t Size>
349 bool operator <=(const fixed_bytes<Size> &c1, const fixed_bytes<Size> &c2) {
350 return c1._data <= c2._data;
351 }
352
353
354 using checksum160 = fixed_bytes<20>;
355 using checksum256 = fixed_bytes<32>;
356 using checksum512 = fixed_bytes<64>;
357
367 template<typename DataStream, size_t Size>
368 inline DataStream& operator<<(DataStream& ds, const fixed_bytes<Size>& d) {
369 auto arr = d.extract_as_byte_array();
370 ds.write( (const char*)arr.data(), arr.size() );
371 return ds;
372 }
373
383 template<typename DataStream, size_t Size>
384 inline DataStream& operator>>(DataStream& ds, fixed_bytes<Size>& d) {
385 std::array<uint8_t, Size> arr;
386 ds.read( (char*)arr.data(), arr.size() );
387 d = fixed_bytes<Size>( arr );
388 return ds;
389 }
390
392}
fixed_bytes(const Word(&arr)[NumWords])
fixed_bytes(const std::array< Word, NumWords > &arr)
static constexpr size_t padded_bytes()
constexpr fixed_bytes()
static constexpr size_t num_words()
std::array< uint8_t, Size > extract_as_byte_array() const
static fixed_bytes< Size > make_from_word_sequence(typename std::enable_if< std::is_integral< FirstWord >::value &&std::is_unsigned< FirstWord >::value &&!std::is_same< FirstWord, bool >::value &&sizeof(FirstWord)<=sizeof(word_t) &&all_true<(std::is_same< FirstWord, Rest >::value)... >::value, FirstWord >::type first_word, Rest... rest)
fixed_bytes(const std::array< word_t, num_words()> &arr)
const auto & get_array() const
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
static const Segment ds(Segment::ds)
datastream< ST > & operator<<(datastream< ST > &s, const sysio::chain::may_not_exist< T > &v)
Definition abi_def.hpp:146
datastream< ST > & operator>>(datastream< ST > &s, sysio::chain::may_not_exist< T > &v)
Definition abi_def.hpp:152
__uint128_t uint128_t
Definition config.hpp:8
bool operator<(const permission_level &lhs, const permission_level &rhs)
Definition action.hpp:21
bool operator<=(const permission_level &lhs, const permission_level &rhs)
Definition action.hpp:25
bool operator==(const permission_level &lhs, const permission_level &rhs)
Definition action.hpp:13
bool operator!=(const permission_level &lhs, const permission_level &rhs)
Definition action.hpp:17
bool operator>(const permission_level &lhs, const permission_level &rhs)
Definition action.hpp:29
unsigned __int128 uint128_t
Definition types.hpp:242
bool operator>=(const permission_level &lhs, const permission_level &rhs)
Definition action.hpp:33
#define value
Definition pkcs11.h:157
unsigned char uint8_t
Definition stdint.h:124
uint8_t key[16]
Definition yubico_otp.c:41
CK_ULONG d