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}