bitstream_io/
lib.rs

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