1use funty::Integral;
2
3use super::bit_buf::BitBuf;
4use crate::prelude::*;
5
6pub trait BitBufExts: BitBuf {
7 #[allow(non_snake_case)]
8 fn get_uN<O: ByteOrder, const N: usize, U, V: Integral>(&mut self) -> std::io::Result<U>
9 where
10 U: TryFrom<V>,
11 U::Error: std::fmt::Debug,
12 {
13 let slice = self.chunk_bits();
17 if slice.len() >= N {
18 let value: V = O::load(&slice[..N]);
19 self.advance_bits(N);
20
21 Ok(U::try_from(value).map_err(|_| std::io::ErrorKind::InvalidData)?)
22 } else {
23 let mut bits = BitVec::repeat(false, N);
24 let slice = bits.as_mut_bitslice();
25 self.try_copy_to_bit_slice(slice)?;
27 let value: V = O::load(slice);
29
30 Ok(U::try_from(value).map_err(|_| std::io::ErrorKind::InvalidData)?)
31 }
32 }
33
34 fn get_bool(&mut self) -> std::io::Result<bool> {
35 Ok(self.get_u1()?.into())
36 }
37
38 fn get_u1(&mut self) -> std::io::Result<u1> {
39 self.get_uN::<BigEndian, 1, u1, u8>()
40 }
41
42 fn get_u2(&mut self) -> std::io::Result<u2> {
43 self.get_uN::<BigEndian, 2, u2, u8>()
44 }
45
46 fn get_u3(&mut self) -> std::io::Result<u3> {
47 self.get_uN::<BigEndian, 3, u3, u8>()
48 }
49
50 fn get_u4(&mut self) -> std::io::Result<u4> {
51 self.get_uN::<BigEndian, 4, u4, u8>()
52 }
53
54 fn get_u5(&mut self) -> std::io::Result<u5> {
55 self.get_uN::<BigEndian, 5, u5, u8>()
56 }
57
58 fn get_u6(&mut self) -> std::io::Result<u6> {
59 self.get_uN::<BigEndian, 6, u6, u8>()
60 }
61
62 fn get_u7(&mut self) -> std::io::Result<u7> {
63 self.get_uN::<BigEndian, 7, u7, u8>()
64 }
65
66 fn get_u8(&mut self) -> std::io::Result<u8> {
67 if self.byte_aligned() {
68 if self.remaining_bytes() < 1 {
69 return Err(std::io::Error::new(
70 std::io::ErrorKind::UnexpectedEof,
71 format!(
72 "Remaining bytes ({}) are less than the size of the dest (1)",
73 self.remaining_bytes(),
74 ),
75 ));
76 }
77 let value = self.chunk_bytes()[0];
78 self.advance_bytes(1);
79 return Ok(value);
80 }
81 self.get_uN::<BigEndian, 8, u8, u8>()
82 }
83
84 fn get_u9<O: ByteOrder>(&mut self) -> std::io::Result<u9> {
85 self.get_uN::<O, 9, u9, u16>()
86 }
87 fn get_u10<O: ByteOrder>(&mut self) -> std::io::Result<u10> {
88 self.get_uN::<O, 10, u10, u16>()
89 }
90 fn get_u11<O: ByteOrder>(&mut self) -> std::io::Result<u11> {
91 self.get_uN::<O, 11, u11, u16>()
92 }
93 fn get_u12<O: ByteOrder>(&mut self) -> std::io::Result<u12> {
94 self.get_uN::<O, 12, u12, u16>()
95 }
96 fn get_u13<O: ByteOrder>(&mut self) -> std::io::Result<u13> {
97 self.get_uN::<O, 13, u13, u16>()
98 }
99 fn get_u14<O: ByteOrder>(&mut self) -> std::io::Result<u14> {
100 self.get_uN::<O, 14, u14, u16>()
101 }
102 fn get_u15<O: ByteOrder>(&mut self) -> std::io::Result<u15> {
103 self.get_uN::<O, 15, u15, u16>()
104 }
105 fn get_u16<O: ByteOrder>(&mut self) -> std::io::Result<u16> {
106 if self.byte_aligned() {
107 if self.remaining_bytes() < 2 {
108 return Err(std::io::Error::new(
109 std::io::ErrorKind::UnexpectedEof,
110 format!(
111 "Remaining bytes ({}) are less than the size of the dest (2)",
112 self.remaining_bytes(),
113 ),
114 ));
115 }
116 let mut dest = [0u8; 2];
117 self.try_copy_to_slice_bytes(&mut dest)?;
118 return Ok(O::load_u16(&dest));
119 }
120 self.get_uN::<O, 16, u16, u16>()
121 }
122 fn get_u17<O: ByteOrder>(&mut self) -> std::io::Result<u17> {
123 self.get_uN::<O, 17, u17, u32>()
124 }
125 fn get_u18<O: ByteOrder>(&mut self) -> std::io::Result<u18> {
126 self.get_uN::<O, 18, u18, u32>()
127 }
128 fn get_u19<O: ByteOrder>(&mut self) -> std::io::Result<u19> {
129 self.get_uN::<O, 19, u19, u32>()
130 }
131 fn get_u20<O: ByteOrder>(&mut self) -> std::io::Result<u20> {
132 self.get_uN::<O, 20, u20, u32>()
133 }
134 fn get_u21<O: ByteOrder>(&mut self) -> std::io::Result<u21> {
135 self.get_uN::<O, 21, u21, u32>()
136 }
137 fn get_u22<O: ByteOrder>(&mut self) -> std::io::Result<u22> {
138 self.get_uN::<O, 22, u22, u32>()
139 }
140 fn get_u23<O: ByteOrder>(&mut self) -> std::io::Result<u23> {
141 self.get_uN::<O, 23, u23, u32>()
142 }
143 fn get_u24<O: ByteOrder>(&mut self) -> std::io::Result<u24> {
144 if self.byte_aligned() {
145 if self.remaining_bytes() < 3 {
146 return Err(std::io::Error::new(
147 std::io::ErrorKind::UnexpectedEof,
148 format!(
149 "Remaining bytes ({}) are less than the size of the dest (3)",
150 self.remaining_bytes(),
151 ),
152 ));
153 }
154 let mut dest = [0u8; 3];
155 self.try_copy_to_slice_bytes(&mut dest)?;
156 return Ok(O::load_u24(&dest));
157 }
158 self.get_uN::<O, 24, u24, u32>()
159 }
160 fn get_u25<O: ByteOrder>(&mut self) -> std::io::Result<u25> {
161 self.get_uN::<O, 25, u25, u32>()
162 }
163 fn get_u26<O: ByteOrder>(&mut self) -> std::io::Result<u26> {
164 self.get_uN::<O, 26, u26, u32>()
165 }
166 fn get_u27<O: ByteOrder>(&mut self) -> std::io::Result<u27> {
167 self.get_uN::<O, 27, u27, u32>()
168 }
169 fn get_u28<O: ByteOrder>(&mut self) -> std::io::Result<u28> {
170 self.get_uN::<O, 28, u28, u32>()
171 }
172 fn get_u29<O: ByteOrder>(&mut self) -> std::io::Result<u29> {
173 self.get_uN::<O, 29, u29, u32>()
174 }
175 fn get_u30<O: ByteOrder>(&mut self) -> std::io::Result<u30> {
176 self.get_uN::<O, 30, u30, u32>()
177 }
178 fn get_u31<O: ByteOrder>(&mut self) -> std::io::Result<u31> {
179 self.get_uN::<O, 31, u31, u32>()
180 }
181 fn get_u32<O: ByteOrder>(&mut self) -> std::io::Result<u32> {
182 if self.byte_aligned() {
183 if self.remaining_bytes() < 4 {
184 return Err(std::io::Error::new(
185 std::io::ErrorKind::UnexpectedEof,
186 format!(
187 "Remaining bytes ({}) are less than the size of the dest (4)",
188 self.remaining_bytes(),
189 ),
190 ));
191 }
192 let mut dest = [0u8; 4];
193 self.try_copy_to_slice_bytes(&mut dest)?;
194 return Ok(O::load_u32(&dest));
195 }
196 self.get_uN::<O, 32, u32, u32>()
197 }
198}
199
200impl<T: BitBuf + ?Sized> BitBufExts for T {}
201
202#[cfg(test)]
203mod tests {
204 use crate::buf::bits::Bits;
205
206 use super::*;
207
208 #[test]
209 fn test_bit_buf_exts() {
210 let mut bits = Bits::copy_from_bit_slice(bits![0, 1, 1, 0, 0, 1, 1, 1]);
211
212 let value = bits.get_u4().unwrap();
213 assert_eq!(value, u4::new(0b0110));
214 let value = bits.get_u1().unwrap();
215 assert_eq!(value, u1::new(0));
216 let value = bits.get_u3().unwrap();
217 assert_eq!(value, u3::new(0b111));
218 }
219
220 #[test]
221 fn test_get_big_endian() {
222 let u9_data = bits![1, 0, 1, 0, 1, 0, 1, 0, 1];
223 let mut bits = Bits::copy_from_bit_slice(u9_data);
224 assert_eq!(bits.get_u9::<BigEndian>().unwrap(), u9::new(0b101010101));
225
226 let u10_data = bits![1, 0, 1, 0, 1, 0, 1, 0, 1, 1];
227 let mut bits = Bits::copy_from_bit_slice(u10_data);
228 assert_eq!(bits.get_u10::<BigEndian>().unwrap(), u10::new(0b1010101011));
229
230 let u11_data = bits![0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0];
231 let mut bits = Bits::copy_from_bit_slice(u11_data);
232 assert_eq!(
233 bits.get_u11::<BigEndian>().unwrap(),
234 u11::new(0b00110011000)
235 );
236
237 let u12_data = bits![0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0];
238 let mut bits = Bits::copy_from_bit_slice(u12_data);
239 assert_eq!(
240 bits.get_u12::<BigEndian>().unwrap(),
241 u12::new(0b011111111000)
242 );
243 }
244
245 #[test]
246 fn test_get_little_endian() {
247 let u9_data = bits![1, 0, 1, 0, 1, 0, 1, 1, 1];
249 let mut bits = Bits::copy_from_bit_slice(u9_data);
250 assert_eq!(
251 bits.get_u9::<LittleEndian>().unwrap(),
252 u9::new(0b1_10101011)
253 );
254
255 let u10_data = bits![1, 0, 1, 0, 1, 0, 1, 1, 1, 1];
257 let mut bits = Bits::copy_from_bit_slice(u10_data);
258 assert_eq!(
259 bits.get_u10::<LittleEndian>().unwrap(),
260 u10::new(0b11_10101011)
261 );
262
263 let u11_data = bits![1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0];
265 let mut bits = Bits::copy_from_bit_slice(u11_data);
266 assert_eq!(
267 bits.get_u11::<LittleEndian>().unwrap(),
268 u11::new(0b110_10101011)
269 );
270
271 let u16_data = bits![1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1];
273 let mut bits = Bits::copy_from_bit_slice(u16_data);
274 assert_eq!(
275 bits.get_u16::<LittleEndian>().unwrap(),
276 0b11001101_11101111u16
277 );
278
279 let u20_data = bits![1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0];
281 let mut bits = Bits::copy_from_bit_slice(u20_data);
282 assert_eq!(
283 bits.get_u20::<LittleEndian>().unwrap(),
284 u20::new(0b1010_10111100_11011110)
285 );
286 }
287}