1use super::MAX_VARINT_VALUE;
5use core::fmt;
6use s2n_codec::{Encoder, EncoderValue};
7
8macro_rules! call_table {
31 ($table:ident) => {
32 $table! {
33 (0b10, 4, 30, 1_073_741_823);
34 (0b01, 2, 14, 16_383);
35 (0b00, 1, 6 , 63);
36 }
37 };
38}
39
40#[derive(Clone, Copy, PartialEq, Eq)]
41pub struct Entry {
42 pub two_bit: u64,
44 pub two_bit_be: u64,
46 pub len: usize,
48 pub usable_bits: u64,
50 pub shift: u64,
52}
53
54impl fmt::Debug for Entry {
55 #[inline]
56 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57 f.debug_struct("Entry")
58 .field("two_bit", &self.two_bit)
59 .field("two_bit_be", &self.two_bit_be.to_ne_bytes())
60 .field("len", &self.len)
61 .field("usable_bits", &self.usable_bits)
62 .field("shift", &self.shift)
63 .finish()
64 }
65}
66
67impl Entry {
68 #[inline(always)]
70 pub fn read(x: u64) -> Self {
71 let optimized = Self::read_optimized(x);
72 debug_assert_eq!(optimized, Self::read_rfc(x));
73 optimized
74 }
75
76 #[inline(always)]
78 pub fn read_rfc(x: u64) -> Self {
79 #[allow(clippy::match_overlapping_arm)]
82 match x {
83 0..=63 => Self {
84 two_bit: 0b00,
85 two_bit_be: 0b00,
86 len: 1,
87 usable_bits: 6,
88 shift: 56,
89 },
90 0..=16383 => Self {
91 two_bit: 0b01,
92 two_bit_be: (0b01u64 << 62).to_be(),
93 len: 2,
94 usable_bits: 14,
95 shift: 48,
96 },
97 0..=1073741823 => Self {
98 two_bit: 0b10,
99 two_bit_be: (0b10u64 << 62).to_be(),
100 len: 4,
101 usable_bits: 30,
102 shift: 32,
103 },
104 0..=4611686018427387903 => Self {
105 two_bit: 0b11,
106 two_bit_be: (0b11u64 << 62).to_be(),
107 len: 8,
108 usable_bits: 62,
109 shift: 0,
110 },
111 _ => unreachable!(),
112 }
113 }
114
115 #[inline(always)]
117 pub fn read_optimized(x: u64) -> Self {
118 unsafe {
119 crate::assume!(x <= MAX_VARINT_VALUE);
120 }
121
122 macro_rules! table {
123 ($(($two_bit:expr, $length:expr, $usable_bits:expr, $max_value:expr);)*) => {{
124 let mut shift = 0;
125 let mut usable_bits = 62;
126 let mut two_bit = 0b11u64;
127 let mut two_bit_be = (two_bit << 62).to_be();
128 let mut len = 8;
129
130 $(
131 if x <= $max_value {
132 shift = 62 - $usable_bits;
133 usable_bits = $usable_bits;
134 two_bit -= 1u64;
135 two_bit_be -= (1u64 << 62).to_be();
136 len = $length;
137 }
138 )*
139
140 Self { two_bit, two_bit_be, len, usable_bits, shift }
141 }};
142 }
143
144 call_table!(table)
145 }
146
147 #[inline(always)]
148 pub fn format(&self, value: u64) -> Formatted {
149 let encoded_be = (value << self.shift).to_be() | self.two_bit_be;
150 let len = self.len;
151 Formatted { encoded_be, len }
152 }
153}
154
155#[derive(Clone, Copy, Debug, PartialEq, Eq)]
156pub struct Formatted {
157 pub(crate) encoded_be: u64,
158 pub(crate) len: usize,
159}
160
161impl Formatted {
162 #[inline(always)]
163 pub(super) fn new(x: u64) -> Self {
164 unsafe {
165 crate::assume!(x <= MAX_VARINT_VALUE);
166 }
167
168 macro_rules! table {
169 ($(($two_bit:expr, $length:expr, $usable_bits:expr, $max_value:expr);)*) => {{
170 let mut shift = 0;
171 let mut two_bit = (0b11u64 << 62).to_be();
172 let mut len = 8;
173
174 $(
175 if x <= $max_value {
176 shift = 62 - $usable_bits;
177 two_bit -= (1u64 << 62).to_be();
178 len = $length;
179 }
180 )*
181
182 #[cfg(debug_assertions)]
183 {
184 let entry = Entry::read_rfc(x);
186 assert_eq!(entry.shift, shift);
187 assert_eq!(entry.two_bit_be, two_bit);
188 assert_eq!(entry.len, len);
189 }
190
191 let encoded_be = (x << shift).to_be() | two_bit;
192
193 let v = Self { encoded_be, len };
194
195 v.invariants();
196
197 v
198 }};
199 }
200
201 call_table!(table)
202 }
203
204 #[inline(always)]
205 pub(super) fn encode_oversized<E: Encoder>(&self, encoder: &mut E) {
206 debug_assert!(encoder.remaining_capacity() >= 8);
207 self.invariants();
208
209 encoder.write_sized(self.len, |dest| {
210 let dest = dest.as_mut_ptr() as *mut [u8; 8];
211 let bytes = self.encoded_be.to_ne_bytes();
212 unsafe {
213 core::ptr::write(dest, bytes);
214 }
215 });
216 }
217
218 #[inline(always)]
219 pub(super) fn encode_maybe_undersized<E: Encoder>(&self, encoder: &mut E) {
220 self.invariants();
221
222 let len = self.len;
223
224 encoder.write_sized(len, |dst| {
225 let src = self.encoded_be.to_ne_bytes();
226 unsafe {
227 use core::ptr::copy_nonoverlapping as copy;
228
229 crate::assume!(dst.len() == len);
230
231 let src = src.as_ptr();
232 let dst = dst.as_mut_ptr();
233
234 match len {
235 1 => copy(src, dst, 1),
236 2 => copy(src, dst, 2),
237 4 => copy(src, dst, 4),
238 8 => copy(src, dst, 8),
239 _ => {
240 assume!(false, "invalid len: {len}");
241 }
242 }
243 }
244 });
245 }
246
247 #[inline(always)]
248 pub(super) fn invariants(&self) {
249 unsafe {
250 let len = self.len;
251 assume!(len == 1 || len == 2 || len == 4 || len == 8);
253 }
254 }
255}
256
257impl EncoderValue for Formatted {
258 #[inline(always)]
259 fn encode<E: Encoder>(&self, encoder: &mut E) {
260 self.invariants();
261
262 if encoder.remaining_capacity() >= 8 && !cfg!(miri) {
268 self.encode_oversized(encoder);
269 } else {
270 self.encode_maybe_undersized(encoder);
271 }
272 }
273
274 #[inline(always)]
275 fn encoding_size(&self) -> usize {
276 self.len
277 }
278
279 #[inline(always)]
280 fn encoding_size_for_encoder<E: Encoder>(&self, _encoder: &E) -> usize {
281 self.len
282 }
283}