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