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 let value_integral: V = value.into();
17 let slice = self.chunk_mut_bits();
18 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}