hyperledger/iroha
Iroha - A simple, decentralized ledger http://iroha.tech
varint.hpp
Go to the documentation of this file.
1 
6 #ifndef IROHA_MULTIHASH_VARINT_HPP
7 #define IROHA_MULTIHASH_VARINT_HPP
8 
9 #include <cassert>
10 #include <cstddef>
12 
13 namespace iroha {
14  namespace multihash {
15 
26  template <typename NumberType>
28  NumberType &number) {
29  static_assert(not std::is_signed<NumberType>::value,
30  "VarInt must be unsigned.");
31 
32  if (buffer.empty()) {
33  return false;
34  }
35  number = 0;
36  constexpr std::byte kSignificantBitsMask{0x7F};
37  constexpr std::byte kContinuationBitMask{0x80};
38  constexpr size_t kMaxVarIntLength = 8;
39 
42  constexpr size_t kTargetCapacityVarIntChunks =
43  ((sizeof(number) << size_t(3)) + size_t(6)) / size_t(7);
45  const size_t kMaxPayloadSize =
46  std::min(kTargetCapacityVarIntChunks,
47  std::min(kMaxVarIntLength, buffer.size()));
48  auto const *const beg = &buffer[0];
49  auto const *const end = &buffer[kMaxPayloadSize];
50  auto const *ptr = beg;
51  bool is_last_block_read = false;
52  size_t bytes_read = 0;
53 
54  do {
55  number |= (static_cast<NumberType>(*ptr & kSignificantBitsMask)
56  << (size_t(7) * bytes_read++));
57  is_last_block_read = std::byte(0) == (*ptr++ & kContinuationBitMask);
58  } while (not is_last_block_read && ptr != end);
59 
60  if (is_last_block_read) {
61  assert(bytes_read == static_cast<size_t>(ptr - beg));
63  beg + bytes_read, buffer.size() - bytes_read};
64  }
65  return is_last_block_read;
66  }
67 
76  template <typename NumberType, typename Container>
77  inline void encodeVarInt(NumberType number, Container &buffer) {
78  static_assert(not std::is_signed<NumberType>::value,
79  "VarInt must be unsigned.");
80 
81  constexpr NumberType kSignificantBitsMask{0x7F};
82  constexpr NumberType kContinuationBitMask{0x80};
83 
84  do {
85  NumberType next = number >> 7;
86  number &= kSignificantBitsMask;
87  number |= kContinuationBitMask;
88  buffer.push_back(static_cast<std::byte>(number));
89  number = next;
90  } while (number != 0);
91  *std::prev(buffer.end()) &= static_cast<std::byte>(~kContinuationBitMask);
92  }
93 
94  } // namespace multihash
95 } // namespace iroha
96 
97 #endif
bool readVarInt(shared_model::interface::types::ByteRange &buffer, NumberType &number)
Definition: varint.hpp:27
Definition: block_query.hpp:15
std::basic_string_view< std::byte > ByteRange
Definition: byte_range.hpp:16
void encodeVarInt(NumberType number, Container &buffer)
Definition: varint.hpp:77