1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#![cfg_attr(feature = "nightly", deny(missing_docs))]
#![cfg_attr(feature = "nightly", feature(external_doc))]
#![cfg_attr(feature = "nightly", doc(include = "../README.md"))]
#![cfg_attr(test, deny(warnings))]
#[inline]
pub fn length(value: u64) -> usize {
let zero_len = 64 - value.leading_zeros();
let offset = if zero_len == 0 { 7 } else { 6 };
((offset + zero_len) / 7) as usize
}
#[inline]
pub fn encode(value: u64, buf: &mut [u8]) -> usize {
encode_with_offset(value, buf, 0)
}
#[inline]
pub fn encode_with_offset(value: u64, buf: &mut [u8], offset: usize) -> usize {
let mut off = offset;
let mut val = value;
while val > 127 {
buf[off] = (val as u8) | 128;
off += 1;
val >>= 7;
}
buf[off] = val as u8;
off + 1 - offset
}
#[inline]
pub fn decode(buf: &[u8], value: &mut u64) -> usize {
decode_with_offset(buf, 0, value)
}
#[inline]
pub fn decode_with_offset(buf: &[u8], offset: usize, value: &mut u64) -> usize {
let mut val = 0 as u64;
let mut fac = 1 as u64;
let mut off = offset;
loop {
let byte = buf[off];
off += 1;
val += fac * ((byte & 127) as u64);
fac <<= 7;
if byte & 128 == 0 {
break;
}
}
*value = val;
off - offset
}
#[inline]
pub fn signed_length(value: i64) -> usize {
length(unsign(value))
}
#[inline]
pub fn signed_encode(value: i64, buf: &mut [u8]) -> usize {
encode_with_offset(unsign(value), buf, 0)
}
#[inline]
pub fn signed_encode_with_offset(
value: i64,
buf: &mut [u8],
offset: usize,
) -> usize {
encode_with_offset(unsign(value), buf, offset)
}
#[inline]
pub fn signed_decode(buf: &[u8], value: &mut i64) -> usize {
signed_decode_with_offset(buf, 0, value)
}
#[inline]
pub fn signed_decode_with_offset(
buf: &[u8],
offset: usize,
value: &mut i64,
) -> usize {
let mut val = 0;
let off = decode_with_offset(buf, offset, &mut val);
*value = sign(val);
off
}
#[inline]
fn unsign(value: i64) -> u64 {
if value >= 0 {
(value * 2) as u64
} else {
(value * -2 - 1) as u64
}
}
#[inline]
fn sign(value: u64) -> i64 {
if value & 1 != 0 {
-(((value + 1) / 2) as i64)
} else {
(value / 2) as i64
}
}