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