bitstream_io/lib.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 helpers for bitstream handling functionality
10//!
11//! Bitstream readers are for reading signed and unsigned integer
12//! values from a stream whose sizes may not be whole bytes.
13//! Bitstream writers are for writing signed and unsigned integer
14//! values to a stream, also potentially un-aligned at a whole byte.
15//!
16//! Both big-endian and little-endian streams are supported.
17//!
18//! The only requirement for wrapped reader streams is that they must
19//! implement the [`io::Read`] trait, and the only requirement
20//! for writer streams is that they must implement the [`io::Write`] trait.
21//!
22//! In addition, reader streams do not consume any more bytes
23//! from the underlying reader than necessary, buffering only a
24//! single partial byte as needed.
25//! Writer streams also write out all whole bytes as they are accumulated.
26//!
27//! Readers and writers are also designed to work with integer
28//! types of any possible size.
29//! Many of Rust's built-in integer types are supported by default.
30
31//! # Minimum Compiler Version
32//!
33//! Beginning with version 2.4, the minimum compiler version has been
34//! updated to Rust 1.79.
35//!
36//! The issue is that reading an excessive number of
37//! bits to a type which is too small to hold them,
38//! or writing an excessive number of bits from too small of a type,
39//! are always errors:
40//! ```
41//! use std::io::{Read, Cursor};
42//! use bitstream_io::{BigEndian, BitReader, BitRead};
43//! let data = [0; 10];
44//! let mut r = BitReader::endian(Cursor::new(&data), BigEndian);
45//! let x: Result<u32, _> = r.read_var(64); // reading 64 bits to u32 always fails at runtime
46//! assert!(x.is_err());
47//! ```
48//! but those errors will not be caught until the program runs,
49//! which is less than ideal for the common case in which
50//! the number of bits is already known at compile-time.
51//!
52//! But starting with Rust 1.79, we can now have read and write methods
53//! which take a constant number of bits and can validate the number of bits
54//! are small enough for the type being read/written at compile-time:
55//! ```rust,compile_fail
56//! use std::io::{Read, Cursor};
57//! use bitstream_io::{BigEndian, BitReader, BitRead};
58//! let data = [0; 10];
59//! let mut r = BitReader::endian(Cursor::new(&data), BigEndian);
60//! let x: Result<u32, _> = r.read::<64, _>(); // doesn't compile at all
61//! ```
62//! Since catching potential bugs at compile-time is preferable
63//! to encountering errors at runtime, this will hopefully be
64//! an improvement in the long run.
65
66//! # Changes From 3.X.X
67//!
68//! Version 4.0.0 features significant optimizations to the [`BitRecorder`]
69//! and deprecates the [`BitCounter`] in favor of [`BitsWritten`],
70//! which no longer requires specifying an endianness.
71//!
72//! In addition, the [`BitRead::read_bytes`] and [`BitWrite::write_bytes`]
73//! methods are significantly optimized in the case of non-aligned
74//! reads and writes.
75//!
76//! Finally, the [`Endianness`] traits have been sealed so as not
77//! to be implemented by other packages. Given that other endianness
78//! types are extremely rare in file formats and end users should not
79//! have to implement this trait themselves, this should not be a
80//! concern.
81//!
82//! # Changes From 2.X.X
83//!
84//! Version 3.0.0 has made many breaking changes to the [`BitRead`] and
85//! [`BitWrite`] traits.
86//!
87//! The [`BitRead::read`] method takes a constant number of bits,
88//! and the [`BitRead::read_var`] method takes a variable number of bits
89//! (reversing the older [`BitRead2::read_in`] and [`BitRead2::read`]
90//! calling methods to emphasize using the constant-based one,
91//! which can do more validation at compile-time).
92//! A new [`BitRead2`] trait uses the older calling convention
93//! for compatibility with existing code and is available
94//! for anything implementing [`BitRead`].
95//!
96//! In addition, the main reading methods return primitive types which
97//! implement a new [`Integer`] trait,
98//! which delegates to [`BitRead::read_unsigned`]
99//! or [`BitRead::read_signed`] depending on whether the output
100//! is an unsigned or signed type.
101//!
102//! [`BitWrite::write`] and [`BitWrite::write_var`] work
103//! similarly to the reader's `read` methods, taking anything
104//! that implements [`Integer`] and writing an unsigned or
105//! signed value to [`BitWrite::write_unsigned`] or
106//! [`BitWrite::write_signed`] as appropriate.
107//!
108//! And as with reading, a [`BitWrite2`] trait is offered
109//! for compatibility.
110//!
111//! In addition, the Huffman code handling has been rewritten
112//! to use a small amount of macro magic to write
113//! code to read and write symbols at compile-time.
114//! This is significantly faster than the older version
115//! and can no longer fail to compile at runtime.
116//!
117//! Lastly, there's a new [`BitCount`] struct which wraps a humble
118//! `u32` but encodes the maximum possible number of bits
119//! at the type level.
120//! This is intended for file formats which encode the number
121//! of bits to be read in the format itself.
122//! For example, FLAC's predictor coefficient precision
123//! is a 4 bit value which indicates how large each predictor
124//! coefficient is in bits
125//! (each coefficient might be an `i32` type).
126//! By keeping track of the maximum value at compile time
127//! (4 bits' worth, in this case), we can eliminate
128//! any need to check that coefficients aren't too large
129//! for an `i32` at runtime.
130//! This is accomplished by using [`BitRead::read_count`] to
131//! read a [`BitCount`] and then reading final values with
132//! that number of bits using [`BitRead::read_counted`].
133
134//! # Migrating From Pre 1.0.0
135//!
136//! There are now [`BitRead`] and [`BitWrite`] traits for bitstream
137//! reading and writing (analogous to the standard library's
138//! `Read` and `Write` traits) which you will also need to import.
139//! The upside to this approach is that library consumers
140//! can now make functions and methods generic over any sort
141//! of bit reader or bit writer, regardless of the underlying
142//! stream byte source or endianness.
143
144#![warn(missing_docs)]
145#![forbid(unsafe_code)]
146#![no_std]
147
148extern crate alloc;
149#[cfg(feature = "std")]
150extern crate std;
151
152#[cfg(not(feature = "std"))]
153use core2::io;
154
155use core::num::NonZero;
156use core::ops::{
157 BitAnd, BitOr, BitOrAssign, BitXor, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
158};
159use core::{fmt::Debug, marker::PhantomData, mem};
160#[cfg(feature = "std")]
161use std::io;
162
163pub mod huffman;
164pub mod read;
165pub mod write;
166pub use read::{
167 BitRead, BitRead2, BitReader, ByteRead, ByteReader, FromBitStream, FromBitStreamWith,
168 FromByteStream, FromByteStreamWith,
169};
170pub use write::{
171 BitRecorder, BitWrite, BitWrite2, BitWriter, BitsWritten, ByteWrite, ByteWriter, ToBitStream,
172 ToBitStreamWith, ToByteStream, ToByteStreamWith,
173};
174
175#[allow(deprecated)]
176pub use write::BitCounter;
177
178/// A trait intended for simple fixed-length primitives (such as ints and floats)
179/// which allows them to be read and written to streams of
180/// different endiannesses verbatim.
181pub trait Primitive {
182 /// The raw byte representation of this numeric type
183 type Bytes: AsRef<[u8]> + AsMut<[u8]>;
184
185 /// An empty buffer of this type's size
186 fn buffer() -> Self::Bytes;
187
188 /// Our value in big-endian bytes
189 fn to_be_bytes(self) -> Self::Bytes;
190
191 /// Our value in little-endian bytes
192 fn to_le_bytes(self) -> Self::Bytes;
193
194 /// Convert big-endian bytes to our value
195 fn from_be_bytes(bytes: Self::Bytes) -> Self;
196
197 /// Convert little-endian bytes to our value
198 fn from_le_bytes(bytes: Self::Bytes) -> Self;
199}
200
201macro_rules! define_primitive_numeric {
202 ($t:ty) => {
203 impl Primitive for $t {
204 type Bytes = [u8; mem::size_of::<$t>()];
205
206 #[inline(always)]
207 fn buffer() -> Self::Bytes {
208 [0; mem::size_of::<$t>()]
209 }
210 #[inline(always)]
211 fn to_be_bytes(self) -> Self::Bytes {
212 self.to_be_bytes()
213 }
214 #[inline(always)]
215 fn to_le_bytes(self) -> Self::Bytes {
216 self.to_le_bytes()
217 }
218 #[inline(always)]
219 fn from_be_bytes(bytes: Self::Bytes) -> Self {
220 <$t>::from_be_bytes(bytes)
221 }
222 #[inline(always)]
223 fn from_le_bytes(bytes: Self::Bytes) -> Self {
224 <$t>::from_le_bytes(bytes)
225 }
226 }
227 };
228}
229
230impl<const N: usize> Primitive for [u8; N] {
231 type Bytes = [u8; N];
232
233 #[inline(always)]
234 fn buffer() -> Self::Bytes {
235 [0; N]
236 }
237
238 #[inline(always)]
239 fn to_be_bytes(self) -> Self::Bytes {
240 self
241 }
242
243 #[inline(always)]
244 fn to_le_bytes(self) -> Self::Bytes {
245 self
246 }
247
248 #[inline(always)]
249 fn from_be_bytes(bytes: Self::Bytes) -> Self {
250 bytes
251 }
252
253 #[inline(always)]
254 fn from_le_bytes(bytes: Self::Bytes) -> Self {
255 bytes
256 }
257}
258
259/// This trait is for integer types which can be read or written
260/// to a bit stream as a partial amount of bits.
261///
262/// It unifies signed and unsigned integer types by delegating
263/// reads and writes to the signed and unsigned reading
264/// and writing methods as appropriate.
265pub trait Integer {
266 /// Reads a value of ourself from the stream
267 /// with the given number of bits.
268 ///
269 /// # Errors
270 ///
271 /// Passes along any I/O error from the underlying stream.
272 /// A compile-time error occurs if the given number of bits
273 /// is larger than our type.
274 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
275 where
276 Self: Sized;
277
278 /// Reads a value of ourself from the stream
279 /// with the given number of bits.
280 ///
281 /// # Errors
282 ///
283 /// Passes along any I/O error from the underlying stream.
284 /// Also returns an error if our type is too small
285 /// to hold the requested number of bits.
286 fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
287 where
288 R: BitRead + ?Sized,
289 Self: Sized;
290
291 /// Writes ourself to the stream using the given const number of bits.
292 ///
293 /// # Errors
294 ///
295 /// Passes along any I/O error from the underlying stream.
296 /// Returns an error if our value is too large
297 /// to fit the given number of bits.
298 /// A compile-time error occurs if the given number of bits
299 /// is larger than our type.
300 fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()>;
301
302 /// Writes ourself to the stream using the given number of bits.
303 ///
304 /// # Errors
305 ///
306 /// Passes along any I/O error from the underlying stream.
307 /// Returns an error if our value is too small
308 /// to hold the given number of bits.
309 /// Returns an error if our value is too large
310 /// to fit the given number of bits.
311 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
312 self,
313 writer: &mut W,
314 bits: BitCount<MAX>,
315 ) -> io::Result<()>;
316}
317
318/// Reading and writing booleans as `Integer` requires the number of bits to be 1.
319///
320/// This is more useful when combined with the fixed array target
321/// for reading blocks of bit flags.
322///
323/// # Example
324/// ```
325/// use bitstream_io::{BitReader, BitRead, BigEndian};
326///
327/// #[derive(Debug, PartialEq, Eq)]
328/// struct Flags {
329/// a: bool,
330/// b: bool,
331/// c: bool,
332/// d: bool,
333/// }
334///
335/// let data: &[u8] = &[0b1011_0000];
336/// let mut r = BitReader::endian(data, BigEndian);
337/// // note the number of bits must be 1 per read
338/// // while the quantity of flags is indicated by the array length
339/// let flags = r.read::<1, [bool; 4]>().map(|[a, b, c, d]| Flags { a, b, c, d }).unwrap();
340/// assert_eq!(flags, Flags { a: true, b: false, c: true, d: true });
341/// ```
342impl Integer for bool {
343 #[inline(always)]
344 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
345 where
346 Self: Sized,
347 {
348 const {
349 assert!(BITS == 1, "booleans require exactly 1 bit");
350 }
351
352 reader.read_bit()
353 }
354
355 fn read_var<const MAX: u32, R>(
356 reader: &mut R,
357 BitCount { bits }: BitCount<MAX>,
358 ) -> io::Result<Self>
359 where
360 R: BitRead + ?Sized,
361 Self: Sized,
362 {
363 if bits == 1 {
364 reader.read_bit()
365 } else {
366 Err(io::Error::new(
367 io::ErrorKind::InvalidInput,
368 "booleans require exactly 1 bit",
369 ))
370 }
371 }
372
373 #[inline(always)]
374 fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()> {
375 const {
376 assert!(BITS == 1, "booleans require exactly 1 bit");
377 }
378
379 writer.write_bit(self)
380 }
381
382 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
383 self,
384 writer: &mut W,
385 BitCount { bits }: BitCount<MAX>,
386 ) -> io::Result<()> {
387 if bits == 1 {
388 writer.write_bit(self)
389 } else {
390 Err(io::Error::new(
391 io::ErrorKind::InvalidInput,
392 "booleans require exactly 1 bit",
393 ))
394 }
395 }
396}
397
398impl<const SIZE: usize, I: Integer + Copy + Default> Integer for [I; SIZE] {
399 #[inline]
400 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
401 where
402 Self: Sized,
403 {
404 let mut a = [I::default(); SIZE];
405
406 a.iter_mut().try_for_each(|v| {
407 *v = reader.read::<BITS, I>()?;
408 Ok::<(), io::Error>(())
409 })?;
410
411 Ok(a)
412 }
413
414 #[inline]
415 fn read_var<const MAX: u32, R>(reader: &mut R, count: BitCount<MAX>) -> io::Result<Self>
416 where
417 R: BitRead + ?Sized,
418 Self: Sized,
419 {
420 let mut a = [I::default(); SIZE];
421
422 a.iter_mut().try_for_each(|v| {
423 *v = reader.read_counted(count)?;
424 Ok::<(), io::Error>(())
425 })?;
426
427 Ok(a)
428 }
429
430 #[inline]
431 fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()> {
432 IntoIterator::into_iter(self).try_for_each(|v| writer.write::<BITS, I>(v))
433 }
434
435 #[inline]
436 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
437 self,
438 writer: &mut W,
439 count: BitCount<MAX>,
440 ) -> io::Result<()> {
441 IntoIterator::into_iter(self).try_for_each(|v| writer.write_counted(count, v))
442 }
443}
444
445/// This trait extends many common integer types (both unsigned and signed)
446/// with a few trivial methods so that they can be used
447/// with the bitstream handling traits.
448pub trait Numeric:
449 Primitive
450 + Sized
451 + Copy
452 + Default
453 + Debug
454 + PartialOrd
455 + Shl<u32, Output = Self>
456 + ShlAssign<u32>
457 + Shr<u32, Output = Self>
458 + ShrAssign<u32>
459 + Rem<Self, Output = Self>
460 + RemAssign<Self>
461 + BitAnd<Self, Output = Self>
462 + BitOr<Self, Output = Self>
463 + BitOrAssign<Self>
464 + BitXor<Self, Output = Self>
465 + Not<Output = Self>
466 + Sub<Self, Output = Self>
467{
468 /// Size of type in bits
469 const BITS_SIZE: u32;
470
471 /// The value of 0 in this type
472 const ZERO: Self;
473
474 /// The value of 1 in this type
475 const ONE: Self;
476
477 /// Returns a `u8` value in this type
478 fn from_u8(u: u8) -> Self;
479
480 /// Assuming 0 <= value < 256, returns this value as a `u8` type
481 fn to_u8(self) -> u8;
482}
483
484macro_rules! define_numeric {
485 ($t:ty) => {
486 define_primitive_numeric!($t);
487
488 impl Numeric for $t {
489 const BITS_SIZE: u32 = mem::size_of::<$t>() as u32 * 8;
490
491 const ZERO: Self = 0;
492
493 const ONE: Self = 1;
494
495 #[inline(always)]
496 fn from_u8(u: u8) -> Self {
497 u as $t
498 }
499 #[inline(always)]
500 fn to_u8(self) -> u8 {
501 self as u8
502 }
503 }
504 };
505}
506
507/// This trait extends many common unsigned integer types
508/// so that they can be used with the bitstream handling traits.
509pub trait UnsignedInteger: Numeric {
510 /// This type's most-significant bit
511 const MSB_BIT: Self;
512
513 /// This type's least significant bit
514 const LSB_BIT: Self;
515
516 /// This type with all bits set
517 const ALL: Self;
518
519 /// The signed variant of ourself
520 type Signed: SignedInteger<Unsigned = Self>;
521
522 /// Given a twos-complement value,
523 /// return this value is a non-negative signed number.
524 /// The location of the sign bit depends on the stream's endianness
525 /// and is not stored in the result.
526 ///
527 /// # Example
528 /// ```
529 /// use bitstream_io::UnsignedInteger;
530 /// assert_eq!(0b00000001u8.as_non_negative(), 1i8);
531 /// ```
532 fn as_non_negative(self) -> Self::Signed;
533
534 /// Given a two-complement positive value and certain number of bits,
535 /// returns this value as a negative signed number.
536 /// The location of the sign bit depends on the stream's endianness
537 /// and is not stored in the result.
538 ///
539 /// # Example
540 /// ```
541 /// use bitstream_io::UnsignedInteger;
542 /// assert_eq!(0b01111111u8.as_negative(8), -1i8);
543 /// ```
544 fn as_negative(self, bits: u32) -> Self::Signed;
545
546 /// Given a two-complement positive value and certain number of bits,
547 /// returns this value as a negative number.
548 ///
549 /// # Example
550 /// ```
551 /// use bitstream_io::UnsignedInteger;
552 /// assert_eq!(0b01111111u8.as_negative_fixed::<8>(), -1i8);
553 /// ```
554 fn as_negative_fixed<const BITS: u32>(self) -> Self::Signed;
555
556 /// Checked shift left
557 fn checked_shl(self, rhs: u32) -> Option<Self>;
558
559 /// Checked shift right
560 fn checked_shr(self, rhs: u32) -> Option<Self>;
561
562 /// Shift left up to our length in bits
563 ///
564 /// If rhs equals our length in bits, returns default
565 fn shl_default(self, rhs: u32) -> Self {
566 self.checked_shl(rhs).unwrap_or(Self::ZERO)
567 }
568
569 /// Shift left up to our length in bits
570 ///
571 /// If rhs equals our length in bits, returns zero
572 fn shr_default(self, rhs: u32) -> Self {
573 self.checked_shr(rhs).unwrap_or(Self::ZERO)
574 }
575}
576
577macro_rules! define_unsigned_integer {
578 ($t:ty, $s:ty) => {
579 define_numeric!($t);
580
581 impl UnsignedInteger for $t {
582 type Signed = $s;
583
584 const MSB_BIT: Self = 1 << (Self::BITS_SIZE - 1);
585
586 const LSB_BIT: Self = 1;
587
588 const ALL: Self = <$t>::MAX;
589
590 #[inline(always)]
591 fn as_non_negative(self) -> Self::Signed {
592 self as $s
593 }
594 #[inline(always)]
595 fn as_negative(self, bits: u32) -> Self::Signed {
596 (self as $s) + (-1 << (bits - 1))
597 }
598 #[inline(always)]
599 fn as_negative_fixed<const BITS: u32>(self) -> Self::Signed {
600 (self as $s) + (-1 << (BITS - 1))
601 }
602 #[inline(always)]
603 fn checked_shl(self, rhs: u32) -> Option<Self> {
604 self.checked_shl(rhs)
605 }
606 #[inline(always)]
607 fn checked_shr(self, rhs: u32) -> Option<Self> {
608 self.checked_shr(rhs)
609 }
610 }
611
612 impl Integer for $t {
613 #[inline(always)]
614 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
615 where
616 Self: Sized,
617 {
618 reader.read_unsigned::<BITS, _>()
619 }
620
621 #[inline(always)]
622 fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
623 where
624 R: BitRead + ?Sized,
625 Self: Sized,
626 {
627 reader.read_unsigned_counted::<MAX, _>(bits)
628 }
629
630 #[inline(always)]
631 fn write<const BITS: u32, W: BitWrite + ?Sized>(
632 self,
633 writer: &mut W,
634 ) -> io::Result<()> {
635 writer.write_unsigned::<BITS, _>(self)
636 }
637
638 #[inline(always)]
639 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
640 self,
641 writer: &mut W,
642 bits: BitCount<MAX>,
643 ) -> io::Result<()> {
644 writer.write_unsigned_counted(bits, self)
645 }
646 }
647
648 /// Unsigned NonZero types increment their value by 1
649 /// when being read and decrement it by 1
650 /// when being written.
651 ///
652 /// # Examples
653 /// ```
654 /// use bitstream_io::{BitReader, BitRead, BigEndian};
655 /// use core::num::NonZero;
656 ///
657 /// let data: &[u8] = &[0b001_00000];
658 /// // reading a regular u8 in 3 bits yields 1
659 /// assert_eq!(BitReader::endian(data, BigEndian).read::<3, u8>().unwrap(), 1);
660 /// // reading a NonZero<u8> in 3 bits of the same data yields 2
661 /// assert_eq!(BitReader::endian(data, BigEndian).read::<3, NonZero<u8>>().unwrap().get(), 2);
662 /// ```
663 ///
664 /// ```
665 /// use bitstream_io::{BitWriter, BitWrite, BigEndian};
666 /// use core::num::NonZero;
667 ///
668 /// let mut w = BitWriter::endian(vec![], BigEndian);
669 /// // writing 1 as a regular u8 in 3 bits
670 /// w.write::<3, u8>(1).unwrap();
671 /// w.byte_align();
672 /// assert_eq!(w.into_writer(), &[0b001_00000]);
673 ///
674 /// let mut w = BitWriter::endian(vec![], BigEndian);
675 /// // writing 1 as a NonZero<u8> in 3 bits
676 /// w.write::<3, NonZero<u8>>(NonZero::new(1).unwrap()).unwrap();
677 /// w.byte_align();
678 /// assert_eq!(w.into_writer(), &[0b000_00000]);
679 /// ```
680 impl Integer for NonZero<$t> {
681 #[inline]
682 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
683 where
684 Self: Sized,
685 {
686 const {
687 assert!(
688 BITS < <$t>::BITS_SIZE,
689 "BITS must be less than the type's size in bits"
690 );
691 }
692
693 <$t as Integer>::read::<BITS, R>(reader).map(|u| NonZero::new(u + 1).unwrap())
694 }
695
696 #[inline]
697 fn read_var<const MAX: u32, R>(
698 reader: &mut R,
699 count @ BitCount { bits }: BitCount<MAX>,
700 ) -> io::Result<Self>
701 where
702 R: BitRead + ?Sized,
703 Self: Sized,
704 {
705 if MAX < <$t>::BITS_SIZE || bits < <$t>::BITS_SIZE {
706 <$t as Integer>::read_var::<MAX, R>(reader, count)
707 .map(|u| NonZero::new(u + 1).unwrap())
708 } else {
709 Err(io::Error::new(
710 io::ErrorKind::InvalidInput,
711 "bit count must be less than the type's size in bits",
712 ))
713 }
714 }
715
716 #[inline]
717 fn write<const BITS: u32, W: BitWrite + ?Sized>(
718 self,
719 writer: &mut W,
720 ) -> io::Result<()> {
721 const {
722 assert!(
723 BITS < <$t>::BITS_SIZE,
724 "BITS must be less than the type's size in bits"
725 );
726 }
727
728 <$t as Integer>::write::<BITS, W>(self.get() - 1, writer)
729 }
730
731 #[inline]
732 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
733 self,
734 writer: &mut W,
735 count @ BitCount { bits }: BitCount<MAX>,
736 ) -> io::Result<()> {
737 if MAX < <$t>::BITS_SIZE || bits < <$t>::BITS_SIZE {
738 <$t as Integer>::write_var::<MAX, W>(self.get() - 1, writer, count)
739 } else {
740 Err(io::Error::new(
741 io::ErrorKind::InvalidInput,
742 "bit count must be less than the type's size in bits",
743 ))
744 }
745 }
746 }
747
748 impl Integer for Option<NonZero<$t>> {
749 #[inline]
750 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
751 where
752 Self: Sized,
753 {
754 <$t as Integer>::read::<BITS, R>(reader).map(NonZero::new)
755 }
756
757 #[inline]
758 fn read_var<const MAX: u32, R>(reader: &mut R, count: BitCount<MAX>) -> io::Result<Self>
759 where
760 R: BitRead + ?Sized,
761 Self: Sized,
762 {
763 <$t as Integer>::read_var::<MAX, R>(reader, count).map(NonZero::new)
764 }
765
766 #[inline]
767 fn write<const BITS: u32, W: BitWrite + ?Sized>(
768 self,
769 writer: &mut W,
770 ) -> io::Result<()> {
771 <$t as Integer>::write::<BITS, W>(self.map(|n| n.get()).unwrap_or(0), writer)
772 }
773
774 #[inline]
775 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
776 self,
777 writer: &mut W,
778 count: BitCount<MAX>,
779 ) -> io::Result<()> {
780 <$t as Integer>::write_var::<MAX, W>(
781 self.map(|n| n.get()).unwrap_or(0),
782 writer,
783 count,
784 )
785 }
786 }
787 };
788}
789
790/// This trait extends many common signed integer types
791/// so that they can be used with the bitstream handling traits.
792///
793/// This trait was formerly named `SignedNumeric` in 2.X.X code.
794/// If backwards-compatibility is needed one can
795/// import `SignedInteger` as `SignedNumeric`.
796pub trait SignedInteger: Numeric {
797 /// The unsigned variant of ourself
798 type Unsigned: UnsignedInteger<Signed = Self>;
799
800 /// Returns true if this value is negative
801 ///
802 /// # Example
803 /// ```
804 /// use bitstream_io::SignedInteger;
805 /// assert!(!1i8.is_negative());
806 /// assert!((-1i8).is_negative());
807 /// ```
808 fn is_negative(self) -> bool;
809
810 /// Returns ourself as a non-negative value.
811 /// The location of the sign bit depends on the stream's endianness
812 /// and is not stored in the result.
813 ///
814 /// # Example
815 /// ```
816 /// use bitstream_io::SignedInteger;
817 /// assert_eq!(1i8.as_non_negative(), 0b00000001u8);
818 /// ```
819 fn as_non_negative(self) -> Self::Unsigned;
820
821 /// Given a negative value and a certain number of bits,
822 /// returns this value as a twos-complement positive number.
823 /// The location of the sign bit depends on the stream's endianness
824 /// and is not stored in the result.
825 ///
826 /// # Example
827 /// ```
828 /// use bitstream_io::SignedInteger;
829 /// assert_eq!((-1i8).as_negative(8), 0b01111111u8);
830 /// ```
831 fn as_negative(self, bits: u32) -> Self::Unsigned;
832
833 /// Given a negative value and a certain number of bits,
834 /// returns this value as a twos-complement positive number.
835 ///
836 /// # Example
837 /// ```
838 /// use bitstream_io::SignedInteger;
839 /// assert_eq!((-1i8).as_negative_fixed::<8>(), 0b01111111u8);
840 /// ```
841 fn as_negative_fixed<const BITS: u32>(self) -> Self::Unsigned;
842}
843
844macro_rules! define_signed_integer {
845 ($t:ty, $u:ty) => {
846 define_numeric!($t);
847
848 impl SignedInteger for $t {
849 type Unsigned = $u;
850
851 #[inline(always)]
852 fn is_negative(self) -> bool {
853 self.is_negative()
854 }
855 fn as_non_negative(self) -> Self::Unsigned {
856 self as $u
857 }
858 fn as_negative(self, bits: u32) -> Self::Unsigned {
859 (self - (-1 << (bits - 1))) as $u
860 }
861 fn as_negative_fixed<const BITS: u32>(self) -> Self::Unsigned {
862 (self - (-1 << (BITS - 1))) as $u
863 }
864 }
865
866 impl Integer for $t {
867 #[inline(always)]
868 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
869 where
870 Self: Sized,
871 {
872 reader.read_signed::<BITS, _>()
873 }
874
875 #[inline(always)]
876 fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
877 where
878 R: BitRead + ?Sized,
879 Self: Sized,
880 {
881 reader.read_signed_counted::<MAX, _>(bits)
882 }
883
884 #[inline(always)]
885 fn write<const BITS: u32, W: BitWrite + ?Sized>(
886 self,
887 writer: &mut W,
888 ) -> io::Result<()> {
889 writer.write_signed::<BITS, _>(self)
890 }
891
892 #[inline(always)]
893 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
894 self,
895 writer: &mut W,
896 bits: BitCount<MAX>,
897 ) -> io::Result<()> {
898 writer.write_signed_counted::<MAX, _>(bits, self)
899 }
900 }
901 };
902}
903
904define_unsigned_integer!(u8, i8);
905define_unsigned_integer!(u16, i16);
906define_unsigned_integer!(u32, i32);
907define_unsigned_integer!(u64, i64);
908define_unsigned_integer!(u128, i128);
909
910define_signed_integer!(i8, u8);
911define_signed_integer!(i16, u16);
912define_signed_integer!(i32, u32);
913define_signed_integer!(i64, u64);
914define_signed_integer!(i128, u128);
915
916define_primitive_numeric!(f32);
917define_primitive_numeric!(f64);
918
919mod private {
920 use crate::{
921 io, BitCount, BitRead, BitWrite, Primitive, SignedBitCount, SignedInteger, UnsignedInteger,
922 };
923
924 pub trait Endianness: Sized {
925 /// Pops the next bit from the queue,
926 /// repleneshing it from the given reader if necessary
927 fn pop_bit_refill<R>(
928 reader: &mut R,
929 queue_value: &mut u8,
930 queue_bits: &mut u32,
931 ) -> io::Result<bool>
932 where
933 R: io::Read;
934
935 /// Pops the next unary value from the source until
936 /// `STOP_BIT` is encountered, replenishing it from the given
937 /// closure if necessary.
938 ///
939 /// `STOP_BIT` must be 0 or 1.
940 fn pop_unary<const STOP_BIT: u8, R>(
941 reader: &mut R,
942 queue_value: &mut u8,
943 queue_bits: &mut u32,
944 ) -> io::Result<u32>
945 where
946 R: io::Read;
947
948 /// Pushes the next bit into the queue,
949 /// and returns `Some` value if the queue is full.
950 fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8>;
951
952 /// For performing bulk reads from a bit source to an output type.
953 fn read_bits<const MAX: u32, R, U>(
954 reader: &mut R,
955 queue_value: &mut u8,
956 queue_bits: &mut u32,
957 count: BitCount<MAX>,
958 ) -> io::Result<U>
959 where
960 R: io::Read,
961 U: UnsignedInteger;
962
963 /// For performing bulk reads from a bit source to an output type.
964 fn read_bits_fixed<const BITS: u32, R, U>(
965 reader: &mut R,
966 queue_value: &mut u8,
967 queue_bits: &mut u32,
968 ) -> io::Result<U>
969 where
970 R: io::Read,
971 U: UnsignedInteger;
972
973 /// For performing bulk writes of a type to a bit sink.
974 fn write_bits<const MAX: u32, W, U>(
975 writer: &mut W,
976 queue_value: &mut u8,
977 queue_bits: &mut u32,
978 count: BitCount<MAX>,
979 value: U,
980 ) -> io::Result<()>
981 where
982 W: io::Write,
983 U: UnsignedInteger;
984
985 /// For performing bulk writes of a type to a bit sink.
986 fn write_bits_fixed<const BITS: u32, W, U>(
987 writer: &mut W,
988 queue_value: &mut u8,
989 queue_bits: &mut u32,
990 value: U,
991 ) -> io::Result<()>
992 where
993 W: io::Write,
994 U: UnsignedInteger;
995
996 /// Reads signed value from reader in this endianness
997 #[inline]
998 fn read_signed<const MAX: u32, R, S>(
999 r: &mut R,
1000 count @ BitCount { bits }: BitCount<MAX>,
1001 ) -> io::Result<S>
1002 where
1003 R: BitRead,
1004 S: SignedInteger,
1005 {
1006 if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
1007 Self::read_signed_counted(
1008 r,
1009 count.signed_count().ok_or(io::Error::new(
1010 io::ErrorKind::InvalidInput,
1011 "signed reads need at least 1 bit for sign",
1012 ))?,
1013 )
1014 } else {
1015 Err(io::Error::new(
1016 io::ErrorKind::InvalidInput,
1017 "excessive bits for type read",
1018 ))
1019 }
1020 }
1021
1022 /// Reads signed value from reader in this endianness
1023 #[inline]
1024 fn read_signed_fixed<R, const BITS: u32, S>(r: &mut R) -> io::Result<S>
1025 where
1026 R: BitRead,
1027 S: SignedInteger,
1028 {
1029 let count = const {
1030 assert!(BITS <= S::BITS_SIZE, "excessive bits for type read");
1031 let count = BitCount::<BITS>::new::<BITS>().signed_count();
1032 assert!(count.is_some(), "signed reads need at least 1 bit for sign");
1033 count.unwrap()
1034 };
1035
1036 Self::read_signed_counted(r, count)
1037 }
1038
1039 /// Reads signed value from reader in this endianness
1040 fn read_signed_counted<const MAX: u32, R, S>(
1041 r: &mut R,
1042 bits: SignedBitCount<MAX>,
1043 ) -> io::Result<S>
1044 where
1045 R: BitRead,
1046 S: SignedInteger;
1047
1048 /// Writes signed value to writer in this endianness
1049 fn write_signed<const MAX: u32, W, S>(
1050 w: &mut W,
1051 count: BitCount<MAX>,
1052 value: S,
1053 ) -> io::Result<()>
1054 where
1055 W: BitWrite,
1056 S: SignedInteger,
1057 {
1058 Self::write_signed_counted(
1059 w,
1060 count.signed_count().ok_or(io::Error::new(
1061 io::ErrorKind::InvalidInput,
1062 "signed writes need at least 1 bit for sign",
1063 ))?,
1064 value,
1065 )
1066 }
1067
1068 /// Writes signed value to writer in this endianness
1069 fn write_signed_fixed<W, const BITS: u32, S>(w: &mut W, value: S) -> io::Result<()>
1070 where
1071 W: BitWrite,
1072 S: SignedInteger,
1073 {
1074 let count = const {
1075 assert!(BITS <= S::BITS_SIZE, "excessive bits for type written");
1076 let count = BitCount::<BITS>::new::<BITS>().signed_count();
1077 assert!(
1078 count.is_some(),
1079 "signed writes need at least 1 bit for sign"
1080 );
1081 count.unwrap()
1082 };
1083
1084 Self::write_signed_counted(w, count, value)
1085 }
1086
1087 /// Writes signed value to writer in this endianness
1088 fn write_signed_counted<const MAX: u32, W, S>(
1089 w: &mut W,
1090 bits: SignedBitCount<MAX>,
1091 value: S,
1092 ) -> io::Result<()>
1093 where
1094 W: BitWrite,
1095 S: SignedInteger;
1096
1097 /// Reads whole set of bytes to output buffer
1098 fn read_bytes<const CHUNK_SIZE: usize, R>(
1099 reader: &mut R,
1100 queue_value: &mut u8,
1101 queue_bits: u32,
1102 buf: &mut [u8],
1103 ) -> io::Result<()>
1104 where
1105 R: io::Read;
1106
1107 /// Writes whole set of bytes to output buffer
1108 fn write_bytes<const CHUNK_SIZE: usize, W>(
1109 writer: &mut W,
1110 queue_value: &mut u8,
1111 queue_bits: u32,
1112 buf: &[u8],
1113 ) -> io::Result<()>
1114 where
1115 W: io::Write;
1116
1117 /// Converts a primitive's byte buffer to a primitive
1118 fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P;
1119
1120 /// Converts a primitive to a primitive's byte buffer
1121 fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes;
1122
1123 /// Reads convertable numeric value from reader in this endianness
1124 #[deprecated(since = "4.0.0")]
1125 fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
1126 where
1127 R: BitRead,
1128 V: Primitive;
1129
1130 /// Writes convertable numeric value to writer in this endianness
1131 #[deprecated(since = "4.0.0")]
1132 fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
1133 where
1134 W: BitWrite,
1135 V: Primitive;
1136 }
1137}
1138
1139/// A stream's endianness, or byte order, for determining
1140/// how bits should be read.
1141///
1142/// It comes in `BigEndian` and `LittleEndian` varieties
1143/// (which may be shortened to `BE` and `LE`)
1144/// and is not something programmers should implement directly.
1145pub trait Endianness: private::Endianness {}
1146
1147#[inline(always)]
1148fn read_byte<R>(mut reader: R) -> io::Result<u8>
1149where
1150 R: io::Read,
1151{
1152 let mut byte = 0;
1153 reader
1154 .read_exact(core::slice::from_mut(&mut byte))
1155 .map(|()| byte)
1156}
1157
1158#[inline(always)]
1159fn write_byte<W>(mut writer: W, byte: u8) -> io::Result<()>
1160where
1161 W: io::Write,
1162{
1163 writer.write_all(core::slice::from_ref(&byte))
1164}
1165
1166/// A number of bits to be consumed or written, with a known maximum
1167///
1168/// Although [`BitRead::read`] and [`BitWrite::write`] should be
1169/// preferred when the number of bits is fixed and known at compile-time -
1170/// because they can validate the bit count is less than or equal
1171/// to the type's size in bits at compile-time -
1172/// there are many instances where bit count is dynamic and
1173/// determined by the file format itself.
1174/// But when using [`BitRead::read_var`] or [`BitWrite::write_var`]
1175/// we must pessimistically assume any number of bits as an argument
1176/// and validate that the number of bits is not larger than the
1177/// type being read or written on every call.
1178///
1179/// ```
1180/// use bitstream_io::{BitRead, BitReader, BigEndian};
1181///
1182/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1183/// let mut r = BitReader::endian(data, BigEndian);
1184/// // our bit count is a 3 bit value
1185/// let count = r.read::<3, u32>().unwrap();
1186/// // that count indicates we need to read 4 bits (0b100)
1187/// assert_eq!(count, 4);
1188/// // read the first 4-bit value
1189/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b0001);
1190/// // read the second 4-bit value
1191/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b1111);
1192/// // read the third 4-bit value
1193/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b0110);
1194/// ```
1195///
1196/// In the preceding example, even though we know `count` is a
1197/// 3 bit value whose maximum value will never be greater than 7,
1198/// the subsequent `read_var` calls have no way to know that.
1199/// They must assume `count` could be 9, or `u32::MAX` or any other `u32` value
1200/// and validate the count is not larger than the `u8` types we're reading.
1201///
1202/// But we can convert our example to use the `BitCount` type:
1203///
1204/// ```
1205/// use bitstream_io::{BitRead, BitReader, BigEndian, BitCount};
1206///
1207/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1208/// let mut r = BitReader::endian(data, BigEndian);
1209/// // our bit count is a 3 bit value with a maximum value of 7
1210/// let count = r.read_count::<0b111>().unwrap();
1211/// // that count indicates we need to read 4 bits (0b100)
1212/// assert_eq!(count, BitCount::<7>::new::<4>());
1213/// // read the first 4-bit value
1214/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b0001);
1215/// // read the second 4-bit value
1216/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b1111);
1217/// // read the third 4-bit value
1218/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b0110);
1219/// ```
1220///
1221/// Because the [`BitRead::read_counted`] methods know at compile-time
1222/// that the bit count will be larger than 7, that check can be eliminated
1223/// simply by taking advantage of information we already know.
1224///
1225/// Leveraging the `BitCount` type also allows us to reason about
1226/// bit counts in a more formal way, and use checked permutation methods
1227/// to modify them while ensuring they remain constrained by
1228/// the file format's requirements.
1229#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1230pub struct BitCount<const MAX: u32> {
1231 // The amount of bits may be less than or equal to the maximum,
1232 // but never more.
1233 bits: u32,
1234}
1235
1236impl<const MAX: u32> BitCount<MAX> {
1237 /// Builds a bit count from a constant number
1238 /// of bits, which must not be greater than `MAX`.
1239 ///
1240 /// Intended to be used for defining constants.
1241 ///
1242 /// Use `TryFrom` to conditionally build
1243 /// counts from values at runtime.
1244 ///
1245 /// # Examples
1246 ///
1247 /// ```
1248 /// use bitstream_io::{BitReader, BitRead, BigEndian, BitCount};
1249 /// let data: &[u8] = &[0b111_00000];
1250 /// let mut r = BitReader::endian(data, BigEndian);
1251 /// // reading 3 bits from a stream out of a maximum of 8
1252 /// // doesn't require checking that the bit count is larger
1253 /// // than a u8 at runtime because specifying the maximum of 8
1254 /// // guarantees our bit count will not be larger than 8
1255 /// assert_eq!(r.read_counted::<8, u8>(BitCount::new::<3>()).unwrap(), 0b111);
1256 /// ```
1257 ///
1258 /// ```rust,compile_fail
1259 /// use bitstream_io::BitCount;
1260 /// // trying to build a count of 10 with a maximum of 8
1261 /// // fails to compile at all
1262 /// let count = BitCount::<8>::new::<10>();
1263 /// ```
1264 pub const fn new<const BITS: u32>() -> Self {
1265 const {
1266 assert!(BITS <= MAX, "BITS must be <= MAX");
1267 }
1268
1269 Self { bits: BITS }
1270 }
1271
1272 /// Add a number of bits to our count,
1273 /// returning a new count with a new maximum.
1274 ///
1275 /// Returns `None` if the new count goes above our new maximum.
1276 ///
1277 /// # Examples
1278 ///
1279 /// ```
1280 /// use bitstream_io::BitCount;
1281 ///
1282 /// let count = BitCount::<2>::new::<1>();
1283 /// // adding 2 to 1 and increasing the max to 3 yields a new count of 3
1284 /// assert_eq!(count.checked_add::<3>(2), Some(BitCount::<3>::new::<3>()));
1285 /// // adding 2 to 1 without increasing the max yields None
1286 /// assert_eq!(count.checked_add::<2>(2), None);
1287 /// ```
1288 #[inline]
1289 pub const fn checked_add<const NEW_MAX: u32>(self, bits: u32) -> Option<BitCount<NEW_MAX>> {
1290 match self.bits.checked_add(bits) {
1291 Some(bits) if bits <= NEW_MAX => Some(BitCount { bits }),
1292 _ => None,
1293 }
1294 }
1295
1296 /// Subtracts a number of bits from our count,
1297 /// returning a new count with a new maximum.
1298 ///
1299 /// Returns `None` if the new count goes below 0
1300 /// or below our new maximum.
1301 ///
1302 /// # Example
1303 /// ```
1304 /// use bitstream_io::BitCount;
1305 /// let count = BitCount::<5>::new::<5>();
1306 /// // subtracting 1 from 5 yields a new count of 4
1307 /// assert_eq!(count.checked_sub::<5>(1), Some(BitCount::<5>::new::<4>()));
1308 /// // subtracting 6 from 5 yields None
1309 /// assert!(count.checked_sub::<5>(6).is_none());
1310 /// // subtracting 1 with a new maximum of 3 also yields None
1311 /// // because 4 is larger than the maximum of 3
1312 /// assert!(count.checked_sub::<3>(1).is_none());
1313 /// ```
1314 #[inline]
1315 pub const fn checked_sub<const NEW_MAX: u32>(self, bits: u32) -> Option<BitCount<NEW_MAX>> {
1316 match self.bits.checked_sub(bits) {
1317 Some(bits) if bits <= NEW_MAX => Some(BitCount { bits }),
1318 _ => None,
1319 }
1320 }
1321
1322 /// Attempt to convert our count to a count with a new
1323 /// bit count and new maximum.
1324 ///
1325 /// Returns `Some(count)` if the updated number of bits
1326 /// is less than or equal to the new maximum.
1327 /// Returns `None` if not.
1328 ///
1329 /// # Examples
1330 /// ```
1331 /// use bitstream_io::BitCount;
1332 ///
1333 /// let count = BitCount::<5>::new::<5>();
1334 /// // muliplying 5 bits by 2 with a new max of 10 is ok
1335 /// assert_eq!(
1336 /// count.try_map::<10, _>(|i| i.checked_mul(2)),
1337 /// Some(BitCount::<10>::new::<10>()),
1338 /// );
1339 ///
1340 /// // multiplying 5 bits by 3 with a new max of 10 overflows
1341 /// assert_eq!(count.try_map::<10, _>(|i| i.checked_mul(3)), None);
1342 /// ```
1343 #[inline]
1344 pub fn try_map<const NEW_MAX: u32, F>(self, f: F) -> Option<BitCount<NEW_MAX>>
1345 where
1346 F: FnOnce(u32) -> Option<u32>,
1347 {
1348 f(self.bits)
1349 .filter(|bits| *bits <= NEW_MAX)
1350 .map(|bits| BitCount { bits })
1351 }
1352
1353 /// Returns our maximum bit count
1354 ///
1355 /// # Example
1356 /// ```
1357 /// use bitstream_io::BitCount;
1358 ///
1359 /// let count = BitCount::<10>::new::<5>();
1360 /// assert_eq!(count.max(), 10);
1361 /// ```
1362 #[inline(always)]
1363 pub const fn max(&self) -> u32 {
1364 MAX
1365 }
1366
1367 /// Returns signed count if our bit count is greater than 0
1368 ///
1369 /// # Example
1370 ///
1371 /// ```
1372 /// use bitstream_io::{BitCount, SignedBitCount};
1373 ///
1374 /// let count = BitCount::<10>::new::<5>();
1375 /// assert_eq!(count.signed_count(), Some(SignedBitCount::<10>::new::<5>()));
1376 ///
1377 /// let count = BitCount::<10>::new::<0>();
1378 /// assert_eq!(count.signed_count(), None);
1379 /// ```
1380 #[inline(always)]
1381 pub const fn signed_count(&self) -> Option<SignedBitCount<MAX>> {
1382 match self.bits.checked_sub(1) {
1383 Some(bits) => Some(SignedBitCount {
1384 bits: *self,
1385 unsigned: BitCount { bits },
1386 }),
1387 None => None,
1388 }
1389 }
1390}
1391
1392impl<const MAX: u32> core::convert::TryFrom<u32> for BitCount<MAX> {
1393 type Error = u32;
1394
1395 /// Attempts to convert a `u32` bit count to a `BitCount`
1396 ///
1397 /// Attempting a bit maximum bit count larger than the
1398 /// largest supported type is a compile-time error
1399 ///
1400 /// # Examples
1401 /// ```
1402 /// use bitstream_io::BitCount;
1403 /// use std::convert::TryInto;
1404 ///
1405 /// assert_eq!(8u32.try_into(), Ok(BitCount::<8>::new::<8>()));
1406 /// assert_eq!(9u32.try_into(), Err::<BitCount<8>, _>(9));
1407 /// ```
1408 fn try_from(bits: u32) -> Result<Self, Self::Error> {
1409 (bits <= MAX).then_some(Self { bits }).ok_or(bits)
1410 }
1411}
1412
1413impl BitCount<{ u32::MAX }> {
1414 /// Builds a bit count where the maximum bits is unknown.
1415 ///
1416 /// # Example
1417 /// ```
1418 /// use bitstream_io::BitCount;
1419 /// assert_eq!(BitCount::unknown(5), BitCount::<{ u32::MAX }>::new::<5>());
1420 /// ```
1421 pub const fn unknown(bits: u32) -> Self {
1422 Self { bits }
1423 }
1424}
1425
1426#[test]
1427fn test_unknown_bitcount() {
1428 let count = BitCount::unknown(u32::MAX);
1429 assert!(u32::from(count) <= count.max());
1430}
1431
1432impl<const MAX: u32> From<BitCount<MAX>> for u32 {
1433 #[inline(always)]
1434 fn from(BitCount { bits }: BitCount<MAX>) -> u32 {
1435 bits
1436 }
1437}
1438
1439/// A number of bits to be read or written for signed integers, with a known maximum
1440///
1441/// This is closely related to the [`BitCount`] type, but further constrained
1442/// to have a minimum value of 1 - because signed values require at least
1443/// 1 bit for the sign.
1444///
1445/// Let's start with a basic example:
1446///
1447/// ```
1448/// use bitstream_io::{BitRead, BitReader, BigEndian};
1449///
1450/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1451/// let mut r = BitReader::endian(data, BigEndian);
1452/// // our bit count is a 3 bit value
1453/// let count = r.read::<3, u32>().unwrap();
1454/// // that count indicates we need to read 4 bits (0b100)
1455/// assert_eq!(count, 4);
1456/// // read the first 4-bit signed value
1457/// assert_eq!(r.read_var::<i8>(count).unwrap(), 1);
1458/// // read the second 4-bit signed value
1459/// assert_eq!(r.read_var::<i8>(count).unwrap(), -1);
1460/// // read the third 4-bit signed value
1461/// assert_eq!(r.read_var::<i8>(count).unwrap(), 6);
1462/// ```
1463///
1464/// In the preceding example, even though we know `count` is a
1465/// 3 bit value whose maximum value will never be greater than 7,
1466/// the subsequent `read_var` calls have no way to know that.
1467/// They must assume `count` could be 9, or `u32::MAX` or any other `u32` value
1468/// and validate the count is not larger than the `i8` types we're reading
1469/// while also greater than 0 because `i8` requires a sign bit.
1470///
1471/// But we can convert our example to use the `SignedBitCount` type:
1472/// ```
1473/// use bitstream_io::{BitRead, BitReader, BigEndian, SignedBitCount};
1474///
1475/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1476/// let mut r = BitReader::endian(data, BigEndian);
1477/// // our bit count is a 3 bit value with a maximum value of 7
1478/// let count = r.read_count::<0b111>().unwrap();
1479/// // convert that count to a signed bit count,
1480/// // which guarantees its value is greater than 0
1481/// let count = count.signed_count().unwrap();
1482/// // that count indicates we need to read 4 bits (0b100)
1483/// assert_eq!(count, SignedBitCount::<7>::new::<4>());
1484/// // read the first 4-bit value
1485/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), 1);
1486/// // read the second 4-bit value
1487/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), -1);
1488/// // read the third 4-bit value
1489/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), 6);
1490/// ```
1491///
1492/// Because the [`BitRead::read_signed_counted`] methods know at compile-time
1493/// that the bit count will be larger than 7, that check can be eliminated
1494/// simply by taking advantage of information we already know.
1495///
1496/// Leveraging the `SignedBitCount` type also allows us to reason about
1497/// bit counts in a more formal way, and use checked permutation methods
1498/// to modify them while ensuring they remain constrained by
1499/// the file format's requirements.
1500#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1501pub struct SignedBitCount<const MAX: u32> {
1502 // the whole original bit count
1503 bits: BitCount<MAX>,
1504 // a bit count with one bit removed for the sign
1505 unsigned: BitCount<MAX>,
1506}
1507
1508impl<const MAX: u32> SignedBitCount<MAX> {
1509 /// Builds a signed bit count from a constant number
1510 /// of bits, which must be greater than 0 and
1511 /// not be greater than `MAX`.
1512 ///
1513 /// Intended to be used for defining constants.
1514 ///
1515 /// Use `TryFrom` to conditionally build
1516 /// counts from values at runtime.
1517 ///
1518 /// # Examples
1519 ///
1520 /// ```
1521 /// use bitstream_io::{BitReader, BitRead, BigEndian, SignedBitCount};
1522 /// let data: &[u8] = &[0b111_00000];
1523 /// let mut r = BitReader::endian(data, BigEndian);
1524 /// // reading 3 bits from a stream out of a maximum of 8
1525 /// // doesn't require checking that the bit count is larger
1526 /// // than a u8 at runtime because specifying the maximum of 8
1527 /// // guarantees our bit count will not be larger than 8
1528 /// assert_eq!(r.read_signed_counted::<8, i8>(SignedBitCount::new::<3>()).unwrap(), -1);
1529 /// ```
1530 ///
1531 /// ```rust,compile_fail
1532 /// use bitstream_io::SignedBitCount;
1533 /// // trying to build a count of 10 with a maximum of 8
1534 /// // fails to compile at all
1535 /// let count = SignedBitCount::<8>::new::<10>();
1536 /// ```
1537 ///
1538 /// ```rust,compile_fail
1539 /// use bitstream_io::SignedBitCount;
1540 /// // trying to build a count of 0 also fails to compile
1541 /// let count = SignedBitCount::<8>::new::<0>();
1542 /// ```
1543 pub const fn new<const BITS: u32>() -> Self {
1544 const {
1545 assert!(BITS > 0, "BITS must be > 0");
1546 }
1547
1548 Self {
1549 bits: BitCount::new::<BITS>(),
1550 unsigned: BitCount { bits: BITS - 1 },
1551 }
1552 }
1553
1554 /// Add a number of bits to our count,
1555 /// returning a new count with a new maximum.
1556 ///
1557 /// Returns `None` if the new count goes above our new maximum.
1558 ///
1559 /// # Examples
1560 ///
1561 /// ```
1562 /// use bitstream_io::SignedBitCount;
1563 ///
1564 /// let count = SignedBitCount::<2>::new::<1>();
1565 /// // adding 2 to 1 and increasing the max to 3 yields a new count of 3
1566 /// assert_eq!(count.checked_add::<3>(2), Some(SignedBitCount::<3>::new::<3>()));
1567 /// // adding 2 to 1 without increasing the max yields None
1568 /// assert_eq!(count.checked_add::<2>(2), None);
1569 /// ```
1570 #[inline]
1571 pub const fn checked_add<const NEW_MAX: u32>(
1572 self,
1573 bits: u32,
1574 ) -> Option<SignedBitCount<NEW_MAX>> {
1575 match self.bits.checked_add(bits) {
1576 Some(bits_new) => match self.unsigned.checked_add(bits) {
1577 Some(unsigned) => Some(SignedBitCount {
1578 bits: bits_new,
1579 unsigned,
1580 }),
1581 None => None,
1582 },
1583 None => None,
1584 }
1585 }
1586
1587 /// Subtracts a number of bits from our count,
1588 /// returning a new count with a new maximum.
1589 ///
1590 /// Returns `None` if the new count goes below 1
1591 /// or below our new maximum.
1592 ///
1593 /// # Example
1594 /// ```
1595 /// use bitstream_io::SignedBitCount;
1596 /// let count = SignedBitCount::<5>::new::<5>();
1597 /// // subtracting 1 from 5 yields a new count of 4
1598 /// assert_eq!(count.checked_sub::<5>(1), Some(SignedBitCount::<5>::new::<4>()));
1599 /// // subtracting 6 from 5 yields None
1600 /// assert!(count.checked_sub::<5>(6).is_none());
1601 /// // subtracting 1 with a new maximum of 3 also yields None
1602 /// // because 4 is larger than the maximum of 3
1603 /// assert!(count.checked_sub::<3>(1).is_none());
1604 /// // subtracting 5 from 5 also yields None
1605 /// // because SignedBitCount always requires 1 bit for the sign
1606 /// assert!(count.checked_sub::<5>(5).is_none());
1607 /// ```
1608 #[inline]
1609 pub const fn checked_sub<const NEW_MAX: u32>(
1610 self,
1611 bits: u32,
1612 ) -> Option<SignedBitCount<NEW_MAX>> {
1613 match self.bits.checked_sub(bits) {
1614 Some(bits_new) => match self.unsigned.checked_sub(bits) {
1615 Some(unsigned) => Some(SignedBitCount {
1616 bits: bits_new,
1617 unsigned,
1618 }),
1619 None => None,
1620 },
1621 None => None,
1622 }
1623 }
1624
1625 /// Attempt to convert our count to a count with a new
1626 /// bit count and new maximum.
1627 ///
1628 /// Returns `Some(count)` if the updated number of bits
1629 /// is less than or equal to the new maximum
1630 /// and greater than 0.
1631 /// Returns `None` if not.
1632 ///
1633 /// # Examples
1634 /// ```
1635 /// use bitstream_io::SignedBitCount;
1636 ///
1637 /// let count = SignedBitCount::<5>::new::<5>();
1638 /// // muliplying 5 bits by 2 with a new max of 10 is ok
1639 /// assert_eq!(
1640 /// count.try_map::<10, _>(|i| i.checked_mul(2)),
1641 /// Some(SignedBitCount::<10>::new::<10>()),
1642 /// );
1643 ///
1644 /// // multiplying 5 bits by 3 with a new max of 10 overflows
1645 /// assert_eq!(count.try_map::<10, _>(|i| i.checked_mul(3)), None);
1646 ///
1647 /// // multiplying 5 bits by 0 results in 0 bits,
1648 /// // which isn't value for a SignedBitCount
1649 /// assert_eq!(count.try_map::<10, _>(|i| Some(i * 0)), None);
1650 /// ```
1651 #[inline]
1652 pub fn try_map<const NEW_MAX: u32, F>(self, f: F) -> Option<SignedBitCount<NEW_MAX>>
1653 where
1654 F: FnOnce(u32) -> Option<u32>,
1655 {
1656 self.bits.try_map(f).and_then(|b| b.signed_count())
1657 }
1658
1659 /// Returns our maximum bit count
1660 ///
1661 /// # Example
1662 /// ```
1663 /// use bitstream_io::SignedBitCount;
1664 ///
1665 /// let count = SignedBitCount::<10>::new::<5>();
1666 /// assert_eq!(count.max(), 10);
1667 /// ```
1668 #[inline(always)]
1669 pub const fn max(&self) -> u32 {
1670 MAX
1671 }
1672
1673 /// Returns regular unsigned bit count
1674 ///
1675 /// # Example
1676 ///
1677 /// ```
1678 /// use bitstream_io::{BitCount, SignedBitCount};
1679 ///
1680 /// let signed_count = SignedBitCount::<10>::new::<5>();
1681 /// assert_eq!(signed_count.count(), BitCount::<10>::new::<5>());
1682 /// ```
1683 #[inline(always)]
1684 pub const fn count(&self) -> BitCount<MAX> {
1685 self.bits
1686 }
1687}
1688
1689impl<const MAX: u32> core::convert::TryFrom<BitCount<MAX>> for SignedBitCount<MAX> {
1690 type Error = ();
1691
1692 #[inline]
1693 fn try_from(count: BitCount<MAX>) -> Result<Self, Self::Error> {
1694 count.signed_count().ok_or(())
1695 }
1696}
1697
1698impl<const MAX: u32> core::convert::TryFrom<u32> for SignedBitCount<MAX> {
1699 type Error = u32;
1700
1701 #[inline]
1702 fn try_from(count: u32) -> Result<Self, Self::Error> {
1703 BitCount::<MAX>::try_from(count).and_then(|b| b.signed_count().ok_or(count))
1704 }
1705}
1706
1707impl<const MAX: u32> From<SignedBitCount<MAX>> for u32 {
1708 #[inline(always)]
1709 fn from(
1710 SignedBitCount {
1711 bits: BitCount { bits },
1712 ..
1713 }: SignedBitCount<MAX>,
1714 ) -> u32 {
1715 bits
1716 }
1717}
1718
1719/// Big-endian, or most significant bits first
1720#[derive(Copy, Clone, Debug)]
1721pub struct BigEndian;
1722
1723/// Big-endian, or most significant bits first
1724pub type BE = BigEndian;
1725
1726impl BigEndian {
1727 // checked in the sense that we've verified
1728 // the output type is large enough to hold the
1729 // requested number of bits
1730 #[inline]
1731 fn read_bits_checked<const MAX: u32, R, U>(
1732 reader: &mut R,
1733 queue: &mut u8,
1734 queue_bits: &mut u32,
1735 BitCount { bits }: BitCount<MAX>,
1736 ) -> io::Result<U>
1737 where
1738 R: io::Read,
1739 U: UnsignedInteger,
1740 {
1741 // reads a whole value with the given number of
1742 // bytes in our endianness, where the number of bytes
1743 // must be less than or equal to the type's size in bytes
1744 #[inline(always)]
1745 fn read_bytes<R, U>(reader: &mut R, bytes: usize) -> io::Result<U>
1746 where
1747 R: io::Read,
1748 U: UnsignedInteger,
1749 {
1750 let mut buf = U::buffer();
1751 reader
1752 .read_exact(&mut buf.as_mut()[(mem::size_of::<U>() - bytes)..])
1753 .map(|()| U::from_be_bytes(buf))
1754 }
1755
1756 if bits <= *queue_bits {
1757 // all bits in queue, so no byte needed
1758 let value = queue.shr_default(u8::BITS_SIZE - bits);
1759 *queue = queue.shl_default(bits);
1760 *queue_bits -= bits;
1761 Ok(U::from_u8(value))
1762 } else {
1763 // at least one byte needed
1764
1765 // bits needed beyond what's in the queue
1766 let needed_bits = bits - *queue_bits;
1767
1768 match (needed_bits / 8, needed_bits % 8) {
1769 (0, needed) => {
1770 // only one additional byte needed,
1771 // which we share between our returned value
1772 // and the bit queue
1773 let next_byte = read_byte(reader)?;
1774
1775 Ok(U::from_u8(
1776 mem::replace(queue, next_byte.shl_default(needed)).shr_default(
1777 u8::BITS_SIZE - mem::replace(queue_bits, u8::BITS_SIZE - needed),
1778 ),
1779 )
1780 .shl_default(needed)
1781 | U::from_u8(next_byte.shr_default(u8::BITS_SIZE - needed)))
1782 }
1783 (bytes, 0) => {
1784 // exact number of bytes needed beyond what's
1785 // available in the queue
1786 // so read a whole value from the reader
1787 // and prepend what's left of our queue onto it
1788
1789 Ok(U::from_u8(
1790 mem::take(queue).shr_default(u8::BITS_SIZE - mem::take(queue_bits)),
1791 )
1792 .shl_default(needed_bits)
1793 | read_bytes(reader, bytes as usize)?)
1794 }
1795 (bytes, needed) => {
1796 // read a whole value from the reader
1797 // prepend what's in the queue at the front of it
1798 // *and* append a partial byte at the end of it
1799 // while also updating the queue and its bit count
1800
1801 let whole: U = read_bytes(reader, bytes as usize)?;
1802 let next_byte = read_byte(reader)?;
1803
1804 Ok(U::from_u8(
1805 mem::replace(queue, next_byte.shl_default(needed)).shr_default(
1806 u8::BITS_SIZE - mem::replace(queue_bits, u8::BITS_SIZE - needed),
1807 ),
1808 )
1809 .shl_default(needed_bits)
1810 | whole.shl_default(needed)
1811 | U::from_u8(next_byte.shr_default(u8::BITS_SIZE - needed)))
1812 }
1813 }
1814 }
1815 }
1816
1817 // checked in the sense that we've verified
1818 // the input type is large enough to hold the
1819 // requested number of bits and that the value is
1820 // not too large for those bits
1821 #[inline]
1822 fn write_bits_checked<const MAX: u32, W, U>(
1823 writer: &mut W,
1824 queue_value: &mut u8,
1825 queue_bits: &mut u32,
1826 BitCount { bits }: BitCount<MAX>,
1827 value: U,
1828 ) -> io::Result<()>
1829 where
1830 W: io::Write,
1831 U: UnsignedInteger,
1832 {
1833 fn write_bytes<W, U>(writer: &mut W, bytes: usize, value: U) -> io::Result<()>
1834 where
1835 W: io::Write,
1836 U: UnsignedInteger,
1837 {
1838 let buf = U::to_be_bytes(value);
1839 writer.write_all(&buf.as_ref()[(mem::size_of::<U>() - bytes)..])
1840 }
1841
1842 // the amount of available bits in the queue
1843 let available_bits = u8::BITS_SIZE - *queue_bits;
1844
1845 if bits < available_bits {
1846 // all bits fit in queue, so no write needed
1847 *queue_value = queue_value.shl_default(bits) | U::to_u8(value);
1848 *queue_bits += bits;
1849 Ok(())
1850 } else {
1851 // at least one byte needs to be written
1852
1853 // bits beyond what can fit in the queue
1854 let excess_bits = bits - available_bits;
1855
1856 match (excess_bits / 8, excess_bits % 8) {
1857 (0, excess) => {
1858 // only one byte to be written,
1859 // while the excess bits are shared
1860 // between the written byte and the bit queue
1861
1862 *queue_bits = excess;
1863
1864 write_byte(
1865 writer,
1866 mem::replace(
1867 queue_value,
1868 U::to_u8(value & U::ALL.shr_default(U::BITS_SIZE - excess)),
1869 )
1870 .shl_default(available_bits)
1871 | U::to_u8(value.shr_default(excess)),
1872 )
1873 }
1874 (bytes, 0) => {
1875 // no excess bytes beyond what can fit the queue
1876 // so write a whole byte and
1877 // the remainder of the whole value
1878
1879 *queue_bits = 0;
1880
1881 write_byte(
1882 writer.by_ref(),
1883 mem::take(queue_value).shl_default(available_bits)
1884 | U::to_u8(value.shr_default(bytes * 8)),
1885 )?;
1886
1887 write_bytes(writer, bytes as usize, value)
1888 }
1889 (bytes, excess) => {
1890 // write what's in the queue along
1891 // with the head of our whole value,
1892 // write the middle section of our whole value,
1893 // while also replacing the queue with
1894 // the tail of our whole value
1895
1896 *queue_bits = excess;
1897
1898 write_byte(
1899 writer.by_ref(),
1900 mem::replace(
1901 queue_value,
1902 U::to_u8(value & U::ALL.shr_default(U::BITS_SIZE - excess)),
1903 )
1904 .shl_default(available_bits)
1905 | U::to_u8(value.shr_default(excess + bytes * 8)),
1906 )?;
1907
1908 write_bytes(writer, bytes as usize, value.shr_default(excess))
1909 }
1910 }
1911 }
1912 }
1913}
1914
1915impl Endianness for BigEndian {}
1916
1917impl private::Endianness for BigEndian {
1918 #[inline]
1919 fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8> {
1920 *queue_value = (*queue_value << 1) | u8::from(bit);
1921 *queue_bits = (*queue_bits + 1) % 8;
1922 (*queue_bits == 0).then(|| mem::take(queue_value))
1923 }
1924
1925 #[inline]
1926 fn read_bits<const MAX: u32, R, U>(
1927 reader: &mut R,
1928 queue_value: &mut u8,
1929 queue_bits: &mut u32,
1930 count @ BitCount { bits }: BitCount<MAX>,
1931 ) -> io::Result<U>
1932 where
1933 R: io::Read,
1934 U: UnsignedInteger,
1935 {
1936 if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
1937 Self::read_bits_checked::<MAX, R, U>(reader, queue_value, queue_bits, count)
1938 } else {
1939 Err(io::Error::new(
1940 io::ErrorKind::InvalidInput,
1941 "excessive bits for type read",
1942 ))
1943 }
1944 }
1945
1946 #[inline]
1947 fn read_bits_fixed<const BITS: u32, R, U>(
1948 reader: &mut R,
1949 queue_value: &mut u8,
1950 queue_bits: &mut u32,
1951 ) -> io::Result<U>
1952 where
1953 R: io::Read,
1954 U: UnsignedInteger,
1955 {
1956 const {
1957 assert!(BITS <= U::BITS_SIZE, "excessive bits for type read");
1958 }
1959
1960 Self::read_bits_checked::<BITS, R, U>(
1961 reader,
1962 queue_value,
1963 queue_bits,
1964 BitCount::new::<BITS>(),
1965 )
1966 }
1967
1968 /// For performing bulk writes of a type to a bit sink.
1969 fn write_bits<const MAX: u32, W, U>(
1970 writer: &mut W,
1971 queue_value: &mut u8,
1972 queue_bits: &mut u32,
1973 count @ BitCount { bits }: BitCount<MAX>,
1974 value: U,
1975 ) -> io::Result<()>
1976 where
1977 W: io::Write,
1978 U: UnsignedInteger,
1979 {
1980 if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
1981 if bits == 0 {
1982 Ok(())
1983 } else if value <= U::ALL >> (U::BITS_SIZE - bits) {
1984 Self::write_bits_checked::<MAX, W, U>(writer, queue_value, queue_bits, count, value)
1985 } else {
1986 Err(io::Error::new(
1987 io::ErrorKind::InvalidInput,
1988 "excessive value for bits written",
1989 ))
1990 }
1991 } else {
1992 Err(io::Error::new(
1993 io::ErrorKind::InvalidInput,
1994 "excessive bits for type written",
1995 ))
1996 }
1997 }
1998
1999 /// For performing bulk writes of a type to a bit sink.
2000 fn write_bits_fixed<const BITS: u32, W, U>(
2001 writer: &mut W,
2002 queue_value: &mut u8,
2003 queue_bits: &mut u32,
2004 value: U,
2005 ) -> io::Result<()>
2006 where
2007 W: io::Write,
2008 U: UnsignedInteger,
2009 {
2010 const {
2011 assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
2012 }
2013
2014 if BITS == 0 {
2015 Ok(())
2016 } else if BITS == U::BITS_SIZE || value <= (U::ALL >> (U::BITS_SIZE - BITS)) {
2017 Self::write_bits_checked::<BITS, W, U>(
2018 writer,
2019 queue_value,
2020 queue_bits,
2021 BitCount::new::<BITS>(),
2022 value,
2023 )
2024 } else {
2025 Err(io::Error::new(
2026 io::ErrorKind::InvalidInput,
2027 "excessive value for bits written",
2028 ))
2029 }
2030 }
2031
2032 #[inline]
2033 fn pop_bit_refill<R>(
2034 reader: &mut R,
2035 queue_value: &mut u8,
2036 queue_bits: &mut u32,
2037 ) -> io::Result<bool>
2038 where
2039 R: io::Read,
2040 {
2041 Ok(if *queue_bits == 0 {
2042 let value = read_byte(reader)?;
2043 let msb = value & u8::MSB_BIT;
2044 *queue_value = value << 1;
2045 *queue_bits = u8::BITS_SIZE - 1;
2046 msb
2047 } else {
2048 let msb = *queue_value & u8::MSB_BIT;
2049 *queue_value <<= 1;
2050 *queue_bits -= 1;
2051 msb
2052 } != 0)
2053 }
2054
2055 #[inline]
2056 fn pop_unary<const STOP_BIT: u8, R>(
2057 reader: &mut R,
2058 queue_value: &mut u8,
2059 queue_bits: &mut u32,
2060 ) -> io::Result<u32>
2061 where
2062 R: io::Read,
2063 {
2064 const {
2065 assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1");
2066 }
2067
2068 match STOP_BIT {
2069 0 => find_unary(
2070 reader,
2071 queue_value,
2072 queue_bits,
2073 |v| v.leading_ones(),
2074 |q| *q,
2075 |v, b| v.checked_shl(b),
2076 ),
2077 1 => find_unary(
2078 reader,
2079 queue_value,
2080 queue_bits,
2081 |v| v.leading_zeros(),
2082 |_| u8::BITS_SIZE,
2083 |v, b| v.checked_shl(b),
2084 ),
2085 _ => unreachable!(),
2086 }
2087 }
2088
2089 #[inline]
2090 fn read_signed_counted<const MAX: u32, R, S>(
2091 r: &mut R,
2092 SignedBitCount {
2093 bits: BitCount { bits },
2094 unsigned,
2095 }: SignedBitCount<MAX>,
2096 ) -> io::Result<S>
2097 where
2098 R: BitRead,
2099 S: SignedInteger,
2100 {
2101 if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2102 let is_negative = r.read_bit()?;
2103 let unsigned = r.read_unsigned_counted::<MAX, S::Unsigned>(unsigned)?;
2104 Ok(if is_negative {
2105 unsigned.as_negative(bits)
2106 } else {
2107 unsigned.as_non_negative()
2108 })
2109 } else {
2110 Err(io::Error::new(
2111 io::ErrorKind::InvalidInput,
2112 "excessive bits for type read",
2113 ))
2114 }
2115 }
2116
2117 fn write_signed_counted<const MAX: u32, W, S>(
2118 w: &mut W,
2119 SignedBitCount {
2120 bits: BitCount { bits },
2121 unsigned,
2122 }: SignedBitCount<MAX>,
2123 value: S,
2124 ) -> io::Result<()>
2125 where
2126 W: BitWrite,
2127 S: SignedInteger,
2128 {
2129 if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2130 w.write_bit(value.is_negative())?;
2131 w.write_unsigned_counted(
2132 unsigned,
2133 if value.is_negative() {
2134 value.as_negative(bits)
2135 } else {
2136 value.as_non_negative()
2137 },
2138 )
2139 } else {
2140 Err(io::Error::new(
2141 io::ErrorKind::InvalidInput,
2142 "excessive bits for type written",
2143 ))
2144 }
2145 }
2146
2147 fn read_bytes<const CHUNK_SIZE: usize, R>(
2148 reader: &mut R,
2149 queue_value: &mut u8,
2150 queue_bits: u32,
2151 buf: &mut [u8],
2152 ) -> io::Result<()>
2153 where
2154 R: io::Read,
2155 {
2156 if queue_bits == 0 {
2157 reader.read_exact(buf)
2158 } else {
2159 let mut input_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
2160
2161 for output_chunk in buf.chunks_mut(CHUNK_SIZE) {
2162 let input_chunk = &mut input_chunk[0..output_chunk.len()];
2163 reader.read_exact(input_chunk)?;
2164
2165 // shift down each byte in our input to eventually
2166 // accomodate the contents of the bit queue
2167 // and make that our output
2168 output_chunk
2169 .iter_mut()
2170 .zip(input_chunk.iter())
2171 .for_each(|(o, i)| {
2172 *o = i >> queue_bits;
2173 });
2174
2175 // include leftover bits from the next byte
2176 // shifted to the top
2177 output_chunk[1..]
2178 .iter_mut()
2179 .zip(input_chunk.iter())
2180 .for_each(|(o, i)| {
2181 *o |= *i << (u8::BITS_SIZE - queue_bits);
2182 });
2183
2184 // finally, prepend the queue's contents
2185 // to the first byte in the chunk
2186 // while replacing those contents
2187 // with the final byte of the input
2188 output_chunk[0] |= mem::replace(
2189 queue_value,
2190 input_chunk.last().unwrap() << (u8::BITS_SIZE - queue_bits),
2191 );
2192 }
2193
2194 Ok(())
2195 }
2196 }
2197
2198 fn write_bytes<const CHUNK_SIZE: usize, W>(
2199 writer: &mut W,
2200 queue_value: &mut u8,
2201 queue_bits: u32,
2202 buf: &[u8],
2203 ) -> io::Result<()>
2204 where
2205 W: io::Write,
2206 {
2207 if queue_bits == 0 {
2208 writer.write_all(buf)
2209 } else {
2210 let mut output_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
2211
2212 for input_chunk in buf.chunks(CHUNK_SIZE) {
2213 let output_chunk = &mut output_chunk[0..input_chunk.len()];
2214
2215 output_chunk
2216 .iter_mut()
2217 .zip(input_chunk.iter())
2218 .for_each(|(o, i)| {
2219 *o = i >> queue_bits;
2220 });
2221
2222 output_chunk[1..]
2223 .iter_mut()
2224 .zip(input_chunk.iter())
2225 .for_each(|(o, i)| {
2226 *o |= *i << (u8::BITS_SIZE - queue_bits);
2227 });
2228
2229 output_chunk[0] |= mem::replace(
2230 queue_value,
2231 input_chunk.last().unwrap() & (u8::ALL >> (u8::BITS_SIZE - queue_bits)),
2232 ) << (u8::BITS_SIZE - queue_bits);
2233
2234 writer.write_all(output_chunk)?;
2235 }
2236
2237 Ok(())
2238 }
2239 }
2240
2241 #[inline(always)]
2242 fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P {
2243 P::from_be_bytes(buf)
2244 }
2245
2246 #[inline(always)]
2247 fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes {
2248 p.to_be_bytes()
2249 }
2250
2251 #[inline]
2252 fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
2253 where
2254 R: BitRead,
2255 V: Primitive,
2256 {
2257 let mut buffer = V::buffer();
2258 r.read_bytes(buffer.as_mut())?;
2259 Ok(V::from_be_bytes(buffer))
2260 }
2261
2262 #[inline]
2263 fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
2264 where
2265 W: BitWrite,
2266 V: Primitive,
2267 {
2268 w.write_bytes(value.to_be_bytes().as_ref())
2269 }
2270}
2271
2272/// Little-endian, or least significant bits first
2273#[derive(Copy, Clone, Debug)]
2274pub struct LittleEndian;
2275
2276/// Little-endian, or least significant bits first
2277pub type LE = LittleEndian;
2278
2279impl LittleEndian {
2280 // checked in the sense that we've verified
2281 // the output type is large enough to hold the
2282 // requested number of bits
2283 #[inline]
2284 fn read_bits_checked<const MAX: u32, R, U>(
2285 reader: &mut R,
2286 queue: &mut u8,
2287 queue_bits: &mut u32,
2288 BitCount { bits }: BitCount<MAX>,
2289 ) -> io::Result<U>
2290 where
2291 R: io::Read,
2292 U: UnsignedInteger,
2293 {
2294 // reads a whole value with the given number of
2295 // bytes in our endianness, where the number of bytes
2296 // must be less than or equal to the type's size in bytes
2297 #[inline(always)]
2298 fn read_bytes<R, U>(reader: &mut R, bytes: usize) -> io::Result<U>
2299 where
2300 R: io::Read,
2301 U: UnsignedInteger,
2302 {
2303 let mut buf = U::buffer();
2304 reader
2305 .read_exact(&mut buf.as_mut()[0..bytes])
2306 .map(|()| U::from_le_bytes(buf))
2307 }
2308
2309 if bits <= *queue_bits {
2310 // all bits in queue, so no byte needed
2311 let value = *queue & u8::ALL.shr_default(u8::BITS_SIZE - bits);
2312 *queue = queue.shr_default(bits);
2313 *queue_bits -= bits;
2314 Ok(U::from_u8(value))
2315 } else {
2316 // at least one byte needed
2317
2318 // bits needed beyond what's in the queue
2319 let needed_bits = bits - *queue_bits;
2320
2321 match (needed_bits / 8, needed_bits % 8) {
2322 (0, needed) => {
2323 // only one additional byte needed,
2324 // which we share between our returned value
2325 // and the bit queue
2326 let next_byte = read_byte(reader)?;
2327
2328 Ok(
2329 U::from_u8(mem::replace(queue, next_byte.shr_default(needed)))
2330 | (U::from_u8(next_byte & (u8::ALL >> (u8::BITS_SIZE - needed)))
2331 << mem::replace(queue_bits, u8::BITS_SIZE - needed)),
2332 )
2333 }
2334 (bytes, 0) => {
2335 // exact number of bytes needed beyond what's
2336 // available in the queue
2337
2338 // so read a whole value from the reader
2339 // and prepend what's left of our queue onto it
2340
2341 Ok(U::from_u8(mem::take(queue))
2342 | (read_bytes::<R, U>(reader, bytes as usize)? << mem::take(queue_bits)))
2343 }
2344 (bytes, needed) => {
2345 // read a whole value from the reader
2346 // prepend what's in the queue at the front of it
2347 // *and* append a partial byte at the end of it
2348 // while also updating the queue and its bit count
2349
2350 let whole: U = read_bytes(reader, bytes as usize)?;
2351 let next_byte = read_byte(reader)?;
2352
2353 Ok(
2354 U::from_u8(mem::replace(queue, next_byte.shr_default(needed)))
2355 | (whole << *queue_bits)
2356 | (U::from_u8(next_byte & (u8::ALL >> (u8::BITS_SIZE - needed)))
2357 << (mem::replace(queue_bits, u8::BITS_SIZE - needed) + bytes * 8)),
2358 )
2359 }
2360 }
2361 }
2362 }
2363
2364 // checked in the sense that we've verified
2365 // the input type is large enough to hold the
2366 // requested number of bits and that the value is
2367 // not too large for those bits
2368 #[inline]
2369 fn write_bits_checked<const MAX: u32, W, U>(
2370 writer: &mut W,
2371 queue_value: &mut u8,
2372 queue_bits: &mut u32,
2373 BitCount { bits }: BitCount<MAX>,
2374 value: U,
2375 ) -> io::Result<()>
2376 where
2377 W: io::Write,
2378 U: UnsignedInteger,
2379 {
2380 fn write_bytes<W, U>(writer: &mut W, bytes: usize, value: U) -> io::Result<()>
2381 where
2382 W: io::Write,
2383 U: UnsignedInteger,
2384 {
2385 let buf = U::to_le_bytes(value);
2386 writer.write_all(&buf.as_ref()[0..bytes])
2387 }
2388
2389 // the amount of available bits in the queue
2390 let available_bits = u8::BITS_SIZE - *queue_bits;
2391
2392 if bits < available_bits {
2393 // all bits fit in queue, so no write needed
2394 *queue_value |= U::to_u8(value.shl_default(*queue_bits));
2395 *queue_bits += bits;
2396 Ok(())
2397 } else {
2398 // at least one byte needs to be written
2399
2400 // bits beyond what can fit in the queue
2401 let excess_bits = bits - available_bits;
2402
2403 match (excess_bits / 8, excess_bits % 8) {
2404 (0, excess) => {
2405 // only one byte to be written,
2406 // while the excess bits are shared
2407 // between the written byte and the bit queue
2408
2409 write_byte(
2410 writer,
2411 mem::replace(queue_value, U::to_u8(value.shr_default(available_bits)))
2412 | U::to_u8(
2413 (value << mem::replace(queue_bits, excess)) & U::from_u8(u8::ALL),
2414 ),
2415 )
2416 }
2417 (bytes, 0) => {
2418 // no excess bytes beyond what can fit the queue
2419 // so write a whole byte and
2420 // the remainder of the whole value
2421
2422 write_byte(
2423 writer.by_ref(),
2424 mem::take(queue_value)
2425 | U::to_u8((value << mem::take(queue_bits)) & U::from_u8(u8::ALL)),
2426 )?;
2427
2428 write_bytes(writer, bytes as usize, value >> available_bits)
2429 }
2430 (bytes, excess) => {
2431 // write what's in the queue along
2432 // with the head of our whole value,
2433 // write the middle section of our whole value,
2434 // while also replacing the queue with
2435 // the tail of our whole value
2436
2437 write_byte(
2438 writer.by_ref(),
2439 mem::replace(
2440 queue_value,
2441 U::to_u8(value.shr_default(available_bits + bytes * 8)),
2442 ) | U::to_u8(
2443 (value << mem::replace(queue_bits, excess)) & U::from_u8(u8::ALL),
2444 ),
2445 )?;
2446
2447 write_bytes(writer, bytes as usize, value >> available_bits)
2448 }
2449 }
2450 }
2451 }
2452}
2453
2454impl Endianness for LittleEndian {}
2455
2456impl private::Endianness for LittleEndian {
2457 #[inline]
2458 fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8> {
2459 *queue_value |= u8::from(bit) << *queue_bits;
2460 *queue_bits = (*queue_bits + 1) % 8;
2461 (*queue_bits == 0).then(|| mem::take(queue_value))
2462 }
2463
2464 #[inline]
2465 fn read_bits<const MAX: u32, R, U>(
2466 reader: &mut R,
2467 queue_value: &mut u8,
2468 queue_bits: &mut u32,
2469 count @ BitCount { bits }: BitCount<MAX>,
2470 ) -> io::Result<U>
2471 where
2472 R: io::Read,
2473 U: UnsignedInteger,
2474 {
2475 if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
2476 Self::read_bits_checked::<MAX, R, U>(reader, queue_value, queue_bits, count)
2477 } else {
2478 Err(io::Error::new(
2479 io::ErrorKind::InvalidInput,
2480 "excessive bits for type read",
2481 ))
2482 }
2483 }
2484
2485 #[inline]
2486 fn read_bits_fixed<const BITS: u32, R, U>(
2487 reader: &mut R,
2488 queue_value: &mut u8,
2489 queue_bits: &mut u32,
2490 ) -> io::Result<U>
2491 where
2492 R: io::Read,
2493 U: UnsignedInteger,
2494 {
2495 const {
2496 assert!(BITS <= U::BITS_SIZE, "excessive bits for type read");
2497 }
2498
2499 Self::read_bits_checked::<BITS, R, U>(
2500 reader,
2501 queue_value,
2502 queue_bits,
2503 BitCount::new::<BITS>(),
2504 )
2505 }
2506
2507 /// For performing bulk writes of a type to a bit sink.
2508 fn write_bits<const MAX: u32, W, U>(
2509 writer: &mut W,
2510 queue_value: &mut u8,
2511 queue_bits: &mut u32,
2512 count @ BitCount { bits }: BitCount<MAX>,
2513 value: U,
2514 ) -> io::Result<()>
2515 where
2516 W: io::Write,
2517 U: UnsignedInteger,
2518 {
2519 if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
2520 if bits == 0 {
2521 Ok(())
2522 } else if value <= U::ALL >> (U::BITS_SIZE - bits) {
2523 Self::write_bits_checked::<MAX, W, U>(writer, queue_value, queue_bits, count, value)
2524 } else {
2525 Err(io::Error::new(
2526 io::ErrorKind::InvalidInput,
2527 "excessive value for bits written",
2528 ))
2529 }
2530 } else {
2531 Err(io::Error::new(
2532 io::ErrorKind::InvalidInput,
2533 "excessive bits for type written",
2534 ))
2535 }
2536 }
2537
2538 /// For performing bulk writes of a type to a bit sink.
2539 fn write_bits_fixed<const BITS: u32, W, U>(
2540 writer: &mut W,
2541 queue_value: &mut u8,
2542 queue_bits: &mut u32,
2543 value: U,
2544 ) -> io::Result<()>
2545 where
2546 W: io::Write,
2547 U: UnsignedInteger,
2548 {
2549 const {
2550 assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
2551 }
2552
2553 if BITS == 0 {
2554 Ok(())
2555 } else if BITS == U::BITS_SIZE || value <= (U::ALL >> (U::BITS_SIZE - BITS)) {
2556 Self::write_bits_checked::<BITS, W, U>(
2557 writer,
2558 queue_value,
2559 queue_bits,
2560 BitCount::new::<BITS>(),
2561 value,
2562 )
2563 } else {
2564 Err(io::Error::new(
2565 io::ErrorKind::InvalidInput,
2566 "excessive value for bits written",
2567 ))
2568 }
2569 }
2570
2571 #[inline]
2572 fn pop_bit_refill<R>(
2573 reader: &mut R,
2574 queue_value: &mut u8,
2575 queue_bits: &mut u32,
2576 ) -> io::Result<bool>
2577 where
2578 R: io::Read,
2579 {
2580 Ok(if *queue_bits == 0 {
2581 let value = read_byte(reader)?;
2582 let lsb = value & u8::LSB_BIT;
2583 *queue_value = value >> 1;
2584 *queue_bits = u8::BITS_SIZE - 1;
2585 lsb
2586 } else {
2587 let lsb = *queue_value & u8::LSB_BIT;
2588 *queue_value >>= 1;
2589 *queue_bits -= 1;
2590 lsb
2591 } != 0)
2592 }
2593
2594 #[inline]
2595 fn pop_unary<const STOP_BIT: u8, R>(
2596 reader: &mut R,
2597 queue_value: &mut u8,
2598 queue_bits: &mut u32,
2599 ) -> io::Result<u32>
2600 where
2601 R: io::Read,
2602 {
2603 const {
2604 assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1");
2605 }
2606
2607 match STOP_BIT {
2608 0 => find_unary(
2609 reader,
2610 queue_value,
2611 queue_bits,
2612 |v| v.trailing_ones(),
2613 |q| *q,
2614 |v, b| v.checked_shr(b),
2615 ),
2616 1 => find_unary(
2617 reader,
2618 queue_value,
2619 queue_bits,
2620 |v| v.trailing_zeros(),
2621 |_| u8::BITS_SIZE,
2622 |v, b| v.checked_shr(b),
2623 ),
2624 _ => unreachable!(),
2625 }
2626 }
2627
2628 #[inline]
2629 fn read_signed_counted<const MAX: u32, R, S>(
2630 r: &mut R,
2631 SignedBitCount {
2632 bits: BitCount { bits },
2633 unsigned,
2634 }: SignedBitCount<MAX>,
2635 ) -> io::Result<S>
2636 where
2637 R: BitRead,
2638 S: SignedInteger,
2639 {
2640 if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2641 let unsigned = r.read_unsigned_counted::<MAX, S::Unsigned>(unsigned)?;
2642 let is_negative = r.read_bit()?;
2643 Ok(if is_negative {
2644 unsigned.as_negative(bits)
2645 } else {
2646 unsigned.as_non_negative()
2647 })
2648 } else {
2649 Err(io::Error::new(
2650 io::ErrorKind::InvalidInput,
2651 "excessive bits for type read",
2652 ))
2653 }
2654 }
2655
2656 fn write_signed_counted<const MAX: u32, W, S>(
2657 w: &mut W,
2658 SignedBitCount {
2659 bits: BitCount { bits },
2660 unsigned,
2661 }: SignedBitCount<MAX>,
2662 value: S,
2663 ) -> io::Result<()>
2664 where
2665 W: BitWrite,
2666 S: SignedInteger,
2667 {
2668 if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2669 w.write_unsigned_counted(
2670 unsigned,
2671 if value.is_negative() {
2672 value.as_negative(bits)
2673 } else {
2674 value.as_non_negative()
2675 },
2676 )?;
2677 w.write_bit(value.is_negative())
2678 } else {
2679 Err(io::Error::new(
2680 io::ErrorKind::InvalidInput,
2681 "excessive bits for type written",
2682 ))
2683 }
2684 }
2685
2686 fn read_bytes<const CHUNK_SIZE: usize, R>(
2687 reader: &mut R,
2688 queue_value: &mut u8,
2689 queue_bits: u32,
2690 buf: &mut [u8],
2691 ) -> io::Result<()>
2692 where
2693 R: io::Read,
2694 {
2695 if queue_bits == 0 {
2696 reader.read_exact(buf)
2697 } else {
2698 let mut input_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
2699
2700 for output_chunk in buf.chunks_mut(CHUNK_SIZE) {
2701 let input_chunk = &mut input_chunk[0..output_chunk.len()];
2702 reader.read_exact(input_chunk)?;
2703
2704 output_chunk
2705 .iter_mut()
2706 .zip(input_chunk.iter())
2707 .for_each(|(o, i)| {
2708 *o = i << queue_bits;
2709 });
2710
2711 output_chunk[1..]
2712 .iter_mut()
2713 .zip(input_chunk.iter())
2714 .for_each(|(o, i)| {
2715 *o |= i >> (u8::BITS_SIZE - queue_bits);
2716 });
2717
2718 output_chunk[0] |= mem::replace(
2719 queue_value,
2720 input_chunk.last().unwrap() >> (u8::BITS_SIZE - queue_bits),
2721 );
2722 }
2723
2724 Ok(())
2725 }
2726 }
2727
2728 fn write_bytes<const CHUNK_SIZE: usize, W>(
2729 writer: &mut W,
2730 queue_value: &mut u8,
2731 queue_bits: u32,
2732 buf: &[u8],
2733 ) -> io::Result<()>
2734 where
2735 W: io::Write,
2736 {
2737 if queue_bits == 0 {
2738 writer.write_all(buf)
2739 } else {
2740 let mut output_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
2741
2742 for input_chunk in buf.chunks(CHUNK_SIZE) {
2743 let output_chunk = &mut output_chunk[0..input_chunk.len()];
2744
2745 output_chunk
2746 .iter_mut()
2747 .zip(input_chunk.iter())
2748 .for_each(|(o, i)| {
2749 *o = i << queue_bits;
2750 });
2751
2752 output_chunk[1..]
2753 .iter_mut()
2754 .zip(input_chunk.iter())
2755 .for_each(|(o, i)| {
2756 *o |= i >> (u8::BITS_SIZE - queue_bits);
2757 });
2758
2759 output_chunk[0] |= mem::replace(
2760 queue_value,
2761 input_chunk.last().unwrap() >> (u8::BITS_SIZE - queue_bits),
2762 );
2763
2764 writer.write_all(output_chunk)?;
2765 }
2766
2767 Ok(())
2768 }
2769 }
2770
2771 #[inline(always)]
2772 fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P {
2773 P::from_le_bytes(buf)
2774 }
2775
2776 #[inline(always)]
2777 fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes {
2778 p.to_le_bytes()
2779 }
2780
2781 #[inline]
2782 fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
2783 where
2784 R: BitRead,
2785 V: Primitive,
2786 {
2787 let mut buffer = V::buffer();
2788 r.read_bytes(buffer.as_mut())?;
2789 Ok(V::from_le_bytes(buffer))
2790 }
2791
2792 #[inline]
2793 fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
2794 where
2795 W: BitWrite,
2796 V: Primitive,
2797 {
2798 w.write_bytes(value.to_le_bytes().as_ref())
2799 }
2800}
2801
2802#[inline]
2803fn find_unary<R>(
2804 reader: &mut R,
2805 queue_value: &mut u8,
2806 queue_bits: &mut u32,
2807 leading_bits: impl Fn(u8) -> u32,
2808 max_bits: impl Fn(&mut u32) -> u32,
2809 checked_shift: impl Fn(u8, u32) -> Option<u8>,
2810) -> io::Result<u32>
2811where
2812 R: io::Read,
2813{
2814 let mut acc = 0;
2815
2816 loop {
2817 match leading_bits(*queue_value) {
2818 bits if bits == max_bits(queue_bits) => {
2819 // all bits exhausted
2820 // fetch another byte and keep going
2821 acc += *queue_bits;
2822 *queue_value = read_byte(reader.by_ref())?;
2823 *queue_bits = u8::BITS_SIZE;
2824 }
2825 bits => match checked_shift(*queue_value, bits + 1) {
2826 Some(value) => {
2827 // fetch part of source byte
2828 *queue_value = value;
2829 *queue_bits -= bits + 1;
2830 break Ok(acc + bits);
2831 }
2832 None => {
2833 // fetch all of source byte
2834 *queue_value = 0;
2835 *queue_bits = 0;
2836 break Ok(acc + bits);
2837 }
2838 },
2839 }
2840 }
2841}