ra_ap_rustc_serialize/
leb128.rs1use crate::int_overflow::DebugStrictAdd;
4use crate::opaque::MemDecoder;
5use crate::serialize::Decoder;
6
7pub const fn max_leb128_len<T>() -> usize {
9 (std::mem::size_of::<T>() * 8 + 6) / 7
11}
12
13pub const fn largest_max_leb128_len() -> usize {
15 max_leb128_len::<u128>()
16}
17
18macro_rules! impl_write_unsigned_leb128 {
19 ($fn_name:ident, $int_ty:ty) => {
20 #[inline]
21 pub fn $fn_name(out: &mut [u8; max_leb128_len::<$int_ty>()], mut value: $int_ty) -> usize {
22 let mut i = 0;
23
24 loop {
25 if value < 0x80 {
26 unsafe {
27 *out.get_unchecked_mut(i) = value as u8;
28 }
29
30 i = i.debug_strict_add(1);
31 break;
32 } else {
33 unsafe {
34 *out.get_unchecked_mut(i) = ((value & 0x7f) | 0x80) as u8;
35 }
36
37 value >>= 7;
38 i = i.debug_strict_add(1);
39 }
40 }
41
42 i
43 }
44 };
45}
46
47impl_write_unsigned_leb128!(write_u16_leb128, u16);
48impl_write_unsigned_leb128!(write_u32_leb128, u32);
49impl_write_unsigned_leb128!(write_u64_leb128, u64);
50impl_write_unsigned_leb128!(write_u128_leb128, u128);
51impl_write_unsigned_leb128!(write_usize_leb128, usize);
52
53macro_rules! impl_read_unsigned_leb128 {
54 ($fn_name:ident, $int_ty:ty) => {
55 #[inline]
56 pub fn $fn_name(decoder: &mut MemDecoder<'_>) -> $int_ty {
57 let byte = decoder.read_u8();
62 if (byte & 0x80) == 0 {
63 return byte as $int_ty;
64 }
65 let mut result = (byte & 0x7F) as $int_ty;
66 let mut shift = 7;
67 loop {
68 let byte = decoder.read_u8();
69 if (byte & 0x80) == 0 {
70 result |= (byte as $int_ty) << shift;
71 return result;
72 } else {
73 result |= ((byte & 0x7F) as $int_ty) << shift;
74 }
75 shift = shift.debug_strict_add(7);
76 }
77 }
78 };
79}
80
81impl_read_unsigned_leb128!(read_u16_leb128, u16);
82impl_read_unsigned_leb128!(read_u32_leb128, u32);
83impl_read_unsigned_leb128!(read_u64_leb128, u64);
84impl_read_unsigned_leb128!(read_u128_leb128, u128);
85impl_read_unsigned_leb128!(read_usize_leb128, usize);
86
87macro_rules! impl_write_signed_leb128 {
88 ($fn_name:ident, $int_ty:ty) => {
89 #[inline]
90 pub fn $fn_name(out: &mut [u8; max_leb128_len::<$int_ty>()], mut value: $int_ty) -> usize {
91 let mut i = 0;
92
93 loop {
94 let mut byte = (value as u8) & 0x7f;
95 value >>= 7;
96 let more = !(((value == 0) && ((byte & 0x40) == 0))
97 || ((value == -1) && ((byte & 0x40) != 0)));
98
99 if more {
100 byte |= 0x80; }
102
103 unsafe {
104 *out.get_unchecked_mut(i) = byte;
105 }
106
107 i = i.debug_strict_add(1);
108
109 if !more {
110 break;
111 }
112 }
113
114 i
115 }
116 };
117}
118
119impl_write_signed_leb128!(write_i16_leb128, i16);
120impl_write_signed_leb128!(write_i32_leb128, i32);
121impl_write_signed_leb128!(write_i64_leb128, i64);
122impl_write_signed_leb128!(write_i128_leb128, i128);
123impl_write_signed_leb128!(write_isize_leb128, isize);
124
125macro_rules! impl_read_signed_leb128 {
126 ($fn_name:ident, $int_ty:ty) => {
127 #[inline]
128 pub fn $fn_name(decoder: &mut MemDecoder<'_>) -> $int_ty {
129 let mut result = 0;
130 let mut shift = 0;
131 let mut byte;
132
133 loop {
134 byte = decoder.read_u8();
135 result |= <$int_ty>::from(byte & 0x7F) << shift;
136 shift = shift.debug_strict_add(7);
137
138 if (byte & 0x80) == 0 {
139 break;
140 }
141 }
142
143 if (shift < <$int_ty>::BITS) && ((byte & 0x40) != 0) {
144 result |= (!0 << shift);
146 }
147
148 result
149 }
150 };
151}
152
153impl_read_signed_leb128!(read_i16_leb128, i16);
154impl_read_signed_leb128!(read_i32_leb128, i32);
155impl_read_signed_leb128!(read_i64_leb128, i64);
156impl_read_signed_leb128!(read_i128_leb128, i128);
157impl_read_signed_leb128!(read_isize_leb128, isize);