Line data Source code
1 : /**
2 : * Copyright Soramitsu Co., Ltd. All Rights Reserved.
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : #ifndef IROHA_COMMON_BLOB_HPP
7 : #define IROHA_COMMON_BLOB_HPP
8 :
9 : #include <algorithm>
10 : #include <array>
11 : #include <cstdint>
12 : #include <stdexcept>
13 : #include <string>
14 :
15 : #include "common/hexutils.hpp"
16 :
17 : namespace iroha {
18 : using BadFormatException = std::invalid_argument;
19 : using byte_t = uint8_t;
20 :
21 : namespace {
22 : static const std::string code = {'0',
23 : '1',
24 : '2',
25 : '3',
26 : '4',
27 : '5',
28 : '6',
29 : '7',
30 : '8',
31 : '9',
32 : 'a',
33 : 'b',
34 : 'c',
35 : 'd',
36 : 'e',
37 : 'f'};
38 : }
39 :
40 : /**
41 : * Base type which represents blob of fixed size.
42 : *
43 : * std::string is convenient to use but it is not safe.
44 : * We can not specify the fixed length for string.
45 : *
46 : * For std::array it is possible, so we prefer it over std::string.
47 : */
48 : template <size_t size_>
49 : class blob_t : public std::array<byte_t, size_> {
50 : public:
51 : /**
52 : * Initialize blob value
53 : */
54 : blob_t() {
55 112221 : this->fill(0);
56 112224 : }
57 :
58 : /**
59 : * In compile-time returns size of current blob.
60 : */
61 : constexpr static size_t size() {
62 718 : return size_;
63 : }
64 :
65 : /**
66 : * Converts current blob to std::string
67 : */
68 : std::string to_string() const noexcept {
69 69495 : return std::string{this->begin(), this->end()};
70 : }
71 :
72 : /**
73 : * Converts current blob to hex string.
74 : */
75 : std::string to_hexstring() const noexcept {
76 331 : std::string res(size_ * 2, 0);
77 331 : auto ptr = this->data();
78 18601 : for (uint32_t i = 0, k = 0; i < size_; i++) {
79 18304 : const auto front = (uint8_t)(ptr[i] & 0xF0) >> 4;
80 18304 : const auto back = (uint8_t)(ptr[i] & 0xF);
81 18304 : res[k++] = code[front];
82 18304 : res[k++] = code[back];
83 18304 : }
84 331 : return res;
85 331 : }
86 :
87 : static blob_t<size_> from_string(const std::string &data) {
88 45991 : if (data.size() != size_) {
89 2 : std::string value = "blob_t: input string has incorrect length. Found: "
90 2 : + std::to_string(data.size())
91 2 : + +", required: " + std::to_string(size_);
92 2 : throw BadFormatException(value.c_str());
93 2 : }
94 :
95 45850 : blob_t<size_> b;
96 45850 : std::copy(data.begin(), data.end(), b.begin());
97 :
98 45850 : return b;
99 2 : }
100 :
101 : static blob_t<size_> from_hexstring(const std::string &hex) {
102 13 : auto bytes = iroha::hexstringToBytestring(hex);
103 13 : if (not bytes) {
104 0 : throw BadFormatException(
105 0 : "Provided data (" + hex
106 0 : + ") is not a valid hex value for blob of size ("
107 0 : + std::to_string(size_) + ").");
108 : }
109 13 : return from_string(*bytes);
110 13 : }
111 : };
112 : } // namespace iroha
113 :
114 : #endif // IROHA_COMMON_BLOB_HPP
|