xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
include
xrpl
nodestore
detail
Varint.h
1
#pragma once
2
3
#include <nudb/detail/stream.hpp>
4
5
#include <
cstddef
>
6
#include <
cstdint
>
7
#include <
type_traits
>
8
9
namespace
xrpl::node_store
{
10
11
// This is a variant of the base128 varint format from
12
// google protocol buffers:
13
// https://developers.google.com/protocol-buffers/docs/encoding#varints
14
15
// field tag
16
struct
Varint;
17
18
// Metafunction to return largest
19
// possible size of T represented as varint.
20
// T must be unsigned
21
template
<
class
T,
bool
= std::is_
unsigned
_v<T>>
22
struct
VarintTraits
;
23
24
template
<
class
T>
25
struct
VarintTraits
<T, true>
26
{
27
explicit
VarintTraits
() =
default
;
28
29
static
constexpr
std::size_t
kMax
= ((8 *
sizeof
(T)) + 6) / 7;
30
};
31
32
// Returns: Number of bytes consumed or 0 on error,
33
// if the buffer was too small or t overflowed.
34
//
35
template
<
class
=
void
>
36
std::size_t
37
readVarint
(
void
const
* buf,
std::size_t
buflen,
std::size_t
& t)
38
{
39
if
(buflen == 0)
40
return
0;
41
t = 0;
42
auto
const
* p =
reinterpret_cast<
std::uint8_t
const*
>
(buf);
43
std::size_t
n = 0;
44
while
(p[n] & 0x80)
45
{
46
if
(++n >= buflen)
47
return
0;
48
}
49
if
(++n > buflen)
50
return
0;
51
// Special case for 0
52
if
(n == 1 && *p == 0)
53
{
54
t = 0;
55
return
1;
56
}
57
auto
const
used = n;
58
while
(n > 0)
59
{
60
--n;
61
auto
const
d = p[n];
62
auto
const
t0 = t;
63
t *= 127;
64
t += d & 0x7f;
65
if
(t <= t0)
66
return
0;
// overflow
67
}
68
return
used;
69
}
70
71
template
<
class
T>
72
std::size_t
73
sizeVarint
(T v)
74
requires
(
std::is_unsigned_v<T>
)
75
{
76
std::size_t
n = 0;
77
do
78
{
79
v /= 127;
80
++n;
81
}
while
(v != 0);
82
return
n;
83
}
84
85
template
<
class
=
void
>
86
std::size_t
87
writeVarint
(
void
* p0,
std::size_t
v)
88
{
89
// NOLINTNEXTLINE(misc-const-correctness)
90
auto
* p =
reinterpret_cast<
std::uint8_t
*
>
(p0);
91
do
92
{
93
std::uint8_t
d = v % 127;
94
v /= 127;
95
if
(v != 0)
96
d |= 0x80;
97
*p++ = d;
98
}
while
(v != 0);
99
return
p -
reinterpret_cast<
std::uint8_t
*
>
(p0);
100
}
101
102
// input stream
103
104
template
<
class
T>
105
void
106
read
(nudb::detail::istream& is,
std::size_t
& u)
107
requires
(
std::is_same_v<T, Varint>
)
108
{
109
auto
p0 = is(1);
110
auto
p1 = p0;
111
while
(*p1++ & 0x80)
112
is(1);
113
readVarint
(p0, p1 - p0, u);
114
}
115
116
// output stream
117
118
template
<
class
T>
119
void
120
write
(nudb::detail::ostream& os,
std::size_t
t)
121
requires
(
std::is_same_v<T, Varint>
)
122
{
123
writeVarint
(os.data(
sizeVarint
(t)), t);
124
}
125
126
}
// namespace xrpl::node_store
cstddef
cstdint
std::uint8_t
std::is_same_v
T is_same_v
std::is_unsigned_v
T is_unsigned_v
xrpl::node_store
Definition
ServiceRegistry.h:18
xrpl::node_store::readVarint
std::size_t readVarint(void const *buf, std::size_t buflen, std::size_t &t)
Definition
Varint.h:37
xrpl::node_store::writeVarint
std::size_t writeVarint(void *p0, std::size_t v)
Definition
Varint.h:87
xrpl::node_store::sizeVarint
std::size_t sizeVarint(T v)
Definition
Varint.h:73
xrpl::node_store::write
void write(nudb::detail::ostream &os, std::size_t t)
Definition
Varint.h:120
xrpl::node_store::read
void read(nudb::detail::istream &is, std::size_t &u)
Definition
Varint.h:106
std::size_t
xrpl::node_store::VarintTraits< T, true >::kMax
static constexpr std::size_t kMax
Definition
Varint.h:29
xrpl::node_store::VarintTraits< T, true >::VarintTraits
VarintTraits()=default
xrpl::node_store::VarintTraits
Definition
Varint.h:22
type_traits
Generated by
1.17.0