/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bitstream-io-4.9.0/src/write.rs
Line | Count | Source |
1 | | // Copyright 2017 Brian Langenberger |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
4 | | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
5 | | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
6 | | // option. This file may not be copied, modified, or distributed |
7 | | // except according to those terms. |
8 | | |
9 | | //! Traits and implementations for writing bits to a stream. |
10 | | |
11 | | #![warn(missing_docs)] |
12 | | |
13 | | #[cfg(not(feature = "std"))] |
14 | | use core2::io; |
15 | | |
16 | | #[cfg(feature = "alloc")] |
17 | | use alloc::vec::Vec; |
18 | | use core::{ |
19 | | convert::{From, TryFrom, TryInto}, |
20 | | fmt, |
21 | | }; |
22 | | #[cfg(feature = "std")] |
23 | | use std::io; |
24 | | |
25 | | use super::{ |
26 | | BitCount, Checkable, CheckedSigned, CheckedUnsigned, Endianness, Integer, Numeric, PhantomData, |
27 | | Primitive, SignedBitCount, SignedInteger, UnsignedInteger, VBRInteger, |
28 | | }; |
29 | | |
30 | | #[cfg(feature = "alloc")] |
31 | | pub use bit_recorder::BitRecorder; |
32 | | |
33 | | /// For writing bit values to an underlying stream in a given endianness. |
34 | | /// |
35 | | /// Because this only writes whole bytes to the underlying stream, |
36 | | /// it is important that output is byte-aligned before the bitstream |
37 | | /// writer's lifetime ends. |
38 | | /// **Partial bytes will be lost** if the writer is disposed of |
39 | | /// before they can be written. |
40 | | pub struct BitWriter<W: io::Write, E: Endianness> { |
41 | | // our underlying writer |
42 | | writer: W, |
43 | | // our partial byte |
44 | | value: u8, |
45 | | // the number of bits in our partial byte |
46 | | bits: u32, |
47 | | // a container for our endianness |
48 | | phantom: PhantomData<E>, |
49 | | } |
50 | | |
51 | | impl<W: io::Write, E: Endianness> BitWriter<W, E> { |
52 | | /// Wraps a BitWriter around something that implements `Write` |
53 | 0 | pub fn new(writer: W) -> BitWriter<W, E> { |
54 | 0 | BitWriter { |
55 | 0 | writer, |
56 | 0 | value: 0, |
57 | 0 | bits: 0, |
58 | 0 | phantom: PhantomData, |
59 | 0 | } |
60 | 0 | } |
61 | | |
62 | | /// Wraps a BitWriter around something that implements `Write` |
63 | | /// with the given endianness. |
64 | 0 | pub fn endian(writer: W, _endian: E) -> BitWriter<W, E> { |
65 | 0 | BitWriter { |
66 | 0 | writer, |
67 | 0 | value: 0, |
68 | 0 | bits: 0, |
69 | 0 | phantom: PhantomData, |
70 | 0 | } |
71 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::LittleEndian>>::endian Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian>>::endian Unexecuted instantiation: <bitstream_io::write::BitWriter<_, _>>::endian |
72 | | |
73 | | /// Unwraps internal writer and disposes of BitWriter. |
74 | | /// |
75 | | /// # Warning |
76 | | /// |
77 | | /// Any unwritten partial bits are discarded. |
78 | | #[inline] |
79 | 0 | pub fn into_writer(self) -> W { |
80 | 0 | self.writer |
81 | 0 | } |
82 | | |
83 | | /// If stream is byte-aligned, provides mutable reference |
84 | | /// to internal writer. Otherwise returns `None` |
85 | | #[inline] |
86 | 0 | pub fn writer(&mut self) -> Option<&mut W> { |
87 | 0 | if BitWrite::byte_aligned(self) { |
88 | 0 | Some(&mut self.writer) |
89 | | } else { |
90 | 0 | None |
91 | | } |
92 | 0 | } |
93 | | |
94 | | /// Returns byte-aligned mutable reference to internal writer. |
95 | | /// |
96 | | /// Bytes aligns stream if it is not already aligned. |
97 | | /// |
98 | | /// # Errors |
99 | | /// |
100 | | /// Passes along any I/O error from the underlying stream. |
101 | | #[inline] |
102 | 0 | pub fn aligned_writer(&mut self) -> io::Result<&mut W> { |
103 | 0 | BitWrite::byte_align(self)?; |
104 | 0 | Ok(&mut self.writer) |
105 | 0 | } |
106 | | |
107 | | /// Converts `BitWriter` to `ByteWriter` in the same endianness. |
108 | | /// |
109 | | /// # Warning |
110 | | /// |
111 | | /// Any written partial bits are discarded. |
112 | | #[inline] |
113 | 0 | pub fn into_bytewriter(self) -> ByteWriter<W, E> { |
114 | 0 | ByteWriter::new(self.into_writer()) |
115 | 0 | } |
116 | | |
117 | | /// If stream is byte-aligned, provides temporary `ByteWriter` |
118 | | /// in the same endianness. Otherwise returns `None` |
119 | | /// |
120 | | /// # Warning |
121 | | /// |
122 | | /// Any unwritten bits left over when `ByteWriter` is dropped are lost. |
123 | | #[inline] |
124 | 0 | pub fn bytewriter(&mut self) -> Option<ByteWriter<&mut W, E>> { |
125 | 0 | self.writer().map(ByteWriter::new) |
126 | 0 | } |
127 | | |
128 | | /// Flushes output stream to disk, if necessary. |
129 | | /// Any partial bytes are not flushed. |
130 | | /// |
131 | | /// # Errors |
132 | | /// |
133 | | /// Passes along any errors from the underlying stream. |
134 | | #[inline(always)] |
135 | 0 | pub fn flush(&mut self) -> io::Result<()> { |
136 | 0 | self.writer.flush() |
137 | 0 | } |
138 | | } |
139 | | |
140 | | /// A trait for anything that can write a variable number of |
141 | | /// potentially un-aligned values to an output stream |
142 | | pub trait BitWrite { |
143 | | /// Writes a single bit to the stream. |
144 | | /// `true` indicates 1, `false` indicates 0 |
145 | | /// |
146 | | /// # Errors |
147 | | /// |
148 | | /// Passes along any I/O error from the underlying stream. |
149 | | /// |
150 | | /// # Examples |
151 | | /// ``` |
152 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
153 | | /// |
154 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
155 | | /// assert!(w.write_bit(true).is_ok()); |
156 | | /// assert!(w.write_bit(false).is_ok()); |
157 | | /// assert!(w.write_bit(false).is_ok()); |
158 | | /// assert!(w.write_bit(false).is_ok()); |
159 | | /// assert!(w.write_bit(true).is_ok()); |
160 | | /// assert!(w.write_bit(true).is_ok()); |
161 | | /// assert!(w.write_bit(true).is_ok()); |
162 | | /// assert!(w.write_bit(false).is_ok()); |
163 | | /// assert_eq!(w.into_writer(), &[0b1000_1110]); |
164 | | /// ``` |
165 | | /// |
166 | | /// ``` |
167 | | /// use bitstream_io::{BitWriter, BitWrite, LittleEndian}; |
168 | | /// |
169 | | /// let mut w = BitWriter::endian(vec![], LittleEndian); |
170 | | /// assert!(w.write_bit(false).is_ok()); |
171 | | /// assert!(w.write_bit(true).is_ok()); |
172 | | /// assert!(w.write_bit(true).is_ok()); |
173 | | /// assert!(w.write_bit(true).is_ok()); |
174 | | /// assert!(w.write_bit(false).is_ok()); |
175 | | /// assert!(w.write_bit(false).is_ok()); |
176 | | /// assert!(w.write_bit(false).is_ok()); |
177 | | /// assert!(w.write_bit(true).is_ok()); |
178 | | /// assert_eq!(w.into_writer(), &[0b1000_1110]); |
179 | | /// ``` |
180 | | #[inline] |
181 | 0 | fn write_bit(&mut self, bit: bool) -> io::Result<()> { |
182 | 0 | self.write_unsigned::<1, u8>(u8::from(bit)) |
183 | 0 | } |
184 | | |
185 | | /// Writes a signed or unsigned value to the stream using the given |
186 | | /// const number of bits. |
187 | | /// |
188 | | /// # Errors |
189 | | /// |
190 | | /// Passes along any I/O error from the underlying stream. |
191 | | /// Returns an error if the value is too large |
192 | | /// to fit the given number of bits. |
193 | | /// A compile-time error occurs if the given number of bits |
194 | | /// is larger than the output type. |
195 | | /// |
196 | | /// # Examples |
197 | | /// ``` |
198 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
199 | | /// |
200 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
201 | | /// // writing unsigned value is ok |
202 | | /// assert!(w.write::<4, u8>(1).is_ok()); |
203 | | /// // writing signed value is ok |
204 | | /// assert!(w.write::<4, i8>(-1).is_ok()); |
205 | | /// // writing an array of bits is ok too |
206 | | /// assert!(w.write::<1, [bool; 4]>([true, false, true, true]).is_ok()); |
207 | | /// // writing an array of any Integer type is ok |
208 | | /// assert!(w.write::<2, [u8; 2]>([0b11, 0b00]).is_ok()); |
209 | | /// // trying to write a value larger than 4 bits in 4 bits is an error |
210 | | /// assert!(w.write::<4, u8>(u8::MAX).is_err()); |
211 | | /// |
212 | | /// assert_eq!(w.into_writer(), &[0b0001_1111, 0b1011_11_00]); |
213 | | /// ``` |
214 | | /// |
215 | | /// ```rust,compile_fail |
216 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
217 | | /// |
218 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
219 | | /// // trying to write 9 bits from a u8 is a compile-time error |
220 | | /// w.write::<9, u8>(1); |
221 | | /// ``` |
222 | | #[inline] |
223 | 0 | fn write<const BITS: u32, I>(&mut self, value: I) -> io::Result<()> |
224 | 0 | where |
225 | 0 | I: Integer, |
226 | | { |
227 | 0 | Integer::write::<BITS, Self>(value, self) |
228 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<16, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<16, u16> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<1, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<1, u16> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<32, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<32, u64> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<2, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<2, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<3, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<3, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<4, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<4, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<5, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<6, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<7, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<8, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<9, u16> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write::<12, u16> Unexecuted instantiation: <_ as bitstream_io::write::BitWrite>::write::<_, _> |
229 | | |
230 | | /// Writes a signed or unsigned value to the stream using the given |
231 | | /// number of bits. |
232 | | /// |
233 | | /// # Errors |
234 | | /// |
235 | | /// Passes along any I/O error from the underlying stream. |
236 | | /// Returns an error if the input type is too small |
237 | | /// to hold the given number of bits. |
238 | | /// Returns an error if the value is too large |
239 | | /// to fit the given number of bits. |
240 | | /// |
241 | | /// # Examples |
242 | | /// ``` |
243 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
244 | | /// |
245 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
246 | | /// // writing unsigned value is ok |
247 | | /// assert!(w.write_var::<u8>(4, 1).is_ok()); |
248 | | /// // writing signed value is also ok |
249 | | /// assert!(w.write_var::<i8>(4, -1).is_ok()); |
250 | | /// assert_eq!(w.into_writer(), &[0b0001_1111]); |
251 | | /// ``` |
252 | | /// |
253 | | /// ``` |
254 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
255 | | /// |
256 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
257 | | /// // writing a value larger than 4 bits in 4 bits is a runtime error |
258 | | /// assert!(w.write_var::<u8>(4, u8::MAX).is_err()); |
259 | | /// // writing 9 bits from a u8 is also a runtime error |
260 | | /// assert!(w.write_var::<u8>(9, 0).is_err()); |
261 | | /// ``` |
262 | | #[inline] |
263 | 0 | fn write_var<I>(&mut self, bits: u32, value: I) -> io::Result<()> |
264 | 0 | where |
265 | 0 | I: Integer, |
266 | | { |
267 | 0 | self.write_counted(BitCount::unknown(bits), value) |
268 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::LittleEndian> as bitstream_io::write::BitWrite>::write_var::<u64> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_var::<u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_var::<i32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_var::<u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_var::<i16> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_var::<u16> Unexecuted instantiation: <_ as bitstream_io::write::BitWrite>::write_var::<_> |
269 | | |
270 | | /// Writes an unsigned value to the stream using the given |
271 | | /// const number of bits. |
272 | | /// |
273 | | /// # Errors |
274 | | /// |
275 | | /// Passes along any I/O error from the underlying stream. |
276 | | /// Returns an error if the value is too large |
277 | | /// to fit the given number of bits. |
278 | | /// A compile-time error occurs if the given number of bits |
279 | | /// is larger than the output type. |
280 | | /// |
281 | | /// # Examples |
282 | | /// ``` |
283 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
284 | | /// |
285 | | /// let mut writer = BitWriter::endian(vec![], BigEndian); |
286 | | /// writer.write_unsigned::<1, u8>(0b1).unwrap(); |
287 | | /// writer.write_unsigned::<2, u8>(0b01).unwrap(); |
288 | | /// writer.write_unsigned::<5, u8>(0b10111).unwrap(); |
289 | | /// assert_eq!(writer.into_writer(), [0b1_01_10111]); |
290 | | /// ``` |
291 | | /// |
292 | | /// ``` |
293 | | /// use bitstream_io::{LittleEndian, BitWriter, BitWrite}; |
294 | | /// |
295 | | /// let mut writer = BitWriter::endian(vec![], LittleEndian); |
296 | | /// writer.write_unsigned::<1, u8>(0b1).unwrap(); |
297 | | /// writer.write_unsigned::<2, u8>(0b11).unwrap(); |
298 | | /// writer.write_unsigned::<5, u8>(0b10110).unwrap(); |
299 | | /// assert_eq!(writer.into_writer(), [0b10110_11_1]); |
300 | | /// ``` |
301 | | /// |
302 | | /// ```rust,compile_fail |
303 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
304 | | /// |
305 | | /// let mut writer = BitWriter::endian(vec![], BigEndian); |
306 | | /// // trying to write 9 bits from a u8 is a compile-time error |
307 | | /// writer.write_unsigned::<9, u8>(1); |
308 | | /// ``` |
309 | | /// |
310 | | /// ``` |
311 | | /// use std::io::{Write, sink}; |
312 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
313 | | /// |
314 | | /// let mut w = BitWriter::endian(sink(), BigEndian); |
315 | | /// assert!(w.write_unsigned::<1, u8>(2).is_err()); // can't write 2 in 1 bit |
316 | | /// assert!(w.write_unsigned::<2, u8>(4).is_err()); // can't write 4 in 2 bits |
317 | | /// assert!(w.write_unsigned::<3, u8>(8).is_err()); // can't write 8 in 3 bits |
318 | | /// assert!(w.write_unsigned::<4, u8>(16).is_err()); // can't write 16 in 4 bits |
319 | | /// ``` |
320 | | #[inline] |
321 | 0 | fn write_unsigned<const BITS: u32, U>(&mut self, value: U) -> io::Result<()> |
322 | 0 | where |
323 | 0 | U: UnsignedInteger, |
324 | | { |
325 | 0 | self.write_unsigned_var(BITS, value) |
326 | 0 | } |
327 | | |
328 | | /// Writes an unsigned value to the stream using the given |
329 | | /// number of bits. |
330 | | /// |
331 | | /// # Errors |
332 | | /// |
333 | | /// Passes along any I/O error from the underlying stream. |
334 | | /// Returns an error if the input type is too small |
335 | | /// to hold the given number of bits. |
336 | | /// Returns an error if the value is too large |
337 | | /// to fit the given number of bits. |
338 | | /// |
339 | | /// # Examples |
340 | | /// ``` |
341 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
342 | | /// |
343 | | /// let mut writer = BitWriter::endian(vec![], BigEndian); |
344 | | /// writer.write_unsigned_var::<u8>(1, 0b1).unwrap(); |
345 | | /// writer.write_unsigned_var::<u8>(2, 0b01).unwrap(); |
346 | | /// writer.write_unsigned_var::<u8>(5, 0b10111).unwrap(); |
347 | | /// assert_eq!(writer.into_writer(), [0b1_01_10111]); |
348 | | /// ``` |
349 | | /// |
350 | | /// ``` |
351 | | /// use std::io::Write; |
352 | | /// use bitstream_io::{LittleEndian, BitWriter, BitWrite}; |
353 | | /// |
354 | | /// let mut writer = BitWriter::endian(vec![], LittleEndian); |
355 | | /// writer.write_unsigned_var::<u8>(1, 0b1).unwrap(); |
356 | | /// writer.write_unsigned_var::<u8>(2, 0b11).unwrap(); |
357 | | /// writer.write_unsigned_var::<u8>(5, 0b10110).unwrap(); |
358 | | /// assert_eq!(writer.into_writer(), [0b10110_11_1]); |
359 | | /// ``` |
360 | | /// |
361 | | /// ``` |
362 | | /// use std::io::{Write, sink}; |
363 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
364 | | /// |
365 | | /// let mut w = BitWriter::endian(sink(), BigEndian); |
366 | | /// assert!(w.write_unsigned_var::<u8>(9, 0).is_err()); // can't write u8 in 9 bits |
367 | | /// assert!(w.write_unsigned_var::<u16>(17, 0).is_err()); // can't write u16 in 17 bits |
368 | | /// assert!(w.write_unsigned_var::<u32>(33, 0).is_err()); // can't write u32 in 33 bits |
369 | | /// assert!(w.write_unsigned_var::<u64>(65, 0).is_err()); // can't write u64 in 65 bits |
370 | | /// assert!(w.write_unsigned_var::<u8>(1, 2).is_err()); // can't write 2 in 1 bit |
371 | | /// assert!(w.write_unsigned_var::<u8>(2, 4).is_err()); // can't write 4 in 2 bits |
372 | | /// assert!(w.write_unsigned_var::<u8>(3, 8).is_err()); // can't write 8 in 3 bits |
373 | | /// assert!(w.write_unsigned_var::<u8>(4, 16).is_err()); // can't write 16 in 4 bits |
374 | | /// ``` |
375 | 0 | fn write_unsigned_var<U>(&mut self, bits: u32, value: U) -> io::Result<()> |
376 | 0 | where |
377 | 0 | U: UnsignedInteger, |
378 | | { |
379 | 0 | self.write_unsigned_counted(BitCount::unknown(bits), value) |
380 | 0 | } |
381 | | |
382 | | /// Writes a twos-complement signed value to the stream |
383 | | /// with the given const number of bits. |
384 | | /// |
385 | | /// # Errors |
386 | | /// |
387 | | /// Passes along any I/O error from the underlying stream. |
388 | | /// Returns an error if the value is too large |
389 | | /// to fit the given number of bits. |
390 | | /// A compile-time error occurs if the number of bits is 0, |
391 | | /// since one bit is always needed for the sign. |
392 | | /// A compile-time error occurs if the given number of bits |
393 | | /// is larger than the output type. |
394 | | /// |
395 | | /// # Examples |
396 | | /// ``` |
397 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
398 | | /// |
399 | | /// let mut writer = BitWriter::endian(vec![], BigEndian); |
400 | | /// writer.write_signed::<4, i8>(-5).unwrap(); |
401 | | /// writer.write_signed::<4, i8>(7).unwrap(); |
402 | | /// assert_eq!(writer.into_writer(), [0b10110111]); |
403 | | /// ``` |
404 | | /// |
405 | | /// ``` |
406 | | /// use bitstream_io::{LittleEndian, BitWriter, BitWrite}; |
407 | | /// |
408 | | /// let mut writer = BitWriter::endian(vec![], LittleEndian); |
409 | | /// writer.write_signed::<4, i8>(7).unwrap(); |
410 | | /// writer.write_signed::<4, i8>(-5).unwrap(); |
411 | | /// assert_eq!(writer.into_writer(), [0b10110111]); |
412 | | /// ``` |
413 | | /// |
414 | | /// ``` |
415 | | /// use bitstream_io::{LittleEndian, BitWriter, BitWrite}; |
416 | | /// |
417 | | /// let mut writer = BitWriter::endian(vec![], LittleEndian); |
418 | | /// // writing a value too large for 4 bits in 4 bits is a runtime error |
419 | | /// assert!(writer.write_signed::<4, i8>(i8::MAX).is_err()); |
420 | | /// ``` |
421 | | /// |
422 | | /// ```rust,compile_fail |
423 | | /// use bitstream_io::{LittleEndian, BitWriter, BitWrite}; |
424 | | /// |
425 | | /// let mut writer = BitWriter::endian(vec![], LittleEndian); |
426 | | /// // writing 9 bits from an i8 is a compile-time error |
427 | | /// assert!(writer.write_signed::<9, i8>(1).is_err()); |
428 | | /// ``` |
429 | 0 | fn write_signed<const BITS: u32, S>(&mut self, value: S) -> io::Result<()> |
430 | 0 | where |
431 | 0 | S: SignedInteger, |
432 | | { |
433 | 0 | self.write_signed_var(BITS, value) |
434 | 0 | } |
435 | | |
436 | | /// Writes a twos-complement signed value to the stream |
437 | | /// with the given number of bits. |
438 | | /// |
439 | | /// # Errors |
440 | | /// |
441 | | /// Passes along any I/O error from the underlying stream. |
442 | | /// Returns an error if the input type is too small |
443 | | /// to hold the given number of bits. |
444 | | /// Returns an error if the number of bits is 0, |
445 | | /// since one bit is always needed for the sign. |
446 | | /// Returns an error if the value is too large |
447 | | /// to fit the given number of bits. |
448 | | /// |
449 | | /// # Examples |
450 | | /// ``` |
451 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
452 | | /// |
453 | | /// let mut writer = BitWriter::endian(vec![], BigEndian); |
454 | | /// writer.write_signed_var(4, -5).unwrap(); |
455 | | /// writer.write_signed_var(4, 7).unwrap(); |
456 | | /// assert_eq!(writer.into_writer(), [0b10110111]); |
457 | | /// ``` |
458 | | /// |
459 | | /// ``` |
460 | | /// use bitstream_io::{LittleEndian, BitWriter, BitWrite}; |
461 | | /// |
462 | | /// let mut writer = BitWriter::endian(vec![], LittleEndian); |
463 | | /// writer.write_signed_var(4, 7).unwrap(); |
464 | | /// writer.write_signed_var(4, -5).unwrap(); |
465 | | /// assert_eq!(writer.into_writer(), [0b10110111]); |
466 | | /// ``` |
467 | | #[inline(always)] |
468 | 0 | fn write_signed_var<S>(&mut self, bits: u32, value: S) -> io::Result<()> |
469 | 0 | where |
470 | 0 | S: SignedInteger, |
471 | | { |
472 | 0 | self.write_signed_counted(BitCount::unknown(bits), value) |
473 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_signed_var::<i16> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_signed_var::<i16> Unexecuted instantiation: <_ as bitstream_io::write::BitWrite>::write_signed_var::<_> |
474 | | |
475 | | /// Writes the given bit count to the stream |
476 | | /// with the necessary maximum number of bits. |
477 | | /// |
478 | | /// For example, if the maximum bit count is 15 - or `0b1111` - |
479 | | /// writes the bit count to the stream as a 4-bit unsigned value |
480 | | /// which can be used in subsequent writes. |
481 | | /// |
482 | | /// Note that `MAX` must be greater than 0. |
483 | | /// Unlike the bit reader, the bit count need not be an exact |
484 | | /// power of two when writing. Any bits higher than the |
485 | | /// bit count can reach are simply left 0. |
486 | | /// |
487 | | /// # Errors |
488 | | /// |
489 | | /// Passes along an I/O error from the underlying stream. |
490 | | /// |
491 | | /// ``` |
492 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
493 | | /// |
494 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
495 | | /// let count = 4; |
496 | | /// w.write::<3, u32>(count).unwrap(); |
497 | | /// // may need to verify count is not larger than u8 at runtime |
498 | | /// w.write_var::<u8>(count, 0b1111).unwrap(); |
499 | | /// w.byte_align().unwrap(); |
500 | | /// assert_eq!(w.into_writer(), &[0b100_11110]); |
501 | | /// ``` |
502 | | /// |
503 | | /// ``` |
504 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite, BitCount}; |
505 | | /// |
506 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
507 | | /// // a bit count of 4, with a maximum of 7 (0b111) |
508 | | /// let count: BitCount<0b111> = BitCount::new::<4>(); |
509 | | /// w.write_count(count).unwrap(); |
510 | | /// // maximum size of count is known to be 7 bits at compile-time |
511 | | /// // so no need to check that 7 bits is larger than a u8 at runtime |
512 | | /// w.write_counted::<0b111, u8>(count, 0b1111).unwrap(); |
513 | | /// w.byte_align().unwrap(); |
514 | | /// assert_eq!(w.into_writer(), &[0b100_11110]); |
515 | | /// ``` |
516 | | /// |
517 | | /// ``` |
518 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite, BitCount}; |
519 | | /// |
520 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
521 | | /// // a bit count of 4, with a maximum of 6 (0b110) |
522 | | /// let count: BitCount<0b110> = BitCount::new::<4>(); |
523 | | /// w.write_count(count).unwrap(); |
524 | | /// w.write_counted::<0b110, u8>(count, 0b1111).unwrap(); |
525 | | /// w.byte_align().unwrap(); |
526 | | /// // bit count is written in 3 bits |
527 | | /// // while actual value is written in 4 bits |
528 | | /// assert_eq!(w.into_writer(), &[0b100_11110]); |
529 | | /// ``` |
530 | 0 | fn write_count<const MAX: u32>(&mut self, BitCount { bits }: BitCount<MAX>) -> io::Result<()> { |
531 | | const { |
532 | | assert!(MAX > 0, "MAX value must be > 0"); |
533 | | } |
534 | | |
535 | 0 | self.write_unsigned_var( |
536 | 0 | if MAX == u32::MAX { |
537 | 0 | 32 |
538 | 0 | } else if (MAX + 1).is_power_of_two() { |
539 | 0 | (MAX + 1).ilog2() |
540 | | } else { |
541 | 0 | (MAX + 1).ilog2() + 1 |
542 | | }, |
543 | 0 | bits, |
544 | | ) |
545 | 0 | } |
546 | | |
547 | | /// Writes a signed or unsigned value to the stream with |
548 | | /// the given number of bits. |
549 | | /// |
550 | | /// # Errors |
551 | | /// |
552 | | /// Passes along any I/O error from the underlying stream. |
553 | | /// Returns an error if the value is too large |
554 | | /// to fit the given number of bits. |
555 | | /// |
556 | | /// # Examples |
557 | | /// ``` |
558 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian, BitCount}; |
559 | | /// |
560 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
561 | | /// // writing 4 bits with a maximum of 8 will fit into a u8 |
562 | | /// // so we only need check the value fits into 4 bits |
563 | | /// assert!(w.write_counted::<4, u8>(BitCount::new::<4>(), 0b1111).is_ok()); |
564 | | /// assert!(w.write_counted::<4, u8>(BitCount::new::<4>(), 0b1111 + 1).is_err()); |
565 | | /// // writing 4 bits with a maximum of 64 might not fit into a u8 |
566 | | /// // so need to verify this at runtime |
567 | | /// assert!(w.write_counted::<64, u8>(BitCount::new::<4>(), 0b0000).is_ok()); |
568 | | /// assert_eq!(w.into_writer(), &[0b1111_0000]); |
569 | | /// ``` |
570 | 0 | fn write_counted<const MAX: u32, I>(&mut self, bits: BitCount<MAX>, value: I) -> io::Result<()> |
571 | 0 | where |
572 | 0 | I: Integer + Sized, |
573 | | { |
574 | 0 | I::write_var::<MAX, _>(value, self, bits) |
575 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::LittleEndian> as bitstream_io::write::BitWrite>::write_counted::<4294967295, u64> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_counted::<4294967295, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_counted::<4294967295, i32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_counted::<4294967295, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_counted::<4294967295, i16> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_counted::<4294967295, u16> Unexecuted instantiation: <_ as bitstream_io::write::BitWrite>::write_counted::<_, _> |
576 | | |
577 | | /// Writes a signed value to the stream with |
578 | | /// the given number of bits. |
579 | | /// |
580 | | /// # Errors |
581 | | /// |
582 | | /// Passes along any I/O error from the underlying stream. |
583 | | /// Returns an error if the value is too large |
584 | | /// to fit the given number of bits. |
585 | | /// |
586 | | /// # Examples |
587 | | /// ``` |
588 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian, BitCount}; |
589 | | /// |
590 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
591 | | /// // writing 4 bits with a maximum of 8 will fit into a u8 |
592 | | /// // so we only need check the value fits into 4 bits |
593 | | /// assert!(w.write_unsigned_counted::<4, u8>(BitCount::new::<4>(), 0b1111).is_ok()); |
594 | | /// assert!(w.write_unsigned_counted::<4, u8>(BitCount::new::<4>(), 0b1111 + 1).is_err()); |
595 | | /// // writing 4 bits with a maximum of 64 might not fit into a u8 |
596 | | /// // so need to verify this at runtime |
597 | | /// assert!(w.write_unsigned_counted::<64, u8>(BitCount::new::<4>(), 0b0000).is_ok()); |
598 | | /// assert_eq!(w.into_writer(), &[0b1111_0000]); |
599 | | /// ``` |
600 | | fn write_unsigned_counted<const BITS: u32, U>( |
601 | | &mut self, |
602 | | bits: BitCount<BITS>, |
603 | | value: U, |
604 | | ) -> io::Result<()> |
605 | | where |
606 | | U: UnsignedInteger; |
607 | | |
608 | | /// Writes an unsigned value to the stream with |
609 | | /// the given number of bits. |
610 | | /// |
611 | | /// # Errors |
612 | | /// |
613 | | /// Passes along any I/O error from the underlying stream. |
614 | | /// Returns an error if the value is too large |
615 | | /// to fit the given number of bits. |
616 | | /// |
617 | | /// # Examples |
618 | | /// ``` |
619 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian, BitCount}; |
620 | | /// |
621 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
622 | | /// // writing 4 bits with a maximum of 8 will fit into an i8 |
623 | | /// // so we only need check the value fits into 4 bits |
624 | | /// assert!(w.write_signed_counted::<4, i8>(BitCount::new::<4>(), 0b0111).is_ok()); |
625 | | /// assert!(w.write_signed_counted::<4, i8>(BitCount::new::<4>(), 0b0111 + 1).is_err()); |
626 | | /// // writing 4 bits with a maximum of 64 might not fit into a i8 |
627 | | /// // so need to verify this at runtime |
628 | | /// assert!(w.write_signed_counted::<64, i8>(BitCount::new::<4>(), 0b0000).is_ok()); |
629 | | /// assert_eq!(w.into_writer(), &[0b0111_0000]); |
630 | | /// ``` |
631 | | fn write_signed_counted<const MAX: u32, S>( |
632 | | &mut self, |
633 | | bits: impl TryInto<SignedBitCount<MAX>>, |
634 | | value: S, |
635 | | ) -> io::Result<()> |
636 | | where |
637 | | S: SignedInteger; |
638 | | |
639 | | /// Writes the given constant value to the stream with |
640 | | /// the given number of bits. |
641 | | /// |
642 | | /// Due to current limitations of constant parameters, |
643 | | /// this is limited to `u32` values. |
644 | | /// |
645 | | /// # Errors |
646 | | /// |
647 | | /// Passes along any I/O error from the underlying stream. |
648 | | /// A compile-time error occurs if the number of bits is larger |
649 | | /// than 32 or if the value is too large too fit the |
650 | | /// requested number of bits. |
651 | | /// |
652 | | /// # Examples |
653 | | /// |
654 | | /// ``` |
655 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
656 | | /// |
657 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
658 | | /// assert!(w.write_const::<4, 0b1000>().is_ok()); |
659 | | /// assert!(w.write_const::<4, 0b1011>().is_ok()); |
660 | | /// assert_eq!(w.into_writer(), &[0b1000_1011]); |
661 | | /// ``` |
662 | | /// |
663 | | /// ```rust,compile_fail |
664 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
665 | | /// |
666 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
667 | | /// // trying to write a 5 bit value in 4 bits is a compile-time error |
668 | | /// w.write_const::<4, 0b11111>(); |
669 | | /// ``` |
670 | | /// |
671 | | /// ```rust,compile_fail |
672 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
673 | | /// |
674 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
675 | | /// // trying to write a 33 bit value is also a compile-time error |
676 | | /// w.write_const::<33, 1>(); |
677 | | /// ``` |
678 | | #[inline] |
679 | 0 | fn write_const<const BITS: u32, const VALUE: u32>(&mut self) -> io::Result<()> { |
680 | | const { |
681 | | assert!( |
682 | | BITS == 0 || VALUE <= (u32::ALL >> (u32::BITS_SIZE - BITS)), |
683 | | "excessive value for bits written" |
684 | | ); |
685 | | } |
686 | | |
687 | 0 | self.write::<BITS, u32>(VALUE) |
688 | 0 | } |
689 | | |
690 | | /// Writes whole value to the stream whose size in bits |
691 | | /// is equal to its type's size. |
692 | | /// |
693 | | /// # Errors |
694 | | /// |
695 | | /// Passes along any I/O error from the underlying stream. |
696 | | /// |
697 | | /// # Examples |
698 | | /// ``` |
699 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
700 | | /// |
701 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
702 | | /// assert!(w.write_from::<u32>(0x12_34_56_78).is_ok()); |
703 | | /// assert_eq!(w.into_writer(), &[0x12, 0x34, 0x56, 0x78]); |
704 | | /// ``` |
705 | | /// |
706 | | /// ``` |
707 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
708 | | /// |
709 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
710 | | /// assert!(w.write_from::<[u8; 4]>([0x12, 0x34, 0x56, 0x78]).is_ok()); |
711 | | /// assert_eq!(w.into_writer(), &[0x12, 0x34, 0x56, 0x78]); |
712 | | /// ``` |
713 | | fn write_from<V>(&mut self, value: V) -> io::Result<()> |
714 | | where |
715 | | V: Primitive; |
716 | | |
717 | | /// Writes whole value to the stream whose size in bits |
718 | | /// is equal to its type's size in an endianness that may |
719 | | /// be different from the stream's endianness. |
720 | | /// |
721 | | /// # Errors |
722 | | /// |
723 | | /// Passes along any I/O error from the underlying stream. |
724 | | /// |
725 | | /// # Examples |
726 | | /// ``` |
727 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian, LittleEndian}; |
728 | | /// |
729 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
730 | | /// assert!(w.write_as_from::<LittleEndian, u32>(0x12_34_56_78).is_ok()); |
731 | | /// assert_eq!(w.into_writer(), &[0x78, 0x56, 0x34, 0x12]); |
732 | | /// ``` |
733 | | fn write_as_from<F, V>(&mut self, value: V) -> io::Result<()> |
734 | | where |
735 | | F: Endianness, |
736 | | V: Primitive; |
737 | | |
738 | | /// Pads the stream by writing 0 over the given number of bits. |
739 | | /// |
740 | | /// # Errors |
741 | | /// |
742 | | /// Passes along any I/O error from the underlying stream. |
743 | | /// |
744 | | /// # Example |
745 | | /// |
746 | | /// ``` |
747 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
748 | | /// |
749 | | /// let mut w = BitWriter::endian(vec![], BigEndian); |
750 | | /// assert!(w.write_bit(true).is_ok()); |
751 | | /// assert!(w.pad(7).is_ok()); |
752 | | /// assert_eq!(w.into_writer(), &[0b1_0000000]); |
753 | | /// ``` |
754 | 0 | fn pad(&mut self, mut bits: u32) -> io::Result<()> { |
755 | | loop { |
756 | 0 | match bits { |
757 | 0 | 0 => break Ok(()), |
758 | 0 | bits @ 1..64 => break self.write_var(bits, 0u64), |
759 | | _ => { |
760 | 0 | self.write::<64, u64>(0)?; |
761 | 0 | bits -= 64; |
762 | | } |
763 | | } |
764 | | } |
765 | 0 | } |
766 | | |
767 | | /// Writes the entirety of a byte buffer to the stream. |
768 | | /// |
769 | | /// # Errors |
770 | | /// |
771 | | /// Passes along any I/O error from the underlying stream. |
772 | | /// |
773 | | /// # Example |
774 | | /// |
775 | | /// ``` |
776 | | /// use std::io::Write; |
777 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
778 | | /// let mut writer = BitWriter::endian(Vec::new(), BigEndian); |
779 | | /// writer.write_var(8, 0x66u8).unwrap(); |
780 | | /// writer.write_var(8, 0x6Fu8).unwrap(); |
781 | | /// writer.write_var(8, 0x6Fu8).unwrap(); |
782 | | /// writer.write_bytes(b"bar").unwrap(); |
783 | | /// assert_eq!(writer.into_writer(), b"foobar"); |
784 | | /// ``` |
785 | | #[inline] |
786 | 0 | fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> { |
787 | 0 | buf.iter().try_for_each(|b| self.write_unsigned::<8, _>(*b)) |
788 | 0 | } |
789 | | |
790 | | /// Writes `value` number of non `STOP_BIT` bits to the stream |
791 | | /// and then writes a `STOP_BIT`. This field is variably-sized. |
792 | | /// `STOP_BIT` must be 0 or 1. |
793 | | /// |
794 | | /// # Errors |
795 | | /// |
796 | | /// Passes along any I/O error from the underyling stream. |
797 | | /// |
798 | | /// # Examples |
799 | | /// ``` |
800 | | /// use std::io::Write; |
801 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
802 | | /// let mut writer = BitWriter::endian(Vec::new(), BigEndian); |
803 | | /// writer.write_unary::<0>(0).unwrap(); |
804 | | /// writer.write_unary::<0>(3).unwrap(); |
805 | | /// writer.write_unary::<0>(10).unwrap(); |
806 | | /// assert_eq!(writer.into_writer(), [0b01110111, 0b11111110]); |
807 | | /// ``` |
808 | | /// |
809 | | /// ``` |
810 | | /// use std::io::Write; |
811 | | /// use bitstream_io::{LittleEndian, BitWriter, BitWrite}; |
812 | | /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian); |
813 | | /// writer.write_unary::<0>(0).unwrap(); |
814 | | /// writer.write_unary::<0>(3).unwrap(); |
815 | | /// writer.write_unary::<0>(10).unwrap(); |
816 | | /// assert_eq!(writer.into_writer(), [0b11101110, 0b01111111]); |
817 | | /// ``` |
818 | | /// |
819 | | /// ``` |
820 | | /// use std::io::Write; |
821 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
822 | | /// let mut writer = BitWriter::endian(Vec::new(), BigEndian); |
823 | | /// writer.write_unary::<1>(0).unwrap(); |
824 | | /// writer.write_unary::<1>(3).unwrap(); |
825 | | /// writer.write_unary::<1>(10).unwrap(); |
826 | | /// assert_eq!(writer.into_writer(), [0b10001000, 0b00000001]); |
827 | | /// ``` |
828 | | /// |
829 | | /// ``` |
830 | | /// use std::io::Write; |
831 | | /// use bitstream_io::{LittleEndian, BitWriter, BitWrite}; |
832 | | /// let mut writer = BitWriter::endian(Vec::new(), LittleEndian); |
833 | | /// writer.write_unary::<1>(0).unwrap(); |
834 | | /// writer.write_unary::<1>(3).unwrap(); |
835 | | /// writer.write_unary::<1>(10).unwrap(); |
836 | | /// assert_eq!(writer.into_writer(), [0b00010001, 0b10000000]); |
837 | | /// ``` |
838 | 0 | fn write_unary<const STOP_BIT: u8>(&mut self, mut value: u32) -> io::Result<()> { |
839 | | const { |
840 | | assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1"); |
841 | | } |
842 | | |
843 | | const MAX: BitCount<32> = BitCount::new::<32>(); |
844 | | |
845 | 0 | match STOP_BIT { |
846 | | 0 => { |
847 | 0 | while value > 0 { |
848 | 0 | let to_write = MAX.min(value); |
849 | 0 | self.write_checked(to_write.all::<u32>())?; |
850 | 0 | value -= u32::from(to_write); |
851 | | } |
852 | 0 | self.write_bit(false) |
853 | | } |
854 | | 1 => { |
855 | 0 | while value > 0 { |
856 | 0 | let to_write = MAX.min(value); |
857 | 0 | self.write_checked(to_write.none::<u32>())?; |
858 | 0 | value -= u32::from(to_write); |
859 | | } |
860 | 0 | self.write_bit(true) |
861 | | } |
862 | 0 | _ => unreachable!(), |
863 | | } |
864 | 0 | } |
865 | | |
866 | | /// Writes checked value that is known to fit a given number of bits |
867 | 0 | fn write_checked<C: Checkable>(&mut self, value: C) -> io::Result<()> { |
868 | | // a naive default implementation |
869 | 0 | value.write(self) |
870 | 0 | } |
871 | | |
872 | | /// Builds and writes complex type |
873 | 0 | fn build<T: ToBitStream>(&mut self, build: &T) -> Result<(), T::Error> { |
874 | 0 | build.to_writer(self) |
875 | 0 | } |
876 | | |
877 | | /// Builds and writes complex type with context |
878 | 0 | fn build_with<'a, T: ToBitStreamWith<'a>>( |
879 | 0 | &mut self, |
880 | 0 | build: &T, |
881 | 0 | context: &T::Context, |
882 | 0 | ) -> Result<(), T::Error> { |
883 | 0 | build.to_writer(self, context) |
884 | 0 | } |
885 | | |
886 | | /// Builds and writes complex type with owned context |
887 | 0 | fn build_using<T: ToBitStreamUsing>( |
888 | 0 | &mut self, |
889 | 0 | build: &T, |
890 | 0 | context: T::Context, |
891 | 0 | ) -> Result<(), T::Error> { |
892 | 0 | build.to_writer(self, context) |
893 | 0 | } |
894 | | |
895 | | /// Returns true if the stream is aligned at a whole byte. |
896 | | /// |
897 | | /// # Example |
898 | | /// ``` |
899 | | /// use std::io::{Write, sink}; |
900 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
901 | | /// let mut writer = BitWriter::endian(sink(), BigEndian); |
902 | | /// assert_eq!(writer.byte_aligned(), true); |
903 | | /// writer.write_var(1, 0u8).unwrap(); |
904 | | /// assert_eq!(writer.byte_aligned(), false); |
905 | | /// writer.write_var(7, 0u8).unwrap(); |
906 | | /// assert_eq!(writer.byte_aligned(), true); |
907 | | /// ``` |
908 | | fn byte_aligned(&self) -> bool; |
909 | | |
910 | | /// Pads the stream with 0 bits until it is aligned at a whole byte. |
911 | | /// Does nothing if the stream is already aligned. |
912 | | /// |
913 | | /// # Errors |
914 | | /// |
915 | | /// Passes along any I/O error from the underyling stream. |
916 | | /// |
917 | | /// # Example |
918 | | /// ``` |
919 | | /// use std::io::Write; |
920 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
921 | | /// let mut writer = BitWriter::endian(Vec::new(), BigEndian); |
922 | | /// writer.write_var(1, 0u8).unwrap(); |
923 | | /// writer.byte_align().unwrap(); |
924 | | /// writer.write_var(8, 0xFFu8).unwrap(); |
925 | | /// assert_eq!(writer.into_writer(), [0x00, 0xFF]); |
926 | | /// ``` |
927 | 0 | fn byte_align(&mut self) -> io::Result<()> { |
928 | 0 | while !BitWrite::byte_aligned(self) { |
929 | 0 | self.write_bit(false)?; |
930 | | } |
931 | 0 | Ok(()) |
932 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::byte_align Unexecuted instantiation: <_ as bitstream_io::write::BitWrite>::byte_align |
933 | | |
934 | | /// Given a symbol, writes its representation to the output stream as bits. |
935 | | /// Generates no output if the symbol isn't defined in the Huffman tree. |
936 | | /// |
937 | | /// # Errors |
938 | | /// |
939 | | /// Passes along any I/O error from the underlying stream. |
940 | | /// |
941 | | /// # Example |
942 | | /// ``` |
943 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
944 | | /// use bitstream_io::define_huffman_tree; |
945 | | /// |
946 | | /// define_huffman_tree!(TreeName : char = ['a', ['b', ['c', 'd']]]); |
947 | | /// // 'a' is 0 |
948 | | /// // 'b' is 1 -> 0 |
949 | | /// // 'c' is 1 -> 1 -> 0 |
950 | | /// // 'd' is 1 -> 1 -> 1 |
951 | | /// |
952 | | /// let mut writer = BitWriter::endian(vec![], BigEndian); |
953 | | /// writer.write_huffman::<TreeName>('b').unwrap(); |
954 | | /// writer.write_huffman::<TreeName>('c').unwrap(); |
955 | | /// writer.write_huffman::<TreeName>('d').unwrap(); |
956 | | /// assert_eq!(writer.into_writer(), [0b10_110_111]); |
957 | | /// ``` |
958 | 0 | fn write_huffman<T>(&mut self, value: T::Symbol) -> io::Result<()> |
959 | 0 | where |
960 | 0 | T: crate::huffman::ToBits, |
961 | | { |
962 | 0 | T::to_bits(value, |b| self.write_bit(b)) |
963 | 0 | } |
964 | | |
965 | | /// Writes a number using a variable using a variable width integer. |
966 | | /// This optimises the case when the number is small. |
967 | | /// |
968 | | /// Given a 4-bit VBR field, any 3-bit value (0 through 7) is encoded directly, with the high bit set to zero. |
969 | | /// Values larger than N-1 bits emit their bits in a series of N-1 bit chunks, where all but the last set the high bit. |
970 | | /// |
971 | | /// # Errors |
972 | | /// |
973 | | /// Passes along any I/O error from the underlying stream. |
974 | | /// |
975 | | /// # Example |
976 | | /// ``` |
977 | | /// use std::io::Write; |
978 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
979 | | /// let mut writer = BitWriter::endian(Vec::new(), BigEndian); |
980 | | /// writer.write_unsigned_vbr::<4,_>(7u32); |
981 | | /// writer.write_unsigned_vbr::<4,_>(100u32); |
982 | | /// assert_eq!(writer.into_writer(), [0b0111_1100, 0b1100_0001]); |
983 | | /// ``` |
984 | 0 | fn write_unsigned_vbr<const FIELD_SIZE: u32, U: UnsignedInteger>( |
985 | 0 | &mut self, |
986 | 0 | value: U, |
987 | 0 | ) -> io::Result<()> { |
988 | | const { assert!(FIELD_SIZE >= 2 && FIELD_SIZE < U::BITS_SIZE) }; |
989 | 0 | let payload_bits = FIELD_SIZE - 1; |
990 | 0 | let continuation_bit = U::ONE.shl(payload_bits); |
991 | 0 | let payload_mask = continuation_bit.sub(U::ONE); |
992 | 0 | let mut value = value; |
993 | | |
994 | | loop { |
995 | 0 | let payload = value & payload_mask; |
996 | 0 | value >>= payload_bits; |
997 | 0 | if value != U::ZERO { |
998 | 0 | self.write_unsigned::<FIELD_SIZE, U>(payload | continuation_bit)?; |
999 | | } else { |
1000 | 0 | self.write_unsigned::<FIELD_SIZE, U>(payload)?; |
1001 | 0 | break; |
1002 | | } |
1003 | | } |
1004 | 0 | Ok(()) |
1005 | 0 | } |
1006 | | |
1007 | | /// Writes a number using a variable using a variable width integer. |
1008 | | /// This optimises the case when the number is small. |
1009 | | /// |
1010 | | /// The integer is mapped to an unsigned value using zigzag encoding. |
1011 | | /// For an integer X: |
1012 | | /// - if X >= 0 -> 2X |
1013 | | /// - else -> -2X + 1 |
1014 | | /// |
1015 | | /// # Errors |
1016 | | /// |
1017 | | /// Passes along any I/O error from the underlying stream. |
1018 | | /// |
1019 | | /// # Example |
1020 | | /// ``` |
1021 | | /// use std::io::Write; |
1022 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
1023 | | /// let mut writer = BitWriter::endian(Vec::new(), BigEndian); |
1024 | | /// writer.write_signed_vbr::<4,_>(3); |
1025 | | /// writer.write_signed_vbr::<4,_>(-50); |
1026 | | /// assert_eq!(writer.into_writer(), [0b0110_1011, 0b1100_0001]); |
1027 | | /// ``` |
1028 | | #[inline] |
1029 | 0 | fn write_signed_vbr<const FIELD_SIZE: u32, I: SignedInteger>( |
1030 | 0 | &mut self, |
1031 | 0 | value: I, |
1032 | 0 | ) -> io::Result<()> { |
1033 | 0 | let zig_zag = value.shl(1).bitxor(value.shr(I::BITS_SIZE - 1)); |
1034 | 0 | self.write_unsigned_vbr::<FIELD_SIZE, _>(zig_zag.as_non_negative()) |
1035 | 0 | } |
1036 | | |
1037 | | /// Writes a signed or unsigned variable width integer to the stream |
1038 | | /// |
1039 | | /// # Errors |
1040 | | /// |
1041 | | /// Passes along any I/O error from the underlying stream. |
1042 | | /// |
1043 | | /// # Example |
1044 | | /// ``` |
1045 | | /// use std::io::Write; |
1046 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
1047 | | /// let mut writer = BitWriter::endian(Vec::new(), BigEndian); |
1048 | | /// writer.write_vbr::<4,_>(6u32); |
1049 | | /// writer.write_vbr::<4,_>(-50i32); |
1050 | | /// assert_eq!(writer.into_writer(), [0b0110_1011, 0b1100_0001]); |
1051 | | /// ``` |
1052 | | #[inline] |
1053 | 0 | fn write_vbr<const FIELD_SIZE: u32, I: VBRInteger>(&mut self, value: I) -> io::Result<()> { |
1054 | 0 | I::write_vbr::<FIELD_SIZE, _>(value, self) |
1055 | 0 | } |
1056 | | |
1057 | | /// Creates a "by reference" adaptor for this `BitWrite` |
1058 | | /// |
1059 | | /// The returned adapter also implements `BitWrite` |
1060 | | /// and will borrow the current reader. |
1061 | | /// |
1062 | | /// # Example |
1063 | | /// ``` |
1064 | | /// use bitstream_io::{BitWriter, BitWrite, BigEndian}; |
1065 | | /// |
1066 | | /// fn build<W: BitWrite>(w: W) { |
1067 | | /// // perform some building |
1068 | | /// } |
1069 | | /// |
1070 | | /// let mut writer = BitWriter::endian(vec![], BigEndian); |
1071 | | /// // performing building by reference |
1072 | | /// build(writer.by_ref()); |
1073 | | /// // original owned writer still available |
1074 | | /// writer.write::<8, u8>(0).unwrap(); |
1075 | | /// assert_eq!(writer.into_writer(), &[0]); |
1076 | | /// ``` |
1077 | | #[inline] |
1078 | 0 | fn by_ref(&mut self) -> &mut Self { |
1079 | 0 | self |
1080 | 0 | } |
1081 | | } |
1082 | | |
1083 | | impl<W: BitWrite + ?Sized> BitWrite for &mut W { |
1084 | | #[inline] |
1085 | 0 | fn write_bit(&mut self, bit: bool) -> io::Result<()> { |
1086 | 0 | (**self).write_bit(bit) |
1087 | 0 | } |
1088 | | |
1089 | | #[inline] |
1090 | 0 | fn write<const BITS: u32, I>(&mut self, value: I) -> io::Result<()> |
1091 | 0 | where |
1092 | 0 | I: Integer, |
1093 | | { |
1094 | 0 | (**self).write::<BITS, I>(value) |
1095 | 0 | } |
1096 | | |
1097 | | #[inline] |
1098 | 0 | fn write_const<const BITS: u32, const VALUE: u32>(&mut self) -> io::Result<()> { |
1099 | 0 | (**self).write_const::<BITS, VALUE>() |
1100 | 0 | } |
1101 | | |
1102 | | #[inline] |
1103 | 0 | fn write_var<I>(&mut self, bits: u32, value: I) -> io::Result<()> |
1104 | 0 | where |
1105 | 0 | I: Integer, |
1106 | | { |
1107 | 0 | (**self).write_var(bits, value) |
1108 | 0 | } |
1109 | | |
1110 | | #[inline] |
1111 | 0 | fn write_unsigned<const BITS: u32, U>(&mut self, value: U) -> io::Result<()> |
1112 | 0 | where |
1113 | 0 | U: UnsignedInteger, |
1114 | | { |
1115 | 0 | (**self).write_unsigned::<BITS, U>(value) |
1116 | 0 | } |
1117 | | |
1118 | | #[inline] |
1119 | 0 | fn write_unsigned_var<U>(&mut self, bits: u32, value: U) -> io::Result<()> |
1120 | 0 | where |
1121 | 0 | U: UnsignedInteger, |
1122 | | { |
1123 | 0 | (**self).write_unsigned_var(bits, value) |
1124 | 0 | } |
1125 | | |
1126 | | #[inline] |
1127 | 0 | fn write_signed<const BITS: u32, S>(&mut self, value: S) -> io::Result<()> |
1128 | 0 | where |
1129 | 0 | S: SignedInteger, |
1130 | | { |
1131 | 0 | (**self).write_signed::<BITS, S>(value) |
1132 | 0 | } |
1133 | | |
1134 | | #[inline(always)] |
1135 | 0 | fn write_signed_var<S>(&mut self, bits: u32, value: S) -> io::Result<()> |
1136 | 0 | where |
1137 | 0 | S: SignedInteger, |
1138 | | { |
1139 | 0 | (**self).write_signed_var(bits, value) |
1140 | 0 | } |
1141 | | |
1142 | | #[inline] |
1143 | 0 | fn write_count<const MAX: u32>(&mut self, count: BitCount<MAX>) -> io::Result<()> { |
1144 | 0 | (**self).write_count::<MAX>(count) |
1145 | 0 | } |
1146 | | |
1147 | | #[inline] |
1148 | 0 | fn write_counted<const MAX: u32, I>(&mut self, bits: BitCount<MAX>, value: I) -> io::Result<()> |
1149 | 0 | where |
1150 | 0 | I: Integer + Sized, |
1151 | | { |
1152 | 0 | (**self).write_counted::<MAX, I>(bits, value) |
1153 | 0 | } |
1154 | | |
1155 | | #[inline] |
1156 | 0 | fn write_unsigned_counted<const BITS: u32, U>( |
1157 | 0 | &mut self, |
1158 | 0 | bits: BitCount<BITS>, |
1159 | 0 | value: U, |
1160 | 0 | ) -> io::Result<()> |
1161 | 0 | where |
1162 | 0 | U: UnsignedInteger, |
1163 | | { |
1164 | 0 | (**self).write_unsigned_counted::<BITS, U>(bits, value) |
1165 | 0 | } |
1166 | | |
1167 | | #[inline] |
1168 | 0 | fn write_signed_counted<const MAX: u32, S>( |
1169 | 0 | &mut self, |
1170 | 0 | bits: impl TryInto<SignedBitCount<MAX>>, |
1171 | 0 | value: S, |
1172 | 0 | ) -> io::Result<()> |
1173 | 0 | where |
1174 | 0 | S: SignedInteger, |
1175 | | { |
1176 | 0 | (**self).write_signed_counted::<MAX, S>(bits, value) |
1177 | 0 | } |
1178 | | |
1179 | | #[inline] |
1180 | 0 | fn write_from<V>(&mut self, value: V) -> io::Result<()> |
1181 | 0 | where |
1182 | 0 | V: Primitive, |
1183 | | { |
1184 | 0 | (**self).write_from::<V>(value) |
1185 | 0 | } |
1186 | | |
1187 | | #[inline] |
1188 | 0 | fn write_as_from<F, V>(&mut self, value: V) -> io::Result<()> |
1189 | 0 | where |
1190 | 0 | F: Endianness, |
1191 | 0 | V: Primitive, |
1192 | | { |
1193 | 0 | (**self).write_as_from::<F, V>(value) |
1194 | 0 | } |
1195 | | |
1196 | | #[inline] |
1197 | 0 | fn pad(&mut self, bits: u32) -> io::Result<()> { |
1198 | 0 | (**self).pad(bits) |
1199 | 0 | } |
1200 | | |
1201 | | #[inline] |
1202 | 0 | fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> { |
1203 | 0 | (**self).write_bytes(buf) |
1204 | 0 | } |
1205 | | |
1206 | | #[inline] |
1207 | 0 | fn write_unary<const STOP_BIT: u8>(&mut self, value: u32) -> io::Result<()> { |
1208 | 0 | (**self).write_unary::<STOP_BIT>(value) |
1209 | 0 | } |
1210 | | |
1211 | | #[inline] |
1212 | 0 | fn write_checked<C: Checkable>(&mut self, value: C) -> io::Result<()> { |
1213 | 0 | (**self).write_checked(value) |
1214 | 0 | } |
1215 | | |
1216 | | #[inline] |
1217 | 0 | fn build<T: ToBitStream>(&mut self, build: &T) -> Result<(), T::Error> { |
1218 | 0 | (**self).build(build) |
1219 | 0 | } |
1220 | | |
1221 | | #[inline] |
1222 | 0 | fn build_with<'a, T: ToBitStreamWith<'a>>( |
1223 | 0 | &mut self, |
1224 | 0 | build: &T, |
1225 | 0 | context: &T::Context, |
1226 | 0 | ) -> Result<(), T::Error> { |
1227 | 0 | (**self).build_with(build, context) |
1228 | 0 | } |
1229 | | |
1230 | | #[inline] |
1231 | 0 | fn byte_aligned(&self) -> bool { |
1232 | 0 | (**self).byte_aligned() |
1233 | 0 | } |
1234 | | |
1235 | | #[inline] |
1236 | 0 | fn byte_align(&mut self) -> io::Result<()> { |
1237 | 0 | (**self).byte_align() |
1238 | 0 | } |
1239 | | |
1240 | | #[inline] |
1241 | 0 | fn write_huffman<T>(&mut self, value: T::Symbol) -> io::Result<()> |
1242 | 0 | where |
1243 | 0 | T: crate::huffman::ToBits, |
1244 | | { |
1245 | 0 | (**self).write_huffman::<T>(value) |
1246 | 0 | } |
1247 | | } |
1248 | | |
1249 | | /// A compatibility trait for older code implementing [`BitWrite`] |
1250 | | /// |
1251 | | /// This is a trait largely compatible with older code |
1252 | | /// from the 2.X.X version, |
1253 | | /// which one can use with a named import as needed. |
1254 | | /// |
1255 | | /// New code should prefer the regular [`BitWrite`] trait. |
1256 | | /// |
1257 | | /// # Example |
1258 | | /// ``` |
1259 | | /// use bitstream_io::BitWrite2 as BitWrite; |
1260 | | /// use bitstream_io::{BitWriter, BigEndian}; |
1261 | | /// let mut byte = vec![]; |
1262 | | /// let mut writer = BitWriter::endian(byte, BigEndian); |
1263 | | /// writer.write::<u8>(4, 0b1111).unwrap(); |
1264 | | /// writer.write_out::<4, u8>(0b0000).unwrap(); |
1265 | | /// assert_eq!(writer.into_writer(), [0b1111_0000]); |
1266 | | /// ``` |
1267 | | pub trait BitWrite2 { |
1268 | | /// Writes a single bit to the stream. |
1269 | | /// `true` indicates 1, `false` indicates 0 |
1270 | | /// |
1271 | | /// # Errors |
1272 | | /// |
1273 | | /// Passes along any I/O error from the underlying stream. |
1274 | 0 | fn write_bit(&mut self, bit: bool) -> io::Result<()> { |
1275 | 0 | self.write_unsigned_out::<1, u8>(u8::from(bit)) |
1276 | 0 | } |
1277 | | |
1278 | | /// Writes a signed or unsigned value to the stream using the given |
1279 | | /// number of bits. |
1280 | | /// |
1281 | | /// # Errors |
1282 | | /// |
1283 | | /// Passes along any I/O error from the underlying stream. |
1284 | | /// Returns an error if the input type is too small |
1285 | | /// to hold the given number of bits. |
1286 | | /// Returns an error if the value is too large |
1287 | | /// to fit the given number of bits. |
1288 | | fn write<I>(&mut self, bits: u32, value: I) -> io::Result<()> |
1289 | | where |
1290 | | I: Integer; |
1291 | | |
1292 | | /// Writes a signed or unsigned value to the stream using the given |
1293 | | /// const number of bits. |
1294 | | /// |
1295 | | /// # Errors |
1296 | | /// |
1297 | | /// Passes along any I/O error from the underlying stream. |
1298 | | /// Returns an error if the value is too large |
1299 | | /// to fit the given number of bits. |
1300 | | /// A compile-time error occurs if the given number of bits |
1301 | | /// is larger than the output type. |
1302 | | fn write_out<const BITS: u32, I>(&mut self, value: I) -> io::Result<()> |
1303 | | where |
1304 | | I: Integer; |
1305 | | |
1306 | | /// Writes an unsigned value to the stream using the given |
1307 | | /// number of bits. |
1308 | | /// |
1309 | | /// # Errors |
1310 | | /// |
1311 | | /// Passes along any I/O error from the underlying stream. |
1312 | | /// Returns an error if the input type is too small |
1313 | | /// to hold the given number of bits. |
1314 | | /// Returns an error if the value is too large |
1315 | | /// to fit the given number of bits. |
1316 | | fn write_unsigned<U>(&mut self, bits: u32, value: U) -> io::Result<()> |
1317 | | where |
1318 | | U: UnsignedInteger; |
1319 | | |
1320 | | /// Writes an unsigned value to the stream using the given |
1321 | | /// const number of bits. |
1322 | | /// |
1323 | | /// # Errors |
1324 | | /// |
1325 | | /// Passes along any I/O error from the underlying stream. |
1326 | | /// Returns an error if the value is too large |
1327 | | /// to fit the given number of bits. |
1328 | | /// A compile-time error occurs if the given number of bits |
1329 | | /// is larger than the output type. |
1330 | | #[inline] |
1331 | 0 | fn write_unsigned_out<const BITS: u32, U>(&mut self, value: U) -> io::Result<()> |
1332 | 0 | where |
1333 | 0 | U: UnsignedInteger, |
1334 | | { |
1335 | 0 | self.write_unsigned(BITS, value) |
1336 | 0 | } |
1337 | | |
1338 | | /// Writes a twos-complement signed value to the stream |
1339 | | /// with the given number of bits. |
1340 | | /// |
1341 | | /// # Errors |
1342 | | /// |
1343 | | /// Passes along any I/O error from the underlying stream. |
1344 | | /// Returns an error if the input type is too small |
1345 | | /// to hold the given number of bits. |
1346 | | /// Returns an error if the number of bits is 0, |
1347 | | /// since one bit is always needed for the sign. |
1348 | | /// Returns an error if the value is too large |
1349 | | /// to fit the given number of bits. |
1350 | | fn write_signed<S>(&mut self, bits: u32, value: S) -> io::Result<()> |
1351 | | where |
1352 | | S: SignedInteger; |
1353 | | |
1354 | | /// Writes a twos-complement signed value to the stream |
1355 | | /// with the given const number of bits. |
1356 | | /// |
1357 | | /// # Errors |
1358 | | /// |
1359 | | /// Passes along any I/O error from the underlying stream. |
1360 | | /// Returns an error if the value is too large |
1361 | | /// to fit the given number of bits. |
1362 | | /// A compile-time error occurs if the number of bits is 0, |
1363 | | /// since one bit is always needed for the sign. |
1364 | | /// A compile-time error occurs if the given number of bits |
1365 | | /// is larger than the output type. |
1366 | 0 | fn write_signed_out<const BITS: u32, S>(&mut self, value: S) -> io::Result<()> |
1367 | 0 | where |
1368 | 0 | S: SignedInteger, |
1369 | | { |
1370 | 0 | self.write_signed(BITS, value) |
1371 | 0 | } |
1372 | | |
1373 | | /// Writes whole value to the stream whose size in bits |
1374 | | /// is equal to its type's size. |
1375 | | /// |
1376 | | /// # Errors |
1377 | | /// |
1378 | | /// Passes along any I/O error from the underlying stream. |
1379 | | fn write_from<V>(&mut self, value: V) -> io::Result<()> |
1380 | | where |
1381 | | V: Primitive; |
1382 | | |
1383 | | /// Writes whole value to the stream whose size in bits |
1384 | | /// is equal to its type's size in an endianness that may |
1385 | | /// be different from the stream's endianness. |
1386 | | /// |
1387 | | /// # Errors |
1388 | | /// |
1389 | | /// Passes along any I/O error from the underlying stream. |
1390 | | fn write_as_from<F, V>(&mut self, value: V) -> io::Result<()> |
1391 | | where |
1392 | | F: Endianness, |
1393 | | V: Primitive; |
1394 | | |
1395 | | /// Pads the stream by writing 0 over the given number of bits. |
1396 | | /// |
1397 | | /// # Errors |
1398 | | /// |
1399 | | /// Passes along any I/O error from the underlying stream. |
1400 | 0 | fn pad(&mut self, mut bits: u32) -> io::Result<()> { |
1401 | | loop { |
1402 | 0 | match bits { |
1403 | 0 | 0 => break Ok(()), |
1404 | 0 | bits @ 1..64 => break self.write(bits, 0u64), |
1405 | | _ => { |
1406 | 0 | self.write_out::<64, u64>(0)?; |
1407 | 0 | bits -= 64; |
1408 | | } |
1409 | | } |
1410 | | } |
1411 | 0 | } |
1412 | | |
1413 | | /// Writes the entirety of a byte buffer to the stream. |
1414 | | /// |
1415 | | /// # Errors |
1416 | | /// |
1417 | | /// Passes along any I/O error from the underlying stream. |
1418 | | /// |
1419 | | /// # Example |
1420 | | /// |
1421 | | /// ``` |
1422 | | /// use std::io::Write; |
1423 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
1424 | | /// let mut writer = BitWriter::endian(Vec::new(), BigEndian); |
1425 | | /// writer.write_var(8, 0x66u8).unwrap(); |
1426 | | /// writer.write_var(8, 0x6Fu8).unwrap(); |
1427 | | /// writer.write_var(8, 0x6Fu8).unwrap(); |
1428 | | /// writer.write_bytes(b"bar").unwrap(); |
1429 | | /// assert_eq!(writer.into_writer(), b"foobar"); |
1430 | | /// ``` |
1431 | | #[inline] |
1432 | 0 | fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> { |
1433 | 0 | buf.iter() |
1434 | 0 | .try_for_each(|b| self.write_unsigned_out::<8, _>(*b)) |
1435 | 0 | } |
1436 | | |
1437 | | /// Writes `value` number of 1 bits to the stream |
1438 | | /// and then writes a 0 bit. This field is variably-sized. |
1439 | | /// |
1440 | | /// # Errors |
1441 | | /// |
1442 | | /// Passes along any I/O error from the underyling stream. |
1443 | | fn write_unary0(&mut self, value: u32) -> io::Result<()>; |
1444 | | |
1445 | | /// Writes `value` number of 0 bits to the stream |
1446 | | /// and then writes a 1 bit. This field is variably-sized. |
1447 | | /// |
1448 | | /// # Errors |
1449 | | /// |
1450 | | /// Passes along any I/O error from the underyling stream. |
1451 | | fn write_unary1(&mut self, value: u32) -> io::Result<()>; |
1452 | | |
1453 | | /// Builds and writes complex type |
1454 | 0 | fn build<T: ToBitStream>(&mut self, build: &T) -> Result<(), T::Error> |
1455 | 0 | where |
1456 | 0 | Self: BitWrite, |
1457 | | { |
1458 | 0 | build.to_writer(self) |
1459 | 0 | } |
1460 | | |
1461 | | /// Builds and writes complex type with context |
1462 | 0 | fn build_with<'a, T: ToBitStreamWith<'a>>( |
1463 | 0 | &mut self, |
1464 | 0 | build: &T, |
1465 | 0 | context: &T::Context, |
1466 | 0 | ) -> Result<(), T::Error> |
1467 | 0 | where |
1468 | 0 | Self: BitWrite, |
1469 | | { |
1470 | 0 | build.to_writer(self, context) |
1471 | 0 | } |
1472 | | |
1473 | | /// Returns true if the stream is aligned at a whole byte. |
1474 | | fn byte_aligned(&self) -> bool; |
1475 | | |
1476 | | /// Pads the stream with 0 bits until it is aligned at a whole byte. |
1477 | | /// Does nothing if the stream is already aligned. |
1478 | | /// |
1479 | | /// # Errors |
1480 | | /// |
1481 | | /// Passes along any I/O error from the underyling stream. |
1482 | | /// |
1483 | | /// # Example |
1484 | | /// ``` |
1485 | | /// use std::io::Write; |
1486 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite}; |
1487 | | /// let mut writer = BitWriter::endian(Vec::new(), BigEndian); |
1488 | | /// writer.write_var(1, 0u8).unwrap(); |
1489 | | /// writer.byte_align().unwrap(); |
1490 | | /// writer.write_var(8, 0xFFu8).unwrap(); |
1491 | | /// assert_eq!(writer.into_writer(), [0x00, 0xFF]); |
1492 | | /// ``` |
1493 | 0 | fn byte_align(&mut self) -> io::Result<()> { |
1494 | 0 | while !self.byte_aligned() { |
1495 | 0 | self.write_bit(false)?; |
1496 | | } |
1497 | 0 | Ok(()) |
1498 | 0 | } |
1499 | | |
1500 | | /// Given a symbol, writes its representation to the output stream as bits. |
1501 | | /// Generates no output if the symbol isn't defined in the Huffman tree. |
1502 | | /// |
1503 | | /// # Errors |
1504 | | /// |
1505 | | /// Passes along any I/O error from the underlying stream. |
1506 | | /// |
1507 | | /// # Example |
1508 | | /// ``` |
1509 | | /// use std::io::Write; |
1510 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite2}; |
1511 | | /// use bitstream_io::define_huffman_tree; |
1512 | | /// define_huffman_tree!(TreeName : char = ['a', ['b', ['c', 'd']]]); |
1513 | | /// let mut writer = BitWriter::endian(Vec::new(), BigEndian); |
1514 | | /// writer.write_huffman::<TreeName>('b').unwrap(); |
1515 | | /// writer.write_huffman::<TreeName>('c').unwrap(); |
1516 | | /// writer.write_huffman::<TreeName>('d').unwrap(); |
1517 | | /// assert_eq!(writer.into_writer(), [0b10_110_111]); |
1518 | | /// ``` |
1519 | 0 | fn write_huffman<T>(&mut self, value: T::Symbol) -> io::Result<()> |
1520 | 0 | where |
1521 | 0 | T: crate::huffman::ToBits, |
1522 | | { |
1523 | 0 | T::to_bits(value, |b| self.write_bit(b)) |
1524 | 0 | } |
1525 | | } |
1526 | | |
1527 | | impl<W: BitWrite> BitWrite2 for W { |
1528 | | #[inline] |
1529 | 0 | fn write_bit(&mut self, bit: bool) -> io::Result<()> { |
1530 | 0 | BitWrite::write_bit(self, bit) |
1531 | 0 | } |
1532 | | |
1533 | | #[inline] |
1534 | 0 | fn write<I>(&mut self, bits: u32, value: I) -> io::Result<()> |
1535 | 0 | where |
1536 | 0 | I: Integer, |
1537 | | { |
1538 | 0 | BitWrite::write_var(self, bits, value) |
1539 | 0 | } |
1540 | | |
1541 | | #[inline] |
1542 | 0 | fn write_out<const BITS: u32, I>(&mut self, value: I) -> io::Result<()> |
1543 | 0 | where |
1544 | 0 | I: Integer, |
1545 | | { |
1546 | 0 | BitWrite::write::<BITS, I>(self, value) |
1547 | 0 | } |
1548 | | |
1549 | | #[inline] |
1550 | 0 | fn write_unsigned<U>(&mut self, bits: u32, value: U) -> io::Result<()> |
1551 | 0 | where |
1552 | 0 | U: UnsignedInteger, |
1553 | | { |
1554 | 0 | BitWrite::write_unsigned_var::<U>(self, bits, value) |
1555 | 0 | } |
1556 | | |
1557 | | #[inline] |
1558 | 0 | fn write_unsigned_out<const BITS: u32, U>(&mut self, value: U) -> io::Result<()> |
1559 | 0 | where |
1560 | 0 | U: UnsignedInteger, |
1561 | | { |
1562 | 0 | BitWrite::write_unsigned::<BITS, U>(self, value) |
1563 | 0 | } |
1564 | | |
1565 | | #[inline] |
1566 | 0 | fn write_signed<S>(&mut self, bits: u32, value: S) -> io::Result<()> |
1567 | 0 | where |
1568 | 0 | S: SignedInteger, |
1569 | | { |
1570 | 0 | BitWrite::write_signed_var::<S>(self, bits, value) |
1571 | 0 | } |
1572 | | |
1573 | | #[inline] |
1574 | 0 | fn write_signed_out<const BITS: u32, S>(&mut self, value: S) -> io::Result<()> |
1575 | 0 | where |
1576 | 0 | S: SignedInteger, |
1577 | | { |
1578 | 0 | BitWrite::write_signed::<BITS, S>(self, value) |
1579 | 0 | } |
1580 | | |
1581 | | #[inline] |
1582 | 0 | fn write_from<V>(&mut self, value: V) -> io::Result<()> |
1583 | 0 | where |
1584 | 0 | V: Primitive, |
1585 | | { |
1586 | 0 | BitWrite::write_from(self, value) |
1587 | 0 | } |
1588 | | |
1589 | | #[inline] |
1590 | 0 | fn write_as_from<F, V>(&mut self, value: V) -> io::Result<()> |
1591 | 0 | where |
1592 | 0 | F: Endianness, |
1593 | 0 | V: Primitive, |
1594 | | { |
1595 | 0 | BitWrite::write_as_from::<F, V>(self, value) |
1596 | 0 | } |
1597 | | |
1598 | | #[inline] |
1599 | 0 | fn pad(&mut self, bits: u32) -> io::Result<()> { |
1600 | 0 | BitWrite::pad(self, bits) |
1601 | 0 | } |
1602 | | |
1603 | | #[inline] |
1604 | 0 | fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> { |
1605 | 0 | BitWrite::write_bytes(self, buf) |
1606 | 0 | } |
1607 | | |
1608 | | #[inline] |
1609 | 0 | fn write_unary0(&mut self, value: u32) -> io::Result<()> { |
1610 | 0 | BitWrite::write_unary::<0>(self, value) |
1611 | 0 | } |
1612 | | |
1613 | | #[inline] |
1614 | 0 | fn write_unary1(&mut self, value: u32) -> io::Result<()> { |
1615 | 0 | BitWrite::write_unary::<1>(self, value) |
1616 | 0 | } |
1617 | | |
1618 | | #[inline] |
1619 | 0 | fn byte_aligned(&self) -> bool { |
1620 | 0 | BitWrite::byte_aligned(self) |
1621 | 0 | } |
1622 | | |
1623 | | #[inline] |
1624 | 0 | fn byte_align(&mut self) -> io::Result<()> { |
1625 | 0 | BitWrite::byte_align(self) |
1626 | 0 | } |
1627 | | } |
1628 | | |
1629 | | impl<W: io::Write, E: Endianness> BitWrite for BitWriter<W, E> { |
1630 | 0 | fn write_bit(&mut self, bit: bool) -> io::Result<()> { |
1631 | 0 | match E::push_bit_flush(&mut self.value, &mut self.bits, bit) { |
1632 | 0 | None => Ok(()), |
1633 | 0 | Some(byte) => write_byte(&mut self.writer, byte), |
1634 | | } |
1635 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_bit Unexecuted instantiation: <bitstream_io::write::BitWriter<_, _> as bitstream_io::write::BitWrite>::write_bit |
1636 | | |
1637 | | #[inline(always)] |
1638 | 0 | fn write_unsigned<const BITS: u32, U>(&mut self, value: U) -> io::Result<()> |
1639 | 0 | where |
1640 | 0 | U: UnsignedInteger, |
1641 | | { |
1642 | | let Self { |
1643 | 0 | value: queue_value, |
1644 | 0 | bits: queue_bits, |
1645 | 0 | writer, |
1646 | | .. |
1647 | 0 | } = self; |
1648 | | |
1649 | 0 | E::write_bits_checked( |
1650 | 0 | writer, |
1651 | 0 | queue_value, |
1652 | 0 | queue_bits, |
1653 | 0 | CheckedUnsigned::<BITS, U>::new_fixed::<BITS>(value)?, |
1654 | | ) |
1655 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<16, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<16, u16> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<1, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<1, u16> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<32, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<32, u64> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<2, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<2, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<3, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<3, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<4, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<4, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<5, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<6, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<7, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<8, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<9, u16> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned::<12, u16> Unexecuted instantiation: <bitstream_io::write::BitWriter<_, _> as bitstream_io::write::BitWrite>::write_unsigned::<_, _> |
1656 | | |
1657 | 0 | fn write_unsigned_counted<const BITS: u32, U>( |
1658 | 0 | &mut self, |
1659 | 0 | count: BitCount<BITS>, |
1660 | 0 | value: U, |
1661 | 0 | ) -> io::Result<()> |
1662 | 0 | where |
1663 | 0 | U: UnsignedInteger, |
1664 | | { |
1665 | | let Self { |
1666 | 0 | value: queue_value, |
1667 | 0 | bits: queue_bits, |
1668 | 0 | writer, |
1669 | | .. |
1670 | 0 | } = self; |
1671 | | |
1672 | 0 | E::write_bits_checked( |
1673 | 0 | writer, |
1674 | 0 | queue_value, |
1675 | 0 | queue_bits, |
1676 | 0 | CheckedUnsigned::new(count, value)?, |
1677 | | ) |
1678 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::LittleEndian> as bitstream_io::write::BitWrite>::write_unsigned_counted::<4294967295, u64> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned_counted::<4294967295, u8> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned_counted::<4294967295, u32> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_unsigned_counted::<4294967295, u16> Unexecuted instantiation: <bitstream_io::write::BitWriter<_, _> as bitstream_io::write::BitWrite>::write_unsigned_counted::<_, _> |
1679 | | |
1680 | | #[inline(always)] |
1681 | 0 | fn write_signed_counted<const BITS: u32, S>( |
1682 | 0 | &mut self, |
1683 | 0 | bits: impl TryInto<SignedBitCount<BITS>>, |
1684 | 0 | value: S, |
1685 | 0 | ) -> io::Result<()> |
1686 | 0 | where |
1687 | 0 | S: SignedInteger, |
1688 | | { |
1689 | 0 | E::write_signed_bits_checked( |
1690 | 0 | &mut self.writer, |
1691 | 0 | &mut self.value, |
1692 | 0 | &mut self.bits, |
1693 | 0 | CheckedSigned::new( |
1694 | 0 | bits.try_into().map_err(|_| { |
1695 | 0 | io::Error::new( |
1696 | 0 | io::ErrorKind::InvalidInput, |
1697 | | "signed writes need at least 1 bit for sign", |
1698 | | ) |
1699 | 0 | })?, Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_signed_counted::<4294967295, i32, bitstream_io::BitCount<4294967295>>::{closure#0}Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_signed_counted::<4294967295, i16, bitstream_io::BitCount<4294967295>>::{closure#0}Unexecuted instantiation: <bitstream_io::write::BitWriter<_, _> as bitstream_io::write::BitWrite>::write_signed_counted::<_, _, _>::{closure#0} |
1700 | 0 | value, |
1701 | 0 | )?, |
1702 | | ) |
1703 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_signed_counted::<4294967295, i16, bitstream_io::BitCount<4294967295>> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_signed_counted::<4294967295, i32, bitstream_io::BitCount<4294967295>> Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_signed_counted::<4294967295, i16, bitstream_io::BitCount<4294967295>> Unexecuted instantiation: <bitstream_io::write::BitWriter<_, _> as bitstream_io::write::BitWrite>::write_signed_counted::<_, _, _> |
1704 | | |
1705 | | #[inline] |
1706 | 0 | fn write_signed<const BITS: u32, S>(&mut self, value: S) -> io::Result<()> |
1707 | 0 | where |
1708 | 0 | S: SignedInteger, |
1709 | | { |
1710 | 0 | E::write_signed_bits_checked( |
1711 | 0 | &mut self.writer, |
1712 | 0 | &mut self.value, |
1713 | 0 | &mut self.bits, |
1714 | 0 | CheckedSigned::<BITS, _>::new_fixed::<BITS>(value)?, |
1715 | | ) |
1716 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_signed::<7, i8> Unexecuted instantiation: <bitstream_io::write::BitWriter<_, _> as bitstream_io::write::BitWrite>::write_signed::<_, _> |
1717 | | |
1718 | | #[inline] |
1719 | 0 | fn write_from<V>(&mut self, value: V) -> io::Result<()> |
1720 | 0 | where |
1721 | 0 | V: Primitive, |
1722 | | { |
1723 | 0 | E::write_bytes::<8, _>( |
1724 | 0 | &mut self.writer, |
1725 | 0 | &mut self.value, |
1726 | 0 | self.bits, |
1727 | 0 | E::primitive_to_bytes(value).as_ref(), |
1728 | | ) |
1729 | 0 | } |
1730 | | |
1731 | | #[inline] |
1732 | 0 | fn write_as_from<F, V>(&mut self, value: V) -> io::Result<()> |
1733 | 0 | where |
1734 | 0 | F: Endianness, |
1735 | 0 | V: Primitive, |
1736 | | { |
1737 | 0 | F::write_bytes::<8, _>( |
1738 | 0 | &mut self.writer, |
1739 | 0 | &mut self.value, |
1740 | 0 | self.bits, |
1741 | 0 | F::primitive_to_bytes(value).as_ref(), |
1742 | | ) |
1743 | 0 | } |
1744 | | |
1745 | | #[inline] |
1746 | 0 | fn write_checked<C: Checkable>(&mut self, value: C) -> io::Result<()> { |
1747 | 0 | value.write_endian::<E, _>(&mut self.writer, &mut self.value, &mut self.bits) |
1748 | 0 | } |
1749 | | |
1750 | | #[inline] |
1751 | 0 | fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> { |
1752 | 0 | E::write_bytes::<1024, _>(&mut self.writer, &mut self.value, self.bits, buf) |
1753 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::write_bytes Unexecuted instantiation: <bitstream_io::write::BitWriter<_, _> as bitstream_io::write::BitWrite>::write_bytes |
1754 | | |
1755 | | #[inline(always)] |
1756 | 0 | fn byte_aligned(&self) -> bool { |
1757 | 0 | self.bits == 0 |
1758 | 0 | } Unexecuted instantiation: <bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian> as bitstream_io::write::BitWrite>::byte_aligned Unexecuted instantiation: <bitstream_io::write::BitWriter<_, _> as bitstream_io::write::BitWrite>::byte_aligned |
1759 | | } |
1760 | | |
1761 | | /// An error returned if performing math operations would overflow |
1762 | | #[derive(Copy, Clone, Debug)] |
1763 | | pub struct Overflowed; |
1764 | | |
1765 | | impl fmt::Display for Overflowed { |
1766 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1767 | 0 | "overflow occured in counter".fmt(f) |
1768 | 0 | } |
1769 | | } |
1770 | | |
1771 | | impl core::error::Error for Overflowed {} |
1772 | | |
1773 | | impl From<Overflowed> for io::Error { |
1774 | 0 | fn from(Overflowed: Overflowed) -> Self { |
1775 | 0 | io::Error::new( |
1776 | | #[cfg(feature = "std")] |
1777 | | { |
1778 | 0 | io::ErrorKind::StorageFull |
1779 | | }, |
1780 | | #[cfg(not(feature = "std"))] |
1781 | | { |
1782 | | io::ErrorKind::Other |
1783 | | }, |
1784 | | "bitstream accumulator overflow", |
1785 | | ) |
1786 | 0 | } |
1787 | | } |
1788 | | |
1789 | | /// A common trait for integer types for performing math operations |
1790 | | /// which may check for overflow. |
1791 | | pub trait Counter: Default + Sized + From<u8> + TryFrom<u32> + TryFrom<usize> { |
1792 | | /// add rhs to self, returning `Overflowed` if the result is too large |
1793 | | fn checked_add_assign(&mut self, rhs: Self) -> Result<(), Overflowed>; |
1794 | | |
1795 | | /// multiply self by rhs, returning `Overflowed` if the result is too large |
1796 | | fn checked_mul(self, rhs: Self) -> Result<Self, Overflowed>; |
1797 | | |
1798 | | /// returns `true` if the number if bits written is divisible by 8 |
1799 | | fn byte_aligned(&self) -> bool; |
1800 | | } |
1801 | | |
1802 | | macro_rules! define_counter { |
1803 | | ($t:ty) => { |
1804 | | impl Counter for $t { |
1805 | 0 | fn checked_add_assign(&mut self, rhs: Self) -> Result<(), Overflowed> { |
1806 | 0 | *self = <$t>::checked_add(*self, rhs).ok_or(Overflowed)?; |
1807 | 0 | Ok(()) |
1808 | 0 | } Unexecuted instantiation: <u8 as bitstream_io::write::Counter>::checked_add_assign Unexecuted instantiation: <u16 as bitstream_io::write::Counter>::checked_add_assign Unexecuted instantiation: <u32 as bitstream_io::write::Counter>::checked_add_assign Unexecuted instantiation: <u64 as bitstream_io::write::Counter>::checked_add_assign Unexecuted instantiation: <u128 as bitstream_io::write::Counter>::checked_add_assign |
1809 | | |
1810 | 0 | fn checked_mul(self, rhs: Self) -> Result<Self, Overflowed> { |
1811 | 0 | <$t>::checked_mul(self, rhs).ok_or(Overflowed) |
1812 | 0 | } Unexecuted instantiation: <u8 as bitstream_io::write::Counter>::checked_mul Unexecuted instantiation: <u16 as bitstream_io::write::Counter>::checked_mul Unexecuted instantiation: <u32 as bitstream_io::write::Counter>::checked_mul Unexecuted instantiation: <u64 as bitstream_io::write::Counter>::checked_mul Unexecuted instantiation: <u128 as bitstream_io::write::Counter>::checked_mul |
1813 | | |
1814 | 0 | fn byte_aligned(&self) -> bool { |
1815 | 0 | self % 8 == 0 |
1816 | 0 | } Unexecuted instantiation: <u8 as bitstream_io::write::Counter>::byte_aligned Unexecuted instantiation: <u16 as bitstream_io::write::Counter>::byte_aligned Unexecuted instantiation: <u32 as bitstream_io::write::Counter>::byte_aligned Unexecuted instantiation: <u64 as bitstream_io::write::Counter>::byte_aligned Unexecuted instantiation: <u128 as bitstream_io::write::Counter>::byte_aligned |
1817 | | } |
1818 | | }; |
1819 | | } |
1820 | | |
1821 | | define_counter!(u8); |
1822 | | define_counter!(u16); |
1823 | | define_counter!(u32); |
1824 | | define_counter!(u64); |
1825 | | define_counter!(u128); |
1826 | | |
1827 | | /// For counting the number of bits written but generating no output. |
1828 | | /// |
1829 | | /// # Example |
1830 | | /// ``` |
1831 | | /// use bitstream_io::{BigEndian, BitWrite, BitsWritten}; |
1832 | | /// let mut writer: BitsWritten<u32> = BitsWritten::new(); |
1833 | | /// writer.write_var(1, 0b1u8).unwrap(); |
1834 | | /// writer.write_var(2, 0b01u8).unwrap(); |
1835 | | /// writer.write_var(5, 0b10111u8).unwrap(); |
1836 | | /// assert_eq!(writer.written(), 8); |
1837 | | /// ``` |
1838 | | #[derive(Default)] |
1839 | | pub struct BitsWritten<N> { |
1840 | | bits: N, |
1841 | | } |
1842 | | |
1843 | | impl<N: Default> BitsWritten<N> { |
1844 | | /// Creates new empty BitsWritten value |
1845 | | #[inline] |
1846 | 0 | pub fn new() -> Self { |
1847 | 0 | Self { bits: N::default() } |
1848 | 0 | } |
1849 | | } |
1850 | | |
1851 | | impl<N: Copy> BitsWritten<N> { |
1852 | | /// Returns number of bits written |
1853 | | #[inline] |
1854 | 0 | pub fn written(&self) -> N { |
1855 | 0 | self.bits |
1856 | 0 | } |
1857 | | } |
1858 | | |
1859 | | impl<N> BitsWritten<N> { |
1860 | | /// Returns number of bits written |
1861 | | #[inline] |
1862 | 0 | pub fn into_written(self) -> N { |
1863 | 0 | self.bits |
1864 | 0 | } |
1865 | | } |
1866 | | |
1867 | | impl<N: Counter> BitWrite for BitsWritten<N> { |
1868 | | #[inline] |
1869 | 0 | fn write_bit(&mut self, _bit: bool) -> io::Result<()> { |
1870 | 0 | self.bits.checked_add_assign(1u8.into())?; |
1871 | 0 | Ok(()) |
1872 | 0 | } |
1873 | | |
1874 | | #[inline] |
1875 | 0 | fn write_const<const BITS: u32, const VALUE: u32>(&mut self) -> io::Result<()> { |
1876 | | const { |
1877 | | assert!( |
1878 | | BITS == 0 || VALUE <= (u32::ALL >> (u32::BITS_SIZE - BITS)), |
1879 | | "excessive value for bits written" |
1880 | | ); |
1881 | | } |
1882 | | |
1883 | 0 | self.bits |
1884 | 0 | .checked_add_assign(BITS.try_into().map_err(|_| Overflowed)?)?; |
1885 | 0 | Ok(()) |
1886 | 0 | } |
1887 | | |
1888 | | #[inline] |
1889 | 0 | fn write_unsigned<const BITS: u32, U>(&mut self, value: U) -> io::Result<()> |
1890 | 0 | where |
1891 | 0 | U: UnsignedInteger, |
1892 | | { |
1893 | | const { |
1894 | | assert!(BITS <= U::BITS_SIZE, "excessive bits for type written"); |
1895 | | } |
1896 | | |
1897 | 0 | if BITS == 0 { |
1898 | 0 | Ok(()) |
1899 | 0 | } else if value <= (U::ALL >> (U::BITS_SIZE - BITS)) { |
1900 | 0 | self.bits |
1901 | 0 | .checked_add_assign(BITS.try_into().map_err(|_| Overflowed)?)?; |
1902 | 0 | Ok(()) |
1903 | | } else { |
1904 | 0 | Err(io::Error::new( |
1905 | 0 | io::ErrorKind::InvalidInput, |
1906 | 0 | "excessive value for bits written", |
1907 | 0 | )) |
1908 | | } |
1909 | 0 | } |
1910 | | |
1911 | | #[inline] |
1912 | 0 | fn write_signed<const BITS: u32, S>(&mut self, value: S) -> io::Result<()> |
1913 | 0 | where |
1914 | 0 | S: SignedInteger, |
1915 | | { |
1916 | | let SignedBitCount { |
1917 | 0 | bits: BitCount { bits }, |
1918 | 0 | unsigned, |
1919 | | } = const { |
1920 | | assert!(BITS <= S::BITS_SIZE, "excessive bits for type written"); |
1921 | | let count = BitCount::<BITS>::new::<BITS>().signed_count(); |
1922 | | assert!( |
1923 | | count.is_some(), |
1924 | | "signed writes need at least 1 bit for sign" |
1925 | | ); |
1926 | | count.unwrap() |
1927 | | }; |
1928 | | |
1929 | | // doesn't matter which side the sign is on |
1930 | | // so long as it's added to the bit count |
1931 | 0 | self.bits.checked_add_assign(1u8.into())?; |
1932 | | |
1933 | 0 | self.write_unsigned_counted( |
1934 | 0 | unsigned, |
1935 | 0 | if value.is_negative() { |
1936 | 0 | value.as_negative(bits) |
1937 | | } else { |
1938 | 0 | value.as_non_negative() |
1939 | | }, |
1940 | | ) |
1941 | 0 | } |
1942 | | |
1943 | | #[inline] |
1944 | 0 | fn write_unsigned_counted<const MAX: u32, U>( |
1945 | 0 | &mut self, |
1946 | 0 | BitCount { bits }: BitCount<MAX>, |
1947 | 0 | value: U, |
1948 | 0 | ) -> io::Result<()> |
1949 | 0 | where |
1950 | 0 | U: UnsignedInteger, |
1951 | | { |
1952 | 0 | if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE { |
1953 | 0 | if bits == 0 { |
1954 | 0 | Ok(()) |
1955 | 0 | } else if value <= U::ALL >> (U::BITS_SIZE - bits) { |
1956 | 0 | self.bits |
1957 | 0 | .checked_add_assign(bits.try_into().map_err(|_| Overflowed)?)?; |
1958 | 0 | Ok(()) |
1959 | | } else { |
1960 | 0 | Err(io::Error::new( |
1961 | 0 | io::ErrorKind::InvalidInput, |
1962 | 0 | "excessive value for bits written", |
1963 | 0 | )) |
1964 | | } |
1965 | | } else { |
1966 | 0 | Err(io::Error::new( |
1967 | 0 | io::ErrorKind::InvalidInput, |
1968 | 0 | "excessive bits for type written", |
1969 | 0 | )) |
1970 | | } |
1971 | 0 | } |
1972 | | |
1973 | | #[inline] |
1974 | 0 | fn write_signed_counted<const MAX: u32, S>( |
1975 | 0 | &mut self, |
1976 | 0 | bits: impl TryInto<SignedBitCount<MAX>>, |
1977 | 0 | value: S, |
1978 | 0 | ) -> io::Result<()> |
1979 | 0 | where |
1980 | 0 | S: SignedInteger, |
1981 | | { |
1982 | | let SignedBitCount { |
1983 | 0 | bits: BitCount { bits }, |
1984 | 0 | unsigned, |
1985 | 0 | } = bits.try_into().map_err(|_| { |
1986 | 0 | io::Error::new( |
1987 | 0 | io::ErrorKind::InvalidInput, |
1988 | | "signed writes need at least 1 bit for sign", |
1989 | | ) |
1990 | 0 | })?; |
1991 | | |
1992 | 0 | if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE { |
1993 | | // doesn't matter which side the sign is on |
1994 | | // so long as it's added to the bit count |
1995 | 0 | self.bits.checked_add_assign(1u8.into())?; |
1996 | | |
1997 | 0 | self.write_unsigned_counted( |
1998 | 0 | unsigned, |
1999 | 0 | if value.is_negative() { |
2000 | 0 | value.as_negative(bits) |
2001 | | } else { |
2002 | 0 | value.as_non_negative() |
2003 | | }, |
2004 | | ) |
2005 | | } else { |
2006 | 0 | Err(io::Error::new( |
2007 | 0 | io::ErrorKind::InvalidInput, |
2008 | 0 | "excessive bits for type written", |
2009 | 0 | )) |
2010 | | } |
2011 | 0 | } |
2012 | | |
2013 | | #[inline] |
2014 | 0 | fn write_from<V>(&mut self, _: V) -> io::Result<()> |
2015 | 0 | where |
2016 | 0 | V: Primitive, |
2017 | | { |
2018 | 0 | self.bits.checked_add_assign( |
2019 | 0 | N::try_from(core::mem::size_of::<V>()) |
2020 | 0 | .map_err(|_| Overflowed)? |
2021 | 0 | .checked_mul(8u8.into())?, |
2022 | 0 | )?; |
2023 | 0 | Ok(()) |
2024 | 0 | } |
2025 | | |
2026 | | #[inline] |
2027 | 0 | fn write_as_from<F, V>(&mut self, _: V) -> io::Result<()> |
2028 | 0 | where |
2029 | 0 | F: Endianness, |
2030 | 0 | V: Primitive, |
2031 | | { |
2032 | 0 | self.bits.checked_add_assign( |
2033 | 0 | N::try_from(core::mem::size_of::<V>()) |
2034 | 0 | .map_err(|_| Overflowed)? |
2035 | 0 | .checked_mul(8u8.into())?, |
2036 | 0 | )?; |
2037 | 0 | Ok(()) |
2038 | 0 | } |
2039 | | |
2040 | | #[inline] |
2041 | 0 | fn pad(&mut self, bits: u32) -> io::Result<()> { |
2042 | 0 | self.bits |
2043 | 0 | .checked_add_assign(bits.try_into().map_err(|_| Overflowed)?)?; |
2044 | 0 | Ok(()) |
2045 | 0 | } |
2046 | | |
2047 | | #[inline] |
2048 | 0 | fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> { |
2049 | 0 | self.bits.checked_add_assign( |
2050 | 0 | N::try_from(buf.len()) |
2051 | 0 | .map_err(|_| Overflowed)? |
2052 | 0 | .checked_mul(8u8.into())?, |
2053 | 0 | )?; |
2054 | 0 | Ok(()) |
2055 | 0 | } |
2056 | | |
2057 | 0 | fn write_unary<const STOP_BIT: u8>(&mut self, value: u32) -> io::Result<()> { |
2058 | | const { |
2059 | | assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1"); |
2060 | | } |
2061 | | |
2062 | 0 | self.bits |
2063 | 0 | .checked_add_assign(value.try_into().map_err(|_| Overflowed)?)?; |
2064 | 0 | self.bits.checked_add_assign(1u8.into())?; |
2065 | 0 | Ok(()) |
2066 | 0 | } |
2067 | | |
2068 | 0 | fn write_checked<C: Checkable>(&mut self, value: C) -> io::Result<()> { |
2069 | 0 | Ok(self |
2070 | 0 | .bits |
2071 | 0 | .checked_add_assign(value.written_bits().try_into().map_err(|_| Overflowed)?)?) |
2072 | 0 | } |
2073 | | |
2074 | | #[inline] |
2075 | 0 | fn byte_aligned(&self) -> bool { |
2076 | 0 | self.bits.byte_aligned() |
2077 | 0 | } |
2078 | | } |
2079 | | |
2080 | | /// For counting the number of bits written but generating no output. |
2081 | | /// |
2082 | | /// # Example |
2083 | | /// ``` |
2084 | | /// use bitstream_io::{BigEndian, BitWrite, BitCounter}; |
2085 | | /// let mut writer: BitCounter<u32, BigEndian> = BitCounter::new(); |
2086 | | /// writer.write_var(1, 0b1u8).unwrap(); |
2087 | | /// writer.write_var(2, 0b01u8).unwrap(); |
2088 | | /// writer.write_var(5, 0b10111u8).unwrap(); |
2089 | | /// assert_eq!(writer.written(), 8); |
2090 | | /// ``` |
2091 | | #[derive(Default)] |
2092 | | #[deprecated(since = "4.0.0", note = "use of BitsWritten is preferred")] |
2093 | | pub struct BitCounter<N, E: Endianness> { |
2094 | | bits: BitsWritten<N>, |
2095 | | phantom: PhantomData<E>, |
2096 | | } |
2097 | | |
2098 | | #[allow(deprecated)] |
2099 | | impl<N: Default, E: Endianness> BitCounter<N, E> { |
2100 | | /// Creates new counter |
2101 | | #[inline] |
2102 | 0 | pub fn new() -> Self { |
2103 | 0 | BitCounter { |
2104 | 0 | bits: BitsWritten::new(), |
2105 | 0 | phantom: PhantomData, |
2106 | 0 | } |
2107 | 0 | } |
2108 | | } |
2109 | | |
2110 | | #[allow(deprecated)] |
2111 | | impl<N: Copy, E: Endianness> BitCounter<N, E> { |
2112 | | /// Returns number of bits written |
2113 | | #[inline] |
2114 | 0 | pub fn written(&self) -> N { |
2115 | 0 | self.bits.written() |
2116 | 0 | } |
2117 | | } |
2118 | | |
2119 | | #[allow(deprecated)] |
2120 | | impl<N, E: Endianness> BitCounter<N, E> { |
2121 | | /// Returns number of bits written |
2122 | | #[inline] |
2123 | 0 | pub fn into_written(self) -> N { |
2124 | 0 | self.bits.into_written() |
2125 | 0 | } |
2126 | | } |
2127 | | |
2128 | | #[allow(deprecated)] |
2129 | | impl<N, E> BitWrite for BitCounter<N, E> |
2130 | | where |
2131 | | E: Endianness, |
2132 | | N: Counter, |
2133 | | { |
2134 | | #[inline] |
2135 | 0 | fn write_bit(&mut self, bit: bool) -> io::Result<()> { |
2136 | 0 | BitWrite::write_bit(&mut self.bits, bit) |
2137 | 0 | } |
2138 | | |
2139 | | #[inline] |
2140 | 0 | fn write_const<const BITS: u32, const VALUE: u32>(&mut self) -> io::Result<()> { |
2141 | 0 | BitWrite::write_const::<BITS, VALUE>(&mut self.bits) |
2142 | 0 | } |
2143 | | |
2144 | | #[inline] |
2145 | 0 | fn write_unsigned<const BITS: u32, U>(&mut self, value: U) -> io::Result<()> |
2146 | 0 | where |
2147 | 0 | U: UnsignedInteger, |
2148 | | { |
2149 | 0 | BitWrite::write_unsigned::<BITS, U>(&mut self.bits, value) |
2150 | 0 | } |
2151 | | |
2152 | | #[inline] |
2153 | 0 | fn write_signed<const BITS: u32, S>(&mut self, value: S) -> io::Result<()> |
2154 | 0 | where |
2155 | 0 | S: SignedInteger, |
2156 | | { |
2157 | 0 | BitWrite::write_signed::<BITS, S>(&mut self.bits, value) |
2158 | 0 | } |
2159 | | |
2160 | | #[inline] |
2161 | 0 | fn write_unsigned_counted<const MAX: u32, U>( |
2162 | 0 | &mut self, |
2163 | 0 | count: BitCount<MAX>, |
2164 | 0 | value: U, |
2165 | 0 | ) -> io::Result<()> |
2166 | 0 | where |
2167 | 0 | U: UnsignedInteger, |
2168 | | { |
2169 | 0 | BitWrite::write_unsigned_counted::<MAX, U>(&mut self.bits, count, value) |
2170 | 0 | } |
2171 | | |
2172 | | #[inline] |
2173 | 0 | fn write_signed_counted<const MAX: u32, S>( |
2174 | 0 | &mut self, |
2175 | 0 | bits: impl TryInto<SignedBitCount<MAX>>, |
2176 | 0 | value: S, |
2177 | 0 | ) -> io::Result<()> |
2178 | 0 | where |
2179 | 0 | S: SignedInteger, |
2180 | | { |
2181 | 0 | BitWrite::write_signed_counted::<MAX, S>(&mut self.bits, bits, value) |
2182 | 0 | } |
2183 | | |
2184 | | #[inline] |
2185 | 0 | fn write_from<V>(&mut self, value: V) -> io::Result<()> |
2186 | 0 | where |
2187 | 0 | V: Primitive, |
2188 | | { |
2189 | 0 | BitWrite::write_from(&mut self.bits, value) |
2190 | 0 | } |
2191 | | |
2192 | | #[inline] |
2193 | 0 | fn write_as_from<F, V>(&mut self, value: V) -> io::Result<()> |
2194 | 0 | where |
2195 | 0 | F: Endianness, |
2196 | 0 | V: Primitive, |
2197 | | { |
2198 | 0 | BitWrite::write_as_from::<F, V>(&mut self.bits, value) |
2199 | 0 | } |
2200 | | |
2201 | | #[inline] |
2202 | 0 | fn pad(&mut self, bits: u32) -> io::Result<()> { |
2203 | 0 | BitWrite::pad(&mut self.bits, bits) |
2204 | 0 | } |
2205 | | |
2206 | | #[inline] |
2207 | 0 | fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> { |
2208 | 0 | BitWrite::write_bytes(&mut self.bits, buf) |
2209 | 0 | } |
2210 | | |
2211 | 0 | fn write_unary<const STOP_BIT: u8>(&mut self, value: u32) -> io::Result<()> { |
2212 | 0 | BitWrite::write_unary::<STOP_BIT>(&mut self.bits, value) |
2213 | 0 | } |
2214 | | |
2215 | | #[inline] |
2216 | 0 | fn byte_aligned(&self) -> bool { |
2217 | 0 | BitWrite::byte_aligned(&self.bits) |
2218 | 0 | } |
2219 | | } |
2220 | | |
2221 | | #[cfg(feature = "alloc")] |
2222 | | mod bit_recorder { |
2223 | | use super::*; |
2224 | | |
2225 | | /// For recording writes in order to play them back on another writer |
2226 | | /// # Example |
2227 | | /// ``` |
2228 | | /// use std::io::Write; |
2229 | | /// use bitstream_io::{BigEndian, BitWriter, BitWrite, BitRecorder}; |
2230 | | /// let mut recorder: BitRecorder<u32, BigEndian> = BitRecorder::new(); |
2231 | | /// recorder.write_var(1, 0b1u8).unwrap(); |
2232 | | /// recorder.write_var(2, 0b01u8).unwrap(); |
2233 | | /// recorder.write_var(5, 0b10111u8).unwrap(); |
2234 | | /// assert_eq!(recorder.written(), 8); |
2235 | | /// let mut writer = BitWriter::endian(Vec::new(), BigEndian); |
2236 | | /// recorder.playback(&mut writer); |
2237 | | /// assert_eq!(writer.into_writer(), [0b10110111]); |
2238 | | /// ``` |
2239 | | #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] |
2240 | | pub struct BitRecorder<N, E: Endianness> { |
2241 | | writer: BitWriter<Vec<u8>, E>, |
2242 | | phantom: PhantomData<N>, |
2243 | | } |
2244 | | |
2245 | | impl<N: Counter, E: Endianness> BitRecorder<N, E> { |
2246 | | /// Creates new recorder |
2247 | | #[inline] |
2248 | 0 | pub fn new() -> Self { |
2249 | 0 | BitRecorder { |
2250 | 0 | writer: BitWriter::new(Vec::new()), |
2251 | 0 | phantom: PhantomData, |
2252 | 0 | } |
2253 | 0 | } |
2254 | | |
2255 | | /// Creates new recorder sized for the given number of bytes |
2256 | | #[inline] |
2257 | 0 | pub fn with_capacity(bytes: usize) -> Self { |
2258 | 0 | BitRecorder { |
2259 | 0 | writer: BitWriter::new(Vec::with_capacity(bytes)), |
2260 | 0 | phantom: PhantomData, |
2261 | 0 | } |
2262 | 0 | } |
2263 | | |
2264 | | /// Creates new recorder with the given endianness |
2265 | | #[inline] |
2266 | 0 | pub fn endian(endian: E) -> Self { |
2267 | 0 | BitRecorder { |
2268 | 0 | writer: BitWriter::endian(Vec::new(), endian), |
2269 | 0 | phantom: PhantomData, |
2270 | 0 | } |
2271 | 0 | } |
2272 | | |
2273 | | /// Returns number of bits written |
2274 | | /// |
2275 | | /// # Panics |
2276 | | /// |
2277 | | /// Panics if the number of bits written is |
2278 | | /// larger than the maximum supported by the counter type. |
2279 | | /// Use [`BitRecorder::written_checked`] for a non-panicking |
2280 | | /// alternative. |
2281 | | #[inline] |
2282 | 0 | pub fn written(&self) -> N { |
2283 | 0 | self.written_checked().unwrap() |
2284 | 0 | } |
2285 | | |
2286 | | /// Returns number of bits written |
2287 | | /// |
2288 | | /// # Errors |
2289 | | /// |
2290 | | /// Returns an error if the number of bits written overflows |
2291 | | /// our counter type. |
2292 | | #[inline] |
2293 | 0 | pub fn written_checked(&self) -> Result<N, Overflowed> { |
2294 | 0 | let mut written = N::try_from(self.writer.writer.len()) |
2295 | 0 | .map_err(|_| Overflowed)? |
2296 | 0 | .checked_mul(8u8.into())?; |
2297 | | |
2298 | 0 | written.checked_add_assign(N::try_from(self.writer.bits).map_err(|_| Overflowed)?)?; |
2299 | | |
2300 | 0 | Ok(written) |
2301 | 0 | } |
2302 | | |
2303 | | /// Plays recorded writes to the given writer |
2304 | | #[inline] |
2305 | 0 | pub fn playback<W: BitWrite>(&self, writer: &mut W) -> io::Result<()> { |
2306 | 0 | writer.write_bytes(self.writer.writer.as_slice())?; |
2307 | 0 | writer.write_var(self.writer.bits, self.writer.value)?; |
2308 | 0 | Ok(()) |
2309 | 0 | } |
2310 | | |
2311 | | /// Clears recorder, removing all values |
2312 | | #[inline] |
2313 | 0 | pub fn clear(&mut self) { |
2314 | 0 | self.writer = BitWriter::new({ |
2315 | 0 | let mut v = core::mem::take(&mut self.writer.writer); |
2316 | 0 | v.clear(); |
2317 | 0 | v |
2318 | | }); |
2319 | 0 | } |
2320 | | } |
2321 | | |
2322 | | impl<N: Counter, E: Endianness> Default for BitRecorder<N, E> { |
2323 | | #[inline] |
2324 | 0 | fn default() -> Self { |
2325 | 0 | Self::new() |
2326 | 0 | } |
2327 | | } |
2328 | | |
2329 | | impl<N, E> BitWrite for BitRecorder<N, E> |
2330 | | where |
2331 | | E: Endianness, |
2332 | | N: Counter, |
2333 | | { |
2334 | | #[inline] |
2335 | 0 | fn write_bit(&mut self, bit: bool) -> io::Result<()> { |
2336 | 0 | BitWrite::write_bit(&mut self.writer, bit) |
2337 | 0 | } |
2338 | | |
2339 | | #[inline] |
2340 | 0 | fn write<const BITS: u32, I>(&mut self, value: I) -> io::Result<()> |
2341 | 0 | where |
2342 | 0 | I: Integer, |
2343 | | { |
2344 | 0 | BitWrite::write::<BITS, I>(&mut self.writer, value) |
2345 | 0 | } |
2346 | | |
2347 | | #[inline] |
2348 | 0 | fn write_const<const BITS: u32, const VALUE: u32>(&mut self) -> io::Result<()> { |
2349 | 0 | self.writer.write_const::<BITS, VALUE>() |
2350 | 0 | } |
2351 | | |
2352 | | #[inline] |
2353 | 0 | fn write_var<I>(&mut self, bits: u32, value: I) -> io::Result<()> |
2354 | 0 | where |
2355 | 0 | I: Integer, |
2356 | | { |
2357 | 0 | self.writer.write_var(bits, value) |
2358 | 0 | } |
2359 | | |
2360 | | #[inline] |
2361 | 0 | fn write_unsigned<const BITS: u32, U>(&mut self, value: U) -> io::Result<()> |
2362 | 0 | where |
2363 | 0 | U: UnsignedInteger, |
2364 | | { |
2365 | 0 | BitWrite::write_unsigned::<BITS, U>(&mut self.writer, value) |
2366 | 0 | } |
2367 | | |
2368 | | #[inline] |
2369 | 0 | fn write_unsigned_var<U>(&mut self, bits: u32, value: U) -> io::Result<()> |
2370 | 0 | where |
2371 | 0 | U: UnsignedInteger, |
2372 | | { |
2373 | 0 | self.writer.write_unsigned_var(bits, value) |
2374 | 0 | } |
2375 | | |
2376 | | #[inline] |
2377 | 0 | fn write_signed<const BITS: u32, S>(&mut self, value: S) -> io::Result<()> |
2378 | 0 | where |
2379 | 0 | S: SignedInteger, |
2380 | | { |
2381 | 0 | BitWrite::write_signed::<BITS, S>(&mut self.writer, value) |
2382 | 0 | } |
2383 | | |
2384 | | #[inline(always)] |
2385 | 0 | fn write_signed_var<S>(&mut self, bits: u32, value: S) -> io::Result<()> |
2386 | 0 | where |
2387 | 0 | S: SignedInteger, |
2388 | | { |
2389 | 0 | self.writer.write_signed_var(bits, value) |
2390 | 0 | } |
2391 | | |
2392 | | #[inline] |
2393 | 0 | fn write_count<const MAX: u32>(&mut self, count: BitCount<MAX>) -> io::Result<()> { |
2394 | 0 | self.writer.write_count::<MAX>(count) |
2395 | 0 | } |
2396 | | |
2397 | | #[inline] |
2398 | 0 | fn write_counted<const MAX: u32, I>( |
2399 | 0 | &mut self, |
2400 | 0 | bits: BitCount<MAX>, |
2401 | 0 | value: I, |
2402 | 0 | ) -> io::Result<()> |
2403 | 0 | where |
2404 | 0 | I: Integer + Sized, |
2405 | | { |
2406 | 0 | self.writer.write_counted::<MAX, I>(bits, value) |
2407 | 0 | } |
2408 | | |
2409 | | #[inline] |
2410 | 0 | fn write_unsigned_counted<const BITS: u32, U>( |
2411 | 0 | &mut self, |
2412 | 0 | bits: BitCount<BITS>, |
2413 | 0 | value: U, |
2414 | 0 | ) -> io::Result<()> |
2415 | 0 | where |
2416 | 0 | U: UnsignedInteger, |
2417 | | { |
2418 | 0 | self.writer.write_unsigned_counted::<BITS, U>(bits, value) |
2419 | 0 | } |
2420 | | |
2421 | | #[inline] |
2422 | 0 | fn write_signed_counted<const MAX: u32, S>( |
2423 | 0 | &mut self, |
2424 | 0 | bits: impl TryInto<SignedBitCount<MAX>>, |
2425 | 0 | value: S, |
2426 | 0 | ) -> io::Result<()> |
2427 | 0 | where |
2428 | 0 | S: SignedInteger, |
2429 | | { |
2430 | 0 | self.writer.write_signed_counted::<MAX, S>(bits, value) |
2431 | 0 | } |
2432 | | |
2433 | | #[inline] |
2434 | 0 | fn write_from<V>(&mut self, value: V) -> io::Result<()> |
2435 | 0 | where |
2436 | 0 | V: Primitive, |
2437 | | { |
2438 | 0 | BitWrite::write_from::<V>(&mut self.writer, value) |
2439 | 0 | } |
2440 | | |
2441 | | #[inline] |
2442 | 0 | fn write_as_from<F, V>(&mut self, value: V) -> io::Result<()> |
2443 | 0 | where |
2444 | 0 | F: Endianness, |
2445 | 0 | V: Primitive, |
2446 | | { |
2447 | 0 | BitWrite::write_as_from::<F, V>(&mut self.writer, value) |
2448 | 0 | } |
2449 | | |
2450 | | #[inline] |
2451 | 0 | fn pad(&mut self, bits: u32) -> io::Result<()> { |
2452 | 0 | BitWrite::pad(&mut self.writer, bits) |
2453 | 0 | } |
2454 | | |
2455 | | #[inline] |
2456 | 0 | fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> { |
2457 | 0 | BitWrite::write_bytes(&mut self.writer, buf) |
2458 | 0 | } |
2459 | | |
2460 | | #[inline] |
2461 | 0 | fn write_unary<const STOP_BIT: u8>(&mut self, value: u32) -> io::Result<()> { |
2462 | 0 | self.writer.write_unary::<STOP_BIT>(value) |
2463 | 0 | } |
2464 | | |
2465 | | #[inline] |
2466 | 0 | fn build<T: ToBitStream>(&mut self, build: &T) -> Result<(), T::Error> { |
2467 | 0 | BitWrite::build(&mut self.writer, build) |
2468 | 0 | } |
2469 | | |
2470 | | #[inline] |
2471 | 0 | fn build_with<'a, T: ToBitStreamWith<'a>>( |
2472 | 0 | &mut self, |
2473 | 0 | build: &T, |
2474 | 0 | context: &T::Context, |
2475 | 0 | ) -> Result<(), T::Error> { |
2476 | 0 | BitWrite::build_with(&mut self.writer, build, context) |
2477 | 0 | } |
2478 | | |
2479 | | #[inline] |
2480 | 0 | fn byte_aligned(&self) -> bool { |
2481 | 0 | BitWrite::byte_aligned(&self.writer) |
2482 | 0 | } |
2483 | | |
2484 | | #[inline] |
2485 | 0 | fn byte_align(&mut self) -> io::Result<()> { |
2486 | 0 | BitWrite::byte_align(&mut self.writer) |
2487 | 0 | } |
2488 | | |
2489 | | #[inline] |
2490 | 0 | fn write_huffman<T>(&mut self, value: T::Symbol) -> io::Result<()> |
2491 | 0 | where |
2492 | 0 | T: crate::huffman::ToBits, |
2493 | | { |
2494 | 0 | BitWrite::write_huffman::<T>(&mut self.writer, value) |
2495 | 0 | } |
2496 | | } |
2497 | | |
2498 | | impl<N: PartialOrd + Counter + Copy, E: Endianness> BitRecorder<N, E> { |
2499 | | /// Returns shortest option between ourself and candidate |
2500 | | /// |
2501 | | /// Executes fallible closure on emptied candidate recorder, |
2502 | | /// compares the lengths of ourself and the candidate, |
2503 | | /// and returns the shorter of the two. |
2504 | | /// |
2505 | | /// If the new candidate is shorter, we swap ourself and |
2506 | | /// the candidate so any recorder capacity can be reused. |
2507 | | /// |
2508 | | /// # Example |
2509 | | /// |
2510 | | /// ``` |
2511 | | /// use bitstream_io::{BitRecorder, BitWrite, BigEndian}; |
2512 | | /// |
2513 | | /// let mut best = BitRecorder::<u8, BigEndian>::new(); |
2514 | | /// let mut candidate = BitRecorder::new(); |
2515 | | /// |
2516 | | /// // write an 8 bit value to our initial candidate |
2517 | | /// best.write::<8, u8>(0); |
2518 | | /// assert_eq!(best.written(), 8); |
2519 | | /// |
2520 | | /// // try another candidate which writes 4 bits |
2521 | | /// best = best.best(&mut candidate, |w| { |
2522 | | /// w.write::<4, u8>(0) |
2523 | | /// }).unwrap(); |
2524 | | /// |
2525 | | /// // which becomes our new best candidate |
2526 | | /// assert_eq!(best.written(), 4); |
2527 | | /// |
2528 | | /// // finally, try a not-so-best candidate |
2529 | | /// // which writes 10 bits |
2530 | | /// best = best.best(&mut candidate, |w| { |
2531 | | /// w.write::<10, u16>(0) |
2532 | | /// }).unwrap(); |
2533 | | /// |
2534 | | /// // so our best candidate remains 4 bits |
2535 | | /// assert_eq!(best.written(), 4); |
2536 | | /// ``` |
2537 | 0 | pub fn best<F>( |
2538 | 0 | mut self, |
2539 | 0 | candidate: &mut Self, |
2540 | 0 | f: impl FnOnce(&mut Self) -> Result<(), F>, |
2541 | 0 | ) -> Result<Self, F> { |
2542 | 0 | candidate.clear(); |
2543 | | |
2544 | 0 | f(candidate)?; |
2545 | | |
2546 | 0 | if candidate.written() < self.written() { |
2547 | 0 | core::mem::swap(&mut self, candidate); |
2548 | 0 | } |
2549 | | |
2550 | 0 | Ok(self) |
2551 | 0 | } |
2552 | | } |
2553 | | } |
2554 | | |
2555 | | #[inline] |
2556 | 0 | fn write_byte<W>(mut writer: W, byte: u8) -> io::Result<()> |
2557 | 0 | where |
2558 | 0 | W: io::Write, |
2559 | | { |
2560 | 0 | writer.write_all(core::slice::from_ref(&byte)) |
2561 | 0 | } Unexecuted instantiation: bitstream_io::write::write_byte::<&mut &mut alloc::vec::Vec<u8>> Unexecuted instantiation: bitstream_io::write::write_byte::<_> |
2562 | | |
2563 | | /// For writing aligned bytes to a stream of bytes in a given endianness. |
2564 | | /// |
2565 | | /// This only writes aligned values and maintains no internal state. |
2566 | | pub struct ByteWriter<W: io::Write, E: Endianness> { |
2567 | | phantom: PhantomData<E>, |
2568 | | writer: W, |
2569 | | } |
2570 | | |
2571 | | impl<W: io::Write, E: Endianness> ByteWriter<W, E> { |
2572 | | /// Wraps a ByteWriter around something that implements `Write` |
2573 | 0 | pub fn new(writer: W) -> ByteWriter<W, E> { |
2574 | 0 | ByteWriter { |
2575 | 0 | phantom: PhantomData, |
2576 | 0 | writer, |
2577 | 0 | } |
2578 | 0 | } |
2579 | | |
2580 | | /// Wraps a BitWriter around something that implements `Write` |
2581 | | /// with the given endianness. |
2582 | 0 | pub fn endian(writer: W, _endian: E) -> ByteWriter<W, E> { |
2583 | 0 | ByteWriter { |
2584 | 0 | phantom: PhantomData, |
2585 | 0 | writer, |
2586 | 0 | } |
2587 | 0 | } |
2588 | | |
2589 | | /// Unwraps internal writer and disposes of `ByteWriter`. |
2590 | | /// Any unwritten partial bits are discarded. |
2591 | | #[inline] |
2592 | 0 | pub fn into_writer(self) -> W { |
2593 | 0 | self.writer |
2594 | 0 | } |
2595 | | |
2596 | | /// Provides mutable reference to internal writer. |
2597 | | #[inline] |
2598 | 0 | pub fn writer(&mut self) -> &mut W { |
2599 | 0 | &mut self.writer |
2600 | 0 | } |
2601 | | |
2602 | | /// Converts `ByteWriter` to `BitWriter` in the same endianness. |
2603 | | #[inline] |
2604 | 0 | pub fn into_bitwriter(self) -> BitWriter<W, E> { |
2605 | 0 | BitWriter::new(self.into_writer()) |
2606 | 0 | } |
2607 | | |
2608 | | /// Provides temporary `BitWriter` in the same endianness. |
2609 | | /// |
2610 | | /// # Warning |
2611 | | /// |
2612 | | /// Any unwritten bits left over when `BitWriter` is dropped are lost. |
2613 | | #[inline] |
2614 | 0 | pub fn bitwriter(&mut self) -> BitWriter<&mut W, E> { |
2615 | 0 | BitWriter::new(self.writer()) |
2616 | 0 | } |
2617 | | } |
2618 | | |
2619 | | /// A trait for anything that can write aligned values to an output stream |
2620 | | pub trait ByteWrite { |
2621 | | /// Writes whole numeric value to stream |
2622 | | /// |
2623 | | /// # Errors |
2624 | | /// |
2625 | | /// Passes along any I/O error from the underlying stream. |
2626 | | /// # Examples |
2627 | | /// ``` |
2628 | | /// use std::io::Write; |
2629 | | /// use bitstream_io::{BigEndian, ByteWriter, ByteWrite}; |
2630 | | /// let mut writer = ByteWriter::endian(Vec::new(), BigEndian); |
2631 | | /// writer.write(0b0000000011111111u16).unwrap(); |
2632 | | /// assert_eq!(writer.into_writer(), [0b00000000, 0b11111111]); |
2633 | | /// ``` |
2634 | | /// |
2635 | | /// ``` |
2636 | | /// use std::io::Write; |
2637 | | /// use bitstream_io::{LittleEndian, ByteWriter, ByteWrite}; |
2638 | | /// let mut writer = ByteWriter::endian(Vec::new(), LittleEndian); |
2639 | | /// writer.write(0b0000000011111111u16).unwrap(); |
2640 | | /// assert_eq!(writer.into_writer(), [0b11111111, 0b00000000]); |
2641 | | /// ``` |
2642 | | fn write<V>(&mut self, value: V) -> io::Result<()> |
2643 | | where |
2644 | | V: Primitive; |
2645 | | |
2646 | | /// Writes whole numeric value to stream in a potentially different endianness |
2647 | | /// |
2648 | | /// # Errors |
2649 | | /// |
2650 | | /// Passes along any I/O error from the underlying stream. |
2651 | | /// |
2652 | | /// # Examples |
2653 | | /// ``` |
2654 | | /// use std::io::Write; |
2655 | | /// use bitstream_io::{BigEndian, ByteWriter, ByteWrite, LittleEndian}; |
2656 | | /// let mut writer = ByteWriter::endian(Vec::new(), BigEndian); |
2657 | | /// writer.write_as::<LittleEndian, u16>(0b0000000011111111).unwrap(); |
2658 | | /// assert_eq!(writer.into_writer(), [0b11111111, 0b00000000]); |
2659 | | /// ``` |
2660 | | /// |
2661 | | /// ``` |
2662 | | /// use std::io::Write; |
2663 | | /// use bitstream_io::{BigEndian, ByteWriter, ByteWrite, LittleEndian}; |
2664 | | /// let mut writer = ByteWriter::endian(Vec::new(), LittleEndian); |
2665 | | /// writer.write_as::<BigEndian, u16>(0b0000000011111111).unwrap(); |
2666 | | /// assert_eq!(writer.into_writer(), [0b00000000, 0b11111111]); |
2667 | | /// ``` |
2668 | | fn write_as<F, V>(&mut self, value: V) -> io::Result<()> |
2669 | | where |
2670 | | F: Endianness, |
2671 | | V: Primitive; |
2672 | | |
2673 | | /// Writes the entirety of a byte buffer to the stream. |
2674 | | /// |
2675 | | /// # Errors |
2676 | | /// |
2677 | | /// Passes along any I/O error from the underlying stream. |
2678 | | fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()>; |
2679 | | |
2680 | | /// Pads the stream by writing 0 over the given number of bytes. |
2681 | | /// |
2682 | | /// # Errors |
2683 | | /// |
2684 | | /// Passes along any I/O error from the underlying stream. |
2685 | | fn pad(&mut self, bytes: u32) -> io::Result<()>; |
2686 | | |
2687 | | /// Builds and writes complex type |
2688 | 0 | fn build<T: ToByteStream>(&mut self, build: &T) -> Result<(), T::Error> { |
2689 | 0 | build.to_writer(self) |
2690 | 0 | } |
2691 | | |
2692 | | /// Builds and writes complex type with context |
2693 | 0 | fn build_with<'a, T: ToByteStreamWith<'a>>( |
2694 | 0 | &mut self, |
2695 | 0 | build: &T, |
2696 | 0 | context: &T::Context, |
2697 | 0 | ) -> Result<(), T::Error> { |
2698 | 0 | build.to_writer(self, context) |
2699 | 0 | } |
2700 | | |
2701 | | /// Builds and writes complex type with owned context |
2702 | 0 | fn build_using<T: ToByteStreamUsing>( |
2703 | 0 | &mut self, |
2704 | 0 | build: &T, |
2705 | 0 | context: T::Context, |
2706 | 0 | ) -> Result<(), T::Error> { |
2707 | 0 | build.to_writer(self, context) |
2708 | 0 | } |
2709 | | |
2710 | | /// Returns mutable reference to underlying writer |
2711 | | fn writer_ref(&mut self) -> &mut dyn io::Write; |
2712 | | } |
2713 | | |
2714 | | impl<W: io::Write, E: Endianness> ByteWrite for ByteWriter<W, E> { |
2715 | | #[inline] |
2716 | 0 | fn write<V>(&mut self, value: V) -> io::Result<()> |
2717 | 0 | where |
2718 | 0 | V: Primitive, |
2719 | | { |
2720 | 0 | self.writer.write_all(E::primitive_to_bytes(value).as_ref()) |
2721 | 0 | } |
2722 | | |
2723 | | #[inline] |
2724 | 0 | fn write_as<F, V>(&mut self, value: V) -> io::Result<()> |
2725 | 0 | where |
2726 | 0 | F: Endianness, |
2727 | 0 | V: Primitive, |
2728 | | { |
2729 | 0 | self.writer.write_all(F::primitive_to_bytes(value).as_ref()) |
2730 | 0 | } |
2731 | | |
2732 | | #[inline] |
2733 | 0 | fn pad(&mut self, mut bytes: u32) -> io::Result<()> { |
2734 | 0 | let buf = [0u8; 8]; |
2735 | | |
2736 | 0 | while bytes > 0 { |
2737 | 0 | let to_write = bytes.min(8); |
2738 | 0 | self.write_bytes(&buf[0..to_write as usize])?; |
2739 | 0 | bytes -= to_write; |
2740 | | } |
2741 | 0 | Ok(()) |
2742 | 0 | } |
2743 | | |
2744 | | #[inline] |
2745 | 0 | fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> { |
2746 | 0 | self.writer.write_all(buf) |
2747 | 0 | } |
2748 | | |
2749 | | #[inline] |
2750 | 0 | fn writer_ref(&mut self) -> &mut dyn io::Write { |
2751 | 0 | &mut self.writer |
2752 | 0 | } |
2753 | | } |
2754 | | |
2755 | | /// Implemented by complex types that don't require any additional context |
2756 | | /// to build themselves to a writer |
2757 | | /// |
2758 | | /// # Example |
2759 | | /// ``` |
2760 | | /// use std::io::Read; |
2761 | | /// use bitstream_io::{BigEndian, BitWrite, BitWriter, ToBitStream}; |
2762 | | /// |
2763 | | /// #[derive(Debug, PartialEq, Eq)] |
2764 | | /// struct BlockHeader { |
2765 | | /// last_block: bool, |
2766 | | /// block_type: u8, |
2767 | | /// block_size: u32, |
2768 | | /// } |
2769 | | /// |
2770 | | /// impl ToBitStream for BlockHeader { |
2771 | | /// type Error = std::io::Error; |
2772 | | /// |
2773 | | /// fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> std::io::Result<()> { |
2774 | | /// w.write_bit(self.last_block)?; |
2775 | | /// w.write::<7, _>(self.block_type)?; |
2776 | | /// w.write::<24, _>(self.block_size) |
2777 | | /// } |
2778 | | /// } |
2779 | | /// |
2780 | | /// let mut data = Vec::new(); |
2781 | | /// let mut writer = BitWriter::endian(&mut data, BigEndian); |
2782 | | /// writer.build(&BlockHeader { last_block: false, block_type: 4, block_size: 122 }).unwrap(); |
2783 | | /// assert_eq!(data, b"\x04\x00\x00\x7A"); |
2784 | | /// ``` |
2785 | | pub trait ToBitStream { |
2786 | | /// Error generated during building, such as `io::Error` |
2787 | | type Error; |
2788 | | |
2789 | | /// Generate self to writer |
2790 | | fn to_writer<W: BitWrite + ?Sized>(&self, w: &mut W) -> Result<(), Self::Error> |
2791 | | where |
2792 | | Self: Sized; |
2793 | | |
2794 | | /// Returns length of self in bits, if possible |
2795 | 0 | fn bits<C: Counter>(&self) -> Result<C, Self::Error> |
2796 | 0 | where |
2797 | 0 | Self: Sized, |
2798 | | { |
2799 | 0 | let mut c: BitsWritten<C> = BitsWritten::default(); |
2800 | 0 | self.to_writer(&mut c)?; |
2801 | 0 | Ok(c.into_written()) |
2802 | 0 | } |
2803 | | |
2804 | | /// Returns total length of self, if possible |
2805 | | #[deprecated(since = "4.0.0", note = "use of bits() is preferred")] |
2806 | | #[inline] |
2807 | 0 | fn bits_len<C: Counter, E: Endianness>(&self) -> Result<C, Self::Error> |
2808 | 0 | where |
2809 | 0 | Self: Sized, |
2810 | | { |
2811 | 0 | self.bits() |
2812 | 0 | } |
2813 | | } |
2814 | | |
2815 | | /// Implemented by complex types that require additional context |
2816 | | /// to build themselves to a writer |
2817 | | pub trait ToBitStreamWith<'a> { |
2818 | | /// Some context to use when writing |
2819 | | type Context: 'a; |
2820 | | |
2821 | | /// Error generated during building, such as `io::Error` |
2822 | | type Error; |
2823 | | |
2824 | | /// Generate self to writer |
2825 | | fn to_writer<W: BitWrite + ?Sized>( |
2826 | | &self, |
2827 | | w: &mut W, |
2828 | | context: &Self::Context, |
2829 | | ) -> Result<(), Self::Error> |
2830 | | where |
2831 | | Self: Sized; |
2832 | | |
2833 | | /// Returns length of self in bits, if possible |
2834 | 0 | fn bits<C: Counter>(&self, context: &Self::Context) -> Result<C, Self::Error> |
2835 | 0 | where |
2836 | 0 | Self: Sized, |
2837 | | { |
2838 | 0 | let mut c: BitsWritten<C> = BitsWritten::default(); |
2839 | 0 | self.to_writer(&mut c, context)?; |
2840 | 0 | Ok(c.into_written()) |
2841 | 0 | } |
2842 | | |
2843 | | /// Returns total length of self, if possible |
2844 | | #[deprecated(since = "4.0.0", note = "use of len() is preferred")] |
2845 | | #[inline] |
2846 | 0 | fn bits_len<C: Counter, E: Endianness>(&self, context: &Self::Context) -> Result<C, Self::Error> |
2847 | 0 | where |
2848 | 0 | Self: Sized, |
2849 | | { |
2850 | 0 | self.bits(context) |
2851 | 0 | } |
2852 | | } |
2853 | | |
2854 | | /// Implemented by complex types that consume additional context |
2855 | | /// to build themselves to a writer |
2856 | | pub trait ToBitStreamUsing { |
2857 | | /// Some context to consume when writing |
2858 | | type Context; |
2859 | | |
2860 | | /// Error generated during building, such as `io::Error` |
2861 | | type Error; |
2862 | | |
2863 | | /// Generate self to writer |
2864 | | fn to_writer<W: BitWrite + ?Sized>( |
2865 | | &self, |
2866 | | w: &mut W, |
2867 | | context: Self::Context, |
2868 | | ) -> Result<(), Self::Error> |
2869 | | where |
2870 | | Self: Sized; |
2871 | | |
2872 | | /// Returns length of self in bits, if possible |
2873 | 0 | fn bits<C: Counter>(&self, context: Self::Context) -> Result<C, Self::Error> |
2874 | 0 | where |
2875 | 0 | Self: Sized, |
2876 | | { |
2877 | 0 | let mut c: BitsWritten<C> = BitsWritten::default(); |
2878 | 0 | self.to_writer(&mut c, context)?; |
2879 | 0 | Ok(c.into_written()) |
2880 | 0 | } |
2881 | | } |
2882 | | |
2883 | | /// Implemented by complex types that don't require any additional context |
2884 | | /// to build themselves to a writer |
2885 | | pub trait ToByteStream { |
2886 | | /// Error generated during building, such as `io::Error` |
2887 | | type Error; |
2888 | | |
2889 | | /// Generate self to writer |
2890 | | fn to_writer<W: ByteWrite + ?Sized>(&self, w: &mut W) -> Result<(), Self::Error> |
2891 | | where |
2892 | | Self: Sized; |
2893 | | |
2894 | | /// Returns length of self in bytes, if possible |
2895 | 0 | fn bytes<C: Counter>(&self) -> Result<C, Self::Error> |
2896 | 0 | where |
2897 | 0 | Self: Sized, |
2898 | | { |
2899 | 0 | let mut counter = ByteCount::default(); |
2900 | 0 | self.to_writer(&mut counter)?; |
2901 | 0 | Ok(counter.writer.count) |
2902 | 0 | } |
2903 | | } |
2904 | | |
2905 | | /// Implemented by complex types that require additional context |
2906 | | /// to build themselves to a writer |
2907 | | pub trait ToByteStreamWith<'a> { |
2908 | | /// Some context to use when writing |
2909 | | type Context: 'a; |
2910 | | |
2911 | | /// Error generated during building, such as `io::Error` |
2912 | | type Error; |
2913 | | |
2914 | | /// Generate self to writer |
2915 | | fn to_writer<W: ByteWrite + ?Sized>( |
2916 | | &self, |
2917 | | w: &mut W, |
2918 | | context: &Self::Context, |
2919 | | ) -> Result<(), Self::Error> |
2920 | | where |
2921 | | Self: Sized; |
2922 | | |
2923 | | /// Returns length of self in bytes, if possible |
2924 | 0 | fn bytes<C: Counter>(&self, context: &Self::Context) -> Result<C, Self::Error> |
2925 | 0 | where |
2926 | 0 | Self: Sized, |
2927 | | { |
2928 | 0 | let mut counter = ByteCount::default(); |
2929 | 0 | self.to_writer(&mut counter, context)?; |
2930 | 0 | Ok(counter.writer.count) |
2931 | 0 | } |
2932 | | } |
2933 | | |
2934 | | /// Implemented by complex types that consume additional context |
2935 | | /// to build themselves to a writer |
2936 | | pub trait ToByteStreamUsing { |
2937 | | /// Some context to consume when writing |
2938 | | type Context; |
2939 | | |
2940 | | /// Error generated during building, such as `io::Error` |
2941 | | type Error; |
2942 | | |
2943 | | /// Generate self to writer |
2944 | | fn to_writer<W: ByteWrite + ?Sized>( |
2945 | | &self, |
2946 | | w: &mut W, |
2947 | | context: Self::Context, |
2948 | | ) -> Result<(), Self::Error> |
2949 | | where |
2950 | | Self: Sized; |
2951 | | |
2952 | | /// Returns length of self in bytes, if possible |
2953 | 0 | fn bytes<C: Counter>(&self, context: Self::Context) -> Result<C, Self::Error> |
2954 | 0 | where |
2955 | 0 | Self: Sized, |
2956 | | { |
2957 | 0 | let mut counter = ByteCount::default(); |
2958 | 0 | self.to_writer(&mut counter, context)?; |
2959 | 0 | Ok(counter.writer.count) |
2960 | 0 | } |
2961 | | } |
2962 | | |
2963 | | #[derive(Default)] |
2964 | | struct ByteCounterWriter<C> { |
2965 | | count: C, |
2966 | | } |
2967 | | |
2968 | | impl<C: Counter> io::Write for ByteCounterWriter<C> { |
2969 | | #[inline] |
2970 | 0 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
2971 | 0 | self.count |
2972 | 0 | .checked_add_assign(buf.len().try_into().map_err(|_| Overflowed)?)?; |
2973 | | |
2974 | 0 | Ok(buf.len()) |
2975 | 0 | } |
2976 | | |
2977 | | #[inline] |
2978 | 0 | fn flush(&mut self) -> io::Result<()> { |
2979 | | // nothing to do |
2980 | 0 | Ok(()) |
2981 | 0 | } |
2982 | | } |
2983 | | |
2984 | | #[derive(Default)] |
2985 | | struct ByteCount<C> { |
2986 | | writer: ByteCounterWriter<C>, |
2987 | | } |
2988 | | |
2989 | | impl<C: Counter> ByteWrite for ByteCount<C> { |
2990 | 0 | fn write<V: Primitive>(&mut self, _value: V) -> io::Result<()> { |
2991 | 0 | self.writer.count.checked_add_assign( |
2992 | 0 | V::buffer() |
2993 | 0 | .as_ref() |
2994 | 0 | .len() |
2995 | 0 | .try_into() |
2996 | 0 | .map_err(|_| Overflowed)?, |
2997 | 0 | )?; |
2998 | | |
2999 | 0 | Ok(()) |
3000 | 0 | } |
3001 | | |
3002 | 0 | fn write_as<F: Endianness, V: Primitive>(&mut self, _value: V) -> io::Result<()> { |
3003 | 0 | self.writer.count.checked_add_assign( |
3004 | 0 | V::buffer() |
3005 | 0 | .as_ref() |
3006 | 0 | .len() |
3007 | 0 | .try_into() |
3008 | 0 | .map_err(|_| Overflowed)?, |
3009 | 0 | )?; |
3010 | | |
3011 | 0 | Ok(()) |
3012 | 0 | } |
3013 | | |
3014 | 0 | fn write_bytes(&mut self, buf: &[u8]) -> io::Result<()> { |
3015 | 0 | self.writer |
3016 | 0 | .count |
3017 | 0 | .checked_add_assign(buf.len().try_into().map_err(|_| Overflowed)?)?; |
3018 | | |
3019 | 0 | Ok(()) |
3020 | 0 | } |
3021 | | |
3022 | 0 | fn pad(&mut self, bytes: u32) -> io::Result<()> { |
3023 | 0 | self.writer |
3024 | 0 | .count |
3025 | 0 | .checked_add_assign(bytes.try_into().map_err(|_| Overflowed)?)?; |
3026 | | |
3027 | 0 | Ok(()) |
3028 | 0 | } |
3029 | | |
3030 | 0 | fn writer_ref(&mut self) -> &mut dyn io::Write { |
3031 | 0 | &mut self.writer |
3032 | 0 | } |
3033 | | } |