Kagome
Polkadot Runtime Engine in C++17
buffer.hpp
Go to the documentation of this file.
1 
6 #ifndef KAGOME_COMMON_BUFFER
7 #define KAGOME_COMMON_BUFFER
8 
9 #include <string_view>
10 #include <vector>
11 
12 #include <fmt/format.h>
13 #include <boost/container_hash/hash.hpp>
14 #include <boost/operators.hpp>
15 #include <gsl/span>
16 
17 #include "common/buffer_view.hpp"
19 #include "hexutil.hpp"
21 #include "outcome/outcome.hpp"
22 
23 namespace kagome::common {
24 
28  template <size_t MaxSize>
29  class SLBuffer : public SLVector<uint8_t, MaxSize> {
30  public:
32 
33  template <size_t OtherMaxSize>
35 
36  SLBuffer() = default;
37 
41  explicit SLBuffer(const typename Base::Base &other) : Base(other) {}
42  explicit SLBuffer(typename Base::Base &&other) : Base(std::move(other)) {}
43 
44  template <size_t OtherMaxSize>
45  SLBuffer(const OtherSLBuffer<OtherMaxSize> &other) : Base(other) {}
46 
47  template <size_t OtherMaxSize>
48  SLBuffer(OtherSLBuffer<OtherMaxSize> &&other) : Base(std::move(other)) {}
49 
50  SLBuffer(const BufferView &s) : Base(s.begin(), s.end()) {}
51 
52  template <size_t N>
53  SLBuffer(const std::array<typename Base::value_type, N> &other)
54  : Base(other.begin(), other.end()) {}
55 
56  SLBuffer(const uint8_t *begin, const uint8_t *end) : Base(begin, end){};
57 
58  using Base::Base;
59  using Base::operator=;
60 
61  SLBuffer &reserve(size_t size) {
62  Base::reserve(size);
63  return *this;
64  }
65 
66  SLBuffer &resize(size_t size) {
67  Base::resize(size);
68  return *this;
69  }
70 
71  SLBuffer &operator+=(const BufferView &view) noexcept {
72  return put(view);
73  }
74 
79  SLBuffer &putUint8(uint8_t n) {
81  return *this;
82  }
83 
89  SLBuffer &putUint32(uint32_t n) {
90  n = htobe32(n);
91  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
92  const auto *begin = reinterpret_cast<uint8_t *>(&n);
93  const auto *end = begin + sizeof(n) / sizeof(uint8_t);
94  Base::insert(this->end(), begin, end);
95  return *this;
96  }
97 
103  SLBuffer &putUint64(uint64_t n) {
104  n = htobe64(n);
105  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
106  const auto *begin = reinterpret_cast<uint8_t *>(&n);
107  const auto *end = begin + sizeof(n) / sizeof(uint8_t);
108  Base::insert(this->end(), begin, end);
109  return *this;
110  }
111 
117  SLBuffer &put(std::string_view view) {
118  Base::insert(Base::end(), view.begin(), view.end());
119  return *this;
120  }
121 
128  Base::insert(Base::end(), view.begin(), view.end());
129  return *this;
130  }
131 
135  const std::vector<uint8_t> &asVector() const {
136  return static_cast<const typename Base::Base &>(*this);
137  }
138 
139  std::vector<uint8_t> &asVector() {
140  return static_cast<typename Base::Base &>(*this);
141  }
142 
143  std::vector<uint8_t> toVector() & {
144  return static_cast<typename Base::Base &>(*this);
145  }
146 
147  std::vector<uint8_t> toVector() && {
148  return std::move(static_cast<typename Base::Base &>(*this));
149  }
150 
155  SLBuffer subbuffer(size_t offset = 0, size_t length = -1) const {
156  return SLBuffer(view(offset, length));
157  }
158 
159  BufferView view(size_t offset = 0, size_t length = -1) const {
160  return BufferView{gsl::make_span(*this).subspan(offset, length)};
161  }
162 
167  std::string toHex() const {
168  return hex_lower(*this);
169  }
170 
177  static outcome::result<SLBuffer> fromHex(std::string_view hex) {
178  OUTCOME_TRY(bytes, unhex(hex));
179  return outcome::success(SLBuffer(std::move(bytes)));
180  }
181 
187  std::string toString() const {
188  return std::string{Base::cbegin(), Base::cend()};
189  }
190 
196  std::string_view asString() const {
197  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
198  return std::string_view(reinterpret_cast<const char *>(Base::data()),
199  Base::size());
200  }
201 
205  static SLBuffer fromString(const std::string_view &src) {
206  return {src.begin(), src.end()};
207  }
208 
209  using Base::operator==;
210 
211  bool operator==(const BufferView &other) const noexcept {
212  return std::equal(
213  Base::cbegin(), Base::cend(), other.cbegin(), other.cend());
214  }
215 
216  template <size_t N>
218  const std::array<typename Base::value_type, N> &other) const noexcept {
219  return std::equal(
220  Base::cbegin(), Base::cend(), other.cbegin(), other.cend());
221  }
222 
223  using Base::operator<;
224 
225  bool operator<(const BufferView &other) const noexcept {
226  return std::lexicographical_compare(
227  Base::cbegin(), Base::cend(), other.cbegin(), other.cend());
228  }
229 
230  template <size_t N>
231  bool operator<(
232  const std::array<typename Base::value_type, N> &other) const noexcept {
233  return std::lexicographical_compare(
234  Base::cbegin(), Base::cend(), other.cbegin(), other.cend());
235  }
236  };
237 
238  template <size_t MaxSize>
239  inline std::ostream &operator<<(std::ostream &os,
240  const SLBuffer<MaxSize> &buffer) {
241  return os << BufferView(buffer);
242  }
243 
245 
246  static inline const Buffer kEmptyBuffer{};
247 
248  using BufferMutRef = std::reference_wrapper<Buffer>;
249  using BufferConstRef = std::reference_wrapper<const Buffer>;
250 
251  namespace literals {
254  inline Buffer operator""_buf(const char *c, size_t s) {
255  std::vector<uint8_t> chars(c, c + s);
256  return Buffer(std::move(chars));
257  }
258 
259  // TODO(GaroRobe): After migrating to C++20 would be good to use
260  // literal operator template
261  inline Buffer operator""_hex2buf(const char *c, size_t s) {
262  return Buffer::fromHex({c, s}).value();
263  }
264  } // namespace literals
265 
266 } // namespace kagome::common
267 
268 template <size_t N>
269 struct std::hash<kagome::common::SLBuffer<N>> {
270  size_t operator()(const kagome::common::SLBuffer<N> &x) const {
271  return boost::hash_range(x.begin(), x.end());
272  }
273 };
274 
275 template <>
276 struct fmt::formatter<kagome::common::Buffer>
277  : fmt::formatter<kagome::common::BufferView> {};
278 
279 #endif // KAGOME_COMMON_BUFFER
Base::iterator insert(Iter pos, const typename Base::value_type &value)
static outcome::result< SLBuffer > fromHex(std::string_view hex)
Construct SLBuffer from hex string.
Definition: buffer.hpp:177
Class represents arbitrary (including empty) byte buffer.
Definition: buffer.hpp:29
SLBuffer & putUint64(uint64_t n)
Put a 64-bit {.
Definition: buffer.hpp:103
size_t operator()(const kagome::common::SLBuffer< N > &x) const
Definition: buffer.hpp:270
std::ostream & operator<<(std::ostream &os, const Blob< N > &blob)
Definition: blob.hpp:234
bool operator<(const BufferView &other) const noexcept
Definition: buffer.hpp:225
SLBuffer & resize(size_t size)
Definition: buffer.hpp:66
std::string hex_lower(const gsl::span< const uint8_t > bytes) noexcept
Converts bytes to hex representation.
Definition: hexutil.cpp:52
SLBuffer(OtherSLBuffer< OtherMaxSize > &&other)
Definition: buffer.hpp:48
void resize(typename Base::size_type size)
std::reference_wrapper< Buffer > BufferMutRef
Definition: buffer.hpp:248
const std::vector< uint8_t > & asVector() const
getter for vector of bytes
Definition: buffer.hpp:135
common::BufferView BufferView
SLBuffer & operator+=(const BufferView &view) noexcept
Definition: buffer.hpp:71
SLBuffer(const uint8_t *begin, const uint8_t *end)
Definition: buffer.hpp:56
STL namespace.
std::string_view asString() const
return content of bytearray as a string copy data
Definition: buffer.hpp:196
std::string toString() const
return content of bytearray as string
Definition: buffer.hpp:187
SLBuffer & put(const BufferView &view)
Put a sequence of bytes as view into byte buffer.
Definition: buffer.hpp:127
gsl::span< const uint8_t > make_span(const rocksdb::Slice &s)
SLBuffer< std::numeric_limits< size_t >::max()> Buffer
Definition: buffer.hpp:244
SLBuffer & put(std::string_view view)
Put a string into byte buffer.
Definition: buffer.hpp:117
SLBuffer subbuffer(size_t offset=0, size_t length=-1) const
Definition: buffer.hpp:155
void reserve(typename Base::size_type size)
std::vector< uint8_t > & asVector()
Definition: buffer.hpp:139
bool operator<(const std::array< typename Base::value_type, N > &other) const noexcept
Definition: buffer.hpp:231
std::string toHex() const
encode bytearray as hex
Definition: buffer.hpp:167
SLBuffer & reserve(size_t size)
Definition: buffer.hpp:61
bool operator==(const BufferView &other) const noexcept
Definition: buffer.hpp:211
SLBuffer & putUint32(uint32_t n)
Put a 32-bit {.
Definition: buffer.hpp:89
std::reference_wrapper< const Buffer > BufferConstRef
Definition: buffer.hpp:249
outcome::result< std::vector< uint8_t > > unhex(std::string_view hex)
Converts hex representation to bytes.
Definition: hexutil.cpp:70
static const Buffer kEmptyBuffer
Definition: buffer.hpp:246
std::vector< uint8_t > toVector()&&
Definition: buffer.hpp:147
SLBuffer & putUint8(uint8_t n)
Put a 8-bit {.
Definition: buffer.hpp:79
static SLBuffer fromString(const std::string_view &src)
stores content of a string to byte array
Definition: buffer.hpp:205
SLBuffer(const typename Base::Base &other)
lvalue construct buffer from a byte vector
Definition: buffer.hpp:41
SLBuffer(const OtherSLBuffer< OtherMaxSize > &other)
Definition: buffer.hpp:45
bool operator==(const std::array< typename Base::value_type, N > &other) const noexcept
Definition: buffer.hpp:217
SLBuffer(const std::array< typename Base::value_type, N > &other)
Definition: buffer.hpp:53
BufferView view(size_t offset=0, size_t length=-1) const
Definition: buffer.hpp:159
std::vector< uint8_t > toVector()&
Definition: buffer.hpp:143
SLBuffer(const BufferView &s)
Definition: buffer.hpp:50
SLBuffer(typename Base::Base &&other)
Definition: buffer.hpp:42