bincode_next/de/
bit_reader.rs1use crate::de::read::Reader;
2use crate::error::DecodeError;
3
4pub struct BitReader<'a, R: Reader> {
6 reader: &'a mut R,
7 current_byte: u8,
8 bits_available: u8,
9}
10
11impl<'a, R: Reader> BitReader<'a, R> {
12 #[inline(always)]
14 pub const fn new(reader: &'a mut R) -> Self {
15 Self {
16 reader,
17 current_byte: 0,
18 bits_available: 0,
19 }
20 }
21
22 #[inline(always)]
24 pub const fn from_state(
25 reader: &'a mut R,
26 current_byte: u8,
27 bits_available: u8,
28 ) -> Self {
29 Self {
30 reader,
31 current_byte,
32 bits_available,
33 }
34 }
35
36 #[inline(always)]
38 #[must_use]
39 pub const fn get_state(&self) -> (u8, u8) {
40 (self.current_byte, self.bits_available)
41 }
42
43 #[inline]
49 pub fn read_bits_lsb(
50 &mut self,
51 mut num_bits: u8,
52 ) -> Result<u64, DecodeError> {
53 let mut result: u64 = 0;
54 let mut bits_read: u8 = 0;
55
56 while num_bits > 0 {
57 if self.bits_available == 0 {
58 let mut buf = [0u8; 1];
59 self.reader.read(&mut buf)?;
60 self.current_byte = buf[0];
61 self.bits_available = 8;
62 }
63
64 let bits_to_read = num_bits.min(self.bits_available);
65 let mask = ((1u16 << bits_to_read) - 1) as u8;
66
67 let chunk = self.current_byte & mask;
68 result |= u64::from(chunk) << bits_read;
69
70 self.current_byte >>= bits_to_read;
71 self.bits_available -= bits_to_read;
72
73 bits_read += bits_to_read;
74 num_bits -= bits_to_read;
75 }
76
77 Ok(result)
78 }
79
80 #[inline]
86 pub fn read_bits_msb(
87 &mut self,
88 mut num_bits: u8,
89 ) -> Result<u64, DecodeError> {
90 let mut result: u64 = 0;
91
92 while num_bits > 0 {
93 if self.bits_available == 0 {
94 let mut buf = [0u8; 1];
95 self.reader.read(&mut buf)?;
96 self.current_byte = buf[0];
97 self.bits_available = 8;
98 }
99
100 let bits_to_read = num_bits.min(self.bits_available);
101 let shift_down = self.bits_available - bits_to_read;
102 let mask = ((1u16 << bits_to_read) - 1) as u8;
103
104 let chunk = (self.current_byte >> shift_down) & mask;
105 result = (result << bits_to_read) | u64::from(chunk);
106
107 self.bits_available -= bits_to_read;
108 num_bits -= bits_to_read;
109 }
110
111 Ok(result)
112 }
113
114 #[inline(always)]
120 pub fn read_bits<C: crate::config::Config>(
121 &mut self,
122 num_bits: u8,
123 config: &C,
124 ) -> Result<u64, DecodeError> {
125 use crate::config::BitOrdering;
126 match config.bit_ordering() {
127 | BitOrdering::Lsb => self.read_bits_lsb(num_bits),
128 | BitOrdering::Msb => self.read_bits_msb(num_bits),
129 }
130 }
131
132 #[inline(always)]
134 pub const fn align_to_byte(&mut self) {
135 self.bits_available = 0;
136 self.current_byte = 0;
137 }
138}
139
140pub trait Unpackable {
142 fn unpack(val: u64) -> Self;
144}
145
146impl Unpackable for bool {
147 #[inline(always)]
148 fn unpack(val: u64) -> Self {
149 val != 0
150 }
151}
152
153macro_rules! impl_unpackable_int {
154 ($($ty:ty),*) => {
155 $(
156 impl Unpackable for $ty {
157 #[inline(always)]
158 fn unpack(val: u64) -> Self {
159 val as $ty
160 }
161 }
162 )*
163 };
164}
165
166impl_unpackable_int!(
167 u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
168);