uts_core/codec/imp/primitives.rs
1use crate::codec::*;
2
3macro_rules! leb128 {
4 ($ty:ty) => {
5 paste::paste! {
6 impl crate::codec::Encode for $ty {
7 #[inline]
8 fn encode(&self, encoder: &mut impl crate::codec::Encoder) -> Result<(), $crate::error::EncodeError> {
9 let mut n = *self;
10 let mut buf = [0u8; <$ty>::BITS.div_ceil(7) as usize];
11 let mut i = 0;
12
13 loop {
14 let mut byte = (n as u8) & 0x7f;
15 n >>= 7;
16
17 if n != 0 {
18 byte |= 0x80;
19 }
20
21 buf[i] = byte;
22 i += 1;
23
24 if n == 0 {
25 break;
26 }
27 }
28
29 encoder.write_all(&buf[..i])?;
30 Ok(())
31 }
32 }
33
34 impl<A: $crate::alloc::Allocator> crate::codec::DecodeIn<A> for $ty {
35 #[inline]
36 fn decode_in(decoder: &mut impl crate::codec::Decoder, _alloc: A) -> Result<Self, $crate::error::DecodeError> {
37 let mut ret: $ty = 0;
38 let mut shift: u32 = 0;
39
40 loop {
41 // Bottom 7 bits are value bits
42 let byte = decoder.decode_byte()?;
43 let value = (byte & 0x7f) as $ty;
44
45 // This is a stable port of `shl_exact`
46 // FIXME: This should be replaced with `shl_exact` once it is stabilized.
47 // ```
48 // ret |= ((byte & 0x7f) as $ty)
49 // .shl_exact(shift)
50 // .ok_or($crate::error::DecodeError::LEB128Overflow(<$ty>::BITS))?;
51 // ```
52 // #[unstable(feature = "exact_bitshifts", issue = "144336")]
53 // #[must_use = "this returns the result of the operation, \
54 // without modifying the original"]
55 // #[inline]
56 // pub const fn shl_exact(self, rhs: u32) -> Option<$SelfT> {
57 // if rhs < self.leading_zeros() || rhs < self.leading_ones() {
58 // // SAFETY: rhs is checked above
59 // Some(unsafe { self.unchecked_shl(rhs) })
60 // } else {
61 // None
62 // }
63 // }
64 if shift < value.leading_zeros() || shift < value.leading_ones() {
65 // SAFETY: shift is checked above
66 ret |= unsafe { ((byte & 0x7f) as $ty).unchecked_shl(shift) };
67 } else {
68 return Err($crate::error::DecodeError::LEB128Overflow(<$ty>::BITS));
69 }
70
71 // Top bit is a continue bit
72 if byte & 0x80 == 0 {
73 break;
74 }
75 shift = shift
76 .checked_add(7)
77 .ok_or($crate::error::DecodeError::LEB128Overflow(<$ty>::BITS))?;
78 }
79
80 Ok(ret)
81 }
82 }
83 }
84 };
85 ($($ty:ty),+ $(,)?) => {
86 $(leb128!($ty);)+
87 };
88}
89
90leb128!(u16, u32, u64, u128);
91
92impl Encode for u8 {
93 #[inline]
94 fn encode(&self, encoder: &mut impl Encoder) -> Result<(), EncodeError> {
95 encoder.write_all([*self])?;
96 Ok(())
97 }
98}
99
100impl<A: Allocator> DecodeIn<A> for u8 {
101 #[inline]
102 fn decode_in(decoder: &mut impl Decoder, _alloc: A) -> Result<Self, DecodeError> {
103 let mut byte = [0u8; 1];
104 decoder.read_exact(&mut byte)?;
105 Ok(byte[0])
106 }
107}
108
109impl Encode for usize {
110 #[inline]
111 fn encode(&self, encoder: &mut impl Encoder) -> Result<(), EncodeError> {
112 let val: u32 = (*self).try_into().map_err(|_| EncodeError::UsizeOverflow)?;
113 val.encode(encoder)?;
114 Ok(())
115 }
116}
117
118impl<A: Allocator> DecodeIn<A> for usize {
119 #[inline]
120 fn decode_in(decoder: &mut impl Decoder, _alloc: A) -> Result<Self, DecodeError> {
121 let val = u32::decode(decoder)?;
122 Ok(val as usize)
123 }
124}