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
use crate::codec::*;
macro_rules! leb128 {
($ty:ty) => {
paste::paste! {
impl crate::codec::Encode for $ty {
#[inline]
fn encode(&self, encoder: &mut impl crate::codec::Encoder) -> Result<(), $crate::error::EncodeError> {
let mut n = *self;
let mut buf = [0u8; <$ty>::BITS.div_ceil(7) as usize];
let mut i = 0;
loop {
let mut byte = (n as u8) & 0x7f;
n >>= 7;
if n != 0 {
byte |= 0x80;
}
buf[i] = byte;
i += 1;
if n == 0 {
break;
}
}
encoder.write_all(&buf[..i])?;
Ok(())
}
}
impl<A: $crate::alloc::Allocator> crate::codec::DecodeIn<A> for $ty {
#[inline]
fn decode_in(decoder: &mut impl crate::codec::Decoder, _alloc: A) -> Result<Self, $crate::error::DecodeError> {
let mut ret: $ty = 0;
let mut shift: u32 = 0;
loop {
// Bottom 7 bits are value bits
let byte = decoder.decode_byte()?;
let value = (byte & 0x7f) as $ty;
// This is a stable port of `shl_exact`
// FIXME: This should be replaced with `shl_exact` once it is stabilized.
// ```
// ret |= ((byte & 0x7f) as $ty)
// .shl_exact(shift)
// .ok_or($crate::error::DecodeError::LEB128Overflow(<$ty>::BITS))?;
// ```
// #[unstable(feature = "exact_bitshifts", issue = "144336")]
// #[must_use = "this returns the result of the operation, \
// without modifying the original"]
// #[inline]
// pub const fn shl_exact(self, rhs: u32) -> Option<$SelfT> {
// if rhs < self.leading_zeros() || rhs < self.leading_ones() {
// // SAFETY: rhs is checked above
// Some(unsafe { self.unchecked_shl(rhs) })
// } else {
// None
// }
// }
if shift < value.leading_zeros() || shift < value.leading_ones() {
// SAFETY: shift is checked above
ret |= unsafe { ((byte & 0x7f) as $ty).unchecked_shl(shift) };
} else {
return Err($crate::error::DecodeError::LEB128Overflow(<$ty>::BITS));
}
// Top bit is a continue bit
if byte & 0x80 == 0 {
break;
}
shift = shift
.checked_add(7)
.ok_or($crate::error::DecodeError::LEB128Overflow(<$ty>::BITS))?;
}
Ok(ret)
}
}
}
};
($($ty:ty),+ $(,)?) => {
$(leb128!($ty);)+
};
}
leb128!(u16, u32, u64, u128);
impl Encode for u8 {
#[inline]
fn encode(&self, encoder: &mut impl Encoder) -> Result<(), EncodeError> {
encoder.write_all([*self])?;
Ok(())
}
}
impl<A: Allocator> DecodeIn<A> for u8 {
#[inline]
fn decode_in(decoder: &mut impl Decoder, _alloc: A) -> Result<Self, DecodeError> {
let mut byte = [0u8; 1];
decoder.read_exact(&mut byte)?;
Ok(byte[0])
}
}
impl Encode for usize {
#[inline]
fn encode(&self, encoder: &mut impl Encoder) -> Result<(), EncodeError> {
let val: u32 = (*self).try_into().map_err(|_| EncodeError::UsizeOverflow)?;
val.encode(encoder)?;
Ok(())
}
}
impl<A: Allocator> DecodeIn<A> for usize {
#[inline]
fn decode_in(decoder: &mut impl Decoder, _alloc: A) -> Result<Self, DecodeError> {
let val = u32::decode(decoder)?;
Ok(val as usize)
}
}