Kagome
Polkadot Runtime Engine in C++17
uvar.hpp
Go to the documentation of this file.
1 
6 #ifndef KAGOME_ADAPTERS_UVAR
7 #define KAGOME_ADAPTERS_UVAR
8 
9 #include <boost/system/error_code.hpp>
10 #include <functional>
11 #include <gsl/span>
12 #include <memory>
13 #include <vector>
14 
16 #include "outcome/outcome.hpp"
17 
18 namespace kagome::network {
19 
20  template <typename T>
22  static constexpr size_t kContinuationBitMask{0x80ull};
23  static constexpr size_t kSignificantBitsMask{0x7Full};
24  static constexpr size_t kMSBBit = (1ull << 63);
25  static constexpr size_t kPayloadSize =
26  ((sizeof(uint64_t) << size_t(3)) + size_t(6)) / size_t(7);
27  static constexpr size_t kSignificantBitsMaskMSB{kSignificantBitsMask << 57};
28 
29  static size_t size(const T & /*t*/) {
30  return kPayloadSize;
31  }
32 
33  static std::vector<uint8_t>::iterator write(
34  const T &t,
35  std::vector<uint8_t> &out,
36  std::vector<uint8_t>::iterator loaded) {
37  const auto remains =
38  static_cast<size_t>(std::distance(out.begin(), loaded));
39  assert(remains >= UVarMessageAdapter<T>::size(t));
40  auto data_sz = out.size() - remains;
41 
43  if (0 == (kMSBBit & data_sz)) {
44  data_sz <<= size_t(1ull);
45  while ((data_sz & kSignificantBitsMaskMSB) == 0 && data_sz != 0)
46  data_sz <<= size_t(7ull);
47  }
48 
49  auto sz_start = --loaded;
50  do {
51  assert(std::distance(out.begin(), loaded) >= 1);
52  *loaded-- = ((data_sz & kSignificantBitsMaskMSB) >> 57ull)
54  } while ((data_sz <<= size_t(7ull)) != 0);
55 
56  *sz_start &= uint8_t(kSignificantBitsMask);
57  return ++loaded;
58  }
59 
60  static outcome::result<std::vector<uint8_t>::const_iterator> read(
61  T & /*out*/,
62  const std::vector<uint8_t> &src,
63  std::vector<uint8_t>::const_iterator from) {
64  if (from == src.end()) return AdaptersError::EMPTY_DATA;
65 
66  uint64_t sz = 0;
67  const auto loaded = std::distance(src.begin(), from);
68 
69  auto const *const beg = from.base();
70  auto const *const end = &src[std::min(loaded + kPayloadSize, src.size())];
71  auto const *ptr = beg;
72  size_t counter = 0;
73 
74  do {
75  sz |= (static_cast<uint64_t>(*ptr & kSignificantBitsMask)
76  << (size_t(7) * counter++));
77  } while (uint8_t(0) != (*ptr++ & uint8_t(kContinuationBitMask)) // NOLINT
78  && ptr != end);
79 
80  if (sz != src.size() - (loaded + counter))
82 
83  std::advance(from, counter);
84  return from;
85  }
86  };
87 
88 } // namespace kagome::network
89 
90 #endif // KAGOME_ADAPTERS_UVAR
static std::vector< uint8_t >::iterator write(const T &t, std::vector< uint8_t > &out, std::vector< uint8_t >::iterator loaded)
Definition: uvar.hpp:33
static constexpr size_t kPayloadSize
Definition: uvar.hpp:25
static constexpr size_t kSignificantBitsMaskMSB
Definition: uvar.hpp:27
static constexpr size_t kSignificantBitsMask
Definition: uvar.hpp:23
static outcome::result< std::vector< uint8_t >::const_iterator > read(T &, const std::vector< uint8_t > &src, std::vector< uint8_t >::const_iterator from)
Definition: uvar.hpp:60
static size_t size(const T &)
Definition: uvar.hpp:29
static constexpr size_t kContinuationBitMask
Definition: uvar.hpp:22
static constexpr size_t kMSBBit
Definition: uvar.hpp:24