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#![cfg_attr(docsrs, feature(doc_cfg))]
145#![warn(missing_docs)]
146#![forbid(unsafe_code)]
147#![no_std]
148
149#[cfg(feature = "alloc")]
150extern crate alloc;
151#[cfg(feature = "std")]
152extern crate std;
153
154#[cfg(not(feature = "std"))]
155use core2::io;
156
157use core::convert::TryInto;
158use core::num::NonZero;
159use core::ops::{
160    BitAnd, BitOr, BitOrAssign, BitXor, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
161};
162use core::{fmt::Debug, marker::PhantomData, mem};
163#[cfg(feature = "std")]
164use std::io;
165
166pub mod huffman;
167pub mod read;
168pub mod write;
169pub use read::{
170    BitRead, BitRead2, BitReader, ByteRead, ByteReader, FromBitStream, FromBitStreamUsing,
171    FromBitStreamWith, FromByteStream, FromByteStreamUsing, FromByteStreamWith,
172};
173#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
174#[cfg(feature = "alloc")]
175pub use write::BitRecorder;
176pub use write::{
177    BitWrite, BitWrite2, BitWriter, BitsWritten, ByteWrite, ByteWriter, ToBitStream,
178    ToBitStreamUsing, ToBitStreamWith, ToByteStream, ToByteStreamUsing, ToByteStreamWith,
179};
180
181#[allow(deprecated)]
182pub use write::BitCounter;
183
184/// A trait intended for simple fixed-length primitives (such as ints and floats)
185/// which allows them to be read and written to streams of
186/// different endiannesses verbatim.
187pub trait Primitive {
188    /// The raw byte representation of this numeric type
189    type Bytes: AsRef<[u8]> + AsMut<[u8]>;
190
191    /// An empty buffer of this type's size
192    fn buffer() -> Self::Bytes;
193
194    /// Our value in big-endian bytes
195    fn to_be_bytes(self) -> Self::Bytes;
196
197    /// Our value in little-endian bytes
198    fn to_le_bytes(self) -> Self::Bytes;
199
200    /// Convert big-endian bytes to our value
201    fn from_be_bytes(bytes: Self::Bytes) -> Self;
202
203    /// Convert little-endian bytes to our value
204    fn from_le_bytes(bytes: Self::Bytes) -> Self;
205}
206
207macro_rules! define_primitive_numeric {
208    ($t:ty) => {
209        impl Primitive for $t {
210            type Bytes = [u8; mem::size_of::<$t>()];
211
212            #[inline(always)]
213            fn buffer() -> Self::Bytes {
214                [0; mem::size_of::<$t>()]
215            }
216            #[inline(always)]
217            fn to_be_bytes(self) -> Self::Bytes {
218                self.to_be_bytes()
219            }
220            #[inline(always)]
221            fn to_le_bytes(self) -> Self::Bytes {
222                self.to_le_bytes()
223            }
224            #[inline(always)]
225            fn from_be_bytes(bytes: Self::Bytes) -> Self {
226                <$t>::from_be_bytes(bytes)
227            }
228            #[inline(always)]
229            fn from_le_bytes(bytes: Self::Bytes) -> Self {
230                <$t>::from_le_bytes(bytes)
231            }
232        }
233    };
234}
235
236impl<const N: usize> Primitive for [u8; N] {
237    type Bytes = [u8; N];
238
239    #[inline(always)]
240    fn buffer() -> Self::Bytes {
241        [0; N]
242    }
243
244    #[inline(always)]
245    fn to_be_bytes(self) -> Self::Bytes {
246        self
247    }
248
249    #[inline(always)]
250    fn to_le_bytes(self) -> Self::Bytes {
251        self
252    }
253
254    #[inline(always)]
255    fn from_be_bytes(bytes: Self::Bytes) -> Self {
256        bytes
257    }
258
259    #[inline(always)]
260    fn from_le_bytes(bytes: Self::Bytes) -> Self {
261        bytes
262    }
263}
264
265/// This trait is for integer types which can be read or written
266/// to a bit stream as a partial amount of bits.
267///
268/// It unifies signed and unsigned integer types by delegating
269/// reads and writes to the signed and unsigned reading
270/// and writing methods as appropriate.
271pub trait Integer {
272    /// Reads a value of ourself from the stream
273    /// with the given number of bits.
274    ///
275    /// # Errors
276    ///
277    /// Passes along any I/O error from the underlying stream.
278    /// A compile-time error occurs if the given number of bits
279    /// is larger than our type.
280    fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
281    where
282        Self: Sized;
283
284    /// Reads a value of ourself from the stream
285    /// with the given number of bits.
286    ///
287    /// # Errors
288    ///
289    /// Passes along any I/O error from the underlying stream.
290    /// Also returns an error if our type is too small
291    /// to hold the requested number of bits.
292    fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
293    where
294        R: BitRead + ?Sized,
295        Self: Sized;
296
297    /// Writes ourself to the stream using the given const number of bits.
298    ///
299    /// # Errors
300    ///
301    /// Passes along any I/O error from the underlying stream.
302    /// Returns an error if our value is too large
303    /// to fit the given number of bits.
304    /// A compile-time error occurs if the given number of bits
305    /// is larger than our type.
306    fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()>;
307
308    /// Writes ourself to the stream using the given number of bits.
309    ///
310    /// # Errors
311    ///
312    /// Passes along any I/O error from the underlying stream.
313    /// Returns an error if our value is too small
314    /// to hold the given number of bits.
315    /// Returns an error if our value is too large
316    /// to fit the given number of bits.
317    fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
318        self,
319        writer: &mut W,
320        bits: BitCount<MAX>,
321    ) -> io::Result<()>;
322}
323
324/// Reading and writing booleans as `Integer` requires the number of bits to be 1.
325///
326/// This is more useful when combined with the fixed array target
327/// for reading blocks of bit flags.
328///
329/// # Example
330/// ```
331/// use bitstream_io::{BitReader, BitRead, BigEndian};
332///
333/// #[derive(Debug, PartialEq, Eq)]
334/// struct Flags {
335///     a: bool,
336///     b: bool,
337///     c: bool,
338///     d: bool,
339/// }
340///
341/// let data: &[u8] = &[0b1011_0000];
342/// let mut r = BitReader::endian(data, BigEndian);
343/// // note the number of bits must be 1 per read
344/// // while the quantity of flags is indicated by the array length
345/// let flags = r.read::<1, [bool; 4]>().map(|[a, b, c, d]| Flags { a, b, c, d }).unwrap();
346/// assert_eq!(flags, Flags { a: true, b: false, c: true, d: true });
347/// ```
348impl Integer for bool {
349    #[inline(always)]
350    fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
351    where
352        Self: Sized,
353    {
354        const {
355            assert!(BITS == 1, "booleans require exactly 1 bit");
356        }
357
358        reader.read_bit()
359    }
360
361    fn read_var<const MAX: u32, R>(
362        reader: &mut R,
363        BitCount { bits }: BitCount<MAX>,
364    ) -> io::Result<Self>
365    where
366        R: BitRead + ?Sized,
367        Self: Sized,
368    {
369        if bits == 1 {
370            reader.read_bit()
371        } else {
372            Err(io::Error::new(
373                io::ErrorKind::InvalidInput,
374                "booleans require exactly 1 bit",
375            ))
376        }
377    }
378
379    #[inline(always)]
380    fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()> {
381        const {
382            assert!(BITS == 1, "booleans require exactly 1 bit");
383        }
384
385        writer.write_bit(self)
386    }
387
388    fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
389        self,
390        writer: &mut W,
391        BitCount { bits }: BitCount<MAX>,
392    ) -> io::Result<()> {
393        if bits == 1 {
394            writer.write_bit(self)
395        } else {
396            Err(io::Error::new(
397                io::ErrorKind::InvalidInput,
398                "booleans require exactly 1 bit",
399            ))
400        }
401    }
402}
403
404impl<const SIZE: usize, I: Integer + Copy + Default> Integer for [I; SIZE] {
405    #[inline]
406    fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
407    where
408        Self: Sized,
409    {
410        let mut a = [I::default(); SIZE];
411
412        a.iter_mut().try_for_each(|v| {
413            *v = reader.read::<BITS, I>()?;
414            Ok::<(), io::Error>(())
415        })?;
416
417        Ok(a)
418    }
419
420    #[inline]
421    fn read_var<const MAX: u32, R>(reader: &mut R, count: BitCount<MAX>) -> io::Result<Self>
422    where
423        R: BitRead + ?Sized,
424        Self: Sized,
425    {
426        let mut a = [I::default(); SIZE];
427
428        a.iter_mut().try_for_each(|v| {
429            *v = reader.read_counted(count)?;
430            Ok::<(), io::Error>(())
431        })?;
432
433        Ok(a)
434    }
435
436    #[inline]
437    fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()> {
438        IntoIterator::into_iter(self).try_for_each(|v| writer.write::<BITS, I>(v))
439    }
440
441    #[inline]
442    fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
443        self,
444        writer: &mut W,
445        count: BitCount<MAX>,
446    ) -> io::Result<()> {
447        IntoIterator::into_iter(self).try_for_each(|v| writer.write_counted(count, v))
448    }
449}
450
451/// This trait extends many common integer types (both unsigned and signed)
452/// with a few trivial methods so that they can be used
453/// with the bitstream handling traits.
454pub trait Numeric:
455    Primitive
456    + Sized
457    + Copy
458    + Default
459    + Debug
460    + PartialOrd
461    + Shl<u32, Output = Self>
462    + ShlAssign<u32>
463    + Shr<u32, Output = Self>
464    + ShrAssign<u32>
465    + Rem<Self, Output = Self>
466    + RemAssign<Self>
467    + BitAnd<Self, Output = Self>
468    + BitOr<Self, Output = Self>
469    + BitOrAssign<Self>
470    + BitXor<Self, Output = Self>
471    + Not<Output = Self>
472    + Sub<Self, Output = Self>
473{
474    /// Size of type in bits
475    const BITS_SIZE: u32;
476
477    /// The value of 0 in this type
478    const ZERO: Self;
479
480    /// The value of 1 in this type
481    const ONE: Self;
482
483    /// Returns a `u8` value in this type
484    fn from_u8(u: u8) -> Self;
485
486    /// Assuming 0 <= value < 256, returns this value as a `u8` type
487    fn to_u8(self) -> u8;
488}
489
490macro_rules! define_numeric {
491    ($t:ty) => {
492        define_primitive_numeric!($t);
493
494        impl Numeric for $t {
495            const BITS_SIZE: u32 = mem::size_of::<$t>() as u32 * 8;
496
497            const ZERO: Self = 0;
498
499            const ONE: Self = 1;
500
501            #[inline(always)]
502            fn from_u8(u: u8) -> Self {
503                u as $t
504            }
505            #[inline(always)]
506            fn to_u8(self) -> u8 {
507                self as u8
508            }
509        }
510    };
511}
512
513/// This trait extends many common unsigned integer types
514/// so that they can be used with the bitstream handling traits.
515pub trait UnsignedInteger: Numeric {
516    /// This type's most-significant bit
517    const MSB_BIT: Self;
518
519    /// This type's least significant bit
520    const LSB_BIT: Self;
521
522    /// This type with all bits set
523    const ALL: Self;
524
525    /// The signed variant of ourself
526    type Signed: SignedInteger<Unsigned = Self>;
527
528    /// Given a twos-complement value,
529    /// return this value is a non-negative signed number.
530    /// The location of the sign bit depends on the stream's endianness
531    /// and is not stored in the result.
532    ///
533    /// # Example
534    /// ```
535    /// use bitstream_io::UnsignedInteger;
536    /// assert_eq!(0b00000001u8.as_non_negative(), 1i8);
537    /// ```
538    fn as_non_negative(self) -> Self::Signed;
539
540    /// Given a two-complement positive value and certain number of bits,
541    /// returns this value as a negative signed number.
542    /// The location of the sign bit depends on the stream's endianness
543    /// and is not stored in the result.
544    ///
545    /// # Example
546    /// ```
547    /// use bitstream_io::UnsignedInteger;
548    /// assert_eq!(0b01111111u8.as_negative(8), -1i8);
549    /// ```
550    fn as_negative(self, bits: u32) -> Self::Signed;
551
552    /// Given a two-complement positive value and certain number of bits,
553    /// returns this value as a negative number.
554    ///
555    /// # Example
556    /// ```
557    /// use bitstream_io::UnsignedInteger;
558    /// assert_eq!(0b01111111u8.as_negative_fixed::<8>(), -1i8);
559    /// ```
560    fn as_negative_fixed<const BITS: u32>(self) -> Self::Signed;
561
562    /// Checked shift left
563    fn checked_shl(self, rhs: u32) -> Option<Self>;
564
565    /// Checked shift right
566    fn checked_shr(self, rhs: u32) -> Option<Self>;
567
568    /// Shift left up to our length in bits
569    ///
570    /// If rhs equals our length in bits, returns default
571    fn shl_default(self, rhs: u32) -> Self {
572        self.checked_shl(rhs).unwrap_or(Self::ZERO)
573    }
574
575    /// Shift left up to our length in bits
576    ///
577    /// If rhs equals our length in bits, returns zero
578    fn shr_default(self, rhs: u32) -> Self {
579        self.checked_shr(rhs).unwrap_or(Self::ZERO)
580    }
581}
582
583macro_rules! define_unsigned_integer {
584    ($t:ty, $s:ty) => {
585        define_numeric!($t);
586
587        impl UnsignedInteger for $t {
588            type Signed = $s;
589
590            const MSB_BIT: Self = 1 << (Self::BITS_SIZE - 1);
591
592            const LSB_BIT: Self = 1;
593
594            const ALL: Self = <$t>::MAX;
595
596            #[inline(always)]
597            fn as_non_negative(self) -> Self::Signed {
598                self as $s
599            }
600            #[inline(always)]
601            fn as_negative(self, bits: u32) -> Self::Signed {
602                (self as $s) + (-1 << (bits - 1))
603            }
604            #[inline(always)]
605            fn as_negative_fixed<const BITS: u32>(self) -> Self::Signed {
606                (self as $s) + (-1 << (BITS - 1))
607            }
608            #[inline(always)]
609            fn checked_shl(self, rhs: u32) -> Option<Self> {
610                self.checked_shl(rhs)
611            }
612            #[inline(always)]
613            fn checked_shr(self, rhs: u32) -> Option<Self> {
614                self.checked_shr(rhs)
615            }
616            // TODO - enable these in the future
617            // #[inline(always)]
618            // fn shl_default(self, rhs: u32) -> Self {
619            //     self.unbounded_shl(rhs)
620            // }
621            // #[inline(always)]
622            // fn shr_default(self, rhs: u32) -> Self {
623            //     self.unbounded_shr(rhs)
624            // }
625        }
626
627        impl Integer for $t {
628            #[inline(always)]
629            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
630            where
631                Self: Sized,
632            {
633                reader.read_unsigned::<BITS, _>()
634            }
635
636            #[inline(always)]
637            fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
638            where
639                R: BitRead + ?Sized,
640                Self: Sized,
641            {
642                reader.read_unsigned_counted::<MAX, _>(bits)
643            }
644
645            #[inline(always)]
646            fn write<const BITS: u32, W: BitWrite + ?Sized>(
647                self,
648                writer: &mut W,
649            ) -> io::Result<()> {
650                writer.write_unsigned::<BITS, _>(self)
651            }
652
653            #[inline(always)]
654            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
655                self,
656                writer: &mut W,
657                bits: BitCount<MAX>,
658            ) -> io::Result<()> {
659                writer.write_unsigned_counted(bits, self)
660            }
661        }
662
663        /// Unsigned NonZero types increment their value by 1
664        /// when being read and decrement it by 1
665        /// when being written.
666        ///
667        /// # Examples
668        /// ```
669        /// use bitstream_io::{BitReader, BitRead, BigEndian};
670        /// use core::num::NonZero;
671        ///
672        /// let data: &[u8] = &[0b001_00000];
673        /// // reading a regular u8 in 3 bits yields 1
674        /// assert_eq!(BitReader::endian(data, BigEndian).read::<3, u8>().unwrap(), 1);
675        /// // reading a NonZero<u8> in 3 bits of the same data yields 2
676        /// assert_eq!(BitReader::endian(data, BigEndian).read::<3, NonZero<u8>>().unwrap().get(), 2);
677        /// ```
678        ///
679        /// ```
680        /// use bitstream_io::{BitWriter, BitWrite, BigEndian};
681        /// use core::num::NonZero;
682        ///
683        /// let mut w = BitWriter::endian(vec![], BigEndian);
684        /// // writing 1 as a regular u8 in 3 bits
685        /// w.write::<3, u8>(1).unwrap();
686        /// w.byte_align();
687        /// assert_eq!(w.into_writer(), &[0b001_00000]);
688        ///
689        /// let mut w = BitWriter::endian(vec![], BigEndian);
690        /// // writing 1 as a NonZero<u8> in 3 bits
691        /// w.write::<3, NonZero<u8>>(NonZero::new(1).unwrap()).unwrap();
692        /// w.byte_align();
693        /// assert_eq!(w.into_writer(), &[0b000_00000]);
694        /// ```
695        impl Integer for NonZero<$t> {
696            #[inline]
697            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
698            where
699                Self: Sized,
700            {
701                const {
702                    assert!(
703                        BITS < <$t>::BITS_SIZE,
704                        "BITS must be less than the type's size in bits"
705                    );
706                }
707
708                <$t as Integer>::read::<BITS, R>(reader).map(|u| NonZero::new(u + 1).unwrap())
709            }
710
711            #[inline]
712            fn read_var<const MAX: u32, R>(
713                reader: &mut R,
714                count @ BitCount { bits }: BitCount<MAX>,
715            ) -> io::Result<Self>
716            where
717                R: BitRead + ?Sized,
718                Self: Sized,
719            {
720                if MAX < <$t>::BITS_SIZE || bits < <$t>::BITS_SIZE {
721                    <$t as Integer>::read_var::<MAX, R>(reader, count)
722                        .map(|u| NonZero::new(u + 1).unwrap())
723                } else {
724                    Err(io::Error::new(
725                        io::ErrorKind::InvalidInput,
726                        "bit count must be less than the type's size in bits",
727                    ))
728                }
729            }
730
731            #[inline]
732            fn write<const BITS: u32, W: BitWrite + ?Sized>(
733                self,
734                writer: &mut W,
735            ) -> io::Result<()> {
736                const {
737                    assert!(
738                        BITS < <$t>::BITS_SIZE,
739                        "BITS must be less than the type's size in bits"
740                    );
741                }
742
743                <$t as Integer>::write::<BITS, W>(self.get() - 1, writer)
744            }
745
746            #[inline]
747            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
748                self,
749                writer: &mut W,
750                count @ BitCount { bits }: BitCount<MAX>,
751            ) -> io::Result<()> {
752                if MAX < <$t>::BITS_SIZE || bits < <$t>::BITS_SIZE {
753                    <$t as Integer>::write_var::<MAX, W>(self.get() - 1, writer, count)
754                } else {
755                    Err(io::Error::new(
756                        io::ErrorKind::InvalidInput,
757                        "bit count must be less than the type's size in bits",
758                    ))
759                }
760            }
761        }
762
763        impl Integer for Option<NonZero<$t>> {
764            #[inline]
765            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
766            where
767                Self: Sized,
768            {
769                <$t as Integer>::read::<BITS, R>(reader).map(NonZero::new)
770            }
771
772            #[inline]
773            fn read_var<const MAX: u32, R>(reader: &mut R, count: BitCount<MAX>) -> io::Result<Self>
774            where
775                R: BitRead + ?Sized,
776                Self: Sized,
777            {
778                <$t as Integer>::read_var::<MAX, R>(reader, count).map(NonZero::new)
779            }
780
781            #[inline]
782            fn write<const BITS: u32, W: BitWrite + ?Sized>(
783                self,
784                writer: &mut W,
785            ) -> io::Result<()> {
786                <$t as Integer>::write::<BITS, W>(self.map(|n| n.get()).unwrap_or(0), writer)
787            }
788
789            #[inline]
790            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
791                self,
792                writer: &mut W,
793                count: BitCount<MAX>,
794            ) -> io::Result<()> {
795                <$t as Integer>::write_var::<MAX, W>(
796                    self.map(|n| n.get()).unwrap_or(0),
797                    writer,
798                    count,
799                )
800            }
801        }
802    };
803}
804
805/// This trait extends many common signed integer types
806/// so that they can be used with the bitstream handling traits.
807///
808/// This trait was formerly named `SignedNumeric` in 2.X.X code.
809/// If backwards-compatibility is needed one can
810/// import `SignedInteger` as `SignedNumeric`.
811pub trait SignedInteger: Numeric {
812    /// The unsigned variant of ourself
813    type Unsigned: UnsignedInteger<Signed = Self>;
814
815    /// Returns true if this value is negative
816    ///
817    /// # Example
818    /// ```
819    /// use bitstream_io::SignedInteger;
820    /// assert!(!1i8.is_negative());
821    /// assert!((-1i8).is_negative());
822    /// ```
823    fn is_negative(self) -> bool;
824
825    /// Returns ourself as a non-negative value.
826    /// The location of the sign bit depends on the stream's endianness
827    /// and is not stored in the result.
828    ///
829    /// # Example
830    /// ```
831    /// use bitstream_io::SignedInteger;
832    /// assert_eq!(1i8.as_non_negative(), 0b00000001u8);
833    /// ```
834    fn as_non_negative(self) -> Self::Unsigned;
835
836    /// Given a negative value and a certain number of bits,
837    /// returns this value as a twos-complement positive number.
838    /// The location of the sign bit depends on the stream's endianness
839    /// and is not stored in the result.
840    ///
841    /// # Example
842    /// ```
843    /// use bitstream_io::SignedInteger;
844    /// assert_eq!((-1i8).as_negative(8), 0b01111111u8);
845    /// ```
846    fn as_negative(self, bits: u32) -> Self::Unsigned;
847
848    /// Given a negative value and a certain number of bits,
849    /// returns this value as a twos-complement positive number.
850    ///
851    /// # Example
852    /// ```
853    /// use bitstream_io::SignedInteger;
854    /// assert_eq!((-1i8).as_negative_fixed::<8>(), 0b01111111u8);
855    /// ```
856    fn as_negative_fixed<const BITS: u32>(self) -> Self::Unsigned;
857}
858
859macro_rules! define_signed_integer {
860    ($t:ty, $u:ty) => {
861        define_numeric!($t);
862
863        impl SignedInteger for $t {
864            type Unsigned = $u;
865
866            #[inline(always)]
867            fn is_negative(self) -> bool {
868                self.is_negative()
869            }
870            fn as_non_negative(self) -> Self::Unsigned {
871                self as $u
872            }
873            fn as_negative(self, bits: u32) -> Self::Unsigned {
874                (self - (-1 << (bits - 1))) as $u
875            }
876            fn as_negative_fixed<const BITS: u32>(self) -> Self::Unsigned {
877                (self - (-1 << (BITS - 1))) as $u
878            }
879        }
880
881        impl Integer for $t {
882            #[inline(always)]
883            fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
884            where
885                Self: Sized,
886            {
887                reader.read_signed::<BITS, _>()
888            }
889
890            #[inline(always)]
891            fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
892            where
893                R: BitRead + ?Sized,
894                Self: Sized,
895            {
896                reader.read_signed_counted::<MAX, _>(bits)
897            }
898
899            #[inline(always)]
900            fn write<const BITS: u32, W: BitWrite + ?Sized>(
901                self,
902                writer: &mut W,
903            ) -> io::Result<()> {
904                writer.write_signed::<BITS, _>(self)
905            }
906
907            #[inline(always)]
908            fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
909                self,
910                writer: &mut W,
911                bits: BitCount<MAX>,
912            ) -> io::Result<()> {
913                writer.write_signed_counted::<MAX, _>(bits, self)
914            }
915        }
916    };
917}
918
919define_unsigned_integer!(u8, i8);
920define_unsigned_integer!(u16, i16);
921define_unsigned_integer!(u32, i32);
922define_unsigned_integer!(u64, i64);
923define_unsigned_integer!(u128, i128);
924
925define_signed_integer!(i8, u8);
926define_signed_integer!(i16, u16);
927define_signed_integer!(i32, u32);
928define_signed_integer!(i64, u64);
929define_signed_integer!(i128, u128);
930
931define_primitive_numeric!(f32);
932define_primitive_numeric!(f64);
933
934mod private {
935    use crate::{
936        io, BitCount, BitRead, BitWrite, CheckedSigned, CheckedUnsigned, Primitive, SignedBitCount,
937        SignedInteger, UnsignedInteger,
938    };
939
940    #[test]
941    fn test_checked_signed() {
942        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<8>(), -128i8).is_ok());
943        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<8>(), 127i8).is_ok());
944        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<7>(), -64i8).is_ok());
945        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<7>(), 63i8).is_ok());
946        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<6>(), -32i8).is_ok());
947        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<6>(), 31i8).is_ok());
948        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<5>(), -16i8).is_ok());
949        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<5>(), 15i8).is_ok());
950        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<4>(), -8i8).is_ok());
951        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<4>(), 7i8).is_ok());
952        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<3>(), -4i8).is_ok());
953        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<3>(), 3i8).is_ok());
954        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<2>(), -2i8).is_ok());
955        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<2>(), 1i8).is_ok());
956        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<1>(), -1i8).is_ok());
957        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<1>(), 0i8).is_ok());
958
959        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<7>(), -65i8).is_err());
960        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<7>(), 64i8).is_err());
961        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<6>(), -33i8).is_err());
962        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<6>(), 32i8).is_err());
963        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<5>(), -17i8).is_err());
964        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<5>(), 16i8).is_err());
965        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<4>(), -9i8).is_err());
966        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<4>(), 8i8).is_err());
967        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<3>(), -5i8).is_err());
968        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<3>(), 4i8).is_err());
969        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<2>(), -3i8).is_err());
970        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<2>(), 2i8).is_err());
971        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<1>(), -2i8).is_err());
972        assert!(CheckedSigned::new(SignedBitCount::<8>::new::<1>(), 1i8).is_err());
973    }
974
975    pub trait Endianness: Sized {
976        /// Pops the next bit from the queue,
977        /// repleneshing it from the given reader if necessary
978        fn pop_bit_refill<R>(
979            reader: &mut R,
980            queue_value: &mut u8,
981            queue_bits: &mut u32,
982        ) -> io::Result<bool>
983        where
984            R: io::Read;
985
986        /// Pops the next unary value from the source until
987        /// `STOP_BIT` is encountered, replenishing it from the given
988        /// closure if necessary.
989        ///
990        /// `STOP_BIT` must be 0 or 1.
991        fn pop_unary<const STOP_BIT: u8, R>(
992            reader: &mut R,
993            queue_value: &mut u8,
994            queue_bits: &mut u32,
995        ) -> io::Result<u32>
996        where
997            R: io::Read;
998
999        /// Pushes the next bit into the queue,
1000        /// and returns `Some` value if the queue is full.
1001        fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8>;
1002
1003        /// For performing bulk reads from a bit source to an output type.
1004        fn read_bits<const MAX: u32, R, U>(
1005            reader: &mut R,
1006            queue_value: &mut u8,
1007            queue_bits: &mut u32,
1008            count: BitCount<MAX>,
1009        ) -> io::Result<U>
1010        where
1011            R: io::Read,
1012            U: UnsignedInteger;
1013
1014        /// For performing bulk reads from a bit source to an output type.
1015        fn read_bits_fixed<const BITS: u32, R, U>(
1016            reader: &mut R,
1017            queue_value: &mut u8,
1018            queue_bits: &mut u32,
1019        ) -> io::Result<U>
1020        where
1021            R: io::Read,
1022            U: UnsignedInteger;
1023
1024        /// For performing a checked write to a bit sink
1025        fn write_bits_checked<const MAX: u32, W, U>(
1026            writer: &mut W,
1027            queue_value: &mut u8,
1028            queue_bits: &mut u32,
1029            value: CheckedUnsigned<MAX, U>,
1030        ) -> io::Result<()>
1031        where
1032            W: io::Write,
1033            U: UnsignedInteger;
1034
1035        /// For performing a checked signed write to a bit sink
1036        fn write_signed_bits_checked<const MAX: u32, W, S>(
1037            writer: &mut W,
1038            queue_value: &mut u8,
1039            queue_bits: &mut u32,
1040            value: CheckedSigned<MAX, S>,
1041        ) -> io::Result<()>
1042        where
1043            W: io::Write,
1044            S: SignedInteger;
1045
1046        /// Reads signed value from reader in this endianness
1047        fn read_signed_counted<const MAX: u32, R, S>(
1048            r: &mut R,
1049            bits: SignedBitCount<MAX>,
1050        ) -> io::Result<S>
1051        where
1052            R: BitRead,
1053            S: SignedInteger;
1054
1055        /// Reads whole set of bytes to output buffer
1056        fn read_bytes<const CHUNK_SIZE: usize, R>(
1057            reader: &mut R,
1058            queue_value: &mut u8,
1059            queue_bits: u32,
1060            buf: &mut [u8],
1061        ) -> io::Result<()>
1062        where
1063            R: io::Read;
1064
1065        /// Writes whole set of bytes to output buffer
1066        fn write_bytes<const CHUNK_SIZE: usize, W>(
1067            writer: &mut W,
1068            queue_value: &mut u8,
1069            queue_bits: u32,
1070            buf: &[u8],
1071        ) -> io::Result<()>
1072        where
1073            W: io::Write;
1074
1075        /// Converts a primitive's byte buffer to a primitive
1076        fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P;
1077
1078        /// Converts a primitive to a primitive's byte buffer
1079        fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes;
1080
1081        /// Reads convertable numeric value from reader in this endianness
1082        #[deprecated(since = "4.0.0")]
1083        fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
1084        where
1085            R: BitRead,
1086            V: Primitive;
1087
1088        /// Writes convertable numeric value to writer in this endianness
1089        #[deprecated(since = "4.0.0")]
1090        fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
1091        where
1092            W: BitWrite,
1093            V: Primitive;
1094    }
1095
1096    pub trait Checkable {
1097        fn write_endian<E, W>(
1098            self,
1099            writer: &mut W,
1100            queue_value: &mut u8,
1101            queue_bits: &mut u32,
1102        ) -> io::Result<()>
1103        where
1104            E: Endianness,
1105            W: io::Write;
1106    }
1107}
1108
1109/// A stream's endianness, or byte order, for determining
1110/// how bits should be read.
1111///
1112/// It comes in `BigEndian` and `LittleEndian` varieties
1113/// (which may be shortened to `BE` and `LE`)
1114/// and is not something programmers should implement directly.
1115pub trait Endianness: private::Endianness {}
1116
1117#[inline(always)]
1118fn read_byte<R>(mut reader: R) -> io::Result<u8>
1119where
1120    R: io::Read,
1121{
1122    let mut byte = 0;
1123    reader
1124        .read_exact(core::slice::from_mut(&mut byte))
1125        .map(|()| byte)
1126}
1127
1128#[inline(always)]
1129fn write_byte<W>(mut writer: W, byte: u8) -> io::Result<()>
1130where
1131    W: io::Write,
1132{
1133    writer.write_all(core::slice::from_ref(&byte))
1134}
1135
1136/// A number of bits to be consumed or written, with a known maximum
1137///
1138/// Although [`BitRead::read`] and [`BitWrite::write`] should be
1139/// preferred when the number of bits is fixed and known at compile-time -
1140/// because they can validate the bit count is less than or equal
1141/// to the type's size in bits at compile-time -
1142/// there are many instances where bit count is dynamic and
1143/// determined by the file format itself.
1144/// But when using [`BitRead::read_var`] or [`BitWrite::write_var`]
1145/// we must pessimistically assume any number of bits as an argument
1146/// and validate that the number of bits is not larger than the
1147/// type being read or written on every call.
1148///
1149/// ```
1150/// use bitstream_io::{BitRead, BitReader, BigEndian};
1151///
1152/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1153/// let mut r = BitReader::endian(data, BigEndian);
1154/// // our bit count is a 3 bit value
1155/// let count = r.read::<3, u32>().unwrap();
1156/// // that count indicates we need to read 4 bits (0b100)
1157/// assert_eq!(count, 4);
1158/// // read the first 4-bit value
1159/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b0001);
1160/// // read the second 4-bit value
1161/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b1111);
1162/// // read the third 4-bit value
1163/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b0110);
1164/// ```
1165///
1166/// In the preceding example, even though we know `count` is a
1167/// 3 bit value whose maximum value will never be greater than 7,
1168/// the subsequent `read_var` calls have no way to know that.
1169/// They must assume `count` could be 9, or `u32::MAX` or any other `u32` value
1170/// and validate the count is not larger than the `u8` types we're reading.
1171///
1172/// But we can convert our example to use the `BitCount` type:
1173///
1174/// ```
1175/// use bitstream_io::{BitRead, BitReader, BigEndian, BitCount};
1176///
1177/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1178/// let mut r = BitReader::endian(data, BigEndian);
1179/// // our bit count is a 3 bit value with a maximum value of 7
1180/// let count = r.read_count::<0b111>().unwrap();
1181/// // that count indicates we need to read 4 bits (0b100)
1182/// assert_eq!(count, BitCount::<7>::new::<4>());
1183/// // read the first 4-bit value
1184/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b0001);
1185/// // read the second 4-bit value
1186/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b1111);
1187/// // read the third 4-bit value
1188/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b0110);
1189/// ```
1190///
1191/// Because the [`BitRead::read_counted`] methods know at compile-time
1192/// that the bit count will be larger than 7, that check can be eliminated
1193/// simply by taking advantage of information we already know.
1194///
1195/// Leveraging the `BitCount` type also allows us to reason about
1196/// bit counts in a more formal way, and use checked permutation methods
1197/// to modify them while ensuring they remain constrained by
1198/// the file format's requirements.
1199#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1200pub struct BitCount<const MAX: u32> {
1201    // The amount of bits may be less than or equal to the maximum,
1202    // but never more.
1203    bits: u32,
1204}
1205
1206impl<const MAX: u32> BitCount<MAX> {
1207    /// Builds a bit count from a constant number
1208    /// of bits, which must not be greater than `MAX`.
1209    ///
1210    /// Intended to be used for defining constants.
1211    ///
1212    /// Use `TryFrom` to conditionally build
1213    /// counts from values at runtime.
1214    ///
1215    /// # Examples
1216    ///
1217    /// ```
1218    /// use bitstream_io::{BitReader, BitRead, BigEndian, BitCount};
1219    /// let data: &[u8] = &[0b111_00000];
1220    /// let mut r = BitReader::endian(data, BigEndian);
1221    /// // reading 3 bits from a stream out of a maximum of 8
1222    /// // doesn't require checking that the bit count is larger
1223    /// // than a u8 at runtime because specifying the maximum of 8
1224    /// // guarantees our bit count will not be larger than 8
1225    /// assert_eq!(r.read_counted::<8, u8>(BitCount::new::<3>()).unwrap(), 0b111);
1226    /// ```
1227    ///
1228    /// ```rust,compile_fail
1229    /// use bitstream_io::BitCount;
1230    /// // trying to build a count of 10 with a maximum of 8
1231    /// // fails to compile at all
1232    /// let count = BitCount::<8>::new::<10>();
1233    /// ```
1234    pub const fn new<const BITS: u32>() -> Self {
1235        const {
1236            assert!(BITS <= MAX, "BITS must be <= MAX");
1237        }
1238
1239        Self { bits: BITS }
1240    }
1241
1242    /// Add a number of bits to our count,
1243    /// returning a new count with a new maximum.
1244    ///
1245    /// Returns `None` if the new count goes above our new maximum.
1246    ///
1247    /// # Examples
1248    ///
1249    /// ```
1250    /// use bitstream_io::BitCount;
1251    ///
1252    /// let count = BitCount::<2>::new::<1>();
1253    /// // adding 2 to 1 and increasing the max to 3 yields a new count of 3
1254    /// assert_eq!(count.checked_add::<3>(2), Some(BitCount::<3>::new::<3>()));
1255    /// // adding 2 to 1 without increasing the max yields None
1256    /// assert_eq!(count.checked_add::<2>(2), None);
1257    /// ```
1258    #[inline]
1259    pub const fn checked_add<const NEW_MAX: u32>(self, bits: u32) -> Option<BitCount<NEW_MAX>> {
1260        match self.bits.checked_add(bits) {
1261            Some(bits) if bits <= NEW_MAX => Some(BitCount { bits }),
1262            _ => None,
1263        }
1264    }
1265
1266    /// Subtracts a number of bits from our count,
1267    /// returning a new count with a new maximum.
1268    ///
1269    /// Returns `None` if the new count goes below 0
1270    /// or below our new maximum.
1271    ///
1272    /// # Example
1273    /// ```
1274    /// use bitstream_io::BitCount;
1275    /// let count = BitCount::<5>::new::<5>();
1276    /// // subtracting 1 from 5 yields a new count of 4
1277    /// assert_eq!(count.checked_sub::<5>(1), Some(BitCount::<5>::new::<4>()));
1278    /// // subtracting 6 from 5 yields None
1279    /// assert!(count.checked_sub::<5>(6).is_none());
1280    /// // subtracting 1 with a new maximum of 3 also yields None
1281    /// // because 4 is larger than the maximum of 3
1282    /// assert!(count.checked_sub::<3>(1).is_none());
1283    /// ```
1284    #[inline]
1285    pub const fn checked_sub<const NEW_MAX: u32>(self, bits: u32) -> Option<BitCount<NEW_MAX>> {
1286        match self.bits.checked_sub(bits) {
1287            Some(bits) if bits <= NEW_MAX => Some(BitCount { bits }),
1288            _ => None,
1289        }
1290    }
1291
1292    /// Attempt to convert our count to a count with a new
1293    /// bit count and new maximum.
1294    ///
1295    /// Returns `Some(count)` if the updated number of bits
1296    /// is less than or equal to the new maximum.
1297    /// Returns `None` if not.
1298    ///
1299    /// # Examples
1300    /// ```
1301    /// use bitstream_io::BitCount;
1302    ///
1303    /// let count = BitCount::<5>::new::<5>();
1304    /// // muliplying 5 bits by 2 with a new max of 10 is ok
1305    /// assert_eq!(
1306    ///     count.try_map::<10, _>(|i| i.checked_mul(2)),
1307    ///     Some(BitCount::<10>::new::<10>()),
1308    /// );
1309    ///
1310    /// // multiplying 5 bits by 3 with a new max of 10 overflows
1311    /// assert_eq!(count.try_map::<10, _>(|i| i.checked_mul(3)), None);
1312    /// ```
1313    #[inline]
1314    pub fn try_map<const NEW_MAX: u32, F>(self, f: F) -> Option<BitCount<NEW_MAX>>
1315    where
1316        F: FnOnce(u32) -> Option<u32>,
1317    {
1318        f(self.bits)
1319            .filter(|bits| *bits <= NEW_MAX)
1320            .map(|bits| BitCount { bits })
1321    }
1322
1323    /// Returns our maximum bit count
1324    ///
1325    /// # Example
1326    /// ```
1327    /// use bitstream_io::BitCount;
1328    ///
1329    /// let count = BitCount::<10>::new::<5>();
1330    /// assert_eq!(count.max(), 10);
1331    /// ```
1332    #[inline(always)]
1333    pub const fn max(&self) -> u32 {
1334        MAX
1335    }
1336
1337    /// Returns signed count if our bit count is greater than 0
1338    ///
1339    /// # Example
1340    ///
1341    /// ```
1342    /// use bitstream_io::{BitCount, SignedBitCount};
1343    ///
1344    /// let count = BitCount::<10>::new::<5>();
1345    /// assert_eq!(count.signed_count(), Some(SignedBitCount::<10>::new::<5>()));
1346    ///
1347    /// let count = BitCount::<10>::new::<0>();
1348    /// assert_eq!(count.signed_count(), None);
1349    /// ```
1350    #[inline(always)]
1351    pub const fn signed_count(&self) -> Option<SignedBitCount<MAX>> {
1352        match self.bits.checked_sub(1) {
1353            Some(bits) => Some(SignedBitCount {
1354                bits: *self,
1355                unsigned: BitCount { bits },
1356            }),
1357            None => None,
1358        }
1359    }
1360
1361    /// Masks off the least-significant bits for the given type
1362    ///
1363    /// Returns closure that takes a value and returns a
1364    /// pair of the most-significant and least-significant
1365    /// bits.  Because the least-significant bits cannot
1366    /// be larger than this bit count, that value is
1367    /// returned as a [`Checked`] type.
1368    ///
1369    /// # Examples
1370    ///
1371    /// ```
1372    /// use bitstream_io::BitCount;
1373    ///
1374    /// // create a bit count of 3
1375    /// let count = BitCount::<8>::new::<3>();
1376    ///
1377    /// // create a mask suitable for u8 types
1378    /// let mask = count.mask_lsb::<u8>();
1379    ///
1380    /// let (msb, lsb) = mask(0b11011_110);
1381    /// assert_eq!(msb, 0b11011);             // the most-significant bits
1382    /// assert_eq!(lsb.into_value(), 0b110);  // the least-significant bits
1383    ///
1384    /// let (msb, lsb) = mask(0b01100_010);
1385    /// assert_eq!(msb, 0b01100);             // the most-significant bits
1386    /// assert_eq!(lsb.into_value(), 0b010);  // the least-significant bits
1387    ///
1388    /// let (msb, lsb) = mask(0b00000_111);
1389    /// assert_eq!(msb, 0b00000);             // the most-significant bits
1390    /// assert_eq!(lsb.into_value(), 0b111);  // the least-significant bits
1391    /// ```
1392    ///
1393    /// ```
1394    /// use bitstream_io::BitCount;
1395    ///
1396    /// // a mask with a bit count of 0 puts everything in msb
1397    /// let mask = BitCount::<8>::new::<0>().mask_lsb::<u8>();
1398    ///
1399    /// let (msb, lsb) = mask(0b11111111);
1400    /// assert_eq!(msb, 0b11111111);
1401    /// assert_eq!(lsb.into_value(), 0);
1402    ///
1403    /// // a mask with a bit count larger than the type
1404    /// // is restricted to that type's size, if possible
1405    /// let mask = BitCount::<16>::new::<9>().mask_lsb::<u8>();
1406    ///
1407    /// let (msb, lsb) = mask(0b11111111);
1408    /// assert_eq!(msb, 0);
1409    /// assert_eq!(lsb.into_value(), 0b11111111);
1410    /// ```
1411    pub fn mask_lsb<U: UnsignedInteger>(self) -> impl Fn(U) -> (U, CheckedUnsigned<MAX, U>) {
1412        use core::convert::TryFrom;
1413
1414        let (mask, shift, count) = match U::BITS_SIZE.checked_sub(self.bits) {
1415            Some(mask_bits) => (U::ALL.shr_default(mask_bits), self.bits, self),
1416            None => (
1417                U::ALL,
1418                U::BITS_SIZE,
1419                BitCount::try_from(U::BITS_SIZE).expect("bit count too small for type"),
1420            ),
1421        };
1422
1423        move |v| {
1424            (
1425                v.shr_default(shift),
1426                Checked {
1427                    value: v & mask,
1428                    count,
1429                },
1430            )
1431        }
1432    }
1433
1434    /// Returns this bit count's range for the given unsigned type
1435    ///
1436    /// # Example
1437    ///
1438    /// ```
1439    /// use bitstream_io::BitCount;
1440    ///
1441    /// assert_eq!(BitCount::<9>::new::<0>().range::<u8>(), 0..=0);
1442    /// assert_eq!(BitCount::<9>::new::<1>().range::<u8>(), 0..=0b1);
1443    /// assert_eq!(BitCount::<9>::new::<2>().range::<u8>(), 0..=0b11);
1444    /// assert_eq!(BitCount::<9>::new::<3>().range::<u8>(), 0..=0b111);
1445    /// assert_eq!(BitCount::<9>::new::<4>().range::<u8>(), 0..=0b1111);
1446    /// assert_eq!(BitCount::<9>::new::<5>().range::<u8>(), 0..=0b11111);
1447    /// assert_eq!(BitCount::<9>::new::<6>().range::<u8>(), 0..=0b111111);
1448    /// assert_eq!(BitCount::<9>::new::<7>().range::<u8>(), 0..=0b1111111);
1449    /// assert_eq!(BitCount::<9>::new::<8>().range::<u8>(), 0..=0b11111111);
1450    /// // a count that exceeds the type's size is
1451    /// // naturally restricted to that type's maximum range
1452    /// assert_eq!(BitCount::<9>::new::<9>().range::<u8>(), 0..=0b11111111);
1453    /// ```
1454    #[inline]
1455    pub fn range<U: UnsignedInteger>(&self) -> core::ops::RangeInclusive<U> {
1456        match U::ONE.checked_shl(self.bits) {
1457            Some(top) => U::ZERO..=(top - U::ONE),
1458            None => U::ZERO..=U::ALL,
1459        }
1460    }
1461
1462    /// Returns minimum value between ourself and bit count
1463    ///
1464    /// # Example
1465    ///
1466    /// ```
1467    /// use bitstream_io::BitCount;
1468    ///
1469    /// let count = BitCount::<8>::new::<7>();
1470    /// assert_eq!(count.min(6), BitCount::new::<6>());
1471    /// assert_eq!(count.min(8), BitCount::new::<7>());
1472    /// ```
1473    #[inline(always)]
1474    pub fn min(self, bits: u32) -> Self {
1475        // the minimum of ourself and another bit count
1476        // can never exceed our maximum bit count
1477        Self {
1478            bits: self.bits.min(bits),
1479        }
1480    }
1481
1482    /// Returns the minimum value of an unsigned int in this bit count
1483    ///
1484    /// # Example
1485    ///
1486    /// ```
1487    /// use bitstream_io::BitCount;
1488    ///
1489    /// assert_eq!(BitCount::<8>::new::<0>().none::<u8>().into_value(), 0b0);
1490    /// assert_eq!(BitCount::<8>::new::<1>().none::<u8>().into_value(), 0b0);
1491    /// assert_eq!(BitCount::<8>::new::<2>().none::<u8>().into_value(), 0b00);
1492    /// assert_eq!(BitCount::<8>::new::<3>().none::<u8>().into_value(), 0b000);
1493    /// assert_eq!(BitCount::<8>::new::<4>().none::<u8>().into_value(), 0b0000);
1494    /// assert_eq!(BitCount::<8>::new::<5>().none::<u8>().into_value(), 0b00000);
1495    /// assert_eq!(BitCount::<8>::new::<6>().none::<u8>().into_value(), 0b000000);
1496    /// assert_eq!(BitCount::<8>::new::<7>().none::<u8>().into_value(), 0b0000000);
1497    /// assert_eq!(BitCount::<8>::new::<8>().none::<u8>().into_value(), 0b00000000);
1498    /// ```
1499    #[inline(always)]
1500    pub fn none<U: UnsignedInteger>(self) -> CheckedUnsigned<MAX, U> {
1501        CheckedUnsigned {
1502            value: U::ZERO,
1503            count: self,
1504        }
1505    }
1506
1507    /// Returns the maximum value of an unsigned int in this bit count
1508    ///
1509    /// # Example
1510    ///
1511    /// ```
1512    /// use bitstream_io::BitCount;
1513    ///
1514    /// assert_eq!(BitCount::<8>::new::<0>().all::<u8>().into_value(), 0b0);
1515    /// assert_eq!(BitCount::<8>::new::<1>().all::<u8>().into_value(), 0b1);
1516    /// assert_eq!(BitCount::<8>::new::<2>().all::<u8>().into_value(), 0b11);
1517    /// assert_eq!(BitCount::<8>::new::<3>().all::<u8>().into_value(), 0b111);
1518    /// assert_eq!(BitCount::<8>::new::<4>().all::<u8>().into_value(), 0b1111);
1519    /// assert_eq!(BitCount::<8>::new::<5>().all::<u8>().into_value(), 0b11111);
1520    /// assert_eq!(BitCount::<8>::new::<6>().all::<u8>().into_value(), 0b111111);
1521    /// assert_eq!(BitCount::<8>::new::<7>().all::<u8>().into_value(), 0b1111111);
1522    /// assert_eq!(BitCount::<8>::new::<8>().all::<u8>().into_value(), 0b11111111);
1523    /// ```
1524    #[inline(always)]
1525    pub fn all<U: UnsignedInteger>(self) -> CheckedUnsigned<MAX, U> {
1526        CheckedUnsigned {
1527            value: match U::ONE.checked_shl(self.bits) {
1528                Some(top) => top - U::ONE,
1529                None => U::ALL,
1530            },
1531            count: self,
1532        }
1533    }
1534}
1535
1536impl<const MAX: u32> core::convert::TryFrom<u32> for BitCount<MAX> {
1537    type Error = u32;
1538
1539    /// Attempts to convert a `u32` bit count to a `BitCount`
1540    ///
1541    /// Attempting a bit maximum bit count larger than the
1542    /// largest supported type is a compile-time error
1543    ///
1544    /// # Examples
1545    /// ```
1546    /// use bitstream_io::BitCount;
1547    /// use std::convert::TryInto;
1548    ///
1549    /// assert_eq!(8u32.try_into(), Ok(BitCount::<8>::new::<8>()));
1550    /// assert_eq!(9u32.try_into(), Err::<BitCount<8>, _>(9));
1551    /// ```
1552    fn try_from(bits: u32) -> Result<Self, Self::Error> {
1553        (bits <= MAX).then_some(Self { bits }).ok_or(bits)
1554    }
1555}
1556
1557impl<const MAX: u32> core::fmt::Display for BitCount<MAX> {
1558    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1559        core::fmt::Display::fmt(&self.bits, f)
1560    }
1561}
1562
1563impl BitCount<{ u32::MAX }> {
1564    /// Builds a bit count where the maximum bits is unknown.
1565    ///
1566    /// # Example
1567    /// ```
1568    /// use bitstream_io::BitCount;
1569    /// assert_eq!(BitCount::unknown(5), BitCount::<{ u32::MAX }>::new::<5>());
1570    /// ```
1571    pub const fn unknown(bits: u32) -> Self {
1572        Self { bits }
1573    }
1574}
1575
1576#[test]
1577fn test_unknown_bitcount() {
1578    let count = BitCount::unknown(u32::MAX);
1579    assert!(u32::from(count) <= count.max());
1580}
1581
1582impl<const MAX: u32> From<BitCount<MAX>> for u32 {
1583    #[inline(always)]
1584    fn from(BitCount { bits }: BitCount<MAX>) -> u32 {
1585        bits
1586    }
1587}
1588
1589/// A number of bits to be read or written for signed integers, with a known maximum
1590///
1591/// This is closely related to the [`BitCount`] type, but further constrained
1592/// to have a minimum value of 1 - because signed values require at least
1593/// 1 bit for the sign.
1594///
1595/// Let's start with a basic example:
1596///
1597/// ```
1598/// use bitstream_io::{BitRead, BitReader, BigEndian};
1599///
1600/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1601/// let mut r = BitReader::endian(data, BigEndian);
1602/// // our bit count is a 3 bit value
1603/// let count = r.read::<3, u32>().unwrap();
1604/// // that count indicates we need to read 4 bits (0b100)
1605/// assert_eq!(count, 4);
1606/// // read the first 4-bit signed value
1607/// assert_eq!(r.read_var::<i8>(count).unwrap(), 1);
1608/// // read the second 4-bit signed value
1609/// assert_eq!(r.read_var::<i8>(count).unwrap(), -1);
1610/// // read the third 4-bit signed value
1611/// assert_eq!(r.read_var::<i8>(count).unwrap(), 6);
1612/// ```
1613///
1614/// In the preceding example, even though we know `count` is a
1615/// 3 bit value whose maximum value will never be greater than 7,
1616/// the subsequent `read_var` calls have no way to know that.
1617/// They must assume `count` could be 9, or `u32::MAX` or any other `u32` value
1618/// and validate the count is not larger than the `i8` types we're reading
1619/// while also greater than 0 because `i8` requires a sign bit.
1620///
1621/// But we can convert our example to use the `SignedBitCount` type:
1622/// ```
1623/// use bitstream_io::{BitRead, BitReader, BigEndian, SignedBitCount};
1624///
1625/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1626/// let mut r = BitReader::endian(data, BigEndian);
1627/// // our bit count is a 3 bit value with a maximum value of 7
1628/// let count = r.read_count::<0b111>().unwrap();
1629/// // convert that count to a signed bit count,
1630/// // which guarantees its value is greater than 0
1631/// let count = count.signed_count().unwrap();
1632/// // that count indicates we need to read 4 bits (0b100)
1633/// assert_eq!(count, SignedBitCount::<7>::new::<4>());
1634/// // read the first 4-bit value
1635/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), 1);
1636/// // read the second 4-bit value
1637/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), -1);
1638/// // read the third 4-bit value
1639/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), 6);
1640/// ```
1641///
1642/// Because the [`BitRead::read_signed_counted`] methods know at compile-time
1643/// that the bit count will be larger than 7, that check can be eliminated
1644/// simply by taking advantage of information we already know.
1645///
1646/// Leveraging the `SignedBitCount` type also allows us to reason about
1647/// bit counts in a more formal way, and use checked permutation methods
1648/// to modify them while ensuring they remain constrained by
1649/// the file format's requirements.
1650#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1651pub struct SignedBitCount<const MAX: u32> {
1652    // the whole original bit count
1653    bits: BitCount<MAX>,
1654    // a bit count with one bit removed for the sign
1655    unsigned: BitCount<MAX>,
1656}
1657
1658impl<const MAX: u32> SignedBitCount<MAX> {
1659    /// Builds a signed bit count from a constant number
1660    /// of bits, which must be greater than 0 and
1661    /// not be greater than `MAX`.
1662    ///
1663    /// Intended to be used for defining constants.
1664    ///
1665    /// Use `TryFrom` to conditionally build
1666    /// counts from values at runtime.
1667    ///
1668    /// # Examples
1669    ///
1670    /// ```
1671    /// use bitstream_io::{BitReader, BitRead, BigEndian, SignedBitCount};
1672    /// let data: &[u8] = &[0b111_00000];
1673    /// let mut r = BitReader::endian(data, BigEndian);
1674    /// // reading 3 bits from a stream out of a maximum of 8
1675    /// // doesn't require checking that the bit count is larger
1676    /// // than a u8 at runtime because specifying the maximum of 8
1677    /// // guarantees our bit count will not be larger than 8
1678    /// assert_eq!(r.read_signed_counted::<8, i8>(SignedBitCount::new::<3>()).unwrap(), -1);
1679    /// ```
1680    ///
1681    /// ```rust,compile_fail
1682    /// use bitstream_io::SignedBitCount;
1683    /// // trying to build a count of 10 with a maximum of 8
1684    /// // fails to compile at all
1685    /// let count = SignedBitCount::<8>::new::<10>();
1686    /// ```
1687    ///
1688    /// ```rust,compile_fail
1689    /// use bitstream_io::SignedBitCount;
1690    /// // trying to build a count of 0 also fails to compile
1691    /// let count = SignedBitCount::<8>::new::<0>();
1692    /// ```
1693    pub const fn new<const BITS: u32>() -> Self {
1694        const {
1695            assert!(BITS > 0, "BITS must be > 0");
1696        }
1697
1698        Self {
1699            bits: BitCount::new::<BITS>(),
1700            unsigned: BitCount { bits: BITS - 1 },
1701        }
1702    }
1703
1704    /// Add a number of bits to our count,
1705    /// returning a new count with a new maximum.
1706    ///
1707    /// Returns `None` if the new count goes above our new maximum.
1708    ///
1709    /// # Examples
1710    ///
1711    /// ```
1712    /// use bitstream_io::SignedBitCount;
1713    ///
1714    /// let count = SignedBitCount::<2>::new::<1>();
1715    /// // adding 2 to 1 and increasing the max to 3 yields a new count of 3
1716    /// assert_eq!(count.checked_add::<3>(2), Some(SignedBitCount::<3>::new::<3>()));
1717    /// // adding 2 to 1 without increasing the max yields None
1718    /// assert_eq!(count.checked_add::<2>(2), None);
1719    /// ```
1720    #[inline]
1721    pub const fn checked_add<const NEW_MAX: u32>(
1722        self,
1723        bits: u32,
1724    ) -> Option<SignedBitCount<NEW_MAX>> {
1725        match self.bits.checked_add(bits) {
1726            Some(bits_new) => match self.unsigned.checked_add(bits) {
1727                Some(unsigned) => Some(SignedBitCount {
1728                    bits: bits_new,
1729                    unsigned,
1730                }),
1731                None => None,
1732            },
1733            None => None,
1734        }
1735    }
1736
1737    /// Subtracts a number of bits from our count,
1738    /// returning a new count with a new maximum.
1739    ///
1740    /// Returns `None` if the new count goes below 1
1741    /// or below our new maximum.
1742    ///
1743    /// # Example
1744    /// ```
1745    /// use bitstream_io::SignedBitCount;
1746    /// let count = SignedBitCount::<5>::new::<5>();
1747    /// // subtracting 1 from 5 yields a new count of 4
1748    /// assert_eq!(count.checked_sub::<5>(1), Some(SignedBitCount::<5>::new::<4>()));
1749    /// // subtracting 6 from 5 yields None
1750    /// assert!(count.checked_sub::<5>(6).is_none());
1751    /// // subtracting 1 with a new maximum of 3 also yields None
1752    /// // because 4 is larger than the maximum of 3
1753    /// assert!(count.checked_sub::<3>(1).is_none());
1754    /// // subtracting 5 from 5 also yields None
1755    /// // because SignedBitCount always requires 1 bit for the sign
1756    /// assert!(count.checked_sub::<5>(5).is_none());
1757    /// ```
1758    #[inline]
1759    pub const fn checked_sub<const NEW_MAX: u32>(
1760        self,
1761        bits: u32,
1762    ) -> Option<SignedBitCount<NEW_MAX>> {
1763        match self.bits.checked_sub(bits) {
1764            Some(bits_new) => match self.unsigned.checked_sub(bits) {
1765                Some(unsigned) => Some(SignedBitCount {
1766                    bits: bits_new,
1767                    unsigned,
1768                }),
1769                None => None,
1770            },
1771            None => None,
1772        }
1773    }
1774
1775    /// Attempt to convert our count to a count with a new
1776    /// bit count and new maximum.
1777    ///
1778    /// Returns `Some(count)` if the updated number of bits
1779    /// is less than or equal to the new maximum
1780    /// and greater than 0.
1781    /// Returns `None` if not.
1782    ///
1783    /// # Examples
1784    /// ```
1785    /// use bitstream_io::SignedBitCount;
1786    ///
1787    /// let count = SignedBitCount::<5>::new::<5>();
1788    /// // muliplying 5 bits by 2 with a new max of 10 is ok
1789    /// assert_eq!(
1790    ///     count.try_map::<10, _>(|i| i.checked_mul(2)),
1791    ///     Some(SignedBitCount::<10>::new::<10>()),
1792    /// );
1793    ///
1794    /// // multiplying 5 bits by 3 with a new max of 10 overflows
1795    /// assert_eq!(count.try_map::<10, _>(|i| i.checked_mul(3)), None);
1796    ///
1797    /// // multiplying 5 bits by 0 results in 0 bits,
1798    /// // which isn't value for a SignedBitCount
1799    /// assert_eq!(count.try_map::<10, _>(|i| Some(i * 0)), None);
1800    /// ```
1801    #[inline]
1802    pub fn try_map<const NEW_MAX: u32, F>(self, f: F) -> Option<SignedBitCount<NEW_MAX>>
1803    where
1804        F: FnOnce(u32) -> Option<u32>,
1805    {
1806        self.bits.try_map(f).and_then(|b| b.signed_count())
1807    }
1808
1809    /// Returns our maximum bit count
1810    ///
1811    /// # Example
1812    /// ```
1813    /// use bitstream_io::SignedBitCount;
1814    ///
1815    /// let count = SignedBitCount::<10>::new::<5>();
1816    /// assert_eq!(count.max(), 10);
1817    /// ```
1818    #[inline(always)]
1819    pub const fn max(&self) -> u32 {
1820        MAX
1821    }
1822
1823    /// Returns regular unsigned bit count
1824    ///
1825    /// # Example
1826    ///
1827    /// ```
1828    /// use bitstream_io::{BitCount, SignedBitCount};
1829    ///
1830    /// let signed_count = SignedBitCount::<10>::new::<5>();
1831    /// assert_eq!(signed_count.count(), BitCount::<10>::new::<5>());
1832    /// ```
1833    #[inline(always)]
1834    pub const fn count(&self) -> BitCount<MAX> {
1835        self.bits
1836    }
1837
1838    /// Returns this bit count's range for the given signed type
1839    ///
1840    /// # Example
1841    ///
1842    /// ```
1843    /// use bitstream_io::SignedBitCount;
1844    ///
1845    /// assert_eq!(SignedBitCount::<9>::new::<1>().range::<i8>(), -1..=0);
1846    /// assert_eq!(SignedBitCount::<9>::new::<2>().range::<i8>(), -2..=1);
1847    /// assert_eq!(SignedBitCount::<9>::new::<3>().range::<i8>(), -4..=3);
1848    /// assert_eq!(SignedBitCount::<9>::new::<4>().range::<i8>(), -8..=7);
1849    /// assert_eq!(SignedBitCount::<9>::new::<5>().range::<i8>(), -16..=15);
1850    /// assert_eq!(SignedBitCount::<9>::new::<6>().range::<i8>(), -32..=31);
1851    /// assert_eq!(SignedBitCount::<9>::new::<7>().range::<i8>(), -64..=63);
1852    /// assert_eq!(SignedBitCount::<9>::new::<8>().range::<i8>(), -128..=127);
1853    /// // a count that exceeds the type's size is
1854    /// // naturally restricted to that type's maximum range
1855    /// assert_eq!(SignedBitCount::<9>::new::<9>().range::<i8>(), -128..=127);
1856    /// ```
1857    pub fn range<S: SignedInteger>(&self) -> core::ops::RangeInclusive<S> {
1858        // a bit of a hack to get around the somewhat restrictive
1859        // SignedInteger trait I've created for myself
1860
1861        if self.bits.bits < S::BITS_SIZE {
1862            (!S::ZERO << self.unsigned.bits)..=((S::ONE << self.unsigned.bits) - S::ONE)
1863        } else {
1864            S::Unsigned::ZERO.as_negative(S::BITS_SIZE)..=(S::Unsigned::ALL >> 1).as_non_negative()
1865        }
1866    }
1867}
1868
1869impl<const MAX: u32> core::fmt::Display for SignedBitCount<MAX> {
1870    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1871        core::fmt::Display::fmt(&self.bits, f)
1872    }
1873}
1874
1875impl<const MAX: u32> core::convert::TryFrom<BitCount<MAX>> for SignedBitCount<MAX> {
1876    type Error = ();
1877
1878    #[inline]
1879    fn try_from(count: BitCount<MAX>) -> Result<Self, Self::Error> {
1880        count.signed_count().ok_or(())
1881    }
1882}
1883
1884impl<const MAX: u32> core::convert::TryFrom<u32> for SignedBitCount<MAX> {
1885    type Error = u32;
1886
1887    #[inline]
1888    fn try_from(count: u32) -> Result<Self, Self::Error> {
1889        BitCount::<MAX>::try_from(count).and_then(|b| b.signed_count().ok_or(count))
1890    }
1891}
1892
1893impl<const MAX: u32> From<SignedBitCount<MAX>> for u32 {
1894    #[inline(always)]
1895    fn from(
1896        SignedBitCount {
1897            bits: BitCount { bits },
1898            ..
1899        }: SignedBitCount<MAX>,
1900    ) -> u32 {
1901        bits
1902    }
1903}
1904
1905/// An error when converting a value to a [`Checked`] struct
1906#[derive(Copy, Clone, Debug)]
1907pub enum CheckedError {
1908    /// Excessive bits for type
1909    ExcessiveBits,
1910    /// Excessive value for bits
1911    ExcessiveValue,
1912}
1913
1914impl core::error::Error for CheckedError {}
1915
1916impl core::fmt::Display for CheckedError {
1917    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
1918        match self {
1919            Self::ExcessiveBits => core::fmt::Display::fmt("excessive bits for type written", f),
1920            Self::ExcessiveValue => core::fmt::Display::fmt("excessive value for bits written", f),
1921        }
1922    }
1923}
1924
1925impl From<CheckedError> for io::Error {
1926    #[inline]
1927    fn from(error: CheckedError) -> Self {
1928        match error {
1929            CheckedError::ExcessiveBits => io::Error::new(
1930                io::ErrorKind::InvalidInput,
1931                "excessive bits for type written",
1932            ),
1933            CheckedError::ExcessiveValue => io::Error::new(
1934                io::ErrorKind::InvalidInput,
1935                "excessive value for bits written",
1936            ),
1937        }
1938    }
1939}
1940
1941/// A type for eliminating redundant validation when writing
1942///
1943/// Normally, when writing a value, not only must the number of bits
1944/// must be checked against the type being written
1945/// (e.g. writing 9 bits from a `u8` is always an error),
1946/// but the value must also be checked against the number of bits
1947/// (e.g. writing a value of 2 in 1 bit is always an error).
1948///
1949/// But when the value's range can be checked in advance,
1950/// the write-time check can be skipped through the use
1951/// of the [`BitWrite::write_checked`] method.
1952#[derive(Copy, Clone, Debug)]
1953pub struct Checked<C, T> {
1954    count: C,
1955    value: T,
1956}
1957
1958impl<C, T> Checked<C, T> {
1959    /// Returns our bit count and value
1960    #[inline]
1961    pub fn into_count_value(self) -> (C, T) {
1962        (self.count, self.value)
1963    }
1964
1965    /// Returns our value
1966    #[inline]
1967    pub fn into_value(self) -> T {
1968        self.value
1969    }
1970}
1971
1972impl<C, T> AsRef<T> for Checked<C, T> {
1973    fn as_ref(&self) -> &T {
1974        &self.value
1975    }
1976}
1977
1978/// An unsigned type with a verified value
1979pub type CheckedUnsigned<const MAX: u32, T> = Checked<BitCount<MAX>, T>;
1980
1981impl<const MAX: u32, U: UnsignedInteger> Checkable for CheckedUnsigned<MAX, U> {
1982    #[inline]
1983    fn write<W: BitWrite + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
1984        // a naive default implementation
1985        writer.write_unsigned_counted(self.count, self.value)
1986    }
1987
1988    #[inline]
1989    fn written_bits(&self) -> u32 {
1990        self.count.bits
1991    }
1992}
1993
1994impl<const MAX: u32, U: UnsignedInteger> CheckablePrimitive for CheckedUnsigned<MAX, U> {
1995    type CountType = BitCount<MAX>;
1996
1997    #[inline]
1998    fn read<R: BitRead + ?Sized>(reader: &mut R, count: Self::CountType) -> io::Result<Self> {
1999        reader
2000            .read_unsigned_counted(count)
2001            .map(|value| Self { value, count })
2002    }
2003}
2004
2005impl<const MAX: u32, U: UnsignedInteger> private::Checkable for CheckedUnsigned<MAX, U> {
2006    fn write_endian<E, W>(
2007        self,
2008        writer: &mut W,
2009        queue_value: &mut u8,
2010        queue_bits: &mut u32,
2011    ) -> io::Result<()>
2012    where
2013        E: private::Endianness,
2014        W: io::Write,
2015    {
2016        E::write_bits_checked(writer, queue_value, queue_bits, self)
2017    }
2018}
2019
2020impl<const MAX: u32, U: UnsignedInteger> CheckedUnsigned<MAX, U> {
2021    /// Returns our value if it fits in the given number of bits
2022    ///
2023    /// # Example
2024    ///
2025    /// ```
2026    /// use bitstream_io::{BitCount, CheckedUnsigned, CheckedError};
2027    ///
2028    /// // a value of 7 fits into a 3 bit count
2029    /// assert!(CheckedUnsigned::<8, u8>::new(3, 0b111).is_ok());
2030    ///
2031    /// // a value of 8 does not fit into a 3 bit count
2032    /// assert!(matches!(
2033    ///     CheckedUnsigned::<8, u8>::new(3, 0b1000),
2034    ///     Err(CheckedError::ExcessiveValue),
2035    /// ));
2036    ///
2037    /// // a bit count of 9 is too large for u8
2038    /// assert!(matches!(
2039    ///     CheckedUnsigned::<9, _>::new(9, 1u8),
2040    ///     Err(CheckedError::ExcessiveBits),
2041    /// ));
2042    /// ```
2043    #[inline]
2044    pub fn new(count: impl TryInto<BitCount<MAX>>, value: U) -> Result<Self, CheckedError> {
2045        let count @ BitCount { bits } =
2046            count.try_into().map_err(|_| CheckedError::ExcessiveBits)?;
2047
2048        if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
2049            if bits == 0 {
2050                Ok(Self {
2051                    count,
2052                    value: U::ZERO,
2053                })
2054            } else if value <= U::ALL >> (U::BITS_SIZE - bits) {
2055                Ok(Self { count, value })
2056            } else {
2057                Err(CheckedError::ExcessiveValue)
2058            }
2059        } else {
2060            Err(CheckedError::ExcessiveBits)
2061        }
2062    }
2063
2064    /// Returns our value if it fits in the given number of const bits
2065    ///
2066    /// # Examples
2067    ///
2068    /// ```
2069    /// use bitstream_io::{CheckedUnsigned, CheckedError};
2070    ///
2071    /// // a value of 7 fits into a 3 bit count
2072    /// assert!(CheckedUnsigned::<8, u8>::new_fixed::<3>(0b111).is_ok());
2073    ///
2074    /// // a value of 8 does not fit into a 3 bit count
2075    /// assert!(matches!(
2076    ///     CheckedUnsigned::<8, u8>::new_fixed::<3>(0b1000),
2077    ///     Err(CheckedError::ExcessiveValue),
2078    /// ));
2079    /// ```
2080    ///
2081    /// ```compile_fail
2082    /// use bitstream_io::{BitCount, CheckedUnsigned};
2083    ///
2084    /// // a bit count of 9 is too large for u8
2085    ///
2086    /// // because this is checked at compile-time,
2087    /// // it does not compile at all
2088    /// let c = CheckedUnsigned::<16, u8>::new_fixed::<9>(1);
2089    /// ```
2090    pub fn new_fixed<const BITS: u32>(value: U) -> Result<Self, CheckedError> {
2091        const {
2092            assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
2093        }
2094
2095        if BITS == 0 {
2096            Ok(Self {
2097                count: BitCount::new::<0>(),
2098                value: U::ZERO,
2099            })
2100        } else if BITS == U::BITS_SIZE || value <= (U::ALL >> (U::BITS_SIZE - BITS)) {
2101            Ok(Self {
2102                // whether BITS is larger than MAX is checked here
2103                count: BitCount::new::<BITS>(),
2104                value,
2105            })
2106        } else {
2107            Err(CheckedError::ExcessiveValue)
2108        }
2109    }
2110}
2111
2112/// A fixed number of bits to be consumed or written
2113///
2114/// Analagous to [`BitCount`], this is a zero-sized type
2115/// whose value is fixed at compile-time and cannot be changed.
2116///
2117/// # Example
2118///
2119/// ```
2120/// use bitstream_io::{
2121///     BigEndian, BitRead, BitReader, BitWrite, BitWriter, CheckedUnsignedFixed, FixedBitCount,
2122/// };
2123///
2124/// type FourBits = CheckedUnsignedFixed<4, u8>;
2125///
2126/// let input: &[u8] = &[0b0001_1111, 0b0110_1001];
2127/// let mut r = BitReader::endian(input, BigEndian);
2128///
2129/// // read 4, 4-bit values
2130/// let v1 = r.read_checked::<FourBits>(FixedBitCount).unwrap();
2131/// let v2 = r.read_checked::<FourBits>(FixedBitCount).unwrap();
2132/// let v3 = r.read_checked::<FourBits>(FixedBitCount).unwrap();
2133/// let v4 = r.read_checked::<FourBits>(FixedBitCount).unwrap();
2134///
2135/// assert_eq!(v1.into_value(), 0b0001);
2136/// assert_eq!(v2.into_value(), 0b1111);
2137/// assert_eq!(v3.into_value(), 0b0110);
2138/// assert_eq!(v4.into_value(), 0b1001);
2139///
2140/// // write those same values back to disk
2141/// let mut w = BitWriter::endian(vec![], BigEndian);
2142/// w.write_checked(v1).unwrap();
2143/// w.write_checked(v2).unwrap();
2144/// w.write_checked(v3).unwrap();
2145/// w.write_checked(v4).unwrap();
2146///
2147/// // ensure they're the same
2148/// assert_eq!(w.into_writer().as_slice(), input);
2149/// ```
2150#[derive(Copy, Clone, Debug)]
2151pub struct FixedBitCount<const BITS: u32>;
2152
2153impl<const BITS: u32> From<FixedBitCount<BITS>> for BitCount<BITS> {
2154    fn from(_count: FixedBitCount<BITS>) -> Self {
2155        BitCount::new::<BITS>()
2156    }
2157}
2158
2159impl<const BITS: u32, const MAX: u32> core::convert::TryFrom<BitCount<MAX>>
2160    for FixedBitCount<BITS>
2161{
2162    type Error = BitCount<MAX>;
2163
2164    fn try_from(count: BitCount<MAX>) -> Result<Self, Self::Error> {
2165        (count.bits == BITS).then_some(FixedBitCount).ok_or(count)
2166    }
2167}
2168
2169/// An unsigned type with a verified value for a fixed number of bits
2170pub type CheckedUnsignedFixed<const BITS: u32, T> = Checked<FixedBitCount<BITS>, T>;
2171
2172impl<const BITS: u32, U: UnsignedInteger> CheckedUnsignedFixed<BITS, U> {
2173    /// Returns our checked value if it fits in the given number of const bits
2174    ///
2175    /// # Examples
2176    ///
2177    /// ```
2178    /// use bitstream_io::{CheckedUnsignedFixed, CheckedError};
2179    ///
2180    /// // a value of 7 fits into a maximum of 3 bits
2181    /// assert!(CheckedUnsignedFixed::<3, u8>::new_fixed(0b111).is_ok());
2182    ///
2183    /// // a value of 8 does not fit into a maximum of 3 bits
2184    /// assert!(matches!(
2185    ///     CheckedUnsignedFixed::<3, u8>::new_fixed(0b1000),
2186    ///     Err(CheckedError::ExcessiveValue),
2187    /// ));
2188    /// ```
2189    ///
2190    /// ```compile_fail
2191    /// use bitstream_io::CheckedUnsignedFixed;
2192    ///
2193    /// // a bit count of 9 is too large for u8
2194    ///
2195    /// // because this is checked at compile-time,
2196    /// // it does not compile at all
2197    /// let c = CheckedUnsignedFixed::<9, u8>::new_fixed(1);
2198    /// ```
2199    pub fn new_fixed(value: U) -> Result<Self, CheckedError> {
2200        const {
2201            assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
2202        }
2203
2204        if BITS == 0 {
2205            Ok(Self {
2206                count: FixedBitCount,
2207                value: U::ZERO,
2208            })
2209        } else if BITS == U::BITS_SIZE || value <= (U::ALL >> (U::BITS_SIZE - BITS)) {
2210            Ok(Self {
2211                count: FixedBitCount,
2212                value,
2213            })
2214        } else {
2215            Err(CheckedError::ExcessiveValue)
2216        }
2217    }
2218}
2219
2220impl<const BITS: u32, U: UnsignedInteger> Checkable for CheckedUnsignedFixed<BITS, U> {
2221    #[inline]
2222    fn write<W: BitWrite + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
2223        // a naive default implementation
2224        writer.write_unsigned::<BITS, _>(self.value)
2225    }
2226
2227    #[inline]
2228    fn written_bits(&self) -> u32 {
2229        BITS
2230    }
2231}
2232
2233impl<const BITS: u32, U: UnsignedInteger> private::Checkable for CheckedUnsignedFixed<BITS, U> {
2234    fn write_endian<E, W>(
2235        self,
2236        writer: &mut W,
2237        queue_value: &mut u8,
2238        queue_bits: &mut u32,
2239    ) -> io::Result<()>
2240    where
2241        E: private::Endianness,
2242        W: io::Write,
2243    {
2244        E::write_bits_checked(
2245            writer,
2246            queue_value,
2247            queue_bits,
2248            Checked {
2249                value: self.value,
2250                count: self.count.into(),
2251            },
2252        )
2253    }
2254}
2255
2256impl<const BITS: u32, U: UnsignedInteger> CheckablePrimitive for CheckedUnsignedFixed<BITS, U> {
2257    type CountType = FixedBitCount<BITS>;
2258
2259    fn read<R: BitRead + ?Sized>(reader: &mut R, count: FixedBitCount<BITS>) -> io::Result<Self> {
2260        Ok(Self {
2261            value: reader.read_unsigned::<BITS, _>()?,
2262            count,
2263        })
2264    }
2265}
2266
2267/// A signed type with a verified value
2268pub type CheckedSigned<const MAX: u32, T> = Checked<SignedBitCount<MAX>, T>;
2269
2270impl<const MAX: u32, S: SignedInteger> Checkable for CheckedSigned<MAX, S> {
2271    #[inline]
2272    fn write<W: BitWrite + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
2273        // a naive default implementation
2274        writer.write_signed_counted(self.count, self.value)
2275    }
2276
2277    #[inline]
2278    fn written_bits(&self) -> u32 {
2279        self.count.bits.into()
2280    }
2281}
2282
2283impl<const MAX: u32, S: SignedInteger> CheckablePrimitive for CheckedSigned<MAX, S> {
2284    type CountType = SignedBitCount<MAX>;
2285
2286    #[inline]
2287    fn read<R: BitRead + ?Sized>(reader: &mut R, count: Self::CountType) -> io::Result<Self> {
2288        reader
2289            .read_signed_counted(count)
2290            .map(|value| Self { value, count })
2291    }
2292}
2293
2294impl<const MAX: u32, S: SignedInteger> private::Checkable for CheckedSigned<MAX, S> {
2295    #[inline]
2296    fn write_endian<E, W>(
2297        self,
2298        writer: &mut W,
2299        queue_value: &mut u8,
2300        queue_bits: &mut u32,
2301    ) -> io::Result<()>
2302    where
2303        E: private::Endianness,
2304        W: io::Write,
2305    {
2306        E::write_signed_bits_checked(writer, queue_value, queue_bits, self)
2307    }
2308}
2309
2310impl<const MAX: u32, S: SignedInteger> CheckedSigned<MAX, S> {
2311    /// Returns our value if it fits in the given number of bits
2312    ///
2313    /// # Example
2314    ///
2315    /// ```
2316    /// use bitstream_io::{SignedBitCount, CheckedSigned, CheckedError};
2317    ///
2318    /// // a value of 3 fits into a 3 bit count
2319    /// assert!(CheckedSigned::<8, _>::new(3, 3i8).is_ok());
2320    ///
2321    /// // a value of 4 does not fit into a 3 bit count
2322    /// assert!(matches!(
2323    ///     CheckedSigned::<8, _>::new(3, 4i8),
2324    ///     Err(CheckedError::ExcessiveValue),
2325    /// ));
2326    ///
2327    /// // a bit count of 9 is too large for i8
2328    /// assert!(matches!(
2329    ///     CheckedSigned::<9, _>::new(9, 1i8),
2330    ///     Err(CheckedError::ExcessiveBits),
2331    /// ));
2332    /// ```
2333    #[inline]
2334    pub fn new(count: impl TryInto<SignedBitCount<MAX>>, value: S) -> Result<Self, CheckedError> {
2335        let count @ SignedBitCount {
2336            bits: BitCount { bits },
2337            unsigned: BitCount {
2338                bits: unsigned_bits,
2339            },
2340        } = count.try_into().map_err(|_| CheckedError::ExcessiveBits)?;
2341
2342        if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2343            if bits == S::BITS_SIZE
2344                || (((S::ZERO - S::ONE) << unsigned_bits) <= value
2345                    && value < (S::ONE << unsigned_bits))
2346            {
2347                Ok(Self { count, value })
2348            } else {
2349                Err(CheckedError::ExcessiveValue)
2350            }
2351        } else {
2352            Err(CheckedError::ExcessiveBits)
2353        }
2354    }
2355
2356    /// Returns our value if it fits in the given number of const bits
2357    ///
2358    /// # Examples
2359    ///
2360    /// ```
2361    /// use bitstream_io::{CheckedSigned, CheckedError};
2362    ///
2363    /// // a value of 3 fits into a 3 bit count
2364    /// assert!(CheckedSigned::<8, i8>::new_fixed::<3>(3).is_ok());
2365    ///
2366    /// // a value of 4 does not fit into a 3 bit count
2367    /// assert!(matches!(
2368    ///     CheckedSigned::<8, i8>::new_fixed::<3>(4),
2369    ///     Err(CheckedError::ExcessiveValue),
2370    /// ));
2371    /// ```
2372    ///
2373    /// ```compile_fail
2374    /// use bitstream_io::{BitCount, CheckedSigned};
2375    ///
2376    /// // a bit count of 9 is too large for i8
2377    ///
2378    /// // because this is checked at compile-time,
2379    /// // it does not compile at all
2380    /// let c = CheckedSigned::<16, i8>::new_fixed::<9>(1);
2381    /// ```
2382    pub fn new_fixed<const BITS: u32>(value: S) -> Result<Self, CheckedError> {
2383        const {
2384            assert!(BITS <= S::BITS_SIZE, "excessive bits for type written");
2385        }
2386
2387        if BITS == S::BITS_SIZE
2388            || (((S::ZERO - S::ONE) << (BITS - 1)) <= value && value < (S::ONE << (BITS - 1)))
2389        {
2390            Ok(Self {
2391                count: SignedBitCount::new::<BITS>(),
2392                value,
2393            })
2394        } else {
2395            Err(CheckedError::ExcessiveValue)
2396        }
2397    }
2398}
2399
2400/// A fixed number of bits to be consumed or written
2401///
2402/// Analagous to [`SignedBitCount`], this is a zero-sized type
2403/// whose value is fixed at compile-time and cannot be changed.
2404///
2405/// # Example
2406///
2407/// ```
2408/// use bitstream_io::{
2409///     BigEndian, BitRead, BitReader, BitWrite, BitWriter,
2410///     CheckedSignedFixed, FixedSignedBitCount,
2411/// };
2412///
2413/// type FourBits = CheckedSignedFixed<4, i8>;
2414///
2415/// let input: &[u8] = &[0b0001_1111, 0b0110_1001];
2416/// let mut r = BitReader::endian(input, BigEndian);
2417///
2418/// // read 4, 4-bit values
2419/// let v1 = r.read_checked::<FourBits>(FixedSignedBitCount).unwrap();
2420/// let v2 = r.read_checked::<FourBits>(FixedSignedBitCount).unwrap();
2421/// let v3 = r.read_checked::<FourBits>(FixedSignedBitCount).unwrap();
2422/// let v4 = r.read_checked::<FourBits>(FixedSignedBitCount).unwrap();
2423///
2424/// assert_eq!(v1.into_value(), 1);
2425/// assert_eq!(v2.into_value(), -1);
2426/// assert_eq!(v3.into_value(), 6);
2427/// assert_eq!(v4.into_value(), -7);
2428///
2429/// // write those same values back to disk
2430/// let mut w = BitWriter::endian(vec![], BigEndian);
2431/// w.write_checked(v1).unwrap();
2432/// w.write_checked(v2).unwrap();
2433/// w.write_checked(v3).unwrap();
2434/// w.write_checked(v4).unwrap();
2435///
2436/// // ensure they're the same
2437/// assert_eq!(w.into_writer().as_slice(), input);
2438/// ```
2439#[derive(Copy, Clone, Debug)]
2440pub struct FixedSignedBitCount<const BITS: u32>;
2441
2442impl<const BITS: u32> From<FixedSignedBitCount<BITS>> for SignedBitCount<BITS> {
2443    fn from(_count: FixedSignedBitCount<BITS>) -> Self {
2444        SignedBitCount::new::<BITS>()
2445    }
2446}
2447
2448impl<const BITS: u32, const MAX: u32> core::convert::TryFrom<SignedBitCount<MAX>>
2449    for FixedSignedBitCount<BITS>
2450{
2451    type Error = SignedBitCount<MAX>;
2452
2453    fn try_from(count: SignedBitCount<MAX>) -> Result<Self, Self::Error> {
2454        (count.bits.bits == BITS)
2455            .then_some(FixedSignedBitCount)
2456            .ok_or(count)
2457    }
2458}
2459
2460/// A signed type with a verified value for a fixed number of bits
2461pub type CheckedSignedFixed<const BITS: u32, T> = Checked<FixedSignedBitCount<BITS>, T>;
2462
2463impl<const BITS: u32, S: SignedInteger> CheckedSignedFixed<BITS, S> {
2464    /// Returns our checked value if it fits in the given number of const bits
2465    ///
2466    /// # Examples
2467    ///
2468    /// ```
2469    /// use bitstream_io::{SignedBitCount, CheckedSignedFixed, CheckedError};
2470    ///
2471    /// // a value of 3 fits into a 3 bit count
2472    /// assert!(CheckedSignedFixed::<3, _>::new_fixed(3i8).is_ok());
2473    ///
2474    /// // a value of 4 does not fit into a 3 bit count
2475    /// assert!(matches!(
2476    ///     CheckedSignedFixed::<3, _>::new_fixed(4i8),
2477    ///     Err(CheckedError::ExcessiveValue),
2478    /// ));
2479    /// ```
2480    ///
2481    /// ```compile_fail
2482    /// use bitstream_io::CheckedSignedFixed;
2483    ///
2484    /// // a bit count of 9 is too large for i8
2485    ///
2486    /// // because this is checked at compile-time,
2487    /// // it does not compile at all
2488    /// let c = CheckedSignedFixed::<9, _>::new_fixed(1i8);
2489    /// ```
2490    pub fn new_fixed(value: S) -> Result<Self, CheckedError> {
2491        const {
2492            assert!(BITS <= S::BITS_SIZE, "excessive bits for type written");
2493        }
2494
2495        if BITS == S::BITS_SIZE
2496            || (((S::ZERO - S::ONE) << (BITS - 1)) <= value && value < (S::ONE << (BITS - 1)))
2497        {
2498            Ok(Self {
2499                count: FixedSignedBitCount,
2500                value,
2501            })
2502        } else {
2503            Err(CheckedError::ExcessiveValue)
2504        }
2505    }
2506}
2507impl<const BITS: u32, S: SignedInteger> Checkable for CheckedSignedFixed<BITS, S> {
2508    #[inline]
2509    fn write<W: BitWrite + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
2510        // a naive default implementation
2511        writer.write_signed::<BITS, _>(self.value)
2512    }
2513
2514    #[inline]
2515    fn written_bits(&self) -> u32 {
2516        BITS
2517    }
2518}
2519
2520impl<const BITS: u32, S: SignedInteger> private::Checkable for CheckedSignedFixed<BITS, S> {
2521    #[inline]
2522    fn write_endian<E, W>(
2523        self,
2524        writer: &mut W,
2525        queue_value: &mut u8,
2526        queue_bits: &mut u32,
2527    ) -> io::Result<()>
2528    where
2529        E: private::Endianness,
2530        W: io::Write,
2531    {
2532        E::write_signed_bits_checked(
2533            writer,
2534            queue_value,
2535            queue_bits,
2536            CheckedSigned {
2537                value: self.value,
2538                count: self.count.into(),
2539            },
2540        )
2541    }
2542}
2543
2544impl<const BITS: u32, S: SignedInteger> CheckablePrimitive for CheckedSignedFixed<BITS, S> {
2545    type CountType = FixedSignedBitCount<BITS>;
2546
2547    fn read<R: BitRead + ?Sized>(
2548        reader: &mut R,
2549        count: FixedSignedBitCount<BITS>,
2550    ) -> io::Result<Self> {
2551        Ok(Self {
2552            value: reader.read_signed::<BITS, _>()?,
2553            count,
2554        })
2555    }
2556}
2557
2558/// A trait for writable types whose values can be validated
2559///
2560/// Ordinarily, when writing a value to a stream with a given
2561/// number of bits, the value must be validated to ensure
2562/// it will fit within that number of bits.
2563///
2564/// # Example 1
2565///
2566/// ```
2567/// use bitstream_io::{BitWrite, BitWriter, BigEndian};
2568///
2569/// let mut w = BitWriter::endian(vec![], BigEndian);
2570///
2571/// // writing a value of 2 in 1 bit is always an error
2572/// // which is checked here at write-time
2573/// assert!(w.write::<1, u8>(2).is_err());
2574/// ```
2575///
2576/// But if the value can be checked beforehand,
2577/// it doesn't need to be checked at write-time.
2578///
2579/// # Example 2
2580///
2581/// ```
2582/// use bitstream_io::{BitWrite, BitWriter, BigEndian, CheckedUnsigned};
2583///
2584/// let mut w = BitWriter::endian(vec![], BigEndian);
2585///
2586/// // writing a value of 1 in 1 bit is ok
2587/// // and we're checking that validity at this stage
2588/// let value = CheckedUnsigned::<1, u8>::new_fixed::<1>(1).unwrap();
2589///
2590/// // because we've pre-validated the value beforehand,
2591/// // it doesn't need to be checked again here
2592/// // (though the write itself may still fail)
2593/// assert!(w.write_checked(value).is_ok());
2594/// ```
2595///
2596pub trait Checkable: private::Checkable + Sized {
2597    /// Write our value to the given stream
2598    fn write<W: BitWrite + ?Sized>(&self, writer: &mut W) -> io::Result<()>;
2599
2600    /// The number of written bits
2601    fn written_bits(&self) -> u32;
2602}
2603
2604/// A trait for readable types whose bit counts can be saved
2605///
2606/// Because the intent of reading checkable values is
2607/// to avoid validating their values when being written,
2608/// implementing the [`Checkable`] trait is required.
2609pub trait CheckablePrimitive: Checkable {
2610    /// Our bit count type for reading
2611    type CountType;
2612
2613    /// Reads our value from the given stream
2614    fn read<R: BitRead + ?Sized>(reader: &mut R, count: Self::CountType) -> io::Result<Self>;
2615}
2616
2617/// Big-endian, or most significant bits first
2618#[derive(Copy, Clone, Debug)]
2619pub struct BigEndian;
2620
2621/// Big-endian, or most significant bits first
2622pub type BE = BigEndian;
2623
2624impl BigEndian {
2625    // checked in the sense that we've verified
2626    // the output type is large enough to hold the
2627    // requested number of bits
2628    #[inline]
2629    fn read_bits_checked<const MAX: u32, R, U>(
2630        reader: &mut R,
2631        queue: &mut u8,
2632        queue_bits: &mut u32,
2633        BitCount { bits }: BitCount<MAX>,
2634    ) -> io::Result<U>
2635    where
2636        R: io::Read,
2637        U: UnsignedInteger,
2638    {
2639        // reads a whole value with the given number of
2640        // bytes in our endianness, where the number of bytes
2641        // must be less than or equal to the type's size in bytes
2642        #[inline(always)]
2643        fn read_bytes<R, U>(reader: &mut R, bytes: usize) -> io::Result<U>
2644        where
2645            R: io::Read,
2646            U: UnsignedInteger,
2647        {
2648            let mut buf = U::buffer();
2649            reader
2650                .read_exact(&mut buf.as_mut()[(mem::size_of::<U>() - bytes)..])
2651                .map(|()| U::from_be_bytes(buf))
2652        }
2653
2654        if bits <= *queue_bits {
2655            // all bits in queue, so no byte needed
2656            let value = queue.shr_default(u8::BITS_SIZE - bits);
2657            *queue = queue.shl_default(bits);
2658            *queue_bits -= bits;
2659            Ok(U::from_u8(value))
2660        } else {
2661            // at least one byte needed
2662
2663            // bits needed beyond what's in the queue
2664            let needed_bits = bits - *queue_bits;
2665
2666            match (needed_bits / 8, needed_bits % 8) {
2667                (0, needed) => {
2668                    // only one additional byte needed,
2669                    // which we share between our returned value
2670                    // and the bit queue
2671                    let next_byte = read_byte(reader)?;
2672
2673                    Ok(U::from_u8(
2674                        mem::replace(queue, next_byte.shl_default(needed)).shr_default(
2675                            u8::BITS_SIZE - mem::replace(queue_bits, u8::BITS_SIZE - needed),
2676                        ),
2677                    )
2678                    .shl_default(needed)
2679                        | U::from_u8(next_byte.shr_default(u8::BITS_SIZE - needed)))
2680                }
2681                (bytes, 0) => {
2682                    // exact number of bytes needed beyond what's
2683                    // available in the queue
2684                    // so read a whole value from the reader
2685                    // and prepend what's left of our queue onto it
2686
2687                    Ok(U::from_u8(
2688                        mem::take(queue).shr_default(u8::BITS_SIZE - mem::take(queue_bits)),
2689                    )
2690                    .shl_default(needed_bits)
2691                        | read_bytes(reader, bytes as usize)?)
2692                }
2693                (bytes, needed) => {
2694                    // read a whole value from the reader
2695                    // prepend what's in the queue at the front of it
2696                    // *and* append a partial byte at the end of it
2697                    // while also updating the queue and its bit count
2698
2699                    let whole: U = read_bytes(reader, bytes as usize)?;
2700                    let next_byte = read_byte(reader)?;
2701
2702                    Ok(U::from_u8(
2703                        mem::replace(queue, next_byte.shl_default(needed)).shr_default(
2704                            u8::BITS_SIZE - mem::replace(queue_bits, u8::BITS_SIZE - needed),
2705                        ),
2706                    )
2707                    .shl_default(needed_bits)
2708                        | whole.shl_default(needed)
2709                        | U::from_u8(next_byte.shr_default(u8::BITS_SIZE - needed)))
2710                }
2711            }
2712        }
2713    }
2714}
2715
2716impl Endianness for BigEndian {}
2717
2718impl private::Endianness for BigEndian {
2719    #[inline]
2720    fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8> {
2721        *queue_value = (*queue_value << 1) | u8::from(bit);
2722        *queue_bits = (*queue_bits + 1) % 8;
2723        (*queue_bits == 0).then(|| mem::take(queue_value))
2724    }
2725
2726    #[inline]
2727    fn read_bits<const MAX: u32, R, U>(
2728        reader: &mut R,
2729        queue_value: &mut u8,
2730        queue_bits: &mut u32,
2731        count @ BitCount { bits }: BitCount<MAX>,
2732    ) -> io::Result<U>
2733    where
2734        R: io::Read,
2735        U: UnsignedInteger,
2736    {
2737        if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
2738            Self::read_bits_checked::<MAX, R, U>(reader, queue_value, queue_bits, count)
2739        } else {
2740            Err(io::Error::new(
2741                io::ErrorKind::InvalidInput,
2742                "excessive bits for type read",
2743            ))
2744        }
2745    }
2746
2747    #[inline]
2748    fn read_bits_fixed<const BITS: u32, R, U>(
2749        reader: &mut R,
2750        queue_value: &mut u8,
2751        queue_bits: &mut u32,
2752    ) -> io::Result<U>
2753    where
2754        R: io::Read,
2755        U: UnsignedInteger,
2756    {
2757        const {
2758            assert!(BITS <= U::BITS_SIZE, "excessive bits for type read");
2759        }
2760
2761        Self::read_bits_checked::<BITS, R, U>(
2762            reader,
2763            queue_value,
2764            queue_bits,
2765            BitCount::new::<BITS>(),
2766        )
2767    }
2768
2769    // checked in the sense that we've verified
2770    // the input type is large enough to hold the
2771    // requested number of bits and that the value is
2772    // not too large for those bits
2773    #[inline]
2774    fn write_bits_checked<const MAX: u32, W, U>(
2775        writer: &mut W,
2776        queue_value: &mut u8,
2777        queue_bits: &mut u32,
2778        CheckedUnsigned {
2779            count: BitCount { bits },
2780            value,
2781        }: CheckedUnsigned<MAX, U>,
2782    ) -> io::Result<()>
2783    where
2784        W: io::Write,
2785        U: UnsignedInteger,
2786    {
2787        fn write_bytes<W, U>(writer: &mut W, bytes: usize, value: U) -> io::Result<()>
2788        where
2789            W: io::Write,
2790            U: UnsignedInteger,
2791        {
2792            let buf = U::to_be_bytes(value);
2793            writer.write_all(&buf.as_ref()[(mem::size_of::<U>() - bytes)..])
2794        }
2795
2796        // the amount of available bits in the queue
2797        let available_bits = u8::BITS_SIZE - *queue_bits;
2798
2799        if bits < available_bits {
2800            // all bits fit in queue, so no write needed
2801            *queue_value = queue_value.shl_default(bits) | U::to_u8(value);
2802            *queue_bits += bits;
2803            Ok(())
2804        } else {
2805            // at least one byte needs to be written
2806
2807            // bits beyond what can fit in the queue
2808            let excess_bits = bits - available_bits;
2809
2810            match (excess_bits / 8, excess_bits % 8) {
2811                (0, excess) => {
2812                    // only one byte to be written,
2813                    // while the excess bits are shared
2814                    // between the written byte and the bit queue
2815
2816                    *queue_bits = excess;
2817
2818                    write_byte(
2819                        writer,
2820                        mem::replace(
2821                            queue_value,
2822                            U::to_u8(value & U::ALL.shr_default(U::BITS_SIZE - excess)),
2823                        )
2824                        .shl_default(available_bits)
2825                            | U::to_u8(value.shr_default(excess)),
2826                    )
2827                }
2828                (bytes, 0) => {
2829                    // no excess bytes beyond what can fit the queue
2830                    // so write a whole byte and
2831                    // the remainder of the whole value
2832
2833                    *queue_bits = 0;
2834
2835                    write_byte(
2836                        writer.by_ref(),
2837                        mem::take(queue_value).shl_default(available_bits)
2838                            | U::to_u8(value.shr_default(bytes * 8)),
2839                    )?;
2840
2841                    write_bytes(writer, bytes as usize, value)
2842                }
2843                (bytes, excess) => {
2844                    // write what's in the queue along
2845                    // with the head of our whole value,
2846                    // write the middle section of our whole value,
2847                    // while also replacing the queue with
2848                    // the tail of our whole value
2849
2850                    *queue_bits = excess;
2851
2852                    write_byte(
2853                        writer.by_ref(),
2854                        mem::replace(
2855                            queue_value,
2856                            U::to_u8(value & U::ALL.shr_default(U::BITS_SIZE - excess)),
2857                        )
2858                        .shl_default(available_bits)
2859                            | U::to_u8(value.shr_default(excess + bytes * 8)),
2860                    )?;
2861
2862                    write_bytes(writer, bytes as usize, value.shr_default(excess))
2863                }
2864            }
2865        }
2866    }
2867
2868    fn write_signed_bits_checked<const MAX: u32, W, S>(
2869        writer: &mut W,
2870        queue_value: &mut u8,
2871        queue_bits: &mut u32,
2872        value: CheckedSigned<MAX, S>,
2873    ) -> io::Result<()>
2874    where
2875        W: io::Write,
2876        S: SignedInteger,
2877    {
2878        let (
2879            SignedBitCount {
2880                bits: BitCount { bits },
2881                unsigned,
2882            },
2883            value,
2884        ) = value.into_count_value();
2885
2886        if let Some(b) = Self::push_bit_flush(queue_value, queue_bits, value.is_negative()) {
2887            write_byte(writer.by_ref(), b)?;
2888        }
2889        Self::write_bits_checked(
2890            writer,
2891            queue_value,
2892            queue_bits,
2893            Checked {
2894                value: if value.is_negative() {
2895                    value.as_negative(bits)
2896                } else {
2897                    value.as_non_negative()
2898                },
2899                count: unsigned,
2900            },
2901        )
2902    }
2903
2904    #[inline]
2905    fn pop_bit_refill<R>(
2906        reader: &mut R,
2907        queue_value: &mut u8,
2908        queue_bits: &mut u32,
2909    ) -> io::Result<bool>
2910    where
2911        R: io::Read,
2912    {
2913        Ok(if *queue_bits == 0 {
2914            let value = read_byte(reader)?;
2915            let msb = value & u8::MSB_BIT;
2916            *queue_value = value << 1;
2917            *queue_bits = u8::BITS_SIZE - 1;
2918            msb
2919        } else {
2920            let msb = *queue_value & u8::MSB_BIT;
2921            *queue_value <<= 1;
2922            *queue_bits -= 1;
2923            msb
2924        } != 0)
2925    }
2926
2927    #[inline]
2928    fn pop_unary<const STOP_BIT: u8, R>(
2929        reader: &mut R,
2930        queue_value: &mut u8,
2931        queue_bits: &mut u32,
2932    ) -> io::Result<u32>
2933    where
2934        R: io::Read,
2935    {
2936        const {
2937            assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1");
2938        }
2939
2940        match STOP_BIT {
2941            0 => find_unary(
2942                reader,
2943                queue_value,
2944                queue_bits,
2945                |v| v.leading_ones(),
2946                |q| *q,
2947                |v, b| v.checked_shl(b),
2948            ),
2949            1 => find_unary(
2950                reader,
2951                queue_value,
2952                queue_bits,
2953                |v| v.leading_zeros(),
2954                |_| u8::BITS_SIZE,
2955                |v, b| v.checked_shl(b),
2956            ),
2957            _ => unreachable!(),
2958        }
2959    }
2960
2961    #[inline]
2962    fn read_signed_counted<const MAX: u32, R, S>(
2963        r: &mut R,
2964        SignedBitCount {
2965            bits: BitCount { bits },
2966            unsigned,
2967        }: SignedBitCount<MAX>,
2968    ) -> io::Result<S>
2969    where
2970        R: BitRead,
2971        S: SignedInteger,
2972    {
2973        if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2974            let is_negative = r.read_bit()?;
2975            let unsigned = r.read_unsigned_counted::<MAX, S::Unsigned>(unsigned)?;
2976            Ok(if is_negative {
2977                unsigned.as_negative(bits)
2978            } else {
2979                unsigned.as_non_negative()
2980            })
2981        } else {
2982            Err(io::Error::new(
2983                io::ErrorKind::InvalidInput,
2984                "excessive bits for type read",
2985            ))
2986        }
2987    }
2988
2989    fn read_bytes<const CHUNK_SIZE: usize, R>(
2990        reader: &mut R,
2991        queue_value: &mut u8,
2992        queue_bits: u32,
2993        buf: &mut [u8],
2994    ) -> io::Result<()>
2995    where
2996        R: io::Read,
2997    {
2998        if queue_bits == 0 {
2999            reader.read_exact(buf)
3000        } else {
3001            let mut input_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
3002
3003            for output_chunk in buf.chunks_mut(CHUNK_SIZE) {
3004                let input_chunk = &mut input_chunk[0..output_chunk.len()];
3005                reader.read_exact(input_chunk)?;
3006
3007                // shift down each byte in our input to eventually
3008                // accomodate the contents of the bit queue
3009                // and make that our output
3010                output_chunk
3011                    .iter_mut()
3012                    .zip(input_chunk.iter())
3013                    .for_each(|(o, i)| {
3014                        *o = i >> queue_bits;
3015                    });
3016
3017                // include leftover bits from the next byte
3018                // shifted to the top
3019                output_chunk[1..]
3020                    .iter_mut()
3021                    .zip(input_chunk.iter())
3022                    .for_each(|(o, i)| {
3023                        *o |= *i << (u8::BITS_SIZE - queue_bits);
3024                    });
3025
3026                // finally, prepend the queue's contents
3027                // to the first byte in the chunk
3028                // while replacing those contents
3029                // with the final byte of the input
3030                output_chunk[0] |= mem::replace(
3031                    queue_value,
3032                    input_chunk.last().unwrap() << (u8::BITS_SIZE - queue_bits),
3033                );
3034            }
3035
3036            Ok(())
3037        }
3038    }
3039
3040    fn write_bytes<const CHUNK_SIZE: usize, W>(
3041        writer: &mut W,
3042        queue_value: &mut u8,
3043        queue_bits: u32,
3044        buf: &[u8],
3045    ) -> io::Result<()>
3046    where
3047        W: io::Write,
3048    {
3049        if queue_bits == 0 {
3050            writer.write_all(buf)
3051        } else {
3052            let mut output_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
3053
3054            for input_chunk in buf.chunks(CHUNK_SIZE) {
3055                let output_chunk = &mut output_chunk[0..input_chunk.len()];
3056
3057                output_chunk
3058                    .iter_mut()
3059                    .zip(input_chunk.iter())
3060                    .for_each(|(o, i)| {
3061                        *o = i >> queue_bits;
3062                    });
3063
3064                output_chunk[1..]
3065                    .iter_mut()
3066                    .zip(input_chunk.iter())
3067                    .for_each(|(o, i)| {
3068                        *o |= *i << (u8::BITS_SIZE - queue_bits);
3069                    });
3070
3071                output_chunk[0] |= mem::replace(
3072                    queue_value,
3073                    input_chunk.last().unwrap() & (u8::ALL >> (u8::BITS_SIZE - queue_bits)),
3074                ) << (u8::BITS_SIZE - queue_bits);
3075
3076                writer.write_all(output_chunk)?;
3077            }
3078
3079            Ok(())
3080        }
3081    }
3082
3083    #[inline(always)]
3084    fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P {
3085        P::from_be_bytes(buf)
3086    }
3087
3088    #[inline(always)]
3089    fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes {
3090        p.to_be_bytes()
3091    }
3092
3093    #[inline]
3094    fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
3095    where
3096        R: BitRead,
3097        V: Primitive,
3098    {
3099        let mut buffer = V::buffer();
3100        r.read_bytes(buffer.as_mut())?;
3101        Ok(V::from_be_bytes(buffer))
3102    }
3103
3104    #[inline]
3105    fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
3106    where
3107        W: BitWrite,
3108        V: Primitive,
3109    {
3110        w.write_bytes(value.to_be_bytes().as_ref())
3111    }
3112}
3113
3114/// Little-endian, or least significant bits first
3115#[derive(Copy, Clone, Debug)]
3116pub struct LittleEndian;
3117
3118/// Little-endian, or least significant bits first
3119pub type LE = LittleEndian;
3120
3121impl LittleEndian {
3122    // checked in the sense that we've verified
3123    // the output type is large enough to hold the
3124    // requested number of bits
3125    #[inline]
3126    fn read_bits_checked<const MAX: u32, R, U>(
3127        reader: &mut R,
3128        queue: &mut u8,
3129        queue_bits: &mut u32,
3130        BitCount { bits }: BitCount<MAX>,
3131    ) -> io::Result<U>
3132    where
3133        R: io::Read,
3134        U: UnsignedInteger,
3135    {
3136        // reads a whole value with the given number of
3137        // bytes in our endianness, where the number of bytes
3138        // must be less than or equal to the type's size in bytes
3139        #[inline(always)]
3140        fn read_bytes<R, U>(reader: &mut R, bytes: usize) -> io::Result<U>
3141        where
3142            R: io::Read,
3143            U: UnsignedInteger,
3144        {
3145            let mut buf = U::buffer();
3146            reader
3147                .read_exact(&mut buf.as_mut()[0..bytes])
3148                .map(|()| U::from_le_bytes(buf))
3149        }
3150
3151        if bits <= *queue_bits {
3152            // all bits in queue, so no byte needed
3153            let value = *queue & u8::ALL.shr_default(u8::BITS_SIZE - bits);
3154            *queue = queue.shr_default(bits);
3155            *queue_bits -= bits;
3156            Ok(U::from_u8(value))
3157        } else {
3158            // at least one byte needed
3159
3160            // bits needed beyond what's in the queue
3161            let needed_bits = bits - *queue_bits;
3162
3163            match (needed_bits / 8, needed_bits % 8) {
3164                (0, needed) => {
3165                    // only one additional byte needed,
3166                    // which we share between our returned value
3167                    // and the bit queue
3168                    let next_byte = read_byte(reader)?;
3169
3170                    Ok(
3171                        U::from_u8(mem::replace(queue, next_byte.shr_default(needed)))
3172                            | (U::from_u8(next_byte & (u8::ALL >> (u8::BITS_SIZE - needed)))
3173                                << mem::replace(queue_bits, u8::BITS_SIZE - needed)),
3174                    )
3175                }
3176                (bytes, 0) => {
3177                    // exact number of bytes needed beyond what's
3178                    // available in the queue
3179
3180                    // so read a whole value from the reader
3181                    // and prepend what's left of our queue onto it
3182
3183                    Ok(U::from_u8(mem::take(queue))
3184                        | (read_bytes::<R, U>(reader, bytes as usize)? << mem::take(queue_bits)))
3185                }
3186                (bytes, needed) => {
3187                    // read a whole value from the reader
3188                    // prepend what's in the queue at the front of it
3189                    // *and* append a partial byte at the end of it
3190                    // while also updating the queue and its bit count
3191
3192                    let whole: U = read_bytes(reader, bytes as usize)?;
3193                    let next_byte = read_byte(reader)?;
3194
3195                    Ok(
3196                        U::from_u8(mem::replace(queue, next_byte.shr_default(needed)))
3197                            | (whole << *queue_bits)
3198                            | (U::from_u8(next_byte & (u8::ALL >> (u8::BITS_SIZE - needed)))
3199                                << (mem::replace(queue_bits, u8::BITS_SIZE - needed) + bytes * 8)),
3200                    )
3201                }
3202            }
3203        }
3204    }
3205}
3206
3207impl Endianness for LittleEndian {}
3208
3209impl private::Endianness for LittleEndian {
3210    #[inline]
3211    fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8> {
3212        *queue_value |= u8::from(bit) << *queue_bits;
3213        *queue_bits = (*queue_bits + 1) % 8;
3214        (*queue_bits == 0).then(|| mem::take(queue_value))
3215    }
3216
3217    #[inline]
3218    fn read_bits<const MAX: u32, R, U>(
3219        reader: &mut R,
3220        queue_value: &mut u8,
3221        queue_bits: &mut u32,
3222        count @ BitCount { bits }: BitCount<MAX>,
3223    ) -> io::Result<U>
3224    where
3225        R: io::Read,
3226        U: UnsignedInteger,
3227    {
3228        if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
3229            Self::read_bits_checked::<MAX, R, U>(reader, queue_value, queue_bits, count)
3230        } else {
3231            Err(io::Error::new(
3232                io::ErrorKind::InvalidInput,
3233                "excessive bits for type read",
3234            ))
3235        }
3236    }
3237
3238    #[inline]
3239    fn read_bits_fixed<const BITS: u32, R, U>(
3240        reader: &mut R,
3241        queue_value: &mut u8,
3242        queue_bits: &mut u32,
3243    ) -> io::Result<U>
3244    where
3245        R: io::Read,
3246        U: UnsignedInteger,
3247    {
3248        const {
3249            assert!(BITS <= U::BITS_SIZE, "excessive bits for type read");
3250        }
3251
3252        Self::read_bits_checked::<BITS, R, U>(
3253            reader,
3254            queue_value,
3255            queue_bits,
3256            BitCount::new::<BITS>(),
3257        )
3258    }
3259
3260    // checked in the sense that we've verified
3261    // the input type is large enough to hold the
3262    // requested number of bits and that the value is
3263    // not too large for those bits
3264    #[inline]
3265    fn write_bits_checked<const MAX: u32, W, U>(
3266        writer: &mut W,
3267        queue_value: &mut u8,
3268        queue_bits: &mut u32,
3269        CheckedUnsigned {
3270            count: BitCount { bits },
3271            value,
3272        }: CheckedUnsigned<MAX, U>,
3273    ) -> io::Result<()>
3274    where
3275        W: io::Write,
3276        U: UnsignedInteger,
3277    {
3278        fn write_bytes<W, U>(writer: &mut W, bytes: usize, value: U) -> io::Result<()>
3279        where
3280            W: io::Write,
3281            U: UnsignedInteger,
3282        {
3283            let buf = U::to_le_bytes(value);
3284            writer.write_all(&buf.as_ref()[0..bytes])
3285        }
3286
3287        // the amount of available bits in the queue
3288        let available_bits = u8::BITS_SIZE - *queue_bits;
3289
3290        if bits < available_bits {
3291            // all bits fit in queue, so no write needed
3292            *queue_value |= U::to_u8(value.shl_default(*queue_bits));
3293            *queue_bits += bits;
3294            Ok(())
3295        } else {
3296            // at least one byte needs to be written
3297
3298            // bits beyond what can fit in the queue
3299            let excess_bits = bits - available_bits;
3300
3301            match (excess_bits / 8, excess_bits % 8) {
3302                (0, excess) => {
3303                    // only one byte to be written,
3304                    // while the excess bits are shared
3305                    // between the written byte and the bit queue
3306
3307                    write_byte(
3308                        writer,
3309                        mem::replace(queue_value, U::to_u8(value.shr_default(available_bits)))
3310                            | U::to_u8(
3311                                (value << mem::replace(queue_bits, excess)) & U::from_u8(u8::ALL),
3312                            ),
3313                    )
3314                }
3315                (bytes, 0) => {
3316                    // no excess bytes beyond what can fit the queue
3317                    // so write a whole byte and
3318                    // the remainder of the whole value
3319
3320                    write_byte(
3321                        writer.by_ref(),
3322                        mem::take(queue_value)
3323                            | U::to_u8((value << mem::take(queue_bits)) & U::from_u8(u8::ALL)),
3324                    )?;
3325
3326                    write_bytes(writer, bytes as usize, value >> available_bits)
3327                }
3328                (bytes, excess) => {
3329                    // write what's in the queue along
3330                    // with the head of our whole value,
3331                    // write the middle section of our whole value,
3332                    // while also replacing the queue with
3333                    // the tail of our whole value
3334
3335                    write_byte(
3336                        writer.by_ref(),
3337                        mem::replace(
3338                            queue_value,
3339                            U::to_u8(value.shr_default(available_bits + bytes * 8)),
3340                        ) | U::to_u8(
3341                            (value << mem::replace(queue_bits, excess)) & U::from_u8(u8::ALL),
3342                        ),
3343                    )?;
3344
3345                    write_bytes(writer, bytes as usize, value >> available_bits)
3346                }
3347            }
3348        }
3349    }
3350
3351    fn write_signed_bits_checked<const MAX: u32, W, S>(
3352        writer: &mut W,
3353        queue_value: &mut u8,
3354        queue_bits: &mut u32,
3355        value: CheckedSigned<MAX, S>,
3356    ) -> io::Result<()>
3357    where
3358        W: io::Write,
3359        S: SignedInteger,
3360    {
3361        // little-endian
3362        let (
3363            SignedBitCount {
3364                bits: BitCount { bits },
3365                unsigned,
3366            },
3367            value,
3368        ) = value.into_count_value();
3369
3370        Self::write_bits_checked(
3371            writer.by_ref(),
3372            queue_value,
3373            queue_bits,
3374            Checked {
3375                value: if value.is_negative() {
3376                    value.as_negative(bits)
3377                } else {
3378                    value.as_non_negative()
3379                },
3380                count: unsigned,
3381            },
3382        )?;
3383        match Self::push_bit_flush(queue_value, queue_bits, value.is_negative()) {
3384            Some(b) => write_byte(writer, b),
3385            None => Ok(()),
3386        }
3387    }
3388
3389    #[inline]
3390    fn pop_bit_refill<R>(
3391        reader: &mut R,
3392        queue_value: &mut u8,
3393        queue_bits: &mut u32,
3394    ) -> io::Result<bool>
3395    where
3396        R: io::Read,
3397    {
3398        Ok(if *queue_bits == 0 {
3399            let value = read_byte(reader)?;
3400            let lsb = value & u8::LSB_BIT;
3401            *queue_value = value >> 1;
3402            *queue_bits = u8::BITS_SIZE - 1;
3403            lsb
3404        } else {
3405            let lsb = *queue_value & u8::LSB_BIT;
3406            *queue_value >>= 1;
3407            *queue_bits -= 1;
3408            lsb
3409        } != 0)
3410    }
3411
3412    #[inline]
3413    fn pop_unary<const STOP_BIT: u8, R>(
3414        reader: &mut R,
3415        queue_value: &mut u8,
3416        queue_bits: &mut u32,
3417    ) -> io::Result<u32>
3418    where
3419        R: io::Read,
3420    {
3421        const {
3422            assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1");
3423        }
3424
3425        match STOP_BIT {
3426            0 => find_unary(
3427                reader,
3428                queue_value,
3429                queue_bits,
3430                |v| v.trailing_ones(),
3431                |q| *q,
3432                |v, b| v.checked_shr(b),
3433            ),
3434            1 => find_unary(
3435                reader,
3436                queue_value,
3437                queue_bits,
3438                |v| v.trailing_zeros(),
3439                |_| u8::BITS_SIZE,
3440                |v, b| v.checked_shr(b),
3441            ),
3442            _ => unreachable!(),
3443        }
3444    }
3445
3446    #[inline]
3447    fn read_signed_counted<const MAX: u32, R, S>(
3448        r: &mut R,
3449        SignedBitCount {
3450            bits: BitCount { bits },
3451            unsigned,
3452        }: SignedBitCount<MAX>,
3453    ) -> io::Result<S>
3454    where
3455        R: BitRead,
3456        S: SignedInteger,
3457    {
3458        if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
3459            let unsigned = r.read_unsigned_counted::<MAX, S::Unsigned>(unsigned)?;
3460            let is_negative = r.read_bit()?;
3461            Ok(if is_negative {
3462                unsigned.as_negative(bits)
3463            } else {
3464                unsigned.as_non_negative()
3465            })
3466        } else {
3467            Err(io::Error::new(
3468                io::ErrorKind::InvalidInput,
3469                "excessive bits for type read",
3470            ))
3471        }
3472    }
3473
3474    fn read_bytes<const CHUNK_SIZE: usize, R>(
3475        reader: &mut R,
3476        queue_value: &mut u8,
3477        queue_bits: u32,
3478        buf: &mut [u8],
3479    ) -> io::Result<()>
3480    where
3481        R: io::Read,
3482    {
3483        if queue_bits == 0 {
3484            reader.read_exact(buf)
3485        } else {
3486            let mut input_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
3487
3488            for output_chunk in buf.chunks_mut(CHUNK_SIZE) {
3489                let input_chunk = &mut input_chunk[0..output_chunk.len()];
3490                reader.read_exact(input_chunk)?;
3491
3492                output_chunk
3493                    .iter_mut()
3494                    .zip(input_chunk.iter())
3495                    .for_each(|(o, i)| {
3496                        *o = i << queue_bits;
3497                    });
3498
3499                output_chunk[1..]
3500                    .iter_mut()
3501                    .zip(input_chunk.iter())
3502                    .for_each(|(o, i)| {
3503                        *o |= i >> (u8::BITS_SIZE - queue_bits);
3504                    });
3505
3506                output_chunk[0] |= mem::replace(
3507                    queue_value,
3508                    input_chunk.last().unwrap() >> (u8::BITS_SIZE - queue_bits),
3509                );
3510            }
3511
3512            Ok(())
3513        }
3514    }
3515
3516    fn write_bytes<const CHUNK_SIZE: usize, W>(
3517        writer: &mut W,
3518        queue_value: &mut u8,
3519        queue_bits: u32,
3520        buf: &[u8],
3521    ) -> io::Result<()>
3522    where
3523        W: io::Write,
3524    {
3525        if queue_bits == 0 {
3526            writer.write_all(buf)
3527        } else {
3528            let mut output_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
3529
3530            for input_chunk in buf.chunks(CHUNK_SIZE) {
3531                let output_chunk = &mut output_chunk[0..input_chunk.len()];
3532
3533                output_chunk
3534                    .iter_mut()
3535                    .zip(input_chunk.iter())
3536                    .for_each(|(o, i)| {
3537                        *o = i << queue_bits;
3538                    });
3539
3540                output_chunk[1..]
3541                    .iter_mut()
3542                    .zip(input_chunk.iter())
3543                    .for_each(|(o, i)| {
3544                        *o |= i >> (u8::BITS_SIZE - queue_bits);
3545                    });
3546
3547                output_chunk[0] |= mem::replace(
3548                    queue_value,
3549                    input_chunk.last().unwrap() >> (u8::BITS_SIZE - queue_bits),
3550                );
3551
3552                writer.write_all(output_chunk)?;
3553            }
3554
3555            Ok(())
3556        }
3557    }
3558
3559    #[inline(always)]
3560    fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P {
3561        P::from_le_bytes(buf)
3562    }
3563
3564    #[inline(always)]
3565    fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes {
3566        p.to_le_bytes()
3567    }
3568
3569    #[inline]
3570    fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
3571    where
3572        R: BitRead,
3573        V: Primitive,
3574    {
3575        let mut buffer = V::buffer();
3576        r.read_bytes(buffer.as_mut())?;
3577        Ok(V::from_le_bytes(buffer))
3578    }
3579
3580    #[inline]
3581    fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
3582    where
3583        W: BitWrite,
3584        V: Primitive,
3585    {
3586        w.write_bytes(value.to_le_bytes().as_ref())
3587    }
3588}
3589
3590#[inline]
3591fn find_unary<R>(
3592    reader: &mut R,
3593    queue_value: &mut u8,
3594    queue_bits: &mut u32,
3595    leading_bits: impl Fn(u8) -> u32,
3596    max_bits: impl Fn(&mut u32) -> u32,
3597    checked_shift: impl Fn(u8, u32) -> Option<u8>,
3598) -> io::Result<u32>
3599where
3600    R: io::Read,
3601{
3602    let mut acc = 0;
3603
3604    loop {
3605        match leading_bits(*queue_value) {
3606            bits if bits == max_bits(queue_bits) => {
3607                // all bits exhausted
3608                // fetch another byte and keep going
3609                acc += *queue_bits;
3610                *queue_value = read_byte(reader.by_ref())?;
3611                *queue_bits = u8::BITS_SIZE;
3612            }
3613            bits => match checked_shift(*queue_value, bits + 1) {
3614                Some(value) => {
3615                    // fetch part of source byte
3616                    *queue_value = value;
3617                    *queue_bits -= bits + 1;
3618                    break Ok(acc + bits);
3619                }
3620                None => {
3621                    // fetch all of source byte
3622                    *queue_value = 0;
3623                    *queue_bits = 0;
3624                    break Ok(acc + bits);
3625                }
3626            },
3627        }
3628    }
3629}