6#ifndef ALT_INTEGRATION_VERIBLOCK_BLOB_HPP_
7#define ALT_INTEGRATION_VERIBLOCK_BLOB_HPP_
26 using value_type = uint8_t;
27 using storage_t = std::array<value_type, N>;
28 using pointer =
typename storage_t::pointer;
29 using const_pointer =
typename storage_t::const_pointer;
30 using reference =
typename storage_t::reference;
31 using const_reference =
typename storage_t::const_reference;
32 using iterator =
typename storage_t::iterator;
33 using const_iterator =
typename storage_t::const_iterator;
34 using size_type =
typename storage_t::size_type;
35 using difference_type =
typename storage_t::difference_type;
36 using reverse_iterator =
typename storage_t::reverse_iterator;
37 using const_reverse_iterator =
typename storage_t::const_reverse_iterator;
39 Blob() { data_.fill(0); };
41 Blob(
const std::initializer_list<uint8_t>& list) {
50 Blob(
const std::vector<uint8_t>& v) {
54 explicit Blob(
const std::string& hex) {
59 template <size_t M, typename = typename std::enable_if<M <= N>::type>
67 Blob(
Blob<N>&& other) noexcept : data_(std::move(other.data_)) {}
69 explicit operator std::vector<uint8_t>()
const {
70 std::vector<uint8_t> ret(begin(), end());
74 void fill(uint8_t value) { std::fill(begin(), end(), value); }
76 iterator begin()
noexcept {
return data_.begin(); }
77 const_iterator begin()
const noexcept {
return data_.begin(); }
78 iterator end()
noexcept {
return data_.end(); }
79 const_iterator end()
const noexcept {
return data_.end(); }
80 reverse_iterator rbegin()
noexcept {
return data_.rbegin(); }
81 const_reverse_iterator rbegin()
const noexcept {
return data_.rbegin(); }
82 reverse_iterator rend()
noexcept {
return data_.rend(); }
83 const_reverse_iterator rend()
const noexcept {
return data_.rend(); }
85 static constexpr size_type size()
noexcept {
return N; }
87 pointer data()
noexcept {
return data_.data(); }
89 const_pointer data()
const noexcept {
return data_.data(); }
91 std::string toHex()
const {
return HexStr(data_.begin(), data_.end()); }
93 static Blob<N> fromHex(
const std::string& hex) {
99 static Blob<N> assertFromHex(
const std::string& hex) {
100 VBK_ASSERT(hex.size() / 2 == N);
104 void setNull() { fill(0); }
106 bool isNull()
const {
107 for (uint8_t i : data_) {
117 this->data_ = other.data_;
126 Blob<N>& operator=(
const std::vector<uint8_t>& vec) {
133 std::reverse(ret.begin(), ret.end());
138 for (
unsigned i = 0; i < N; ++i) data_[i] = ~data_[i];
142 std::vector<value_type> asVector()
const {
143 return std::vector<value_type>{data_.begin(), data_.end()};
146 std::string asString()
const {
147 return std::string{data_.begin(), data_.end()};
150 const value_type& operator[](
size_t index)
noexcept {
151 VBK_ASSERT(index < N);
154 const value_type& operator[](
size_t index)
const noexcept {
155 VBK_ASSERT(index < N);
159 int compareTo(
const Blob<N>& b)
const {
160 for (
int i = N - 1; i >= 0; i--) {
161 if (data_[i] < b.data_[i]) {
164 if (data_[i] > b.data_[i]) {
172 return memcmp(a.data_.data(), b.data_.data(), a.size()) == 0;
175 return memcmp(a.data_.data(), b.data_.data(), a.size()) != 0;
178 return a.compareTo(b) > 0;
181 return a.compareTo(b) < 0;
184 return a.compareTo(b) >= 0;
187 return a.compareTo(b) <= 0;
190 template <size_t M, typename = typename std::enable_if<M <= N>::type>
193 std::copy(data(), data() + M, m.begin());
197 template <size_t M, typename = typename std::enable_if<M <= N>::type>
200 std::copy(data() + size() - M, data() + size(), m.begin());
204 uint64_t getLow64()
const {
206 memcpy(&ret, &data_[0],
sizeof(uint64_t));
210 std::string toPrettyString()
const {
211 return format(
"Blob<{}>({})", N, toHex());
215 void resize(
size_t size) {
216 VBK_ASSERT_MSG(size == N,
"Size=%d N=%d", size, N);
220 inline void assign(
const std::initializer_list<uint8_t>& list) {
221 if (list.size() > N) {
222 throw std::domain_error(
223 fmt::format(
"Blob({}) invalid input size: {}", N, list.size()));
226 std::copy(list.begin(), list.end(), data_.begin());
230 if (slice.size() > N) {
231 throw std::domain_error(
232 fmt::format(
"Blob({}) invalid input size: {}", N, slice.size()));
235 std::copy(slice.begin(), slice.end(), data_.begin());
242template <
size_t size>
248template <
typename Value,
size_t N>
250 return ToJSON<Value>(blob.toHex());
263 return std::hash<std::string>{}(std::string(x.begin(), x.end()));
269 typename std::conditional<N >= 8, std::true_type, std::false_type>::type f;
270 return operator()(f, x);
278 auto parse(format_parse_context& ctx) ->
decltype(ctx.begin()) {
279 auto it = ctx.begin(), end = ctx.end();
281 VBK_ASSERT_MSG(it == end || *it ==
'}',
"invalid format");
287 template <
typename FormatContext>
289 ->
decltype(ctx.out()) {
290 return format_to(ctx.out(),
"{:s}", val.toHex());
std::string HexStr(const T itbegin, const T itend)
Convert bytes to hex.
void PrintTo(const ArithUint256 &uint, ::std::ostream *os)
custom gtest printer, which prints Blob of any size as hexstring @ private
std::vector< uint8_t > ParseHex(const char *psz)
Parse bytes from hex.
Contiguous byte array of fixed size.
Non-owning contiguous array.