1 #ifndef PROTOZERO_VARINT_HPP
2 #define PROTOZERO_VARINT_HPP
33 inline uint64_t decode_varint_impl(
const char** data,
const char* end) {
34 const auto begin = reinterpret_cast<const int8_t*>(*data);
35 const auto iend = reinterpret_cast<const int8_t*>(end);
36 const int8_t* p = begin;
42 b = *p++; val = ((uint64_t(b) & 0x7fU) );
if (b >= 0) {
break; }
43 b = *p++; val |= ((uint64_t(b) & 0x7fU) << 7U);
if (b >= 0) {
break; }
44 b = *p++; val |= ((uint64_t(b) & 0x7fU) << 14U);
if (b >= 0) {
break; }
45 b = *p++; val |= ((uint64_t(b) & 0x7fU) << 21U);
if (b >= 0) {
break; }
46 b = *p++; val |= ((uint64_t(b) & 0x7fU) << 28U);
if (b >= 0) {
break; }
47 b = *p++; val |= ((uint64_t(b) & 0x7fU) << 35U);
if (b >= 0) {
break; }
48 b = *p++; val |= ((uint64_t(b) & 0x7fU) << 42U);
if (b >= 0) {
break; }
49 b = *p++; val |= ((uint64_t(b) & 0x7fU) << 49U);
if (b >= 0) {
break; }
50 b = *p++; val |= ((uint64_t(b) & 0x7fU) << 56U);
if (b >= 0) {
break; }
51 b = *p++; val |= ((uint64_t(b) & 0x01U) << 63U);
if (b >= 0) {
break; }
52 throw varint_too_long_exception{};
55 unsigned int shift = 0;
56 while (p != iend && *p < 0) {
57 val |= (uint64_t(*p++) & 0x7fU) << shift;
61 throw end_of_buffer_exception{};
63 val |= uint64_t(*p++) << shift;
66 *data = reinterpret_cast<const char*>(p);
89 inline uint64_t
decode_varint(
const char** data,
const char* end) {
91 if (end != *data && ((static_cast<uint64_t>(**data) & 0x80U) == 0)) {
92 const auto val = static_cast<uint64_t>(**data);
97 return detail::decode_varint_impl(data, end);
112 inline void skip_varint(
const char** data,
const char* end) {
113 const auto begin = reinterpret_cast<const int8_t*>(*data);
114 const auto iend = reinterpret_cast<const int8_t*>(end);
115 const int8_t* p = begin;
117 while (p != iend && *p < 0) {
122 throw varint_too_long_exception{};
126 throw end_of_buffer_exception{};
131 *data = reinterpret_cast<const char*>(p);
144 template <
typename T>
148 while (value >= 0x80U) {
149 *data++ = char((value & 0x7fU) | 0x80U);
153 *data++ = char(value);
167 while (value >= 0x80U) {
179 return (static_cast<uint32_t>(value) << 1U) ^ static_cast<uint32_t>(-static_cast<int32_t>(static_cast<uint32_t>(value) >> 31U));
186 return (static_cast<uint64_t>(value) << 1U) ^ static_cast<uint64_t>(-static_cast<int64_t>(static_cast<uint64_t>(value) >> 63U));
193 return static_cast<int32_t>((value >> 1U) ^ static_cast<uint32_t>(-static_cast<int32_t>(value & 1U)));
200 return static_cast<int64_t>((value >> 1U) ^ static_cast<uint64_t>(-static_cast<int64_t>(value & 1U)));
205 #endif // PROTOZERO_VARINT_HPP