bits_io/buf/
bit_buf_mut_exts.rs

1use funty::Integral;
2
3use crate::prelude::*;
4
5pub trait BitBufMutExts: BitBufMut {
6    #[allow(non_snake_case)]
7    fn put_uN<O: ByteOrder, const N: usize, U, V: Integral>(
8        &mut self,
9        value: U,
10    ) -> std::io::Result<()>
11    where
12        U: Into<V>,
13    {
14        // Convert the given value into the given integral type we're told it should map to (V).
15        // E.g. u8, u16, u32.
16        let value_integral: V = value.into();
17        let slice = self.chunk_mut_bits();
18        // If this buffer is chained to another we may have enough space to store the value but it
19        // may not be contiguous.  If it is, then we can write directly into the slice instead of
20        // copying to an intermediary first
21        if slice.len() >= N {
22            O::store(&mut slice[..N], value_integral);
23            self.advance_mut_bits(N);
24            Ok(())
25        } else {
26            let mut bits = BitVec::repeat(false, N);
27            let value_slice = bits.as_mut_bitslice();
28            O::store(value_slice, value_integral);
29            self.try_put_bit_slice(value_slice)?;
30            Ok(())
31        }
32    }
33
34    fn put_bool(&mut self, value: bool) -> std::io::Result<()> {
35        self.put_u1(u1::new(value as u8))
36    }
37
38    fn put_u1(&mut self, value: u1) -> std::io::Result<()> {
39        self.put_uN::<BigEndian, 1, u1, u8>(value)
40    }
41
42    fn put_u2(&mut self, value: u2) -> std::io::Result<()> {
43        self.put_uN::<BigEndian, 2, u2, u8>(value)
44    }
45
46    fn put_u3(&mut self, value: u3) -> std::io::Result<()> {
47        self.put_uN::<BigEndian, 3, u3, u8>(value)
48    }
49
50    fn put_u4(&mut self, value: u4) -> std::io::Result<()> {
51        self.put_uN::<BigEndian, 4, u4, u8>(value)
52    }
53
54    fn put_u5(&mut self, value: u5) -> std::io::Result<()> {
55        self.put_uN::<BigEndian, 5, u5, u8>(value)
56    }
57
58    fn put_u6(&mut self, value: u6) -> std::io::Result<()> {
59        self.put_uN::<BigEndian, 6, u6, u8>(value)
60    }
61
62    fn put_u7(&mut self, value: u7) -> std::io::Result<()> {
63        self.put_uN::<BigEndian, 7, u7, u8>(value)
64    }
65
66    fn put_u8(&mut self, value: u8) -> std::io::Result<()> {
67        if self.byte_aligned_mut() {
68            if self.remaining_mut_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 source (1)",
73                        self.remaining_mut_bytes(),
74                    ),
75                ));
76            }
77            self.chunk_mut_bytes().write_byte(0, value);
78            self.advance_mut_bytes(1);
79            return Ok(());
80        }
81        self.put_uN::<BigEndian, 8, u8, u8>(value)
82    }
83
84    fn put_u9<O: ByteOrder>(&mut self, value: u9) -> std::io::Result<()> {
85        self.put_uN::<O, 9, u9, u16>(value)
86    }
87    fn put_u10<O: ByteOrder>(&mut self, value: u10) -> std::io::Result<()> {
88        self.put_uN::<O, 10, u10, u16>(value)
89    }
90    fn put_u11<O: ByteOrder>(&mut self, value: u11) -> std::io::Result<()> {
91        self.put_uN::<O, 11, u11, u16>(value)
92    }
93    fn put_u12<O: ByteOrder>(&mut self, value: u12) -> std::io::Result<()> {
94        self.put_uN::<O, 12, u12, u16>(value)
95    }
96    fn put_u13<O: ByteOrder>(&mut self, value: u13) -> std::io::Result<()> {
97        self.put_uN::<O, 13, u13, u16>(value)
98    }
99    fn put_u14<O: ByteOrder>(&mut self, value: u14) -> std::io::Result<()> {
100        self.put_uN::<O, 14, u14, u16>(value)
101    }
102    fn put_u15<O: ByteOrder>(&mut self, value: u15) -> std::io::Result<()> {
103        self.put_uN::<O, 15, u15, u16>(value)
104    }
105    fn put_u16<O: ByteOrder>(&mut self, value: u16) -> std::io::Result<()> {
106        if self.byte_aligned_mut() {
107            if self.remaining_mut_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 source (2)",
112                        self.remaining_mut_bytes(),
113                    ),
114                ));
115            }
116            let mut buf = [0u8; 2];
117            O::store_u16(&mut buf, value);
118            return self.try_put_slice_bytes(&buf);
119        }
120        self.put_uN::<O, 16, u16, u16>(value)
121    }
122    fn put_u17<O: ByteOrder>(&mut self, value: u17) -> std::io::Result<()> {
123        self.put_uN::<O, 17, u17, u32>(value)
124    }
125    fn put_u18<O: ByteOrder>(&mut self, value: u18) -> std::io::Result<()> {
126        self.put_uN::<O, 18, u18, u32>(value)
127    }
128    fn put_u19<O: ByteOrder>(&mut self, value: u19) -> std::io::Result<()> {
129        self.put_uN::<O, 19, u19, u32>(value)
130    }
131    fn put_u20<O: ByteOrder>(&mut self, value: u20) -> std::io::Result<()> {
132        self.put_uN::<O, 20, u20, u32>(value)
133    }
134    fn put_u21<O: ByteOrder>(&mut self, value: u21) -> std::io::Result<()> {
135        self.put_uN::<O, 21, u21, u32>(value)
136    }
137    fn put_u22<O: ByteOrder>(&mut self, value: u22) -> std::io::Result<()> {
138        self.put_uN::<O, 22, u22, u32>(value)
139    }
140    fn put_u23<O: ByteOrder>(&mut self, value: u23) -> std::io::Result<()> {
141        self.put_uN::<O, 23, u23, u32>(value)
142    }
143    fn put_u24<O: ByteOrder>(&mut self, value: u24) -> std::io::Result<()> {
144        if self.byte_aligned_mut() {
145            if self.remaining_mut_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 source (3)",
150                        self.remaining_mut_bytes(),
151                    ),
152                ));
153            }
154
155            let mut buf = [0u8; 3];
156            O::store_u24(&mut buf, value);
157            return self.try_put_slice_bytes(&buf);
158        }
159        self.put_uN::<O, 24, u24, u32>(value)
160    }
161    fn put_u25<O: ByteOrder>(&mut self, value: u25) -> std::io::Result<()> {
162        self.put_uN::<O, 25, u25, u32>(value)
163    }
164    fn put_u26<O: ByteOrder>(&mut self, value: u26) -> std::io::Result<()> {
165        self.put_uN::<O, 26, u26, u32>(value)
166    }
167    fn put_u27<O: ByteOrder>(&mut self, value: u27) -> std::io::Result<()> {
168        self.put_uN::<O, 27, u27, u32>(value)
169    }
170    fn put_u28<O: ByteOrder>(&mut self, value: u28) -> std::io::Result<()> {
171        self.put_uN::<O, 28, u28, u32>(value)
172    }
173    fn put_u29<O: ByteOrder>(&mut self, value: u29) -> std::io::Result<()> {
174        self.put_uN::<O, 29, u29, u32>(value)
175    }
176    fn put_u30<O: ByteOrder>(&mut self, value: u30) -> std::io::Result<()> {
177        self.put_uN::<O, 30, u30, u32>(value)
178    }
179    fn put_u31<O: ByteOrder>(&mut self, value: u31) -> std::io::Result<()> {
180        self.put_uN::<O, 31, u31, u32>(value)
181    }
182    fn put_u32<O: ByteOrder>(&mut self, value: u32) -> std::io::Result<()> {
183        if self.byte_aligned_mut() {
184            if self.remaining_mut_bytes() < 4 {
185                return Err(std::io::Error::new(
186                    std::io::ErrorKind::UnexpectedEof,
187                    format!(
188                        "Remaining bytes ({}) are less than the size of the source (4)",
189                        self.remaining_mut_bytes(),
190                    ),
191                ));
192            }
193            let mut buf = [0u8; 4];
194            O::store_u32(&mut buf, value);
195            return self.try_put_slice_bytes(&buf);
196        }
197        self.put_uN::<O, 32, u32, u32>(value)
198    }
199}
200
201impl<T: BitBufMut + ?Sized> BitBufMutExts for T {}
202
203#[cfg(test)]
204mod tests {
205    use crate::prelude::*;
206
207    #[test]
208    fn test_put() {
209        let mut bits_mut = BitsMut::new();
210        bits_mut.put_u1(u1::new(0b1)).unwrap();
211        bits_mut.put_u3(u3::new(0b001)).unwrap();
212        bits_mut.put_u5(u5::new(0b00001)).unwrap();
213        bits_mut.put_u7(u7::new(0b0000001)).unwrap();
214
215        assert_eq!(
216            &bits_mut[..],
217            bits![1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]
218        );
219    }
220
221    #[test]
222    fn test_put_big_endian() {
223        {
224            let mut bits_mut = BitsMut::new();
225            let value = u9::new(0b1_01010101);
226            bits_mut.put_u9::<BigEndian>(value).unwrap();
227            assert_eq!(&bits_mut[..], bits![1, 0, 1, 0, 1, 0, 1, 0, 1]);
228        }
229        {
230            let mut bits_mut = BitsMut::new();
231            let value = u21::new(0b10101_01010101_01010101);
232            bits_mut.put_u21::<BigEndian>(value).unwrap();
233            assert_eq!(
234                &bits_mut[..],
235                bits![1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
236            );
237        }
238    }
239
240    #[test]
241    fn test_put_little_endian() {
242        {
243            let mut bits_mut = BitsMut::new();
244            let value = u9::new(0b1_00001111);
245            bits_mut.put_u9::<LittleEndian>(value).unwrap();
246            assert_eq!(&bits_mut[..], bits![0, 0, 0, 0, 1, 1, 1, 1, 1]);
247        }
248        {
249            let mut bits_mut = BitsMut::new();
250            let value = u21::new(0b00110_00001111_00011100);
251            bits_mut.put_u21::<LittleEndian>(value).unwrap();
252            assert_eq!(
253                &bits_mut[..],
254                bits![0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0]
255            );
256        }
257    }
258}