bits_io/buf/
bit_buf_exts.rs

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        // If this buffer is chained to another there may be enough room to read the value but it
14        // may not be contiguous.  If it is, then we can read directly instead of copying to an
15        // intermediary first.
16        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            // Copy the raw bits into the slice
26            self.try_copy_to_bit_slice(slice)?;
27            // Now 'load' the value from that slice according to the given ByteOrder.
28            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        // Little-endian form of 1_10101011
248        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        // Little-endian form of 11_10101011
256        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        // Little-endian form of 110_10101011
264        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        // Little-endian form of 11001101_11101111
272        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        // Little-endian form of 11001101_11101111
280        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}