1use crate::decode;
2
3pub(crate) const MAX_BYTES_FINAL: usize = 28;
4pub(crate) const MAX_BYTES_NONFINAL: usize = 23;
5
6pub(crate) struct Bits {
7 bitpos: u8,
8 packed: [u8; MAX_BYTES_FINAL],
9}
10
11impl Bits {
12 pub(crate) const fn new() -> Self {
13 Bits {
14 bitpos: 0,
15 packed: [0u8; MAX_BYTES_FINAL],
16 }
17 }
18
19 pub(crate) const fn push(&mut self, val: u8, len: u8) {
20 self.packed[(self.bitpos / 8) as usize] |= val << (self.bitpos % 8);
21 if val.leading_zeros() < (self.bitpos % 8) as u32 {
22 self.packed[(self.bitpos / 8 + 1) as usize] |= val >> (8 - self.bitpos % 8);
23 }
24 self.bitpos += len;
25 }
26
27 pub(crate) fn as_slice(&self) -> &[u8] {
28 &self.packed[..self.bitpos.div_ceil(8) as usize]
29 }
30}
31
32macro_rules! push {
33 ($bits:ident, $($lit:literal)+) => {
34 $(
35 $bits.push(
36 const {
37 match u8::from_str_radix(stringify!($lit), 2) {
38 Ok(val) => val,
39 Err(_) => panic!(),
40 }
41 },
42 stringify!($lit).len() as u8,
43 );
44 )+
45 };
46}
47
48pub(crate) fn encode(bfinal: bool, payload: u64) -> Bits {
49 {
match (&payload, &0) {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = ::core::panicking::AssertKind::Ne;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_ne!(payload, 0);
50
51 let mut bits = Bits::new();
52 bits.push(u8::from(bfinal), 1); bits.push(const {
match u8::from_str_radix("10", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "10".len() as u8);push!(bits, 10); bits.push(const {
match u8::from_str_radix("00000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "00000".len() as u8);push!(bits, 00000); bits.push(const {
match u8::from_str_radix("00000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "00000".len() as u8);push!(bits, 00000); bits.push(const {
match u8::from_str_radix("1110", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "1110".len() as u8);push!(bits, 1110); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("001", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "001".len() as u8);push!(bits, 001); bits.push(const {
match u8::from_str_radix("010", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "010".len() as u8);push!(bits, 010); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "000".len() as u8);push!(bits, 000); bits.push(const {
match u8::from_str_radix("010", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "010".len() as u8);push!(bits, 010); let mut rest = payload;
84 let mut zeros = 0;
85 while rest != 0 {
86 bits.push(const {
match u8::from_str_radix("0", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "0".len() as u8);push!(bits, 0);
87 bits.push(rest as u8 & 0b111, 3);
88 zeros += 3 + (rest & 0b111);
89 rest >>= 3;
90 }
91 match zeros {
92 4..=97 => {
93 bits.push(const {
match u8::from_str_radix("1111111", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "1111111".len() as u8);push!(bits, 11 1111111);
95 bits.push(const {
match u8::from_str_radix("11", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "11".len() as u8);push!(bits, 11);
96 bits.push((256 - (zeros + 138) - 11) as u8, 7);
97 }
98 98..=107 => {
99 bits.push(const {
match u8::from_str_radix("11", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "11".len() as u8);push!(bits, 11);
101 bits.push((256 - (zeros + 20) - 11) as u8, 7);
102 bits.push(const {
match u8::from_str_radix("111", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "111".len() as u8);push!(bits, 0 111);
103 bits.push(const {
match u8::from_str_radix("111", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "111".len() as u8);push!(bits, 0 111);
104 }
105 108..=117 => {
106 bits.push(const {
match u8::from_str_radix("11", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "11".len() as u8);push!(bits, 11);
108 bits.push((256 - (zeros + 10) - 11) as u8, 7);
109 bits.push(const {
match u8::from_str_radix("111", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "111".len() as u8);push!(bits, 0 111);
110 }
111 118..=214 => {
112 bits.push(const {
match u8::from_str_radix("11", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "11".len() as u8);push!(bits, 11);
114 bits.push((256 - zeros - 11) as u8, 7);
115 }
116 0..=3 | 215.. => {
117 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
120 }
121 }
122
123 bits.push(const {
match u8::from_str_radix("01", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "01".len() as u8);push!(bits, 01); bits.push(const {
match u8::from_str_radix("01", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "01".len() as u8);push!(bits, 01); bits.push(const {
match u8::from_str_radix("0", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "0".len() as u8);push!(bits, 0);
130
131 if !bits.as_slice().starts_with(&decode::prefix(bfinal)) {
::core::panicking::panic("assertion failed: bits.as_slice().starts_with(&decode::prefix(bfinal))")
};assert!(bits.as_slice().starts_with(&decode::prefix(bfinal)));
132
133 if !bfinal {
135 match bits.bitpos % 8 {
136 0 => {}
137 n @ (1..=5 | 7) => {
138 bits.push(const {
match u8::from_str_radix("0", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "0".len() as u8);push!(bits, 0); bits.push(const {
match u8::from_str_radix("00", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "00".len() as u8);push!(bits, 00); bits.push(0, (13 - n) % 8); bits.push(const {
match u8::from_str_radix("00000000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "00000000".len() as u8);push!(bits, 00000000 00000000); bits.push(const {
match u8::from_str_radix("11111111", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "11111111".len() as u8);push!(bits, 11111111 11111111); }
144 6 => {
145 bits.push(const {
match u8::from_str_radix("0", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "0".len() as u8);push!(bits, 0); bits.push(const {
match u8::from_str_radix("01", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "01".len() as u8);push!(bits, 01); bits.push(const {
match u8::from_str_radix("0000000", 2) {
Ok(val) => val,
Err(_) => ::core::panicking::panic("explicit panic"),
}
}, "0000000".len() as u8);push!(bits, 0000000); }
149 8.. => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
150 }
151 }
152
153 bits
154}