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 2.X.X
67//!
68//! Version 3.0.0 has made many breaking changes to the [`BitRead`] and
69//! [`BitWrite`] traits.
70//!
71//! The [`BitRead::read`] method takes a constant number of bits,
72//! and the [`BitRead::read_var`] method takes a variable number of bits
73//! (reversing the older [`BitRead2::read_in`] and [`BitRead2::read`]
74//! calling methods to emphasize using the constant-based one,
75//! which can do more validation at compile-time).
76//! A new [`BitRead2`] trait uses the older calling convention
77//! for compatibility with existing code and is available
78//! for anything implementing [`BitRead`].
79//!
80//! In addition, the main reading methods return primitive types which
81//! implement a new [`Integer`] trait,
82//! which delegates to [`BitRead::read_unsigned`]
83//! or [`BitRead::read_signed`] depending on whether the output
84//! is an unsigned or signed type.
85//!
86//! [`BitWrite::write`] and [`BitWrite::write_var`] work
87//! similarly to the reader's `read` methods, taking anything
88//! that implements [`Integer`] and writing an unsigned or
89//! signed value to [`BitWrite::write_unsigned`] or
90//! [`BitWrite::write_signed`] as appropriate.
91//!
92//! And as with reading, a [`BitWrite2`] trait is offered
93//! for compatibility.
94//!
95//! In addition, the Huffman code handling has been rewritten
96//! to use a small amount of macro magic to write
97//! code to read and write symbols at compile-time.
98//! This is significantly faster than the older version
99//! and can no longer fail to compile at runtime.
100//!
101//! Lastly, there's a new [`BitCount`] struct which wraps a humble
102//! `u32` but encodes the maximum possible number of bits
103//! at the type level.
104//! This is intended for file formats which encode the number
105//! of bits to be read in the format itself.
106//! For example, FLAC's predictor coefficient precision
107//! is a 4 bit value which indicates how large each predictor
108//! coefficient is in bits
109//! (each coefficient might be an `i32` type).
110//! By keeping track of the maximum value at compile time
111//! (4 bits' worth, in this case), we can eliminate
112//! any need to check that coefficients aren't too large
113//! for an `i32` at runtime.
114//! This is accomplished by using [`BitRead::read_count`] to
115//! read a [`BitCount`] and then reading final values with
116//! that number of bits using [`BitRead::read_counted`].
117
118//! # Migrating From Pre 1.0.0
119//!
120//! There are now [`BitRead`] and [`BitWrite`] traits for bitstream
121//! reading and writing (analogous to the standard library's
122//! `Read` and `Write` traits) which you will also need to import.
123//! The upside to this approach is that library consumers
124//! can now make functions and methods generic over any sort
125//! of bit reader or bit writer, regardless of the underlying
126//! stream byte source or endianness.
127
128#![warn(missing_docs)]
129#![forbid(unsafe_code)]
130#![no_std]
131
132extern crate alloc;
133#[cfg(feature = "std")]
134extern crate std;
135
136#[cfg(not(feature = "std"))]
137use core2::io;
138
139use core::num::NonZero;
140use core::ops::{
141    BitAnd, BitOr, BitOrAssign, BitXor, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
142};
143use core::{fmt::Debug, marker::PhantomData, mem};
144#[cfg(feature = "std")]
145use std::io;
146
147pub mod huffman;
148pub mod read;
149pub mod write;
150pub use read::{
151    BitRead, BitRead2, BitReader, ByteRead, ByteReader, FromBitStream, FromBitStreamWith,
152    FromByteStream, FromByteStreamWith,
153};
154pub use write::{
155    BitCounter, BitRecorder, BitWrite, BitWrite2, BitWriter, ByteWrite, ByteWriter, ToBitStream,
156    ToBitStreamWith, ToByteStream, ToByteStreamWith,
157};
158
159/// A trait intended for simple fixed-length primitives (such as ints and floats)
160/// which allows them to be read and written to streams of
161/// different endiannesses verbatim.
162pub trait Primitive {
163    /// The raw byte representation of this numeric type
164    type Bytes: AsRef<[u8]> + AsMut<[u8]>;
165
166    /// An empty buffer of this type's size
167    fn buffer() -> Self::Bytes;
168
169    /// Our value in big-endian bytes
170    fn to_be_bytes(self) -> Self::Bytes;
171
172    /// Our value in little-endian bytes
173    fn to_le_bytes(self) -> Self::Bytes;
174
175    /// Convert big-endian bytes to our value
176    fn from_be_bytes(bytes: Self::Bytes) -> Self;
177
178    /// Convert little-endian bytes to our value
179    fn from_le_bytes(bytes: Self::Bytes) -> Self;
180}
181
182macro_rules! define_primitive_numeric {
183    ($t:ty) => {
184        impl Primitive for $t {
185            type Bytes = [u8; mem::size_of::<$t>()];
186
187            #[inline(always)]
188            fn buffer() -> Self::Bytes {
189                [0; mem::size_of::<$t>()]
190            }
191            #[inline(always)]
192            fn to_be_bytes(self) -> Self::Bytes {
193                self.to_be_bytes()
194            }
195            #[inline(always)]
196            fn to_le_bytes(self) -> Self::Bytes {
197                self.to_le_bytes()
198            }
199            #[inline(always)]
200            fn from_be_bytes(bytes: Self::Bytes) -> Self {
201                <$t>::from_be_bytes(bytes)
202            }
203            #[inline(always)]
204            fn from_le_bytes(bytes: Self::Bytes) -> Self {
205                <$t>::from_le_bytes(bytes)
206            }
207        }
208    };
209}
210
211impl<const N: usize> Primitive for [u8; N] {
212    type Bytes = [u8; N];
213
214    #[inline(always)]
215    fn buffer() -> Self::Bytes {
216        [0; N]
217    }
218
219    #[inline(always)]
220    fn to_be_bytes(self) -> Self::Bytes {
221        self
222    }
223
224    #[inline(always)]
225    fn to_le_bytes(self) -> Self::Bytes {
226        self
227    }
228
229    #[inline(always)]
230    fn from_be_bytes(bytes: Self::Bytes) -> Self {
231        bytes
232    }
233
234    #[inline(always)]
235    fn from_le_bytes(bytes: Self::Bytes) -> Self {
236        bytes
237    }
238}
239
240/// This trait is for integer types which can be read or written
241/// to a bit stream as a partial amount of bits.
242///
243/// It unifies signed and unsigned integer types by delegating
244/// reads and writes to the signed and unsigned reading
245/// and writing methods as appropriate.
246pub trait Integer {
247    /// Reads a value of ourself from the stream
248    /// with the given number of bits.
249    ///
250    /// # Errors
251    ///
252    /// Passes along any I/O error from the underlying stream.
253    /// A compile-time error occurs if the given number of bits
254    /// is larger than our type.
255    fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
256    where
257        Self: Sized;
258
259    /// Reads a value of ourself from the stream
260    /// with the given number of bits.
261    ///
262    /// # Errors
263    ///
264    /// Passes along any I/O error from the underlying stream.
265    /// Also returns an error if our type is too small
266    /// to hold the requested number of bits.
267    fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
268    where
269        R: BitRead + ?Sized,
270        Self: Sized;
271
272    /// Writes ourself to the stream using the given const number of bits.
273    ///
274    /// # Errors
275    ///
276    /// Passes along any I/O error from the underlying stream.
277    /// Returns an error if our value is too large
278    /// to fit the given number of bits.
279    /// A compile-time error occurs if the given number of bits
280    /// is larger than our type.
281    fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()>;
282
283    /// Writes ourself to the stream using the given number of bits.
284    ///
285    /// # Errors
286    ///
287    /// Passes along any I/O error from the underlying stream.
288    /// Returns an error if our value is too small
289    /// to hold the given number of bits.
290    /// Returns an error if our value is too large
291    /// to fit the given number of bits.
292    fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
293        self,
294        writer: &mut W,
295        bits: BitCount<MAX>,
296    ) -> io::Result<()>;
297}
298
299/// This trait extends many common integer types (both unsigned and signed)
300/// with a few trivial methods so that they can be used
301/// with the bitstream handling traits.
302pub trait Numeric:
303    Primitive
304    + Sized
305    + Copy
306    + Default
307    + Debug
308    + PartialOrd
309    + Shl<u32, Output = Self>
310    + ShlAssign<u32>
311    + Shr<u32, Output = Self>
312    + ShrAssign<u32>
313    + Rem<Self, Output = Self>
314    + RemAssign<Self>
315    + BitAnd<Self, Output = Self>
316    + BitOr<Self, Output = Self>
317    + BitOrAssign<Self>
318    + BitXor<Self, Output = Self>
319    + Not<Output = Self>
320    + Sub<Self, Output = Self>
321{
322    /// Size of type in bits
323    const BITS_SIZE: u32;
324
325    /// The value of 0 in this type
326    const ZERO: Self;
327
328    /// The value of 1 in this type
329    const ONE: Self;
330
331    /// Returns a `u8` value in this type
332    fn from_u8(u: u8) -> Self;
333
334    /// Assuming 0 <= value < 256, returns this value as a `u8` type
335    fn to_u8(self) -> u8;
336}
337
338macro_rules! define_numeric {
339    ($t:ty) => {
340        define_primitive_numeric!($t);
341
342        impl Numeric for $t {
343            const BITS_SIZE: u32 = mem::size_of::<$t>() as u32 * 8;
344
345            const ZERO: Self = 0;
346
347            const ONE: Self = 1;
348
349            #[inline(always)]
350            fn from_u8(u: u8) -> Self {
351                u as $t
352            }
353            #[inline(always)]
354            fn to_u8(self) -> u8 {
355                self as u8
356            }
357        }
358    };
359}
360
361/// This trait extends many common unsigned integer types
362/// so that they can be used with the bitstream handling traits.
363pub trait UnsignedInteger: Numeric + Into<crate::write::UnsignedValue> {
364    /// This type's most-significant bit
365    const MSB_BIT: Self;
366
367    /// This type's least significant bit
368    const LSB_BIT: Self;
369
370    /// This type with all bits set
371    const ALL: Self;
372
373    /// The signed variant of ourself
374    type Signed: SignedInteger<Unsigned = Self>;
375
376    /// Given a twos-complement value,
377    /// return this value is a non-negative signed number.
378    /// The location of the sign bit depends on the stream's endianness
379    /// and is not stored in the result.
380    ///
381    /// # Example
382    /// ```
383    /// use bitstream_io::UnsignedInteger;
384    /// assert_eq!(0b00000001u8.as_non_negative(), 1i8);
385    /// ```
386    fn as_non_negative(self) -> Self::Signed;
387
388    /// Given a two-complement positive value and certain number of bits,
389    /// returns this value as a negative signed number.
390    /// The location of the sign bit depends on the stream's endianness
391    /// and is not stored in the result.
392    ///
393    /// # Example
394    /// ```
395    /// use bitstream_io::UnsignedInteger;
396    /// assert_eq!(0b01111111u8.as_negative(8), -1i8);
397    /// ```
398    fn as_negative(self, bits: u32) -> Self::Signed;
399
400    /// Given a two-complement positive value and certain number of bits,
401    /// returns this value as a negative number.
402    ///
403    /// # Example
404    /// ```
405    /// use bitstream_io::UnsignedInteger;
406    /// assert_eq!(0b01111111u8.as_negative_fixed::<8>(), -1i8);
407    /// ```
408    fn as_negative_fixed<const BITS: u32>(self) -> Self::Signed;
409
410    /// Checked shift left
411    fn checked_shl(self, rhs: u32) -> Option<Self>;
412
413    /// Checked shift right
414    fn checked_shr(self, rhs: u32) -> Option<Self>;
415
416    /// Shift left up to our length in bits
417    ///
418    /// If rhs equals our length in bits, returns default
419    fn shl_default(self, rhs: u32) -> Self {
420        self.checked_shl(rhs).unwrap_or(Self::ZERO)
421    }
422
423    /// Shift left up to our length in bits
424    ///
425    /// If rhs equals our length in bits, returns zero
426    fn shr_default(self, rhs: u32) -> Self {
427        self.checked_shr(rhs).unwrap_or(Self::ZERO)
428    }
429}
430
431macro_rules! define_unsigned_integer {
432    ($t:ty, $s:ty) => {
433        define_numeric!($t);
434
435        impl UnsignedInteger for $t {
436            type Signed = $s;
437
438            const MSB_BIT: Self = 1 << (Self::BITS_SIZE - 1);
439
440            const LSB_BIT: Self = 1;
441
442            const ALL: Self = <$t>::MAX;
443
444            #[inline(always)]
445            fn as_non_negative(self) -> Self::Signed {
446                self as $s
447            }
448            #[inline(always)]
449            fn as_negative(self, bits: u32) -> Self::Signed {
450                (self as $s) + (-1 << (bits - 1))
451            }
452            #[inline(always)]
453            fn as_negative_fixed<const BITS: u32>(self) -> Self::Signed {
454                (self as $s) + (-1 << (BITS - 1))
455            }
456            #[inline(always)]
457            fn checked_shl(self, rhs: u32) -> Option<Self> {
458                self.checked_shl(rhs)
459            }
460            #[inline(always)]
461            fn checked_shr(self, rhs: u32) -> Option<Self> {
462                self.checked_shr(rhs)
463            }
464        }
465
466        impl Integer for $t {
467            #[inline(always)]
468            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
469            where
470                Self: Sized,
471            {
472                reader.read_unsigned::<BITS, _>()
473            }
474
475            #[inline(always)]
476            fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
477            where
478                R: BitRead + ?Sized,
479                Self: Sized,
480            {
481                reader.read_unsigned_counted::<MAX, _>(bits)
482            }
483
484            #[inline(always)]
485            fn write<const BITS: u32, W: BitWrite + ?Sized>(
486                self,
487                writer: &mut W,
488            ) -> io::Result<()> {
489                writer.write_unsigned::<BITS, _>(self)
490            }
491
492            #[inline(always)]
493            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
494                self,
495                writer: &mut W,
496                bits: BitCount<MAX>,
497            ) -> io::Result<()> {
498                writer.write_unsigned_counted(bits, self)
499            }
500        }
501
502        /// Unsigned NonZero types increment their value by 1
503        /// when being read and decrement it by 1
504        /// when being written.
505        ///
506        /// # Examples
507        /// ```
508        /// use bitstream_io::{BitReader, BitRead, BigEndian};
509        /// use core::num::NonZero;
510        ///
511        /// let data: &[u8] = &[0b001_00000];
512        /// // reading a regular u8 in 3 bits yields 1
513        /// assert_eq!(BitReader::endian(data, BigEndian).read::<3, u8>().unwrap(), 1);
514        /// // reading a NonZero<u8> in 3 bits of the same data yields 2
515        /// assert_eq!(BitReader::endian(data, BigEndian).read::<3, NonZero<u8>>().unwrap().get(), 2);
516        /// ```
517        ///
518        /// ```
519        /// use bitstream_io::{BitWriter, BitWrite, BigEndian};
520        /// use core::num::NonZero;
521        ///
522        /// let mut w = BitWriter::endian(vec![], BigEndian);
523        /// // writing 1 as a regular u8 in 3 bits
524        /// w.write::<3, u8>(1).unwrap();
525        /// w.byte_align();
526        /// assert_eq!(w.into_writer(), &[0b001_00000]);
527        ///
528        /// let mut w = BitWriter::endian(vec![], BigEndian);
529        /// // writing 1 as a NonZero<u8> in 3 bits
530        /// w.write::<3, NonZero<u8>>(NonZero::new(1).unwrap()).unwrap();
531        /// w.byte_align();
532        /// assert_eq!(w.into_writer(), &[0b000_00000]);
533        /// ```
534        impl Integer for NonZero<$t> {
535            #[inline]
536            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
537            where
538                Self: Sized,
539            {
540                const {
541                    assert!(
542                        BITS < <$t>::BITS_SIZE,
543                        "BITS must be less than the type's size in bits"
544                    );
545                }
546
547                <$t as Integer>::read::<BITS, R>(reader).map(|u| NonZero::new(u + 1).unwrap())
548            }
549
550            #[inline]
551            fn read_var<const MAX: u32, R>(
552                reader: &mut R,
553                count @ BitCount { bits }: BitCount<MAX>,
554            ) -> io::Result<Self>
555            where
556                R: BitRead + ?Sized,
557                Self: Sized,
558            {
559                if MAX < <$t>::BITS_SIZE || bits < <$t>::BITS_SIZE {
560                    <$t as Integer>::read_var::<MAX, R>(reader, count)
561                        .map(|u| NonZero::new(u + 1).unwrap())
562                } else {
563                    Err(io::Error::new(
564                        io::ErrorKind::InvalidInput,
565                        "bit count must be less than the type's size in bits",
566                    ))
567                }
568            }
569
570            #[inline]
571            fn write<const BITS: u32, W: BitWrite + ?Sized>(
572                self,
573                writer: &mut W,
574            ) -> io::Result<()> {
575                const {
576                    assert!(
577                        BITS < <$t>::BITS_SIZE,
578                        "BITS must be less than the type's size in bits"
579                    );
580                }
581
582                <$t as Integer>::write::<BITS, W>(self.get() - 1, writer)
583            }
584
585            #[inline]
586            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
587                self,
588                writer: &mut W,
589                count @ BitCount { bits }: BitCount<MAX>,
590            ) -> io::Result<()> {
591                if MAX < <$t>::BITS_SIZE || bits < <$t>::BITS_SIZE {
592                    <$t as Integer>::write_var::<MAX, W>(self.get() - 1, writer, count)
593                } else {
594                    Err(io::Error::new(
595                        io::ErrorKind::InvalidInput,
596                        "bit count must be less than the type's size in bits",
597                    ))
598                }
599            }
600        }
601
602        impl Integer for Option<NonZero<$t>> {
603            #[inline]
604            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
605            where
606                Self: Sized,
607            {
608                <$t as Integer>::read::<BITS, R>(reader).map(NonZero::new)
609            }
610
611            #[inline]
612            fn read_var<const MAX: u32, R>(reader: &mut R, count: BitCount<MAX>) -> io::Result<Self>
613            where
614                R: BitRead + ?Sized,
615                Self: Sized,
616            {
617                <$t as Integer>::read_var::<MAX, R>(reader, count).map(NonZero::new)
618            }
619
620            #[inline]
621            fn write<const BITS: u32, W: BitWrite + ?Sized>(
622                self,
623                writer: &mut W,
624            ) -> io::Result<()> {
625                <$t as Integer>::write::<BITS, W>(self.map(|n| n.get()).unwrap_or(0), writer)
626            }
627
628            #[inline]
629            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
630                self,
631                writer: &mut W,
632                count: BitCount<MAX>,
633            ) -> io::Result<()> {
634                <$t as Integer>::write_var::<MAX, W>(
635                    self.map(|n| n.get()).unwrap_or(0),
636                    writer,
637                    count,
638                )
639            }
640        }
641    };
642}
643
644/// This trait extends many common signed integer types
645/// so that they can be used with the bitstream handling traits.
646///
647/// This trait was formerly named `SignedNumeric` in 2.X.X code.
648/// If backwards-compatibility is needed one can
649/// import `SignedInteger` as `SignedNumeric`.
650pub trait SignedInteger: Numeric + Into<crate::write::SignedValue> {
651    /// The unsigned variant of ourself
652    type Unsigned: UnsignedInteger<Signed = Self>;
653
654    /// Returns true if this value is negative
655    ///
656    /// # Example
657    /// ```
658    /// use bitstream_io::SignedInteger;
659    /// assert!(!1i8.is_negative());
660    /// assert!((-1i8).is_negative());
661    /// ```
662    fn is_negative(self) -> bool;
663
664    /// Returns ourself as a non-negative value.
665    /// The location of the sign bit depends on the stream's endianness
666    /// and is not stored in the result.
667    ///
668    /// # Example
669    /// ```
670    /// use bitstream_io::SignedInteger;
671    /// assert_eq!(1i8.as_non_negative(), 0b00000001u8);
672    /// ```
673    fn as_non_negative(self) -> Self::Unsigned;
674
675    /// Given a negative value and a certain number of bits,
676    /// returns this value as a twos-complement positive number.
677    /// The location of the sign bit depends on the stream's endianness
678    /// and is not stored in the result.
679    ///
680    /// # Example
681    /// ```
682    /// use bitstream_io::SignedInteger;
683    /// assert_eq!((-1i8).as_negative(8), 0b01111111u8);
684    /// ```
685    fn as_negative(self, bits: u32) -> Self::Unsigned;
686
687    /// Given a negative value and a certain number of bits,
688    /// returns this value as a twos-complement positive number.
689    ///
690    /// # Example
691    /// ```
692    /// use bitstream_io::SignedInteger;
693    /// assert_eq!((-1i8).as_negative_fixed::<8>(), 0b01111111u8);
694    /// ```
695    fn as_negative_fixed<const BITS: u32>(self) -> Self::Unsigned;
696}
697
698macro_rules! define_signed_integer {
699    ($t:ty, $u:ty) => {
700        define_numeric!($t);
701
702        impl SignedInteger for $t {
703            type Unsigned = $u;
704
705            #[inline(always)]
706            fn is_negative(self) -> bool {
707                self.is_negative()
708            }
709            fn as_non_negative(self) -> Self::Unsigned {
710                self as $u
711            }
712            fn as_negative(self, bits: u32) -> Self::Unsigned {
713                (self - (-1 << (bits - 1))) as $u
714            }
715            fn as_negative_fixed<const BITS: u32>(self) -> Self::Unsigned {
716                (self - (-1 << (BITS - 1))) as $u
717            }
718        }
719
720        impl Integer for $t {
721            #[inline(always)]
722            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
723            where
724                Self: Sized,
725            {
726                reader.read_signed::<BITS, _>()
727            }
728
729            #[inline(always)]
730            fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
731            where
732                R: BitRead + ?Sized,
733                Self: Sized,
734            {
735                reader.read_signed_counted::<MAX, _>(bits)
736            }
737
738            #[inline(always)]
739            fn write<const BITS: u32, W: BitWrite + ?Sized>(
740                self,
741                writer: &mut W,
742            ) -> io::Result<()> {
743                writer.write_signed::<BITS, _>(self)
744            }
745
746            #[inline(always)]
747            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
748                self,
749                writer: &mut W,
750                bits: BitCount<MAX>,
751            ) -> io::Result<()> {
752                writer.write_signed_counted::<MAX, _>(bits, self)
753            }
754        }
755    };
756}
757
758define_unsigned_integer!(u8, i8);
759define_unsigned_integer!(u16, i16);
760define_unsigned_integer!(u32, i32);
761define_unsigned_integer!(u64, i64);
762define_unsigned_integer!(u128, i128);
763
764define_signed_integer!(i8, u8);
765define_signed_integer!(i16, u16);
766define_signed_integer!(i32, u32);
767define_signed_integer!(i64, u64);
768define_signed_integer!(i128, u128);
769
770define_primitive_numeric!(f32);
771define_primitive_numeric!(f64);
772
773/// A stream's endianness, or byte order, for determining
774/// how bits should be read.
775///
776/// It comes in `BigEndian` and `LittleEndian` varieties
777/// (which may be shortened to `BE` and `LE`)
778/// and is not something programmers should have to implement
779/// in most cases.
780pub trait Endianness: Sized {
781    /// Pops the next bit from the queue,
782    /// repleneshing it from the given reader if necessary
783    fn pop_bit_refill<R>(
784        reader: &mut R,
785        queue_value: &mut u8,
786        queue_bits: &mut u32,
787    ) -> io::Result<bool>
788    where
789        R: io::Read;
790
791    /// Pops the next unary value from the source until
792    /// `STOP_BIT` is encountered, replenishing it from the given
793    /// closure if necessary.
794    ///
795    /// `STOP_BIT` must be 0 or 1.
796    fn pop_unary<const STOP_BIT: u8, R>(
797        reader: &mut R,
798        queue_value: &mut u8,
799        queue_bits: &mut u32,
800    ) -> io::Result<u32>
801    where
802        R: io::Read;
803
804    /// Pushes the next bit into the queue,
805    /// and returns `Some` value if the queue is full.
806    fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8>;
807
808    /// For performing bulk reads from a bit source to an output type.
809    fn read_bits<const MAX: u32, R, U>(
810        reader: &mut R,
811        queue_value: &mut u8,
812        queue_bits: &mut u32,
813        count: BitCount<MAX>,
814    ) -> io::Result<U>
815    where
816        R: io::Read,
817        U: UnsignedInteger;
818
819    /// For performing bulk reads from a bit source to an output type.
820    fn read_bits_fixed<const BITS: u32, R, U>(
821        reader: &mut R,
822        queue_value: &mut u8,
823        queue_bits: &mut u32,
824    ) -> io::Result<U>
825    where
826        R: io::Read,
827        U: UnsignedInteger;
828
829    /// For performing bulk writes of a type to a bit sink.
830    fn write_bits<const MAX: u32, W, U>(
831        writer: &mut W,
832        queue_value: &mut u8,
833        queue_bits: &mut u32,
834        count: BitCount<MAX>,
835        value: U,
836    ) -> io::Result<()>
837    where
838        W: io::Write,
839        U: UnsignedInteger;
840
841    /// For performing bulk writes of a constant value to a bit sink.
842    fn write_bits_const<const BITS: u32, const VALUE: u32, W>(
843        writer: &mut W,
844        queue_value: &mut u8,
845        queue_bits: &mut u32,
846    ) -> io::Result<()>
847    where
848        W: io::Write;
849
850    /// For performing bulk writes of a type to a bit sink.
851    fn write_bits_fixed<const BITS: u32, W, U>(
852        writer: &mut W,
853        queue_value: &mut u8,
854        queue_bits: &mut u32,
855        value: U,
856    ) -> io::Result<()>
857    where
858        W: io::Write,
859        U: UnsignedInteger;
860
861    /// Reads signed value from reader in this endianness
862    fn read_signed<const MAX: u32, R, S>(r: &mut R, bits: BitCount<MAX>) -> io::Result<S>
863    where
864        R: BitRead,
865        S: SignedInteger;
866
867    /// Reads signed value from reader in this endianness
868    fn read_signed_fixed<R, const B: u32, S>(r: &mut R) -> io::Result<S>
869    where
870        R: BitRead,
871        S: SignedInteger;
872
873    /// Writes signed value to writer in this endianness
874    fn write_signed<const MAX: u32, W, S>(
875        w: &mut W,
876        bits: BitCount<MAX>,
877        value: S,
878    ) -> io::Result<()>
879    where
880        W: BitWrite,
881        S: SignedInteger;
882
883    /// Writes signed value to writer in this endianness
884    fn write_signed_fixed<W, const B: u32, S>(w: &mut W, value: S) -> io::Result<()>
885    where
886        W: BitWrite,
887        S: SignedInteger;
888
889    /// Reads convertable numeric value from reader in this endianness
890    fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
891    where
892        R: BitRead,
893        V: Primitive;
894
895    /// Writes convertable numeric value to writer in this endianness
896    fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
897    where
898        W: BitWrite,
899        V: Primitive;
900
901    /// Reads entire numeric value from reader in this endianness
902    fn read_numeric<R, V>(r: R) -> io::Result<V>
903    where
904        R: io::Read,
905        V: Primitive;
906
907    /// Writes entire numeric value to writer in this endianness
908    fn write_numeric<W, V>(w: W, value: V) -> io::Result<()>
909    where
910        W: io::Write,
911        V: Primitive;
912}
913
914#[inline(always)]
915fn read_byte<R>(mut reader: R) -> io::Result<u8>
916where
917    R: io::Read,
918{
919    let mut byte = 0;
920    reader
921        .read_exact(core::slice::from_mut(&mut byte))
922        .map(|()| byte)
923}
924
925#[inline(always)]
926fn write_byte<W>(mut writer: W, byte: u8) -> io::Result<()>
927where
928    W: io::Write,
929{
930    writer.write_all(core::slice::from_ref(&byte))
931}
932
933// These "read_bits" and "write_bits" functions are
934// to be used by the endianness traits to fill in their closures
935// and build specialized reading and writing routines
936// that shift and consume bits in the proper directions.
937//
938// So while they have a lot of arguments, they're not intended
939// for public consumption.
940
941/// A number of bits to be consumed or written, with a known maximum
942#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
943pub struct BitCount<const MAX: u32> {
944    // The amount of bits may be less than or equal to the maximum,
945    // but never more.
946    bits: u32,
947}
948
949impl<const MAX: u32> BitCount<MAX> {
950    /// The largest possible BitCount maximum value
951    ///
952    /// This corresponds to the largest unsigned integer
953    /// type supported.
954    const MAX: u32 = u128::BITS_SIZE;
955
956    /// Builds a bit count from a constant number
957    /// of bits, which must not be greater than `MAX`
958    /// or greater than the largest supported type.
959    ///
960    /// Intended to be used for defining constants.
961    ///
962    /// Use `TryFrom` to conditionally build
963    /// counts from values at runtime.
964    ///
965    /// # Examples
966    ///
967    /// ```
968    /// use bitstream_io::{BitReader, BitRead, BigEndian, BitCount};
969    /// let data: &[u8] = &[0b111_00000];
970    /// let mut r = BitReader::endian(data, BigEndian);
971    /// // reading 3 bits from a stream out of a maximum of 8
972    /// // doesn't require checking that the bit count is larger
973    /// // than a u8 at runtime because specifying the maximum of 8
974    /// // guarantees our bit count will not be larger than 8
975    /// assert_eq!(r.read_counted::<8, u8>(BitCount::new::<3>()).unwrap(), 0b111);
976    /// ```
977    ///
978    /// ```rust,compile_fail
979    /// use bitstream_io::BitCount;
980    /// // trying to build a count of 10 with a maximum of 8
981    /// // fails to compile at all
982    /// let count = BitCount::<8>::new::<10>();
983    /// ```
984    ///
985    /// ```rust,compile_fail
986    /// use bitstream_io::BitCount;
987    /// // trying to build a count of 10 with a maximum of 129
988    /// // fails to compile at all
989    /// let count = BitCount::<129>::new::<10>();
990    /// ```
991    pub const fn new<const BITS: u32>() -> Self {
992        const {
993            assert!(MAX <= BitCount::<BITS>::MAX, "MAX must be <= BitCount::MAX");
994            assert!(BITS <= MAX, "BITS must be <= MAX");
995        }
996
997        Self { bits: BITS }
998    }
999
1000    /// Add a number of bits to our count,
1001    /// returning a new count with a new maximum.
1002    ///
1003    /// Returns `None` if the new count goes above our new maximum.
1004    /// A compile-time error occurs if `NEW_MAX` is larger than
1005    /// the largest supported type.
1006    ///
1007    /// # Examples
1008    ///
1009    /// ```
1010    /// use bitstream_io::BitCount;
1011    ///
1012    /// let count = BitCount::<2>::new::<1>();
1013    /// // adding 2 to 1 and increasing the max to 3 yields a new count of 3
1014    /// assert_eq!(count.checked_add::<3>(2), Some(BitCount::<3>::new::<3>()));
1015    /// // adding 2 to 1 without increasing the max yields None
1016    /// assert_eq!(count.checked_add::<2>(2), None);
1017    /// ```
1018    ///
1019    /// ```rust,compile_fail
1020    /// use bitstream_io::BitCount;
1021    ///
1022    /// let count = BitCount::<2>::new::<1>();
1023    /// // a new maximum of 129 is larger than our largest supported type
1024    /// let count2 = count.checked_add::<129>(1);
1025    /// ```
1026    #[inline]
1027    pub const fn checked_add<const NEW_MAX: u32>(self, bits: u32) -> Option<BitCount<NEW_MAX>> {
1028        const {
1029            assert!(
1030                NEW_MAX <= BitCount::<NEW_MAX>::MAX,
1031                "NEW_MAX must be <= BitCount::MAX"
1032            );
1033        }
1034
1035        match self.bits.checked_add(bits) {
1036            Some(bits) if bits <= NEW_MAX => Some(BitCount { bits }),
1037            _ => None,
1038        }
1039    }
1040
1041    /// Subtracts a number of bits from our count,
1042    /// returning a new count with a new maximum.
1043    ///
1044    /// Returns `None` if the new count goes below 0
1045    /// or below our new maximum.
1046    /// A compile-time error occurs if `NEW_MAX` is larger
1047    /// than the largest supported type.
1048    ///
1049    /// # Example
1050    /// ```
1051    /// use bitstream_io::BitCount;
1052    /// let count = BitCount::<5>::new::<5>();
1053    /// // subtracting 1 from 5 yields a new count of 4
1054    /// assert_eq!(count.checked_sub::<5>(1), Some(BitCount::<5>::new::<4>()));
1055    /// // subtracting 6 from 5 yields None
1056    /// assert!(count.checked_sub::<5>(6).is_none());
1057    /// // subtracting 1 with a new maximum of 3 also yields None
1058    /// // because 4 is larger than the maximum of 3
1059    /// assert!(count.checked_sub::<3>(1).is_none());
1060    /// ```
1061    #[inline]
1062    pub const fn checked_sub<const NEW_MAX: u32>(self, bits: u32) -> Option<Self> {
1063        const {
1064            assert!(
1065                NEW_MAX <= BitCount::<NEW_MAX>::MAX,
1066                "NEW_MAX must be <= BitCount::MAX"
1067            );
1068        }
1069
1070        match self.bits.checked_sub(bits) {
1071            Some(bits) if bits <= NEW_MAX => Some(BitCount { bits }),
1072            _ => None,
1073        }
1074    }
1075
1076    /// Attempt to convert our count to a count with a new
1077    /// bit count and new maximum.
1078    ///
1079    /// Returns `Some(count)` if the updated number of bits
1080    /// is less than or equal to the new maximum.
1081    /// Returns `None` if not.
1082    ///
1083    /// A compile-time error occurs if one tries to
1084    /// use a maximum bit count larger than the largest
1085    /// supported type.
1086    ///
1087    /// # Examples
1088    /// ```
1089    /// use bitstream_io::BitCount;
1090    ///
1091    /// let count = BitCount::<5>::new::<5>();
1092    /// // muliplying 5 bits by 2 with a new max of 10 is ok
1093    /// assert_eq!(
1094    ///     count.try_map::<10, _>(|i| i.checked_mul(2)),
1095    ///     Some(BitCount::<10>::new::<10>()),
1096    /// );
1097    /// // multiplying 5 bits by 3 with a new max of 10 overflows
1098    /// assert_eq!(count.try_map::<10, _>(|i| i.checked_mul(3)), None);
1099    /// ```
1100    ///
1101    /// ```rust,compile_fail
1102    /// use bitstream_io::BitCount;
1103    ///
1104    /// // 129 bits is larger than the largest supported type
1105    /// let count = BitCount::<5>::new::<5>();
1106    /// let new_count = count.try_map::<129, _>(|i| i).unwrap();
1107    /// ```
1108    #[inline]
1109    pub fn try_map<const NEW_MAX: u32, F>(self, f: F) -> Option<BitCount<NEW_MAX>>
1110    where
1111        F: FnOnce(u32) -> Option<u32>,
1112    {
1113        const {
1114            assert!(
1115                NEW_MAX <= BitCount::<NEW_MAX>::MAX,
1116                "NEW_MAX must be <= BitCount::MAX"
1117            );
1118        }
1119
1120        f(self.bits)
1121            .filter(|bits| *bits <= NEW_MAX)
1122            .map(|bits| BitCount { bits })
1123    }
1124}
1125
1126impl<const MAX: u32> core::convert::TryFrom<u32> for BitCount<MAX> {
1127    type Error = u32;
1128
1129    /// Attempts to convert a `u32` bit count to a `BitCount`
1130    ///
1131    /// Attempting a bit maximum bit count larger than the
1132    /// largest supported type is a compile-time error
1133    ///
1134    /// # Examples
1135    /// ```
1136    /// use bitstream_io::BitCount;
1137    /// use std::convert::TryInto;
1138    ///
1139    /// assert_eq!(8u32.try_into(), Ok(BitCount::<8>::new::<8>()));
1140    /// assert_eq!(9u32.try_into(), Err::<BitCount<8>, _>(9));
1141    /// ```
1142    ///
1143    /// ```rust,compile_fail
1144    /// use bitstream_io::BitCount;
1145    /// use std::convert::TryInto;
1146    ///
1147    /// // largest bit count is 128
1148    /// assert_eq!(129u32.try_into(), Err::<BitCount<129>, _>(129));
1149    /// ```
1150    fn try_from(bits: u32) -> Result<Self, Self::Error> {
1151        const {
1152            assert!(MAX <= BitCount::<MAX>::MAX, "MAX must be <= BitCount::MAX");
1153        }
1154
1155        (bits <= MAX).then_some(Self { bits }).ok_or(bits)
1156    }
1157}
1158
1159impl BitCount<{ u128::BITS_SIZE }> {
1160    /// Builds a bit count where the maximum bits is unknown.
1161    ///
1162    /// In this case, `u128::BITS_SIZE` is assumed,
1163    /// because that's the largest type supported.
1164    ///
1165    /// # Example
1166    /// ```
1167    /// use bitstream_io::BitCount;
1168    /// assert_eq!(BitCount::unknown(5), BitCount::<128>::new::<5>());
1169    /// ```
1170    pub const fn unknown(bits: u32) -> Self {
1171        Self { bits }
1172    }
1173}
1174
1175impl<const MAX: u32> From<BitCount<MAX>> for u32 {
1176    #[inline(always)]
1177    fn from(BitCount { bits }: BitCount<MAX>) -> u32 {
1178        bits
1179    }
1180}
1181
1182/// Big-endian, or most significant bits first
1183#[derive(Copy, Clone, Debug)]
1184pub struct BigEndian;
1185
1186/// Big-endian, or most significant bits first
1187pub type BE = BigEndian;
1188
1189impl BigEndian {
1190    // checked in the sense that we've verified
1191    // the output type is large enough to hold the
1192    // requested number of bits
1193    #[inline]
1194    fn read_bits_checked<const MAX: u32, R, U>(
1195        reader: &mut R,
1196        queue: &mut u8,
1197        queue_bits: &mut u32,
1198        BitCount { bits }: BitCount<MAX>,
1199    ) -> io::Result<U>
1200    where
1201        R: io::Read,
1202        U: UnsignedInteger,
1203    {
1204        // reads a whole value with the given number of
1205        // bytes in our endianness, where the number of bytes
1206        // must be less than or equal to the type's size in bytes
1207        #[inline(always)]
1208        fn read_bytes<R, U>(reader: &mut R, bytes: usize) -> io::Result<U>
1209        where
1210            R: io::Read,
1211            U: UnsignedInteger,
1212        {
1213            let mut buf = U::buffer();
1214            reader
1215                .read_exact(&mut buf.as_mut()[(mem::size_of::<U>() - bytes)..])
1216                .map(|()| U::from_be_bytes(buf))
1217        }
1218
1219        if bits <= *queue_bits {
1220            // all bits in queue, so no byte needed
1221            let value = queue.shr_default(u8::BITS_SIZE - bits);
1222            *queue = queue.shl_default(bits);
1223            *queue_bits -= bits;
1224            Ok(U::from_u8(value))
1225        } else {
1226            // at least one byte needed
1227
1228            // bits needed beyond what's in the queue
1229            let needed_bits = bits - *queue_bits;
1230
1231            match (needed_bits / 8, needed_bits % 8) {
1232                (0, needed) => {
1233                    // only one additional byte needed,
1234                    // which we share between our returned value
1235                    // and the bit queue
1236                    let next_byte = read_byte(reader)?;
1237
1238                    Ok(U::from_u8(
1239                        mem::replace(queue, next_byte.shl_default(needed)).shr_default(
1240                            u8::BITS_SIZE - mem::replace(queue_bits, u8::BITS_SIZE - needed),
1241                        ),
1242                    )
1243                    .shl_default(needed)
1244                        | U::from_u8(next_byte.shr_default(u8::BITS_SIZE - needed)))
1245                }
1246                (bytes, 0) => {
1247                    // exact number of bytes needed beyond what's
1248                    // available in the queue
1249                    // so read a whole value from the reader
1250                    // and prepend what's left of our queue onto it
1251
1252                    Ok(U::from_u8(
1253                        mem::take(queue).shr_default(u8::BITS_SIZE - mem::take(queue_bits)),
1254                    )
1255                    .shl_default(needed_bits)
1256                        | read_bytes(reader, bytes as usize)?)
1257                }
1258                (bytes, needed) => {
1259                    // read a whole value from the reader
1260                    // prepend what's in the queue at the front of it
1261                    // *and* append a partial byte at the end of it
1262                    // while also updating the queue and its bit count
1263
1264                    let whole: U = read_bytes(reader, bytes as usize)?;
1265                    let next_byte = read_byte(reader)?;
1266
1267                    Ok(U::from_u8(
1268                        mem::replace(queue, next_byte.shl_default(needed)).shr_default(
1269                            u8::BITS_SIZE - mem::replace(queue_bits, u8::BITS_SIZE - needed),
1270                        ),
1271                    )
1272                    .shl_default(needed_bits)
1273                        | whole.shl_default(needed)
1274                        | U::from_u8(next_byte.shr_default(u8::BITS_SIZE - needed)))
1275                }
1276            }
1277        }
1278    }
1279
1280    // checked in the sense that we've verified
1281    // the input type is large enough to hold the
1282    // requested number of bits and that the value is
1283    // not too large for those bits
1284    #[inline]
1285    fn write_bits_checked<const MAX: u32, W, U>(
1286        writer: &mut W,
1287        queue_value: &mut u8,
1288        queue_bits: &mut u32,
1289        BitCount { bits }: BitCount<MAX>,
1290        value: U,
1291    ) -> io::Result<()>
1292    where
1293        W: io::Write,
1294        U: UnsignedInteger,
1295    {
1296        fn write_bytes<W, U>(writer: &mut W, bytes: usize, value: U) -> io::Result<()>
1297        where
1298            W: io::Write,
1299            U: UnsignedInteger,
1300        {
1301            let buf = U::to_be_bytes(value);
1302            writer.write_all(&buf.as_ref()[(mem::size_of::<U>() - bytes)..])
1303        }
1304
1305        // the amount of available bits in the queue
1306        let available_bits = u8::BITS_SIZE - *queue_bits;
1307
1308        if bits < available_bits {
1309            // all bits fit in queue, so no write needed
1310            *queue_value = queue_value.shl_default(bits) | U::to_u8(value);
1311            *queue_bits += bits;
1312            Ok(())
1313        } else {
1314            // at least one byte needs to be written
1315
1316            // bits beyond what can fit in the queue
1317            let excess_bits = bits - available_bits;
1318
1319            match (excess_bits / 8, excess_bits % 8) {
1320                (0, excess) => {
1321                    // only one byte to be written,
1322                    // while the excess bits are shared
1323                    // between the written byte and the bit queue
1324
1325                    *queue_bits = excess;
1326
1327                    write_byte(
1328                        writer,
1329                        mem::replace(
1330                            queue_value,
1331                            U::to_u8(value & U::ALL.shr_default(U::BITS_SIZE - excess)),
1332                        )
1333                        .shl_default(available_bits)
1334                            | U::to_u8(value.shr_default(excess)),
1335                    )
1336                }
1337                (bytes, 0) => {
1338                    // no excess bytes beyond what can fit the queue
1339                    // so write a whole byte and
1340                    // the remainder of the whole value
1341
1342                    *queue_bits = 0;
1343
1344                    write_byte(
1345                        writer.by_ref(),
1346                        mem::take(queue_value).shl_default(available_bits)
1347                            | U::to_u8(value.shr_default(bytes * 8)),
1348                    )?;
1349
1350                    write_bytes(writer, bytes as usize, value)
1351                }
1352                (bytes, excess) => {
1353                    // write what's in the queue along
1354                    // with the head of our whole value,
1355                    // write the middle section of our whole value,
1356                    // while also replacing the queue with
1357                    // the tail of our whole value
1358
1359                    *queue_bits = excess;
1360
1361                    write_byte(
1362                        writer.by_ref(),
1363                        mem::replace(
1364                            queue_value,
1365                            U::to_u8(value & U::ALL.shr_default(U::BITS_SIZE - excess)),
1366                        )
1367                        .shl_default(available_bits)
1368                            | U::to_u8(value.shr_default(excess + bytes * 8)),
1369                    )?;
1370
1371                    write_bytes(writer, bytes as usize, value.shr_default(excess))
1372                }
1373            }
1374        }
1375    }
1376}
1377
1378impl Endianness for BigEndian {
1379    #[inline]
1380    fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8> {
1381        *queue_value = (*queue_value << 1) | u8::from(bit);
1382        *queue_bits = (*queue_bits + 1) % 8;
1383        (*queue_bits == 0).then(|| mem::take(queue_value))
1384    }
1385
1386    #[inline]
1387    fn read_bits<const MAX: u32, R, U>(
1388        reader: &mut R,
1389        queue_value: &mut u8,
1390        queue_bits: &mut u32,
1391        count @ BitCount { bits }: BitCount<MAX>,
1392    ) -> io::Result<U>
1393    where
1394        R: io::Read,
1395        U: UnsignedInteger,
1396    {
1397        if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
1398            Self::read_bits_checked::<MAX, R, U>(reader, queue_value, queue_bits, count)
1399        } else {
1400            Err(io::Error::new(
1401                io::ErrorKind::InvalidInput,
1402                "excessive bits for type read",
1403            ))
1404        }
1405    }
1406
1407    #[inline]
1408    fn read_bits_fixed<const BITS: u32, R, U>(
1409        reader: &mut R,
1410        queue_value: &mut u8,
1411        queue_bits: &mut u32,
1412    ) -> io::Result<U>
1413    where
1414        R: io::Read,
1415        U: UnsignedInteger,
1416    {
1417        const {
1418            assert!(BITS <= U::BITS_SIZE, "excessive bits for type read");
1419        }
1420
1421        Self::read_bits_checked::<BITS, R, U>(
1422            reader,
1423            queue_value,
1424            queue_bits,
1425            BitCount::new::<BITS>(),
1426        )
1427    }
1428
1429    /// For performing bulk writes of a type to a bit sink.
1430    fn write_bits<const MAX: u32, W, U>(
1431        writer: &mut W,
1432        queue_value: &mut u8,
1433        queue_bits: &mut u32,
1434        count @ BitCount { bits }: BitCount<MAX>,
1435        value: U,
1436    ) -> io::Result<()>
1437    where
1438        W: io::Write,
1439        U: UnsignedInteger,
1440    {
1441        if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
1442            if bits == 0 {
1443                Ok(())
1444            } else if value <= U::ALL >> (U::BITS_SIZE - bits) {
1445                Self::write_bits_checked::<MAX, W, U>(writer, queue_value, queue_bits, count, value)
1446            } else {
1447                Err(io::Error::new(
1448                    io::ErrorKind::InvalidInput,
1449                    "excessive value for bits written",
1450                ))
1451            }
1452        } else {
1453            Err(io::Error::new(
1454                io::ErrorKind::InvalidInput,
1455                "excessive bits for type written",
1456            ))
1457        }
1458    }
1459
1460    /// For performing bulk writes of a constant value to a bit sink.
1461    fn write_bits_const<const BITS: u32, const VALUE: u32, W>(
1462        writer: &mut W,
1463        queue_value: &mut u8,
1464        queue_bits: &mut u32,
1465    ) -> io::Result<()>
1466    where
1467        W: io::Write,
1468    {
1469        const {
1470            assert!(BITS <= u32::BITS_SIZE, "excessive bits for type written");
1471            assert!(
1472                BITS == 0 || VALUE <= (u32::ALL >> (u32::BITS_SIZE - BITS)),
1473                "excessive value for bits written"
1474            );
1475        }
1476
1477        if BITS == 0 {
1478            Ok(())
1479        } else {
1480            Self::write_bits_checked::<BITS, W, u32>(
1481                writer,
1482                queue_value,
1483                queue_bits,
1484                BitCount::new::<BITS>(),
1485                VALUE,
1486            )
1487        }
1488    }
1489
1490    /// For performing bulk writes of a type to a bit sink.
1491    fn write_bits_fixed<const BITS: u32, W, U>(
1492        writer: &mut W,
1493        queue_value: &mut u8,
1494        queue_bits: &mut u32,
1495        value: U,
1496    ) -> io::Result<()>
1497    where
1498        W: io::Write,
1499        U: UnsignedInteger,
1500    {
1501        const {
1502            assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
1503        }
1504
1505        if BITS == 0 {
1506            Ok(())
1507        } else if value <= (U::ALL >> (U::BITS_SIZE - BITS)) {
1508            Self::write_bits_checked::<BITS, W, U>(
1509                writer,
1510                queue_value,
1511                queue_bits,
1512                BitCount::new::<BITS>(),
1513                value,
1514            )
1515        } else {
1516            Err(io::Error::new(
1517                io::ErrorKind::InvalidInput,
1518                "excessive value for bits written",
1519            ))
1520        }
1521    }
1522
1523    #[inline]
1524    fn pop_bit_refill<R>(
1525        reader: &mut R,
1526        queue_value: &mut u8,
1527        queue_bits: &mut u32,
1528    ) -> io::Result<bool>
1529    where
1530        R: io::Read,
1531    {
1532        Ok(if *queue_bits == 0 {
1533            let value = read_byte(reader)?;
1534            let msb = value & u8::MSB_BIT;
1535            *queue_value = value << 1;
1536            *queue_bits = u8::BITS_SIZE - 1;
1537            msb
1538        } else {
1539            let msb = *queue_value & u8::MSB_BIT;
1540            *queue_value <<= 1;
1541            *queue_bits -= 1;
1542            msb
1543        } != 0)
1544    }
1545
1546    #[inline]
1547    fn pop_unary<const STOP_BIT: u8, R>(
1548        reader: &mut R,
1549        queue_value: &mut u8,
1550        queue_bits: &mut u32,
1551    ) -> io::Result<u32>
1552    where
1553        R: io::Read,
1554    {
1555        const {
1556            assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1");
1557        }
1558
1559        match STOP_BIT {
1560            0 => find_unary(
1561                reader,
1562                queue_value,
1563                queue_bits,
1564                |v| v.leading_ones(),
1565                |q| *q,
1566                |v, b| v.checked_shl(b),
1567            ),
1568            1 => find_unary(
1569                reader,
1570                queue_value,
1571                queue_bits,
1572                |v| v.leading_zeros(),
1573                |_| u8::BITS_SIZE,
1574                |v, b| v.checked_shl(b),
1575            ),
1576            _ => unreachable!(),
1577        }
1578    }
1579
1580    fn read_signed<const MAX: u32, R, S>(
1581        r: &mut R,
1582        count @ BitCount { bits }: BitCount<MAX>,
1583    ) -> io::Result<S>
1584    where
1585        R: BitRead,
1586        S: SignedInteger,
1587    {
1588        if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
1589            let is_negative = r.read_bit()?;
1590            let unsigned = r.read_unsigned_counted::<MAX, S::Unsigned>(
1591                count.checked_sub::<MAX>(1).ok_or(io::Error::new(
1592                    io::ErrorKind::InvalidInput,
1593                    "signed reads need at least 1 bit for sign",
1594                ))?,
1595            )?;
1596            Ok(if is_negative {
1597                unsigned.as_negative(bits)
1598            } else {
1599                unsigned.as_non_negative()
1600            })
1601        } else {
1602            Err(io::Error::new(
1603                io::ErrorKind::InvalidInput,
1604                "excessive bits for type read",
1605            ))
1606        }
1607    }
1608
1609    fn read_signed_fixed<R, const B: u32, S>(r: &mut R) -> io::Result<S>
1610    where
1611        R: BitRead,
1612        S: SignedInteger,
1613    {
1614        if B == S::BITS_SIZE {
1615            r.read_to()
1616        } else {
1617            let is_negative = r.read_bit()?;
1618            let unsigned = r.read_unsigned_var::<S::Unsigned>(B - 1)?;
1619            Ok(if is_negative {
1620                unsigned.as_negative_fixed::<B>()
1621            } else {
1622                unsigned.as_non_negative()
1623            })
1624        }
1625    }
1626
1627    fn write_signed<const MAX: u32, W, S>(
1628        w: &mut W,
1629        count @ BitCount { bits }: BitCount<MAX>,
1630        value: S,
1631    ) -> io::Result<()>
1632    where
1633        W: BitWrite,
1634        S: SignedInteger,
1635    {
1636        if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
1637            w.write_bit(value.is_negative())?;
1638            w.write_unsigned_counted(
1639                count.checked_sub::<MAX>(1).ok_or(io::Error::new(
1640                    io::ErrorKind::InvalidInput,
1641                    "signed writes need at least 1 bit for sign",
1642                ))?,
1643                if value.is_negative() {
1644                    value.as_negative(bits)
1645                } else {
1646                    value.as_non_negative()
1647                },
1648            )
1649        } else {
1650            Err(io::Error::new(
1651                io::ErrorKind::InvalidInput,
1652                "excessive bits for type written",
1653            ))
1654        }
1655    }
1656
1657    fn write_signed_fixed<W, const B: u32, S>(w: &mut W, value: S) -> io::Result<()>
1658    where
1659        W: BitWrite,
1660        S: SignedInteger,
1661    {
1662        if B == S::BITS_SIZE {
1663            w.write_bytes(value.to_be_bytes().as_ref())
1664        } else if value.is_negative() {
1665            w.write_bit(true)
1666                .and_then(|()| w.write_unsigned_var(B - 1, value.as_negative_fixed::<B>()))
1667        } else {
1668            w.write_bit(false)
1669                .and_then(|()| w.write_unsigned_var(B - 1, value.as_non_negative()))
1670        }
1671    }
1672
1673    #[inline]
1674    fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
1675    where
1676        R: BitRead,
1677        V: Primitive,
1678    {
1679        let mut buffer = V::buffer();
1680        r.read_bytes(buffer.as_mut())?;
1681        Ok(V::from_be_bytes(buffer))
1682    }
1683
1684    #[inline]
1685    fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
1686    where
1687        W: BitWrite,
1688        V: Primitive,
1689    {
1690        w.write_bytes(value.to_be_bytes().as_ref())
1691    }
1692
1693    #[inline]
1694    fn read_numeric<R, V>(mut r: R) -> io::Result<V>
1695    where
1696        R: io::Read,
1697        V: Primitive,
1698    {
1699        let mut buffer = V::buffer();
1700        r.read_exact(buffer.as_mut())?;
1701        Ok(V::from_be_bytes(buffer))
1702    }
1703
1704    #[inline]
1705    fn write_numeric<W, V>(mut w: W, value: V) -> io::Result<()>
1706    where
1707        W: io::Write,
1708        V: Primitive,
1709    {
1710        w.write_all(value.to_be_bytes().as_ref())
1711    }
1712}
1713
1714/// Little-endian, or least significant bits first
1715#[derive(Copy, Clone, Debug)]
1716pub struct LittleEndian;
1717
1718/// Little-endian, or least significant bits first
1719pub type LE = LittleEndian;
1720
1721impl LittleEndian {
1722    // checked in the sense that we've verified
1723    // the output type is large enough to hold the
1724    // requested number of bits
1725    #[inline]
1726    fn read_bits_checked<const MAX: u32, R, U>(
1727        reader: &mut R,
1728        queue: &mut u8,
1729        queue_bits: &mut u32,
1730        BitCount { bits }: BitCount<MAX>,
1731    ) -> io::Result<U>
1732    where
1733        R: io::Read,
1734        U: UnsignedInteger,
1735    {
1736        // reads a whole value with the given number of
1737        // bytes in our endianness, where the number of bytes
1738        // must be less than or equal to the type's size in bytes
1739        #[inline(always)]
1740        fn read_bytes<R, U>(reader: &mut R, bytes: usize) -> io::Result<U>
1741        where
1742            R: io::Read,
1743            U: UnsignedInteger,
1744        {
1745            let mut buf = U::buffer();
1746            reader
1747                .read_exact(&mut buf.as_mut()[0..bytes])
1748                .map(|()| U::from_le_bytes(buf))
1749        }
1750
1751        if bits <= *queue_bits {
1752            // all bits in queue, so no byte needed
1753            let value = *queue & u8::ALL.shr_default(u8::BITS_SIZE - bits);
1754            *queue = queue.shr_default(bits);
1755            *queue_bits -= bits;
1756            Ok(U::from_u8(value))
1757        } else {
1758            // at least one byte needed
1759
1760            // bits needed beyond what's in the queue
1761            let needed_bits = bits - *queue_bits;
1762
1763            match (needed_bits / 8, needed_bits % 8) {
1764                (0, needed) => {
1765                    // only one additional byte needed,
1766                    // which we share between our returned value
1767                    // and the bit queue
1768                    let next_byte = read_byte(reader)?;
1769
1770                    Ok(
1771                        U::from_u8(mem::replace(queue, next_byte.shr_default(needed)))
1772                            | (U::from_u8(next_byte & (u8::ALL >> (u8::BITS_SIZE - needed)))
1773                                << mem::replace(queue_bits, u8::BITS_SIZE - needed)),
1774                    )
1775                }
1776                (bytes, 0) => {
1777                    // exact number of bytes needed beyond what's
1778                    // available in the queue
1779
1780                    // so read a whole value from the reader
1781                    // and prepend what's left of our queue onto it
1782
1783                    Ok(U::from_u8(mem::take(queue))
1784                        | (read_bytes::<R, U>(reader, bytes as usize)? << mem::take(queue_bits)))
1785                }
1786                (bytes, needed) => {
1787                    // read a whole value from the reader
1788                    // prepend what's in the queue at the front of it
1789                    // *and* append a partial byte at the end of it
1790                    // while also updating the queue and its bit count
1791
1792                    let whole: U = read_bytes(reader, bytes as usize)?;
1793                    let next_byte = read_byte(reader)?;
1794
1795                    Ok(
1796                        U::from_u8(mem::replace(queue, next_byte.shr_default(needed)))
1797                            | (whole << *queue_bits)
1798                            | (U::from_u8(next_byte & (u8::ALL >> (u8::BITS_SIZE - needed)))
1799                                << (mem::replace(queue_bits, u8::BITS_SIZE - needed) + bytes * 8)),
1800                    )
1801                }
1802            }
1803        }
1804    }
1805
1806    // checked in the sense that we've verified
1807    // the input type is large enough to hold the
1808    // requested number of bits and that the value is
1809    // not too large for those bits
1810    #[inline]
1811    fn write_bits_checked<const MAX: u32, W, U>(
1812        writer: &mut W,
1813        queue_value: &mut u8,
1814        queue_bits: &mut u32,
1815        BitCount { bits }: BitCount<MAX>,
1816        value: U,
1817    ) -> io::Result<()>
1818    where
1819        W: io::Write,
1820        U: UnsignedInteger,
1821    {
1822        fn write_bytes<W, U>(writer: &mut W, bytes: usize, value: U) -> io::Result<()>
1823        where
1824            W: io::Write,
1825            U: UnsignedInteger,
1826        {
1827            let buf = U::to_le_bytes(value);
1828            writer.write_all(&buf.as_ref()[0..bytes])
1829        }
1830
1831        // the amount of available bits in the queue
1832        let available_bits = u8::BITS_SIZE - *queue_bits;
1833
1834        if bits < available_bits {
1835            // all bits fit in queue, so no write needed
1836            *queue_value |= U::to_u8(value.shl_default(*queue_bits));
1837            *queue_bits += bits;
1838            Ok(())
1839        } else {
1840            // at least one byte needs to be written
1841
1842            // bits beyond what can fit in the queue
1843            let excess_bits = bits - available_bits;
1844
1845            match (excess_bits / 8, excess_bits % 8) {
1846                (0, excess) => {
1847                    // only one byte to be written,
1848                    // while the excess bits are shared
1849                    // between the written byte and the bit queue
1850
1851                    write_byte(
1852                        writer,
1853                        mem::replace(queue_value, U::to_u8(value.shr_default(available_bits)))
1854                            | U::to_u8(
1855                                (value << mem::replace(queue_bits, excess)) & U::from_u8(u8::ALL),
1856                            ),
1857                    )
1858                }
1859                (bytes, 0) => {
1860                    // no excess bytes beyond what can fit the queue
1861                    // so write a whole byte and
1862                    // the remainder of the whole value
1863
1864                    write_byte(
1865                        writer.by_ref(),
1866                        mem::take(queue_value)
1867                            | U::to_u8((value << mem::take(queue_bits)) & U::from_u8(u8::ALL)),
1868                    )?;
1869
1870                    write_bytes(writer, bytes as usize, value >> available_bits)
1871                }
1872                (bytes, excess) => {
1873                    // write what's in the queue along
1874                    // with the head of our whole value,
1875                    // write the middle section of our whole value,
1876                    // while also replacing the queue with
1877                    // the tail of our whole value
1878
1879                    write_byte(
1880                        writer.by_ref(),
1881                        mem::replace(
1882                            queue_value,
1883                            U::to_u8(value.shr_default(available_bits + bytes * 8)),
1884                        ) | U::to_u8(
1885                            (value << mem::replace(queue_bits, excess)) & U::from_u8(u8::ALL),
1886                        ),
1887                    )?;
1888
1889                    write_bytes(writer, bytes as usize, value >> available_bits)
1890                }
1891            }
1892        }
1893    }
1894}
1895
1896impl Endianness for LittleEndian {
1897    #[inline]
1898    fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8> {
1899        *queue_value |= u8::from(bit) << *queue_bits;
1900        *queue_bits = (*queue_bits + 1) % 8;
1901        (*queue_bits == 0).then(|| mem::take(queue_value))
1902    }
1903
1904    #[inline]
1905    fn read_bits<const MAX: u32, R, U>(
1906        reader: &mut R,
1907        queue_value: &mut u8,
1908        queue_bits: &mut u32,
1909        count @ BitCount { bits }: BitCount<MAX>,
1910    ) -> io::Result<U>
1911    where
1912        R: io::Read,
1913        U: UnsignedInteger,
1914    {
1915        if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
1916            Self::read_bits_checked::<MAX, R, U>(reader, queue_value, queue_bits, count)
1917        } else {
1918            Err(io::Error::new(
1919                io::ErrorKind::InvalidInput,
1920                "excessive bits for type read",
1921            ))
1922        }
1923    }
1924
1925    #[inline]
1926    fn read_bits_fixed<const BITS: u32, R, U>(
1927        reader: &mut R,
1928        queue_value: &mut u8,
1929        queue_bits: &mut u32,
1930    ) -> io::Result<U>
1931    where
1932        R: io::Read,
1933        U: UnsignedInteger,
1934    {
1935        const {
1936            assert!(BITS <= U::BITS_SIZE, "excessive bits for type read");
1937        }
1938
1939        Self::read_bits_checked::<BITS, R, U>(
1940            reader,
1941            queue_value,
1942            queue_bits,
1943            BitCount::new::<BITS>(),
1944        )
1945    }
1946
1947    /// For performing bulk writes of a type to a bit sink.
1948    fn write_bits<const MAX: u32, W, U>(
1949        writer: &mut W,
1950        queue_value: &mut u8,
1951        queue_bits: &mut u32,
1952        count @ BitCount { bits }: BitCount<MAX>,
1953        value: U,
1954    ) -> io::Result<()>
1955    where
1956        W: io::Write,
1957        U: UnsignedInteger,
1958    {
1959        if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
1960            if bits == 0 {
1961                Ok(())
1962            } else if value <= U::ALL >> (U::BITS_SIZE - bits) {
1963                Self::write_bits_checked::<MAX, W, U>(writer, queue_value, queue_bits, count, value)
1964            } else {
1965                Err(io::Error::new(
1966                    io::ErrorKind::InvalidInput,
1967                    "excessive value for bits written",
1968                ))
1969            }
1970        } else {
1971            Err(io::Error::new(
1972                io::ErrorKind::InvalidInput,
1973                "excessive bits for type written",
1974            ))
1975        }
1976    }
1977
1978    /// For performing bulk writes of a constant value to a bit sink.
1979    fn write_bits_const<const BITS: u32, const VALUE: u32, W>(
1980        writer: &mut W,
1981        queue_value: &mut u8,
1982        queue_bits: &mut u32,
1983    ) -> io::Result<()>
1984    where
1985        W: io::Write,
1986    {
1987        const {
1988            assert!(BITS <= u32::BITS_SIZE, "excessive bits for type written");
1989            assert!(
1990                BITS == 0 || VALUE <= (u32::ALL >> (u32::BITS_SIZE - BITS)),
1991                "excessive value for bits written"
1992            );
1993        }
1994
1995        if BITS == 0 {
1996            Ok(())
1997        } else {
1998            Self::write_bits_checked::<BITS, W, u32>(
1999                writer,
2000                queue_value,
2001                queue_bits,
2002                BitCount::new::<BITS>(),
2003                VALUE,
2004            )
2005        }
2006    }
2007
2008    /// For performing bulk writes of a type to a bit sink.
2009    fn write_bits_fixed<const BITS: u32, W, U>(
2010        writer: &mut W,
2011        queue_value: &mut u8,
2012        queue_bits: &mut u32,
2013        value: U,
2014    ) -> io::Result<()>
2015    where
2016        W: io::Write,
2017        U: UnsignedInteger,
2018    {
2019        const {
2020            assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
2021        }
2022
2023        if BITS == 0 {
2024            Ok(())
2025        } else if value <= (U::ALL >> (U::BITS_SIZE - BITS)) {
2026            Self::write_bits_checked::<BITS, W, U>(
2027                writer,
2028                queue_value,
2029                queue_bits,
2030                BitCount::new::<BITS>(),
2031                value,
2032            )
2033        } else {
2034            Err(io::Error::new(
2035                io::ErrorKind::InvalidInput,
2036                "excessive value for bits written",
2037            ))
2038        }
2039    }
2040
2041    #[inline]
2042    fn pop_bit_refill<R>(
2043        reader: &mut R,
2044        queue_value: &mut u8,
2045        queue_bits: &mut u32,
2046    ) -> io::Result<bool>
2047    where
2048        R: io::Read,
2049    {
2050        Ok(if *queue_bits == 0 {
2051            let value = read_byte(reader)?;
2052            let lsb = value & u8::LSB_BIT;
2053            *queue_value = value >> 1;
2054            *queue_bits = u8::BITS_SIZE - 1;
2055            lsb
2056        } else {
2057            let lsb = *queue_value & u8::LSB_BIT;
2058            *queue_value >>= 1;
2059            *queue_bits -= 1;
2060            lsb
2061        } != 0)
2062    }
2063
2064    #[inline]
2065    fn pop_unary<const STOP_BIT: u8, R>(
2066        reader: &mut R,
2067        queue_value: &mut u8,
2068        queue_bits: &mut u32,
2069    ) -> io::Result<u32>
2070    where
2071        R: io::Read,
2072    {
2073        const {
2074            assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1");
2075        }
2076
2077        match STOP_BIT {
2078            0 => find_unary(
2079                reader,
2080                queue_value,
2081                queue_bits,
2082                |v| v.trailing_ones(),
2083                |q| *q,
2084                |v, b| v.checked_shr(b),
2085            ),
2086            1 => find_unary(
2087                reader,
2088                queue_value,
2089                queue_bits,
2090                |v| v.trailing_zeros(),
2091                |_| u8::BITS_SIZE,
2092                |v, b| v.checked_shr(b),
2093            ),
2094            _ => unreachable!(),
2095        }
2096    }
2097
2098    fn read_signed<const MAX: u32, R, S>(
2099        r: &mut R,
2100        count @ BitCount { bits }: BitCount<MAX>,
2101    ) -> io::Result<S>
2102    where
2103        R: BitRead,
2104        S: SignedInteger,
2105    {
2106        if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2107            let unsigned = r.read_unsigned_counted::<MAX, S::Unsigned>(
2108                count.checked_sub::<MAX>(1).ok_or(io::Error::new(
2109                    io::ErrorKind::InvalidInput,
2110                    "signed reads need at least 1 bit for sign",
2111                ))?,
2112            )?;
2113            let is_negative = r.read_bit()?;
2114            Ok(if is_negative {
2115                unsigned.as_negative(bits)
2116            } else {
2117                unsigned.as_non_negative()
2118            })
2119        } else {
2120            Err(io::Error::new(
2121                io::ErrorKind::InvalidInput,
2122                "excessive bits for type read",
2123            ))
2124        }
2125    }
2126
2127    fn read_signed_fixed<R, const B: u32, S>(r: &mut R) -> io::Result<S>
2128    where
2129        R: BitRead,
2130        S: SignedInteger,
2131    {
2132        if B == S::BITS_SIZE {
2133            r.read_to()
2134        } else {
2135            let unsigned = r.read_unsigned_var::<S::Unsigned>(B - 1)?;
2136            let is_negative = r.read_bit()?;
2137            Ok(if is_negative {
2138                unsigned.as_negative_fixed::<B>()
2139            } else {
2140                unsigned.as_non_negative()
2141            })
2142        }
2143    }
2144
2145    fn write_signed<const MAX: u32, W, S>(
2146        w: &mut W,
2147        count @ BitCount { bits }: BitCount<MAX>,
2148        value: S,
2149    ) -> io::Result<()>
2150    where
2151        W: BitWrite,
2152        S: SignedInteger,
2153    {
2154        if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2155            w.write_unsigned_counted(
2156                count.checked_sub::<MAX>(1).ok_or(io::Error::new(
2157                    io::ErrorKind::InvalidInput,
2158                    "signed writes need at least 1 bit for sign",
2159                ))?,
2160                if value.is_negative() {
2161                    value.as_negative(bits)
2162                } else {
2163                    value.as_non_negative()
2164                },
2165            )?;
2166            w.write_bit(value.is_negative())
2167        } else {
2168            Err(io::Error::new(
2169                io::ErrorKind::InvalidInput,
2170                "excessive bits for type written",
2171            ))
2172        }
2173    }
2174
2175    fn write_signed_fixed<W, const B: u32, S>(w: &mut W, value: S) -> io::Result<()>
2176    where
2177        W: BitWrite,
2178        S: SignedInteger,
2179    {
2180        if B == S::BITS_SIZE {
2181            w.write_bytes(value.to_le_bytes().as_ref())
2182        } else if value.is_negative() {
2183            w.write_unsigned_var(B - 1, value.as_negative_fixed::<B>())
2184                .and_then(|()| w.write_bit(true))
2185        } else {
2186            w.write_unsigned_var(B - 1, value.as_non_negative())
2187                .and_then(|()| w.write_bit(false))
2188        }
2189    }
2190
2191    #[inline]
2192    fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
2193    where
2194        R: BitRead,
2195        V: Primitive,
2196    {
2197        let mut buffer = V::buffer();
2198        r.read_bytes(buffer.as_mut())?;
2199        Ok(V::from_le_bytes(buffer))
2200    }
2201
2202    #[inline]
2203    fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
2204    where
2205        W: BitWrite,
2206        V: Primitive,
2207    {
2208        w.write_bytes(value.to_le_bytes().as_ref())
2209    }
2210
2211    fn read_numeric<R, V>(mut r: R) -> io::Result<V>
2212    where
2213        R: io::Read,
2214        V: Primitive,
2215    {
2216        let mut buffer = V::buffer();
2217        r.read_exact(buffer.as_mut())?;
2218        Ok(V::from_le_bytes(buffer))
2219    }
2220
2221    #[inline]
2222    fn write_numeric<W, V>(mut w: W, value: V) -> io::Result<()>
2223    where
2224        W: io::Write,
2225        V: Primitive,
2226    {
2227        w.write_all(value.to_le_bytes().as_ref())
2228    }
2229}
2230
2231#[inline]
2232fn find_unary<R>(
2233    reader: &mut R,
2234    queue_value: &mut u8,
2235    queue_bits: &mut u32,
2236    leading_bits: impl Fn(u8) -> u32,
2237    max_bits: impl Fn(&mut u32) -> u32,
2238    checked_shift: impl Fn(u8, u32) -> Option<u8>,
2239) -> io::Result<u32>
2240where
2241    R: io::Read,
2242{
2243    let mut acc = 0;
2244
2245    loop {
2246        match leading_bits(*queue_value) {
2247            bits if bits == max_bits(queue_bits) => {
2248                // all bits exhausted
2249                // fetch another byte and keep going
2250                acc += *queue_bits;
2251                *queue_value = read_byte(reader.by_ref())?;
2252                *queue_bits = u8::BITS_SIZE;
2253            }
2254            bits => match checked_shift(*queue_value, bits + 1) {
2255                Some(value) => {
2256                    // fetch part of source byte
2257                    *queue_value = value;
2258                    *queue_bits -= bits + 1;
2259                    break Ok(acc + bits);
2260                }
2261                None => {
2262                    // fetch all of source byte
2263                    *queue_value = 0;
2264                    *queue_bits = 0;
2265                    break Ok(acc + bits);
2266                }
2267            },
2268        }
2269    }
2270}