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}