bitstream_io/lib.rs
1// Copyright 2017 Brian Langenberger
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Traits and helpers for bitstream handling functionality
10//!
11//! Bitstream readers are for reading signed and unsigned integer
12//! values from a stream whose sizes may not be whole bytes.
13//! Bitstream writers are for writing signed and unsigned integer
14//! values to a stream, also potentially un-aligned at a whole byte.
15//!
16//! Both big-endian and little-endian streams are supported.
17//!
18//! The only requirement for wrapped reader streams is that they must
19//! implement the [`io::Read`] trait, and the only requirement
20//! for writer streams is that they must implement the [`io::Write`] trait.
21//!
22//! In addition, reader streams do not consume any more bytes
23//! from the underlying reader than necessary, buffering only a
24//! single partial byte as needed.
25//! Writer streams also write out all whole bytes as they are accumulated.
26//!
27//! Readers and writers are also designed to work with integer
28//! types of any possible size.
29//! Many of Rust's built-in integer types are supported by default.
30
31//! # Minimum Compiler Version
32//!
33//! Beginning with version 2.4, the minimum compiler version has been
34//! updated to Rust 1.79.
35//!
36//! The issue is that reading an excessive number of
37//! bits to a type which is too small to hold them,
38//! or writing an excessive number of bits from too small of a type,
39//! are always errors:
40//! ```
41//! use std::io::{Read, Cursor};
42//! use bitstream_io::{BigEndian, BitReader, BitRead};
43//! let data = [0; 10];
44//! let mut r = BitReader::endian(Cursor::new(&data), BigEndian);
45//! let x: Result<u32, _> = r.read_var(64); // reading 64 bits to u32 always fails at runtime
46//! assert!(x.is_err());
47//! ```
48//! but those errors will not be caught until the program runs,
49//! which is less than ideal for the common case in which
50//! the number of bits is already known at compile-time.
51//!
52//! But starting with Rust 1.79, we can now have read and write methods
53//! which take a constant number of bits and can validate the number of bits
54//! are small enough for the type being read/written at compile-time:
55//! ```rust,compile_fail
56//! use std::io::{Read, Cursor};
57//! use bitstream_io::{BigEndian, BitReader, BitRead};
58//! let data = [0; 10];
59//! let mut r = BitReader::endian(Cursor::new(&data), BigEndian);
60//! let x: Result<u32, _> = r.read::<64, _>(); // doesn't compile at all
61//! ```
62//! Since catching potential bugs at compile-time is preferable
63//! to encountering errors at runtime, this will hopefully be
64//! an improvement in the long run.
65
66//! # Changes From 2.X.X
67//!
68//! Version 3.0.0 has made many breaking changes to the [`BitRead`] and
69//! [`BitWrite`] traits.
70//!
71//! The [`BitRead::read`] method takes a constant number of bits,
72//! and the [`BitRead::read_var`] method takes a variable number of bits
73//! (reversing the older [`BitRead2::read_in`] and [`BitRead2::read`]
74//! calling methods to emphasize using the constant-based one,
75//! which can do more validation at compile-time).
76//! A new [`BitRead2`] trait uses the older calling convention
77//! for compatibility with existing code and is available
78//! for anything implementing [`BitRead`].
79//!
80//! In addition, the main reading methods return primitive types which
81//! implement a new [`Integer`] trait,
82//! which delegates to [`BitRead::read_unsigned`]
83//! or [`BitRead::read_signed`] depending on whether the output
84//! is an unsigned or signed type.
85//!
86//! [`BitWrite::write`] and [`BitWrite::write_var`] work
87//! similarly to the reader's `read` methods, taking anything
88//! that implements [`Integer`] and writing an unsigned or
89//! signed value to [`BitWrite::write_unsigned`] or
90//! [`BitWrite::write_signed`] as appropriate.
91//!
92//! And as with reading, a [`BitWrite2`] trait is offered
93//! for compatibility.
94//!
95//! In addition, the Huffman code handling has been rewritten
96//! to use a small amount of macro magic to write
97//! code to read and write symbols at compile-time.
98//! This is significantly faster than the older version
99//! and can no longer fail to compile at runtime.
100//!
101//! Lastly, there's a new [`BitCount`] struct which wraps a humble
102//! `u32` but encodes the maximum possible number of bits
103//! at the type level.
104//! This is intended for file formats which encode the number
105//! of bits to be read in the format itself.
106//! For example, FLAC's predictor coefficient precision
107//! is a 4 bit value which indicates how large each predictor
108//! coefficient is in bits
109//! (each coefficient might be an `i32` type).
110//! By keeping track of the maximum value at compile time
111//! (4 bits' worth, in this case), we can eliminate
112//! any need to check that coefficients aren't too large
113//! for an `i32` at runtime.
114//! This is accomplished by using [`BitRead::read_count`] to
115//! read a [`BitCount`] and then reading final values with
116//! that number of bits using [`BitRead::read_counted`].
117
118//! # Migrating From Pre 1.0.0
119//!
120//! There are now [`BitRead`] and [`BitWrite`] traits for bitstream
121//! reading and writing (analogous to the standard library's
122//! `Read` and `Write` traits) which you will also need to import.
123//! The upside to this approach is that library consumers
124//! can now make functions and methods generic over any sort
125//! of bit reader or bit writer, regardless of the underlying
126//! stream byte source or endianness.
127
128#![warn(missing_docs)]
129#![forbid(unsafe_code)]
130#![no_std]
131
132extern crate alloc;
133#[cfg(feature = "std")]
134extern crate std;
135
136#[cfg(not(feature = "std"))]
137use core2::io;
138
139use core::num::NonZero;
140use core::ops::{
141 BitAnd, BitOr, BitOrAssign, BitXor, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
142};
143use core::{fmt::Debug, marker::PhantomData, mem};
144#[cfg(feature = "std")]
145use std::io;
146
147pub mod huffman;
148pub mod read;
149pub mod write;
150pub use read::{
151 BitRead, BitRead2, BitReader, ByteRead, ByteReader, FromBitStream, FromBitStreamWith,
152 FromByteStream, FromByteStreamWith,
153};
154pub use write::{
155 BitCounter, BitRecorder, BitWrite, BitWrite2, BitWriter, ByteWrite, ByteWriter, ToBitStream,
156 ToBitStreamWith, ToByteStream, ToByteStreamWith,
157};
158
159/// A trait intended for simple fixed-length primitives (such as ints and floats)
160/// which allows them to be read and written to streams of
161/// different endiannesses verbatim.
162pub trait Primitive {
163 /// The raw byte representation of this numeric type
164 type Bytes: AsRef<[u8]> + AsMut<[u8]>;
165
166 /// An empty buffer of this type's size
167 fn buffer() -> Self::Bytes;
168
169 /// Our value in big-endian bytes
170 fn to_be_bytes(self) -> Self::Bytes;
171
172 /// Our value in little-endian bytes
173 fn to_le_bytes(self) -> Self::Bytes;
174
175 /// Convert big-endian bytes to our value
176 fn from_be_bytes(bytes: Self::Bytes) -> Self;
177
178 /// Convert little-endian bytes to our value
179 fn from_le_bytes(bytes: Self::Bytes) -> Self;
180}
181
182macro_rules! define_primitive_numeric {
183 ($t:ty) => {
184 impl Primitive for $t {
185 type Bytes = [u8; mem::size_of::<$t>()];
186
187 #[inline(always)]
188 fn buffer() -> Self::Bytes {
189 [0; mem::size_of::<$t>()]
190 }
191 #[inline(always)]
192 fn to_be_bytes(self) -> Self::Bytes {
193 self.to_be_bytes()
194 }
195 #[inline(always)]
196 fn to_le_bytes(self) -> Self::Bytes {
197 self.to_le_bytes()
198 }
199 #[inline(always)]
200 fn from_be_bytes(bytes: Self::Bytes) -> Self {
201 <$t>::from_be_bytes(bytes)
202 }
203 #[inline(always)]
204 fn from_le_bytes(bytes: Self::Bytes) -> Self {
205 <$t>::from_le_bytes(bytes)
206 }
207 }
208 };
209}
210
211impl<const N: usize> Primitive for [u8; N] {
212 type Bytes = [u8; N];
213
214 #[inline(always)]
215 fn buffer() -> Self::Bytes {
216 [0; N]
217 }
218
219 #[inline(always)]
220 fn to_be_bytes(self) -> Self::Bytes {
221 self
222 }
223
224 #[inline(always)]
225 fn to_le_bytes(self) -> Self::Bytes {
226 self
227 }
228
229 #[inline(always)]
230 fn from_be_bytes(bytes: Self::Bytes) -> Self {
231 bytes
232 }
233
234 #[inline(always)]
235 fn from_le_bytes(bytes: Self::Bytes) -> Self {
236 bytes
237 }
238}
239
240/// This trait is for integer types which can be read or written
241/// to a bit stream as a partial amount of bits.
242///
243/// It unifies signed and unsigned integer types by delegating
244/// reads and writes to the signed and unsigned reading
245/// and writing methods as appropriate.
246pub trait Integer {
247 /// Reads a value of ourself from the stream
248 /// with the given number of bits.
249 ///
250 /// # Errors
251 ///
252 /// Passes along any I/O error from the underlying stream.
253 /// A compile-time error occurs if the given number of bits
254 /// is larger than our type.
255 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
256 where
257 Self: Sized;
258
259 /// Reads a value of ourself from the stream
260 /// with the given number of bits.
261 ///
262 /// # Errors
263 ///
264 /// Passes along any I/O error from the underlying stream.
265 /// Also returns an error if our type is too small
266 /// to hold the requested number of bits.
267 fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
268 where
269 R: BitRead + ?Sized,
270 Self: Sized;
271
272 /// Writes ourself to the stream using the given const number of bits.
273 ///
274 /// # Errors
275 ///
276 /// Passes along any I/O error from the underlying stream.
277 /// Returns an error if our value is too large
278 /// to fit the given number of bits.
279 /// A compile-time error occurs if the given number of bits
280 /// is larger than our type.
281 fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()>;
282
283 /// Writes ourself to the stream using the given number of bits.
284 ///
285 /// # Errors
286 ///
287 /// Passes along any I/O error from the underlying stream.
288 /// Returns an error if our value is too small
289 /// to hold the given number of bits.
290 /// Returns an error if our value is too large
291 /// to fit the given number of bits.
292 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
293 self,
294 writer: &mut W,
295 bits: BitCount<MAX>,
296 ) -> io::Result<()>;
297}
298
299/// Reading and writing booleans as `Integer` requires the number of bits to be 1.
300///
301/// This is more useful when combined with the fixed array target
302/// for reading blocks of bit flags.
303///
304/// # Example
305/// ```
306/// use bitstream_io::{BitReader, BitRead, BigEndian};
307///
308/// #[derive(Debug, PartialEq, Eq)]
309/// struct Flags {
310/// a: bool,
311/// b: bool,
312/// c: bool,
313/// d: bool,
314/// }
315///
316/// let data: &[u8] = &[0b1011_0000];
317/// let mut r = BitReader::endian(data, BigEndian);
318/// // note the number of bits must be 1 per read
319/// // while the quantity of flags is indicated by the array length
320/// let flags = r.read::<1, [bool; 4]>().map(|[a, b, c, d]| Flags { a, b, c, d }).unwrap();
321/// assert_eq!(flags, Flags { a: true, b: false, c: true, d: true });
322/// ```
323impl Integer for bool {
324 #[inline(always)]
325 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
326 where
327 Self: Sized,
328 {
329 const {
330 assert!(BITS == 1, "booleans require exactly 1 bit");
331 }
332
333 reader.read_bit()
334 }
335
336 fn read_var<const MAX: u32, R>(
337 reader: &mut R,
338 BitCount { bits }: BitCount<MAX>,
339 ) -> io::Result<Self>
340 where
341 R: BitRead + ?Sized,
342 Self: Sized,
343 {
344 if bits == 1 {
345 reader.read_bit()
346 } else {
347 Err(io::Error::new(
348 io::ErrorKind::InvalidInput,
349 "booleans require exactly 1 bit",
350 ))
351 }
352 }
353
354 #[inline(always)]
355 fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()> {
356 const {
357 assert!(BITS == 1, "booleans require exactly 1 bit");
358 }
359
360 writer.write_bit(self)
361 }
362
363 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
364 self,
365 writer: &mut W,
366 BitCount { bits }: BitCount<MAX>,
367 ) -> io::Result<()> {
368 if bits == 1 {
369 writer.write_bit(self)
370 } else {
371 Err(io::Error::new(
372 io::ErrorKind::InvalidInput,
373 "booleans require exactly 1 bit",
374 ))
375 }
376 }
377}
378
379impl<const SIZE: usize, I: Integer + Copy + Default> Integer for [I; SIZE] {
380 #[inline]
381 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
382 where
383 Self: Sized,
384 {
385 let mut a = [I::default(); SIZE];
386
387 a.iter_mut().try_for_each(|v| {
388 *v = reader.read::<BITS, I>()?;
389 Ok::<(), io::Error>(())
390 })?;
391
392 Ok(a)
393 }
394
395 #[inline]
396 fn read_var<const MAX: u32, R>(reader: &mut R, count: BitCount<MAX>) -> io::Result<Self>
397 where
398 R: BitRead + ?Sized,
399 Self: Sized,
400 {
401 let mut a = [I::default(); SIZE];
402
403 a.iter_mut().try_for_each(|v| {
404 *v = reader.read_counted(count)?;
405 Ok::<(), io::Error>(())
406 })?;
407
408 Ok(a)
409 }
410
411 #[inline]
412 fn write<const BITS: u32, W: BitWrite + ?Sized>(self, writer: &mut W) -> io::Result<()> {
413 IntoIterator::into_iter(self).try_for_each(|v| writer.write::<BITS, I>(v))
414 }
415
416 #[inline]
417 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
418 self,
419 writer: &mut W,
420 count: BitCount<MAX>,
421 ) -> io::Result<()> {
422 IntoIterator::into_iter(self).try_for_each(|v| writer.write_counted(count, v))
423 }
424}
425
426/// This trait extends many common integer types (both unsigned and signed)
427/// with a few trivial methods so that they can be used
428/// with the bitstream handling traits.
429pub trait Numeric:
430 Primitive
431 + Sized
432 + Copy
433 + Default
434 + Debug
435 + PartialOrd
436 + Shl<u32, Output = Self>
437 + ShlAssign<u32>
438 + Shr<u32, Output = Self>
439 + ShrAssign<u32>
440 + Rem<Self, Output = Self>
441 + RemAssign<Self>
442 + BitAnd<Self, Output = Self>
443 + BitOr<Self, Output = Self>
444 + BitOrAssign<Self>
445 + BitXor<Self, Output = Self>
446 + Not<Output = Self>
447 + Sub<Self, Output = Self>
448{
449 /// Size of type in bits
450 const BITS_SIZE: u32;
451
452 /// The value of 0 in this type
453 const ZERO: Self;
454
455 /// The value of 1 in this type
456 const ONE: Self;
457
458 /// Returns a `u8` value in this type
459 fn from_u8(u: u8) -> Self;
460
461 /// Assuming 0 <= value < 256, returns this value as a `u8` type
462 fn to_u8(self) -> u8;
463}
464
465macro_rules! define_numeric {
466 ($t:ty) => {
467 define_primitive_numeric!($t);
468
469 impl Numeric for $t {
470 const BITS_SIZE: u32 = mem::size_of::<$t>() as u32 * 8;
471
472 const ZERO: Self = 0;
473
474 const ONE: Self = 1;
475
476 #[inline(always)]
477 fn from_u8(u: u8) -> Self {
478 u as $t
479 }
480 #[inline(always)]
481 fn to_u8(self) -> u8 {
482 self as u8
483 }
484 }
485 };
486}
487
488/// This trait extends many common unsigned integer types
489/// so that they can be used with the bitstream handling traits.
490pub trait UnsignedInteger: Numeric {
491 /// This type's most-significant bit
492 const MSB_BIT: Self;
493
494 /// This type's least significant bit
495 const LSB_BIT: Self;
496
497 /// This type with all bits set
498 const ALL: Self;
499
500 /// The signed variant of ourself
501 type Signed: SignedInteger<Unsigned = Self>;
502
503 /// Given a twos-complement value,
504 /// return this value is a non-negative signed number.
505 /// The location of the sign bit depends on the stream's endianness
506 /// and is not stored in the result.
507 ///
508 /// # Example
509 /// ```
510 /// use bitstream_io::UnsignedInteger;
511 /// assert_eq!(0b00000001u8.as_non_negative(), 1i8);
512 /// ```
513 fn as_non_negative(self) -> Self::Signed;
514
515 /// Given a two-complement positive value and certain number of bits,
516 /// returns this value as a negative signed number.
517 /// The location of the sign bit depends on the stream's endianness
518 /// and is not stored in the result.
519 ///
520 /// # Example
521 /// ```
522 /// use bitstream_io::UnsignedInteger;
523 /// assert_eq!(0b01111111u8.as_negative(8), -1i8);
524 /// ```
525 fn as_negative(self, bits: u32) -> Self::Signed;
526
527 /// Given a two-complement positive value and certain number of bits,
528 /// returns this value as a negative number.
529 ///
530 /// # Example
531 /// ```
532 /// use bitstream_io::UnsignedInteger;
533 /// assert_eq!(0b01111111u8.as_negative_fixed::<8>(), -1i8);
534 /// ```
535 fn as_negative_fixed<const BITS: u32>(self) -> Self::Signed;
536
537 /// Checked shift left
538 fn checked_shl(self, rhs: u32) -> Option<Self>;
539
540 /// Checked shift right
541 fn checked_shr(self, rhs: u32) -> Option<Self>;
542
543 /// Shift left up to our length in bits
544 ///
545 /// If rhs equals our length in bits, returns default
546 fn shl_default(self, rhs: u32) -> Self {
547 self.checked_shl(rhs).unwrap_or(Self::ZERO)
548 }
549
550 /// Shift left up to our length in bits
551 ///
552 /// If rhs equals our length in bits, returns zero
553 fn shr_default(self, rhs: u32) -> Self {
554 self.checked_shr(rhs).unwrap_or(Self::ZERO)
555 }
556}
557
558macro_rules! define_unsigned_integer {
559 ($t:ty, $s:ty) => {
560 define_numeric!($t);
561
562 impl UnsignedInteger for $t {
563 type Signed = $s;
564
565 const MSB_BIT: Self = 1 << (Self::BITS_SIZE - 1);
566
567 const LSB_BIT: Self = 1;
568
569 const ALL: Self = <$t>::MAX;
570
571 #[inline(always)]
572 fn as_non_negative(self) -> Self::Signed {
573 self as $s
574 }
575 #[inline(always)]
576 fn as_negative(self, bits: u32) -> Self::Signed {
577 (self as $s) + (-1 << (bits - 1))
578 }
579 #[inline(always)]
580 fn as_negative_fixed<const BITS: u32>(self) -> Self::Signed {
581 (self as $s) + (-1 << (BITS - 1))
582 }
583 #[inline(always)]
584 fn checked_shl(self, rhs: u32) -> Option<Self> {
585 self.checked_shl(rhs)
586 }
587 #[inline(always)]
588 fn checked_shr(self, rhs: u32) -> Option<Self> {
589 self.checked_shr(rhs)
590 }
591 }
592
593 impl Integer for $t {
594 #[inline(always)]
595 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
596 where
597 Self: Sized,
598 {
599 reader.read_unsigned::<BITS, _>()
600 }
601
602 #[inline(always)]
603 fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
604 where
605 R: BitRead + ?Sized,
606 Self: Sized,
607 {
608 reader.read_unsigned_counted::<MAX, _>(bits)
609 }
610
611 #[inline(always)]
612 fn write<const BITS: u32, W: BitWrite + ?Sized>(
613 self,
614 writer: &mut W,
615 ) -> io::Result<()> {
616 writer.write_unsigned::<BITS, _>(self)
617 }
618
619 #[inline(always)]
620 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
621 self,
622 writer: &mut W,
623 bits: BitCount<MAX>,
624 ) -> io::Result<()> {
625 writer.write_unsigned_counted(bits, self)
626 }
627 }
628
629 /// Unsigned NonZero types increment their value by 1
630 /// when being read and decrement it by 1
631 /// when being written.
632 ///
633 /// # Examples
634 /// ```
635 /// use bitstream_io::{BitReader, BitRead, BigEndian};
636 /// use core::num::NonZero;
637 ///
638 /// let data: &[u8] = &[0b001_00000];
639 /// // reading a regular u8 in 3 bits yields 1
640 /// assert_eq!(BitReader::endian(data, BigEndian).read::<3, u8>().unwrap(), 1);
641 /// // reading a NonZero<u8> in 3 bits of the same data yields 2
642 /// assert_eq!(BitReader::endian(data, BigEndian).read::<3, NonZero<u8>>().unwrap().get(), 2);
643 /// ```
644 ///
645 /// ```
646 /// use bitstream_io::{BitWriter, BitWrite, BigEndian};
647 /// use core::num::NonZero;
648 ///
649 /// let mut w = BitWriter::endian(vec![], BigEndian);
650 /// // writing 1 as a regular u8 in 3 bits
651 /// w.write::<3, u8>(1).unwrap();
652 /// w.byte_align();
653 /// assert_eq!(w.into_writer(), &[0b001_00000]);
654 ///
655 /// let mut w = BitWriter::endian(vec![], BigEndian);
656 /// // writing 1 as a NonZero<u8> in 3 bits
657 /// w.write::<3, NonZero<u8>>(NonZero::new(1).unwrap()).unwrap();
658 /// w.byte_align();
659 /// assert_eq!(w.into_writer(), &[0b000_00000]);
660 /// ```
661 impl Integer for NonZero<$t> {
662 #[inline]
663 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
664 where
665 Self: Sized,
666 {
667 const {
668 assert!(
669 BITS < <$t>::BITS_SIZE,
670 "BITS must be less than the type's size in bits"
671 );
672 }
673
674 <$t as Integer>::read::<BITS, R>(reader).map(|u| NonZero::new(u + 1).unwrap())
675 }
676
677 #[inline]
678 fn read_var<const MAX: u32, R>(
679 reader: &mut R,
680 count @ BitCount { bits }: BitCount<MAX>,
681 ) -> io::Result<Self>
682 where
683 R: BitRead + ?Sized,
684 Self: Sized,
685 {
686 if MAX < <$t>::BITS_SIZE || bits < <$t>::BITS_SIZE {
687 <$t as Integer>::read_var::<MAX, R>(reader, count)
688 .map(|u| NonZero::new(u + 1).unwrap())
689 } else {
690 Err(io::Error::new(
691 io::ErrorKind::InvalidInput,
692 "bit count must be less than the type's size in bits",
693 ))
694 }
695 }
696
697 #[inline]
698 fn write<const BITS: u32, W: BitWrite + ?Sized>(
699 self,
700 writer: &mut W,
701 ) -> io::Result<()> {
702 const {
703 assert!(
704 BITS < <$t>::BITS_SIZE,
705 "BITS must be less than the type's size in bits"
706 );
707 }
708
709 <$t as Integer>::write::<BITS, W>(self.get() - 1, writer)
710 }
711
712 #[inline]
713 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
714 self,
715 writer: &mut W,
716 count @ BitCount { bits }: BitCount<MAX>,
717 ) -> io::Result<()> {
718 if MAX < <$t>::BITS_SIZE || bits < <$t>::BITS_SIZE {
719 <$t as Integer>::write_var::<MAX, W>(self.get() - 1, writer, count)
720 } else {
721 Err(io::Error::new(
722 io::ErrorKind::InvalidInput,
723 "bit count must be less than the type's size in bits",
724 ))
725 }
726 }
727 }
728
729 impl Integer for Option<NonZero<$t>> {
730 #[inline]
731 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
732 where
733 Self: Sized,
734 {
735 <$t as Integer>::read::<BITS, R>(reader).map(NonZero::new)
736 }
737
738 #[inline]
739 fn read_var<const MAX: u32, R>(reader: &mut R, count: BitCount<MAX>) -> io::Result<Self>
740 where
741 R: BitRead + ?Sized,
742 Self: Sized,
743 {
744 <$t as Integer>::read_var::<MAX, R>(reader, count).map(NonZero::new)
745 }
746
747 #[inline]
748 fn write<const BITS: u32, W: BitWrite + ?Sized>(
749 self,
750 writer: &mut W,
751 ) -> io::Result<()> {
752 <$t as Integer>::write::<BITS, W>(self.map(|n| n.get()).unwrap_or(0), writer)
753 }
754
755 #[inline]
756 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
757 self,
758 writer: &mut W,
759 count: BitCount<MAX>,
760 ) -> io::Result<()> {
761 <$t as Integer>::write_var::<MAX, W>(
762 self.map(|n| n.get()).unwrap_or(0),
763 writer,
764 count,
765 )
766 }
767 }
768 };
769}
770
771/// This trait extends many common signed integer types
772/// so that they can be used with the bitstream handling traits.
773///
774/// This trait was formerly named `SignedNumeric` in 2.X.X code.
775/// If backwards-compatibility is needed one can
776/// import `SignedInteger` as `SignedNumeric`.
777pub trait SignedInteger: Numeric {
778 /// The unsigned variant of ourself
779 type Unsigned: UnsignedInteger<Signed = Self>;
780
781 /// Returns true if this value is negative
782 ///
783 /// # Example
784 /// ```
785 /// use bitstream_io::SignedInteger;
786 /// assert!(!1i8.is_negative());
787 /// assert!((-1i8).is_negative());
788 /// ```
789 fn is_negative(self) -> bool;
790
791 /// Returns ourself as a non-negative value.
792 /// The location of the sign bit depends on the stream's endianness
793 /// and is not stored in the result.
794 ///
795 /// # Example
796 /// ```
797 /// use bitstream_io::SignedInteger;
798 /// assert_eq!(1i8.as_non_negative(), 0b00000001u8);
799 /// ```
800 fn as_non_negative(self) -> Self::Unsigned;
801
802 /// Given a negative value and a certain number of bits,
803 /// returns this value as a twos-complement positive number.
804 /// The location of the sign bit depends on the stream's endianness
805 /// and is not stored in the result.
806 ///
807 /// # Example
808 /// ```
809 /// use bitstream_io::SignedInteger;
810 /// assert_eq!((-1i8).as_negative(8), 0b01111111u8);
811 /// ```
812 fn as_negative(self, bits: u32) -> Self::Unsigned;
813
814 /// Given a negative value and a certain number of bits,
815 /// returns this value as a twos-complement positive number.
816 ///
817 /// # Example
818 /// ```
819 /// use bitstream_io::SignedInteger;
820 /// assert_eq!((-1i8).as_negative_fixed::<8>(), 0b01111111u8);
821 /// ```
822 fn as_negative_fixed<const BITS: u32>(self) -> Self::Unsigned;
823}
824
825macro_rules! define_signed_integer {
826 ($t:ty, $u:ty) => {
827 define_numeric!($t);
828
829 impl SignedInteger for $t {
830 type Unsigned = $u;
831
832 #[inline(always)]
833 fn is_negative(self) -> bool {
834 self.is_negative()
835 }
836 fn as_non_negative(self) -> Self::Unsigned {
837 self as $u
838 }
839 fn as_negative(self, bits: u32) -> Self::Unsigned {
840 (self - (-1 << (bits - 1))) as $u
841 }
842 fn as_negative_fixed<const BITS: u32>(self) -> Self::Unsigned {
843 (self - (-1 << (BITS - 1))) as $u
844 }
845 }
846
847 impl Integer for $t {
848 #[inline(always)]
849 fn read<const BITS: u32, R: BitRead + ?Sized>(reader: &mut R) -> io::Result<Self>
850 where
851 Self: Sized,
852 {
853 reader.read_signed::<BITS, _>()
854 }
855
856 #[inline(always)]
857 fn read_var<const MAX: u32, R>(reader: &mut R, bits: BitCount<MAX>) -> io::Result<Self>
858 where
859 R: BitRead + ?Sized,
860 Self: Sized,
861 {
862 reader.read_signed_counted::<MAX, _>(bits)
863 }
864
865 #[inline(always)]
866 fn write<const BITS: u32, W: BitWrite + ?Sized>(
867 self,
868 writer: &mut W,
869 ) -> io::Result<()> {
870 writer.write_signed::<BITS, _>(self)
871 }
872
873 #[inline(always)]
874 fn write_var<const MAX: u32, W: BitWrite + ?Sized>(
875 self,
876 writer: &mut W,
877 bits: BitCount<MAX>,
878 ) -> io::Result<()> {
879 writer.write_signed_counted::<MAX, _>(bits, self)
880 }
881 }
882 };
883}
884
885define_unsigned_integer!(u8, i8);
886define_unsigned_integer!(u16, i16);
887define_unsigned_integer!(u32, i32);
888define_unsigned_integer!(u64, i64);
889define_unsigned_integer!(u128, i128);
890
891define_signed_integer!(i8, u8);
892define_signed_integer!(i16, u16);
893define_signed_integer!(i32, u32);
894define_signed_integer!(i64, u64);
895define_signed_integer!(i128, u128);
896
897define_primitive_numeric!(f32);
898define_primitive_numeric!(f64);
899
900/// A stream's endianness, or byte order, for determining
901/// how bits should be read.
902///
903/// It comes in `BigEndian` and `LittleEndian` varieties
904/// (which may be shortened to `BE` and `LE`)
905/// and is not something programmers should have to implement
906/// in most cases.
907pub trait Endianness: Sized {
908 /// Pops the next bit from the queue,
909 /// repleneshing it from the given reader if necessary
910 fn pop_bit_refill<R>(
911 reader: &mut R,
912 queue_value: &mut u8,
913 queue_bits: &mut u32,
914 ) -> io::Result<bool>
915 where
916 R: io::Read;
917
918 /// Pops the next unary value from the source until
919 /// `STOP_BIT` is encountered, replenishing it from the given
920 /// closure if necessary.
921 ///
922 /// `STOP_BIT` must be 0 or 1.
923 fn pop_unary<const STOP_BIT: u8, R>(
924 reader: &mut R,
925 queue_value: &mut u8,
926 queue_bits: &mut u32,
927 ) -> io::Result<u32>
928 where
929 R: io::Read;
930
931 /// Pushes the next bit into the queue,
932 /// and returns `Some` value if the queue is full.
933 fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8>;
934
935 /// For performing bulk reads from a bit source to an output type.
936 fn read_bits<const MAX: u32, R, U>(
937 reader: &mut R,
938 queue_value: &mut u8,
939 queue_bits: &mut u32,
940 count: BitCount<MAX>,
941 ) -> io::Result<U>
942 where
943 R: io::Read,
944 U: UnsignedInteger;
945
946 /// For performing bulk reads from a bit source to an output type.
947 fn read_bits_fixed<const BITS: u32, R, U>(
948 reader: &mut R,
949 queue_value: &mut u8,
950 queue_bits: &mut u32,
951 ) -> io::Result<U>
952 where
953 R: io::Read,
954 U: UnsignedInteger;
955
956 /// For performing bulk writes of a type to a bit sink.
957 fn write_bits<const MAX: u32, W, U>(
958 writer: &mut W,
959 queue_value: &mut u8,
960 queue_bits: &mut u32,
961 count: BitCount<MAX>,
962 value: U,
963 ) -> io::Result<()>
964 where
965 W: io::Write,
966 U: UnsignedInteger;
967
968 /// For performing bulk writes of a type to a bit sink.
969 fn write_bits_fixed<const BITS: u32, W, U>(
970 writer: &mut W,
971 queue_value: &mut u8,
972 queue_bits: &mut u32,
973 value: U,
974 ) -> io::Result<()>
975 where
976 W: io::Write,
977 U: UnsignedInteger;
978
979 /// Reads signed value from reader in this endianness
980 #[inline]
981 fn read_signed<const MAX: u32, R, S>(
982 r: &mut R,
983 count @ BitCount { bits }: BitCount<MAX>,
984 ) -> io::Result<S>
985 where
986 R: BitRead,
987 S: SignedInteger,
988 {
989 if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
990 Self::read_signed_counted(
991 r,
992 count.signed_count().ok_or(io::Error::new(
993 io::ErrorKind::InvalidInput,
994 "signed reads need at least 1 bit for sign",
995 ))?,
996 )
997 } else {
998 Err(io::Error::new(
999 io::ErrorKind::InvalidInput,
1000 "excessive bits for type read",
1001 ))
1002 }
1003 }
1004
1005 /// Reads signed value from reader in this endianness
1006 #[inline]
1007 fn read_signed_fixed<R, const BITS: u32, S>(r: &mut R) -> io::Result<S>
1008 where
1009 R: BitRead,
1010 S: SignedInteger,
1011 {
1012 let count = const {
1013 assert!(BITS <= S::BITS_SIZE, "excessive bits for type read");
1014 let count = BitCount::<BITS>::new::<BITS>().signed_count();
1015 assert!(count.is_some(), "signed reads need at least 1 bit for sign");
1016 count.unwrap()
1017 };
1018
1019 Self::read_signed_counted(r, count)
1020 }
1021
1022 /// Reads signed value from reader in this endianness
1023 fn read_signed_counted<const MAX: u32, R, S>(
1024 r: &mut R,
1025 bits: SignedBitCount<MAX>,
1026 ) -> io::Result<S>
1027 where
1028 R: BitRead,
1029 S: SignedInteger;
1030
1031 /// Writes signed value to writer in this endianness
1032 fn write_signed<const MAX: u32, W, S>(
1033 w: &mut W,
1034 count: BitCount<MAX>,
1035 value: S,
1036 ) -> io::Result<()>
1037 where
1038 W: BitWrite,
1039 S: SignedInteger,
1040 {
1041 Self::write_signed_counted(
1042 w,
1043 count.signed_count().ok_or(io::Error::new(
1044 io::ErrorKind::InvalidInput,
1045 "signed writes need at least 1 bit for sign",
1046 ))?,
1047 value,
1048 )
1049 }
1050
1051 /// Writes signed value to writer in this endianness
1052 fn write_signed_fixed<W, const BITS: u32, S>(w: &mut W, value: S) -> io::Result<()>
1053 where
1054 W: BitWrite,
1055 S: SignedInteger,
1056 {
1057 let count = const {
1058 assert!(BITS <= S::BITS_SIZE, "excessive bits for type written");
1059 let count = BitCount::<BITS>::new::<BITS>().signed_count();
1060 assert!(
1061 count.is_some(),
1062 "signed writes need at least 1 bit for sign"
1063 );
1064 count.unwrap()
1065 };
1066
1067 Self::write_signed_counted(w, count, value)
1068 }
1069
1070 /// Writes signed value to writer in this endianness
1071 fn write_signed_counted<const MAX: u32, W, S>(
1072 w: &mut W,
1073 bits: SignedBitCount<MAX>,
1074 value: S,
1075 ) -> io::Result<()>
1076 where
1077 W: BitWrite,
1078 S: SignedInteger;
1079
1080 /// Reads whole set of bytes to output buffer
1081 fn read_bytes<const CHUNK_SIZE: usize, R>(
1082 reader: &mut R,
1083 queue_value: &mut u8,
1084 queue_bits: u32,
1085 buf: &mut [u8],
1086 ) -> io::Result<()>
1087 where
1088 R: io::Read;
1089
1090 /// Writes whole set of bytes to output buffer
1091 fn write_bytes<const CHUNK_SIZE: usize, W>(
1092 writer: &mut W,
1093 queue_value: &mut u8,
1094 queue_bits: u32,
1095 buf: &[u8],
1096 ) -> io::Result<()>
1097 where
1098 W: io::Write;
1099
1100 /// Converts a primitive's byte buffer to a primitive
1101 fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P;
1102
1103 /// Converts a primitive to a primitive's byte buffer
1104 fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes;
1105}
1106
1107#[inline(always)]
1108fn read_byte<R>(mut reader: R) -> io::Result<u8>
1109where
1110 R: io::Read,
1111{
1112 let mut byte = 0;
1113 reader
1114 .read_exact(core::slice::from_mut(&mut byte))
1115 .map(|()| byte)
1116}
1117
1118#[inline(always)]
1119fn write_byte<W>(mut writer: W, byte: u8) -> io::Result<()>
1120where
1121 W: io::Write,
1122{
1123 writer.write_all(core::slice::from_ref(&byte))
1124}
1125
1126/// A number of bits to be consumed or written, with a known maximum
1127///
1128/// Although [`BitRead::read`] and [`BitWrite::write`] should be
1129/// preferred when the number of bits is fixed and known at compile-time -
1130/// because they can validate the bit count is less than or equal
1131/// to the type's size in bits at compile-time -
1132/// there are many instances where bit count is dynamic and
1133/// determined by the file format itself.
1134/// But when using [`BitRead::read_var`] or [`BitWrite::write_var`]
1135/// we must pessimistically assume any number of bits as an argument
1136/// and validate that the number of bits is not larger than the
1137/// type being read or written on every call.
1138///
1139/// ```
1140/// use bitstream_io::{BitRead, BitReader, BigEndian};
1141///
1142/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1143/// let mut r = BitReader::endian(data, BigEndian);
1144/// // our bit count is a 3 bit value
1145/// let count = r.read::<3, u32>().unwrap();
1146/// // that count indicates we need to read 4 bits (0b100)
1147/// assert_eq!(count, 4);
1148/// // read the first 4-bit value
1149/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b0001);
1150/// // read the second 4-bit value
1151/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b1111);
1152/// // read the third 4-bit value
1153/// assert_eq!(r.read_var::<u8>(count).unwrap(), 0b0110);
1154/// ```
1155///
1156/// In the preceding example, even though we know `count` is a
1157/// 3 bit value whose maximum value will never be greater than 7,
1158/// the subsequent `read_var` calls have no way to know that.
1159/// They must assume `count` could be 9, or `u32::MAX` or any other `u32` value
1160/// and validate the count is not larger than the `u8` types we're reading.
1161///
1162/// But we can convert our example to use the `BitCount` type:
1163///
1164/// ```
1165/// use bitstream_io::{BitRead, BitReader, BigEndian, BitCount};
1166///
1167/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1168/// let mut r = BitReader::endian(data, BigEndian);
1169/// // our bit count is a 3 bit value with a maximum value of 7
1170/// let count = r.read_count::<0b111>().unwrap();
1171/// // that count indicates we need to read 4 bits (0b100)
1172/// assert_eq!(count, BitCount::<7>::new::<4>());
1173/// // read the first 4-bit value
1174/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b0001);
1175/// // read the second 4-bit value
1176/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b1111);
1177/// // read the third 4-bit value
1178/// assert_eq!(r.read_counted::<7, u8>(count).unwrap(), 0b0110);
1179/// ```
1180///
1181/// Because the [`BitRead::read_counted`] methods know at compile-time
1182/// that the bit count will be larger than 7, that check can be eliminated
1183/// simply by taking advantage of information we already know.
1184///
1185/// Leveraging the `BitCount` type also allows us to reason about
1186/// bit counts in a more formal way, and use checked permutation methods
1187/// to modify them while ensuring they remain constrained by
1188/// the file format's requirements.
1189#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1190pub struct BitCount<const MAX: u32> {
1191 // The amount of bits may be less than or equal to the maximum,
1192 // but never more.
1193 bits: u32,
1194}
1195
1196impl<const MAX: u32> BitCount<MAX> {
1197 /// Builds a bit count from a constant number
1198 /// of bits, which must not be greater than `MAX`.
1199 ///
1200 /// Intended to be used for defining constants.
1201 ///
1202 /// Use `TryFrom` to conditionally build
1203 /// counts from values at runtime.
1204 ///
1205 /// # Examples
1206 ///
1207 /// ```
1208 /// use bitstream_io::{BitReader, BitRead, BigEndian, BitCount};
1209 /// let data: &[u8] = &[0b111_00000];
1210 /// let mut r = BitReader::endian(data, BigEndian);
1211 /// // reading 3 bits from a stream out of a maximum of 8
1212 /// // doesn't require checking that the bit count is larger
1213 /// // than a u8 at runtime because specifying the maximum of 8
1214 /// // guarantees our bit count will not be larger than 8
1215 /// assert_eq!(r.read_counted::<8, u8>(BitCount::new::<3>()).unwrap(), 0b111);
1216 /// ```
1217 ///
1218 /// ```rust,compile_fail
1219 /// use bitstream_io::BitCount;
1220 /// // trying to build a count of 10 with a maximum of 8
1221 /// // fails to compile at all
1222 /// let count = BitCount::<8>::new::<10>();
1223 /// ```
1224 pub const fn new<const BITS: u32>() -> Self {
1225 const {
1226 assert!(BITS <= MAX, "BITS must be <= MAX");
1227 }
1228
1229 Self { bits: BITS }
1230 }
1231
1232 /// Add a number of bits to our count,
1233 /// returning a new count with a new maximum.
1234 ///
1235 /// Returns `None` if the new count goes above our new maximum.
1236 ///
1237 /// # Examples
1238 ///
1239 /// ```
1240 /// use bitstream_io::BitCount;
1241 ///
1242 /// let count = BitCount::<2>::new::<1>();
1243 /// // adding 2 to 1 and increasing the max to 3 yields a new count of 3
1244 /// assert_eq!(count.checked_add::<3>(2), Some(BitCount::<3>::new::<3>()));
1245 /// // adding 2 to 1 without increasing the max yields None
1246 /// assert_eq!(count.checked_add::<2>(2), None);
1247 /// ```
1248 #[inline]
1249 pub const fn checked_add<const NEW_MAX: u32>(self, bits: u32) -> Option<BitCount<NEW_MAX>> {
1250 match self.bits.checked_add(bits) {
1251 Some(bits) if bits <= NEW_MAX => Some(BitCount { bits }),
1252 _ => None,
1253 }
1254 }
1255
1256 /// Subtracts a number of bits from our count,
1257 /// returning a new count with a new maximum.
1258 ///
1259 /// Returns `None` if the new count goes below 0
1260 /// or below our new maximum.
1261 ///
1262 /// # Example
1263 /// ```
1264 /// use bitstream_io::BitCount;
1265 /// let count = BitCount::<5>::new::<5>();
1266 /// // subtracting 1 from 5 yields a new count of 4
1267 /// assert_eq!(count.checked_sub::<5>(1), Some(BitCount::<5>::new::<4>()));
1268 /// // subtracting 6 from 5 yields None
1269 /// assert!(count.checked_sub::<5>(6).is_none());
1270 /// // subtracting 1 with a new maximum of 3 also yields None
1271 /// // because 4 is larger than the maximum of 3
1272 /// assert!(count.checked_sub::<3>(1).is_none());
1273 /// ```
1274 #[inline]
1275 pub const fn checked_sub<const NEW_MAX: u32>(self, bits: u32) -> Option<BitCount<NEW_MAX>> {
1276 match self.bits.checked_sub(bits) {
1277 Some(bits) if bits <= NEW_MAX => Some(BitCount { bits }),
1278 _ => None,
1279 }
1280 }
1281
1282 /// Attempt to convert our count to a count with a new
1283 /// bit count and new maximum.
1284 ///
1285 /// Returns `Some(count)` if the updated number of bits
1286 /// is less than or equal to the new maximum.
1287 /// Returns `None` if not.
1288 ///
1289 /// # Examples
1290 /// ```
1291 /// use bitstream_io::BitCount;
1292 ///
1293 /// let count = BitCount::<5>::new::<5>();
1294 /// // muliplying 5 bits by 2 with a new max of 10 is ok
1295 /// assert_eq!(
1296 /// count.try_map::<10, _>(|i| i.checked_mul(2)),
1297 /// Some(BitCount::<10>::new::<10>()),
1298 /// );
1299 ///
1300 /// // multiplying 5 bits by 3 with a new max of 10 overflows
1301 /// assert_eq!(count.try_map::<10, _>(|i| i.checked_mul(3)), None);
1302 /// ```
1303 #[inline]
1304 pub fn try_map<const NEW_MAX: u32, F>(self, f: F) -> Option<BitCount<NEW_MAX>>
1305 where
1306 F: FnOnce(u32) -> Option<u32>,
1307 {
1308 f(self.bits)
1309 .filter(|bits| *bits <= NEW_MAX)
1310 .map(|bits| BitCount { bits })
1311 }
1312
1313 /// Returns our maximum bit count
1314 ///
1315 /// # Example
1316 /// ```
1317 /// use bitstream_io::BitCount;
1318 ///
1319 /// let count = BitCount::<10>::new::<5>();
1320 /// assert_eq!(count.max(), 10);
1321 /// ```
1322 #[inline(always)]
1323 pub const fn max(&self) -> u32 {
1324 MAX
1325 }
1326
1327 /// Returns signed count if our bit count is greater than 0
1328 ///
1329 /// # Example
1330 ///
1331 /// ```
1332 /// use bitstream_io::{BitCount, SignedBitCount};
1333 ///
1334 /// let count = BitCount::<10>::new::<5>();
1335 /// assert_eq!(count.signed_count(), Some(SignedBitCount::<10>::new::<5>()));
1336 ///
1337 /// let count = BitCount::<10>::new::<0>();
1338 /// assert_eq!(count.signed_count(), None);
1339 /// ```
1340 #[inline(always)]
1341 pub const fn signed_count(&self) -> Option<SignedBitCount<MAX>> {
1342 match self.bits.checked_sub(1) {
1343 Some(bits) => Some(SignedBitCount {
1344 bits: *self,
1345 unsigned: BitCount { bits },
1346 }),
1347 None => None,
1348 }
1349 }
1350}
1351
1352impl<const MAX: u32> core::convert::TryFrom<u32> for BitCount<MAX> {
1353 type Error = u32;
1354
1355 /// Attempts to convert a `u32` bit count to a `BitCount`
1356 ///
1357 /// Attempting a bit maximum bit count larger than the
1358 /// largest supported type is a compile-time error
1359 ///
1360 /// # Examples
1361 /// ```
1362 /// use bitstream_io::BitCount;
1363 /// use std::convert::TryInto;
1364 ///
1365 /// assert_eq!(8u32.try_into(), Ok(BitCount::<8>::new::<8>()));
1366 /// assert_eq!(9u32.try_into(), Err::<BitCount<8>, _>(9));
1367 /// ```
1368 fn try_from(bits: u32) -> Result<Self, Self::Error> {
1369 (bits <= MAX).then_some(Self { bits }).ok_or(bits)
1370 }
1371}
1372
1373impl BitCount<{ u32::MAX }> {
1374 /// Builds a bit count where the maximum bits is unknown.
1375 ///
1376 /// # Example
1377 /// ```
1378 /// use bitstream_io::BitCount;
1379 /// assert_eq!(BitCount::unknown(5), BitCount::<{ u32::MAX }>::new::<5>());
1380 /// ```
1381 pub const fn unknown(bits: u32) -> Self {
1382 Self { bits }
1383 }
1384}
1385
1386#[test]
1387fn test_unknown_bitcount() {
1388 let count = BitCount::unknown(u32::MAX);
1389 assert!(u32::from(count) <= count.max());
1390}
1391
1392impl<const MAX: u32> From<BitCount<MAX>> for u32 {
1393 #[inline(always)]
1394 fn from(BitCount { bits }: BitCount<MAX>) -> u32 {
1395 bits
1396 }
1397}
1398
1399/// A number of bits to be read or written for signed integers, with a known maximum
1400///
1401/// This is closely related to the [`BitCount`] type, but further constrained
1402/// to have a minimum value of 1 - because signed values require at least
1403/// 1 bit for the sign.
1404///
1405/// Let's start with a basic example:
1406///
1407/// ```
1408/// use bitstream_io::{BitRead, BitReader, BigEndian};
1409///
1410/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1411/// let mut r = BitReader::endian(data, BigEndian);
1412/// // our bit count is a 3 bit value
1413/// let count = r.read::<3, u32>().unwrap();
1414/// // that count indicates we need to read 4 bits (0b100)
1415/// assert_eq!(count, 4);
1416/// // read the first 4-bit signed value
1417/// assert_eq!(r.read_var::<i8>(count).unwrap(), 1);
1418/// // read the second 4-bit signed value
1419/// assert_eq!(r.read_var::<i8>(count).unwrap(), -1);
1420/// // read the third 4-bit signed value
1421/// assert_eq!(r.read_var::<i8>(count).unwrap(), 6);
1422/// ```
1423///
1424/// In the preceding example, even though we know `count` is a
1425/// 3 bit value whose maximum value will never be greater than 7,
1426/// the subsequent `read_var` calls have no way to know that.
1427/// They must assume `count` could be 9, or `u32::MAX` or any other `u32` value
1428/// and validate the count is not larger than the `i8` types we're reading
1429/// while also greater than 0 because `i8` requires a sign bit.
1430///
1431/// But we can convert our example to use the `SignedBitCount` type:
1432/// ```
1433/// use bitstream_io::{BitRead, BitReader, BigEndian, SignedBitCount};
1434///
1435/// let data: &[u8] = &[0b100_0001_1, 0b111_0110_0];
1436/// let mut r = BitReader::endian(data, BigEndian);
1437/// // our bit count is a 3 bit value with a maximum value of 7
1438/// let count = r.read_count::<0b111>().unwrap();
1439/// // convert that count to a signed bit count,
1440/// // which guarantees its value is greater than 0
1441/// let count = count.signed_count().unwrap();
1442/// // that count indicates we need to read 4 bits (0b100)
1443/// assert_eq!(count, SignedBitCount::<7>::new::<4>());
1444/// // read the first 4-bit value
1445/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), 1);
1446/// // read the second 4-bit value
1447/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), -1);
1448/// // read the third 4-bit value
1449/// assert_eq!(r.read_signed_counted::<7, i8>(count).unwrap(), 6);
1450/// ```
1451///
1452/// Because the [`BitRead::read_signed_counted`] methods know at compile-time
1453/// that the bit count will be larger than 7, that check can be eliminated
1454/// simply by taking advantage of information we already know.
1455///
1456/// Leveraging the `SignedBitCount` type also allows us to reason about
1457/// bit counts in a more formal way, and use checked permutation methods
1458/// to modify them while ensuring they remain constrained by
1459/// the file format's requirements.
1460#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1461pub struct SignedBitCount<const MAX: u32> {
1462 // the whole original bit count
1463 bits: BitCount<MAX>,
1464 // a bit count with one bit removed for the sign
1465 unsigned: BitCount<MAX>,
1466}
1467
1468impl<const MAX: u32> SignedBitCount<MAX> {
1469 /// Builds a signed bit count from a constant number
1470 /// of bits, which must be greater than 0 and
1471 /// not be greater than `MAX`.
1472 ///
1473 /// Intended to be used for defining constants.
1474 ///
1475 /// Use `TryFrom` to conditionally build
1476 /// counts from values at runtime.
1477 ///
1478 /// # Examples
1479 ///
1480 /// ```
1481 /// use bitstream_io::{BitReader, BitRead, BigEndian, SignedBitCount};
1482 /// let data: &[u8] = &[0b111_00000];
1483 /// let mut r = BitReader::endian(data, BigEndian);
1484 /// // reading 3 bits from a stream out of a maximum of 8
1485 /// // doesn't require checking that the bit count is larger
1486 /// // than a u8 at runtime because specifying the maximum of 8
1487 /// // guarantees our bit count will not be larger than 8
1488 /// assert_eq!(r.read_signed_counted::<8, i8>(SignedBitCount::new::<3>()).unwrap(), -1);
1489 /// ```
1490 ///
1491 /// ```rust,compile_fail
1492 /// use bitstream_io::SignedBitCount;
1493 /// // trying to build a count of 10 with a maximum of 8
1494 /// // fails to compile at all
1495 /// let count = SignedBitCount::<8>::new::<10>();
1496 /// ```
1497 ///
1498 /// ```rust,compile_fail
1499 /// use bitstream_io::SignedBitCount;
1500 /// // trying to build a count of 0 also fails to compile
1501 /// let count = SignedBitCount::<8>::new::<0>();
1502 /// ```
1503 pub const fn new<const BITS: u32>() -> Self {
1504 const {
1505 assert!(BITS > 0, "BITS must be > 0");
1506 }
1507
1508 Self {
1509 bits: BitCount::new::<BITS>(),
1510 unsigned: BitCount { bits: BITS - 1 },
1511 }
1512 }
1513
1514 /// Add a number of bits to our count,
1515 /// returning a new count with a new maximum.
1516 ///
1517 /// Returns `None` if the new count goes above our new maximum.
1518 ///
1519 /// # Examples
1520 ///
1521 /// ```
1522 /// use bitstream_io::SignedBitCount;
1523 ///
1524 /// let count = SignedBitCount::<2>::new::<1>();
1525 /// // adding 2 to 1 and increasing the max to 3 yields a new count of 3
1526 /// assert_eq!(count.checked_add::<3>(2), Some(SignedBitCount::<3>::new::<3>()));
1527 /// // adding 2 to 1 without increasing the max yields None
1528 /// assert_eq!(count.checked_add::<2>(2), None);
1529 /// ```
1530 #[inline]
1531 pub const fn checked_add<const NEW_MAX: u32>(
1532 self,
1533 bits: u32,
1534 ) -> Option<SignedBitCount<NEW_MAX>> {
1535 match self.bits.checked_add(bits) {
1536 Some(bits_new) => match self.unsigned.checked_add(bits) {
1537 Some(unsigned) => Some(SignedBitCount {
1538 bits: bits_new,
1539 unsigned,
1540 }),
1541 None => None,
1542 },
1543 None => None,
1544 }
1545 }
1546
1547 /// Subtracts a number of bits from our count,
1548 /// returning a new count with a new maximum.
1549 ///
1550 /// Returns `None` if the new count goes below 1
1551 /// or below our new maximum.
1552 ///
1553 /// # Example
1554 /// ```
1555 /// use bitstream_io::SignedBitCount;
1556 /// let count = SignedBitCount::<5>::new::<5>();
1557 /// // subtracting 1 from 5 yields a new count of 4
1558 /// assert_eq!(count.checked_sub::<5>(1), Some(SignedBitCount::<5>::new::<4>()));
1559 /// // subtracting 6 from 5 yields None
1560 /// assert!(count.checked_sub::<5>(6).is_none());
1561 /// // subtracting 1 with a new maximum of 3 also yields None
1562 /// // because 4 is larger than the maximum of 3
1563 /// assert!(count.checked_sub::<3>(1).is_none());
1564 /// // subtracting 5 from 5 also yields None
1565 /// // because SignedBitCount always requires 1 bit for the sign
1566 /// assert!(count.checked_sub::<5>(5).is_none());
1567 /// ```
1568 #[inline]
1569 pub const fn checked_sub<const NEW_MAX: u32>(
1570 self,
1571 bits: u32,
1572 ) -> Option<SignedBitCount<NEW_MAX>> {
1573 match self.bits.checked_sub(bits) {
1574 Some(bits_new) => match self.unsigned.checked_sub(bits) {
1575 Some(unsigned) => Some(SignedBitCount {
1576 bits: bits_new,
1577 unsigned,
1578 }),
1579 None => None,
1580 },
1581 None => None,
1582 }
1583 }
1584
1585 /// Attempt to convert our count to a count with a new
1586 /// bit count and new maximum.
1587 ///
1588 /// Returns `Some(count)` if the updated number of bits
1589 /// is less than or equal to the new maximum
1590 /// and greater than 0.
1591 /// Returns `None` if not.
1592 ///
1593 /// # Examples
1594 /// ```
1595 /// use bitstream_io::SignedBitCount;
1596 ///
1597 /// let count = SignedBitCount::<5>::new::<5>();
1598 /// // muliplying 5 bits by 2 with a new max of 10 is ok
1599 /// assert_eq!(
1600 /// count.try_map::<10, _>(|i| i.checked_mul(2)),
1601 /// Some(SignedBitCount::<10>::new::<10>()),
1602 /// );
1603 ///
1604 /// // multiplying 5 bits by 3 with a new max of 10 overflows
1605 /// assert_eq!(count.try_map::<10, _>(|i| i.checked_mul(3)), None);
1606 ///
1607 /// // multiplying 5 bits by 0 results in 0 bits,
1608 /// // which isn't value for a SignedBitCount
1609 /// assert_eq!(count.try_map::<10, _>(|i| Some(i * 0)), None);
1610 /// ```
1611 #[inline]
1612 pub fn try_map<const NEW_MAX: u32, F>(self, f: F) -> Option<SignedBitCount<NEW_MAX>>
1613 where
1614 F: FnOnce(u32) -> Option<u32>,
1615 {
1616 self.bits.try_map(f).and_then(|b| b.signed_count())
1617 }
1618
1619 /// Returns our maximum bit count
1620 ///
1621 /// # Example
1622 /// ```
1623 /// use bitstream_io::SignedBitCount;
1624 ///
1625 /// let count = SignedBitCount::<10>::new::<5>();
1626 /// assert_eq!(count.max(), 10);
1627 /// ```
1628 #[inline(always)]
1629 pub const fn max(&self) -> u32 {
1630 MAX
1631 }
1632
1633 /// Returns regular unsigned bit count
1634 ///
1635 /// # Example
1636 ///
1637 /// ```
1638 /// use bitstream_io::{BitCount, SignedBitCount};
1639 ///
1640 /// let signed_count = SignedBitCount::<10>::new::<5>();
1641 /// assert_eq!(signed_count.count(), BitCount::<10>::new::<5>());
1642 /// ```
1643 #[inline(always)]
1644 pub const fn count(&self) -> BitCount<MAX> {
1645 self.bits
1646 }
1647}
1648
1649impl<const MAX: u32> core::convert::TryFrom<BitCount<MAX>> for SignedBitCount<MAX> {
1650 type Error = ();
1651
1652 #[inline]
1653 fn try_from(count: BitCount<MAX>) -> Result<Self, Self::Error> {
1654 count.signed_count().ok_or(())
1655 }
1656}
1657
1658impl<const MAX: u32> core::convert::TryFrom<u32> for SignedBitCount<MAX> {
1659 type Error = u32;
1660
1661 #[inline]
1662 fn try_from(count: u32) -> Result<Self, Self::Error> {
1663 BitCount::<MAX>::try_from(count).and_then(|b| b.signed_count().ok_or(count))
1664 }
1665}
1666
1667impl<const MAX: u32> From<SignedBitCount<MAX>> for u32 {
1668 #[inline(always)]
1669 fn from(
1670 SignedBitCount {
1671 bits: BitCount { bits },
1672 ..
1673 }: SignedBitCount<MAX>,
1674 ) -> u32 {
1675 bits
1676 }
1677}
1678
1679/// Big-endian, or most significant bits first
1680#[derive(Copy, Clone, Debug)]
1681pub struct BigEndian;
1682
1683/// Big-endian, or most significant bits first
1684pub type BE = BigEndian;
1685
1686impl BigEndian {
1687 // checked in the sense that we've verified
1688 // the output type is large enough to hold the
1689 // requested number of bits
1690 #[inline]
1691 fn read_bits_checked<const MAX: u32, R, U>(
1692 reader: &mut R,
1693 queue: &mut u8,
1694 queue_bits: &mut u32,
1695 BitCount { bits }: BitCount<MAX>,
1696 ) -> io::Result<U>
1697 where
1698 R: io::Read,
1699 U: UnsignedInteger,
1700 {
1701 // reads a whole value with the given number of
1702 // bytes in our endianness, where the number of bytes
1703 // must be less than or equal to the type's size in bytes
1704 #[inline(always)]
1705 fn read_bytes<R, U>(reader: &mut R, bytes: usize) -> io::Result<U>
1706 where
1707 R: io::Read,
1708 U: UnsignedInteger,
1709 {
1710 let mut buf = U::buffer();
1711 reader
1712 .read_exact(&mut buf.as_mut()[(mem::size_of::<U>() - bytes)..])
1713 .map(|()| U::from_be_bytes(buf))
1714 }
1715
1716 if bits <= *queue_bits {
1717 // all bits in queue, so no byte needed
1718 let value = queue.shr_default(u8::BITS_SIZE - bits);
1719 *queue = queue.shl_default(bits);
1720 *queue_bits -= bits;
1721 Ok(U::from_u8(value))
1722 } else {
1723 // at least one byte needed
1724
1725 // bits needed beyond what's in the queue
1726 let needed_bits = bits - *queue_bits;
1727
1728 match (needed_bits / 8, needed_bits % 8) {
1729 (0, needed) => {
1730 // only one additional byte needed,
1731 // which we share between our returned value
1732 // and the bit queue
1733 let next_byte = read_byte(reader)?;
1734
1735 Ok(U::from_u8(
1736 mem::replace(queue, next_byte.shl_default(needed)).shr_default(
1737 u8::BITS_SIZE - mem::replace(queue_bits, u8::BITS_SIZE - needed),
1738 ),
1739 )
1740 .shl_default(needed)
1741 | U::from_u8(next_byte.shr_default(u8::BITS_SIZE - needed)))
1742 }
1743 (bytes, 0) => {
1744 // exact number of bytes needed beyond what's
1745 // available in the queue
1746 // so read a whole value from the reader
1747 // and prepend what's left of our queue onto it
1748
1749 Ok(U::from_u8(
1750 mem::take(queue).shr_default(u8::BITS_SIZE - mem::take(queue_bits)),
1751 )
1752 .shl_default(needed_bits)
1753 | read_bytes(reader, bytes as usize)?)
1754 }
1755 (bytes, needed) => {
1756 // read a whole value from the reader
1757 // prepend what's in the queue at the front of it
1758 // *and* append a partial byte at the end of it
1759 // while also updating the queue and its bit count
1760
1761 let whole: U = read_bytes(reader, bytes as usize)?;
1762 let next_byte = read_byte(reader)?;
1763
1764 Ok(U::from_u8(
1765 mem::replace(queue, next_byte.shl_default(needed)).shr_default(
1766 u8::BITS_SIZE - mem::replace(queue_bits, u8::BITS_SIZE - needed),
1767 ),
1768 )
1769 .shl_default(needed_bits)
1770 | whole.shl_default(needed)
1771 | U::from_u8(next_byte.shr_default(u8::BITS_SIZE - needed)))
1772 }
1773 }
1774 }
1775 }
1776
1777 // checked in the sense that we've verified
1778 // the input type is large enough to hold the
1779 // requested number of bits and that the value is
1780 // not too large for those bits
1781 #[inline]
1782 fn write_bits_checked<const MAX: u32, W, U>(
1783 writer: &mut W,
1784 queue_value: &mut u8,
1785 queue_bits: &mut u32,
1786 BitCount { bits }: BitCount<MAX>,
1787 value: U,
1788 ) -> io::Result<()>
1789 where
1790 W: io::Write,
1791 U: UnsignedInteger,
1792 {
1793 fn write_bytes<W, U>(writer: &mut W, bytes: usize, value: U) -> io::Result<()>
1794 where
1795 W: io::Write,
1796 U: UnsignedInteger,
1797 {
1798 let buf = U::to_be_bytes(value);
1799 writer.write_all(&buf.as_ref()[(mem::size_of::<U>() - bytes)..])
1800 }
1801
1802 // the amount of available bits in the queue
1803 let available_bits = u8::BITS_SIZE - *queue_bits;
1804
1805 if bits < available_bits {
1806 // all bits fit in queue, so no write needed
1807 *queue_value = queue_value.shl_default(bits) | U::to_u8(value);
1808 *queue_bits += bits;
1809 Ok(())
1810 } else {
1811 // at least one byte needs to be written
1812
1813 // bits beyond what can fit in the queue
1814 let excess_bits = bits - available_bits;
1815
1816 match (excess_bits / 8, excess_bits % 8) {
1817 (0, excess) => {
1818 // only one byte to be written,
1819 // while the excess bits are shared
1820 // between the written byte and the bit queue
1821
1822 *queue_bits = excess;
1823
1824 write_byte(
1825 writer,
1826 mem::replace(
1827 queue_value,
1828 U::to_u8(value & U::ALL.shr_default(U::BITS_SIZE - excess)),
1829 )
1830 .shl_default(available_bits)
1831 | U::to_u8(value.shr_default(excess)),
1832 )
1833 }
1834 (bytes, 0) => {
1835 // no excess bytes beyond what can fit the queue
1836 // so write a whole byte and
1837 // the remainder of the whole value
1838
1839 *queue_bits = 0;
1840
1841 write_byte(
1842 writer.by_ref(),
1843 mem::take(queue_value).shl_default(available_bits)
1844 | U::to_u8(value.shr_default(bytes * 8)),
1845 )?;
1846
1847 write_bytes(writer, bytes as usize, value)
1848 }
1849 (bytes, excess) => {
1850 // write what's in the queue along
1851 // with the head of our whole value,
1852 // write the middle section of our whole value,
1853 // while also replacing the queue with
1854 // the tail of our whole value
1855
1856 *queue_bits = excess;
1857
1858 write_byte(
1859 writer.by_ref(),
1860 mem::replace(
1861 queue_value,
1862 U::to_u8(value & U::ALL.shr_default(U::BITS_SIZE - excess)),
1863 )
1864 .shl_default(available_bits)
1865 | U::to_u8(value.shr_default(excess + bytes * 8)),
1866 )?;
1867
1868 write_bytes(writer, bytes as usize, value.shr_default(excess))
1869 }
1870 }
1871 }
1872 }
1873}
1874
1875impl Endianness for BigEndian {
1876 #[inline]
1877 fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8> {
1878 *queue_value = (*queue_value << 1) | u8::from(bit);
1879 *queue_bits = (*queue_bits + 1) % 8;
1880 (*queue_bits == 0).then(|| mem::take(queue_value))
1881 }
1882
1883 #[inline]
1884 fn read_bits<const MAX: u32, R, U>(
1885 reader: &mut R,
1886 queue_value: &mut u8,
1887 queue_bits: &mut u32,
1888 count @ BitCount { bits }: BitCount<MAX>,
1889 ) -> io::Result<U>
1890 where
1891 R: io::Read,
1892 U: UnsignedInteger,
1893 {
1894 if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
1895 Self::read_bits_checked::<MAX, R, U>(reader, queue_value, queue_bits, count)
1896 } else {
1897 Err(io::Error::new(
1898 io::ErrorKind::InvalidInput,
1899 "excessive bits for type read",
1900 ))
1901 }
1902 }
1903
1904 #[inline]
1905 fn read_bits_fixed<const BITS: u32, R, U>(
1906 reader: &mut R,
1907 queue_value: &mut u8,
1908 queue_bits: &mut u32,
1909 ) -> io::Result<U>
1910 where
1911 R: io::Read,
1912 U: UnsignedInteger,
1913 {
1914 const {
1915 assert!(BITS <= U::BITS_SIZE, "excessive bits for type read");
1916 }
1917
1918 Self::read_bits_checked::<BITS, R, U>(
1919 reader,
1920 queue_value,
1921 queue_bits,
1922 BitCount::new::<BITS>(),
1923 )
1924 }
1925
1926 /// For performing bulk writes of a type to a bit sink.
1927 fn write_bits<const MAX: u32, W, U>(
1928 writer: &mut W,
1929 queue_value: &mut u8,
1930 queue_bits: &mut u32,
1931 count @ BitCount { bits }: BitCount<MAX>,
1932 value: U,
1933 ) -> io::Result<()>
1934 where
1935 W: io::Write,
1936 U: UnsignedInteger,
1937 {
1938 if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
1939 if bits == 0 {
1940 Ok(())
1941 } else if value <= U::ALL >> (U::BITS_SIZE - bits) {
1942 Self::write_bits_checked::<MAX, W, U>(writer, queue_value, queue_bits, count, value)
1943 } else {
1944 Err(io::Error::new(
1945 io::ErrorKind::InvalidInput,
1946 "excessive value for bits written",
1947 ))
1948 }
1949 } else {
1950 Err(io::Error::new(
1951 io::ErrorKind::InvalidInput,
1952 "excessive bits for type written",
1953 ))
1954 }
1955 }
1956
1957 /// For performing bulk writes of a type to a bit sink.
1958 fn write_bits_fixed<const BITS: u32, W, U>(
1959 writer: &mut W,
1960 queue_value: &mut u8,
1961 queue_bits: &mut u32,
1962 value: U,
1963 ) -> io::Result<()>
1964 where
1965 W: io::Write,
1966 U: UnsignedInteger,
1967 {
1968 const {
1969 assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
1970 }
1971
1972 if BITS == 0 {
1973 Ok(())
1974 } else if BITS == U::BITS_SIZE || value <= (U::ALL >> (U::BITS_SIZE - BITS)) {
1975 Self::write_bits_checked::<BITS, W, U>(
1976 writer,
1977 queue_value,
1978 queue_bits,
1979 BitCount::new::<BITS>(),
1980 value,
1981 )
1982 } else {
1983 Err(io::Error::new(
1984 io::ErrorKind::InvalidInput,
1985 "excessive value for bits written",
1986 ))
1987 }
1988 }
1989
1990 #[inline]
1991 fn pop_bit_refill<R>(
1992 reader: &mut R,
1993 queue_value: &mut u8,
1994 queue_bits: &mut u32,
1995 ) -> io::Result<bool>
1996 where
1997 R: io::Read,
1998 {
1999 Ok(if *queue_bits == 0 {
2000 let value = read_byte(reader)?;
2001 let msb = value & u8::MSB_BIT;
2002 *queue_value = value << 1;
2003 *queue_bits = u8::BITS_SIZE - 1;
2004 msb
2005 } else {
2006 let msb = *queue_value & u8::MSB_BIT;
2007 *queue_value <<= 1;
2008 *queue_bits -= 1;
2009 msb
2010 } != 0)
2011 }
2012
2013 #[inline]
2014 fn pop_unary<const STOP_BIT: u8, R>(
2015 reader: &mut R,
2016 queue_value: &mut u8,
2017 queue_bits: &mut u32,
2018 ) -> io::Result<u32>
2019 where
2020 R: io::Read,
2021 {
2022 const {
2023 assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1");
2024 }
2025
2026 match STOP_BIT {
2027 0 => find_unary(
2028 reader,
2029 queue_value,
2030 queue_bits,
2031 |v| v.leading_ones(),
2032 |q| *q,
2033 |v, b| v.checked_shl(b),
2034 ),
2035 1 => find_unary(
2036 reader,
2037 queue_value,
2038 queue_bits,
2039 |v| v.leading_zeros(),
2040 |_| u8::BITS_SIZE,
2041 |v, b| v.checked_shl(b),
2042 ),
2043 _ => unreachable!(),
2044 }
2045 }
2046
2047 #[inline]
2048 fn read_signed_counted<const MAX: u32, R, S>(
2049 r: &mut R,
2050 SignedBitCount {
2051 bits: BitCount { bits },
2052 unsigned,
2053 }: SignedBitCount<MAX>,
2054 ) -> io::Result<S>
2055 where
2056 R: BitRead,
2057 S: SignedInteger,
2058 {
2059 if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2060 let is_negative = r.read_bit()?;
2061 let unsigned = r.read_unsigned_counted::<MAX, S::Unsigned>(unsigned)?;
2062 Ok(if is_negative {
2063 unsigned.as_negative(bits)
2064 } else {
2065 unsigned.as_non_negative()
2066 })
2067 } else {
2068 Err(io::Error::new(
2069 io::ErrorKind::InvalidInput,
2070 "excessive bits for type read",
2071 ))
2072 }
2073 }
2074
2075 fn write_signed_counted<const MAX: u32, W, S>(
2076 w: &mut W,
2077 SignedBitCount {
2078 bits: BitCount { bits },
2079 unsigned,
2080 }: SignedBitCount<MAX>,
2081 value: S,
2082 ) -> io::Result<()>
2083 where
2084 W: BitWrite,
2085 S: SignedInteger,
2086 {
2087 if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2088 w.write_bit(value.is_negative())?;
2089 w.write_unsigned_counted(
2090 unsigned,
2091 if value.is_negative() {
2092 value.as_negative(bits)
2093 } else {
2094 value.as_non_negative()
2095 },
2096 )
2097 } else {
2098 Err(io::Error::new(
2099 io::ErrorKind::InvalidInput,
2100 "excessive bits for type written",
2101 ))
2102 }
2103 }
2104
2105 fn read_bytes<const CHUNK_SIZE: usize, R>(
2106 reader: &mut R,
2107 queue_value: &mut u8,
2108 queue_bits: u32,
2109 buf: &mut [u8],
2110 ) -> io::Result<()>
2111 where
2112 R: io::Read,
2113 {
2114 if queue_bits == 0 {
2115 reader.read_exact(buf)
2116 } else {
2117 let mut input_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
2118
2119 for output_chunk in buf.chunks_mut(CHUNK_SIZE) {
2120 let input_chunk = &mut input_chunk[0..output_chunk.len()];
2121 reader.read_exact(input_chunk)?;
2122
2123 // shift down each byte in our input to eventually
2124 // accomodate the contents of the bit queue
2125 // and make that our output
2126 output_chunk
2127 .iter_mut()
2128 .zip(input_chunk.iter())
2129 .for_each(|(o, i)| {
2130 *o = i >> queue_bits;
2131 });
2132
2133 // include leftover bits from the next byte
2134 // shifted to the top
2135 output_chunk[1..]
2136 .iter_mut()
2137 .zip(input_chunk.iter())
2138 .for_each(|(o, i)| {
2139 *o |= *i << (u8::BITS_SIZE - queue_bits);
2140 });
2141
2142 // finally, prepend the queue's contents
2143 // to the first byte in the chunk
2144 // while replacing those contents
2145 // with the final byte of the input
2146 output_chunk[0] |= core::mem::replace(
2147 queue_value,
2148 input_chunk.last().unwrap() << (u8::BITS_SIZE - queue_bits),
2149 );
2150 }
2151
2152 Ok(())
2153 }
2154 }
2155
2156 fn write_bytes<const CHUNK_SIZE: usize, W>(
2157 writer: &mut W,
2158 queue_value: &mut u8,
2159 queue_bits: u32,
2160 buf: &[u8],
2161 ) -> io::Result<()>
2162 where
2163 W: io::Write,
2164 {
2165 if queue_bits == 0 {
2166 writer.write_all(buf)
2167 } else {
2168 let mut output_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
2169
2170 for input_chunk in buf.chunks(CHUNK_SIZE) {
2171 let output_chunk = &mut output_chunk[0..input_chunk.len()];
2172
2173 output_chunk
2174 .iter_mut()
2175 .zip(input_chunk.iter())
2176 .for_each(|(o, i)| {
2177 *o = i >> queue_bits;
2178 });
2179
2180 output_chunk[1..]
2181 .iter_mut()
2182 .zip(input_chunk.iter())
2183 .for_each(|(o, i)| {
2184 *o |= *i << (u8::BITS_SIZE - queue_bits);
2185 });
2186
2187 output_chunk[0] |= core::mem::replace(
2188 queue_value,
2189 input_chunk.last().unwrap() & (u8::ALL >> (u8::BITS_SIZE - queue_bits)),
2190 ) << (u8::BITS_SIZE - queue_bits);
2191
2192 writer.write_all(output_chunk)?;
2193 }
2194
2195 Ok(())
2196 }
2197 }
2198
2199 #[inline(always)]
2200 fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P {
2201 P::from_be_bytes(buf)
2202 }
2203
2204 #[inline(always)]
2205 fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes {
2206 p.to_be_bytes()
2207 }
2208}
2209
2210/// Little-endian, or least significant bits first
2211#[derive(Copy, Clone, Debug)]
2212pub struct LittleEndian;
2213
2214/// Little-endian, or least significant bits first
2215pub type LE = LittleEndian;
2216
2217impl LittleEndian {
2218 // checked in the sense that we've verified
2219 // the output type is large enough to hold the
2220 // requested number of bits
2221 #[inline]
2222 fn read_bits_checked<const MAX: u32, R, U>(
2223 reader: &mut R,
2224 queue: &mut u8,
2225 queue_bits: &mut u32,
2226 BitCount { bits }: BitCount<MAX>,
2227 ) -> io::Result<U>
2228 where
2229 R: io::Read,
2230 U: UnsignedInteger,
2231 {
2232 // reads a whole value with the given number of
2233 // bytes in our endianness, where the number of bytes
2234 // must be less than or equal to the type's size in bytes
2235 #[inline(always)]
2236 fn read_bytes<R, U>(reader: &mut R, bytes: usize) -> io::Result<U>
2237 where
2238 R: io::Read,
2239 U: UnsignedInteger,
2240 {
2241 let mut buf = U::buffer();
2242 reader
2243 .read_exact(&mut buf.as_mut()[0..bytes])
2244 .map(|()| U::from_le_bytes(buf))
2245 }
2246
2247 if bits <= *queue_bits {
2248 // all bits in queue, so no byte needed
2249 let value = *queue & u8::ALL.shr_default(u8::BITS_SIZE - bits);
2250 *queue = queue.shr_default(bits);
2251 *queue_bits -= bits;
2252 Ok(U::from_u8(value))
2253 } else {
2254 // at least one byte needed
2255
2256 // bits needed beyond what's in the queue
2257 let needed_bits = bits - *queue_bits;
2258
2259 match (needed_bits / 8, needed_bits % 8) {
2260 (0, needed) => {
2261 // only one additional byte needed,
2262 // which we share between our returned value
2263 // and the bit queue
2264 let next_byte = read_byte(reader)?;
2265
2266 Ok(
2267 U::from_u8(mem::replace(queue, next_byte.shr_default(needed)))
2268 | (U::from_u8(next_byte & (u8::ALL >> (u8::BITS_SIZE - needed)))
2269 << mem::replace(queue_bits, u8::BITS_SIZE - needed)),
2270 )
2271 }
2272 (bytes, 0) => {
2273 // exact number of bytes needed beyond what's
2274 // available in the queue
2275
2276 // so read a whole value from the reader
2277 // and prepend what's left of our queue onto it
2278
2279 Ok(U::from_u8(mem::take(queue))
2280 | (read_bytes::<R, U>(reader, bytes as usize)? << mem::take(queue_bits)))
2281 }
2282 (bytes, needed) => {
2283 // read a whole value from the reader
2284 // prepend what's in the queue at the front of it
2285 // *and* append a partial byte at the end of it
2286 // while also updating the queue and its bit count
2287
2288 let whole: U = read_bytes(reader, bytes as usize)?;
2289 let next_byte = read_byte(reader)?;
2290
2291 Ok(
2292 U::from_u8(mem::replace(queue, next_byte.shr_default(needed)))
2293 | (whole << *queue_bits)
2294 | (U::from_u8(next_byte & (u8::ALL >> (u8::BITS_SIZE - needed)))
2295 << (mem::replace(queue_bits, u8::BITS_SIZE - needed) + bytes * 8)),
2296 )
2297 }
2298 }
2299 }
2300 }
2301
2302 // checked in the sense that we've verified
2303 // the input type is large enough to hold the
2304 // requested number of bits and that the value is
2305 // not too large for those bits
2306 #[inline]
2307 fn write_bits_checked<const MAX: u32, W, U>(
2308 writer: &mut W,
2309 queue_value: &mut u8,
2310 queue_bits: &mut u32,
2311 BitCount { bits }: BitCount<MAX>,
2312 value: U,
2313 ) -> io::Result<()>
2314 where
2315 W: io::Write,
2316 U: UnsignedInteger,
2317 {
2318 fn write_bytes<W, U>(writer: &mut W, bytes: usize, value: U) -> io::Result<()>
2319 where
2320 W: io::Write,
2321 U: UnsignedInteger,
2322 {
2323 let buf = U::to_le_bytes(value);
2324 writer.write_all(&buf.as_ref()[0..bytes])
2325 }
2326
2327 // the amount of available bits in the queue
2328 let available_bits = u8::BITS_SIZE - *queue_bits;
2329
2330 if bits < available_bits {
2331 // all bits fit in queue, so no write needed
2332 *queue_value |= U::to_u8(value.shl_default(*queue_bits));
2333 *queue_bits += bits;
2334 Ok(())
2335 } else {
2336 // at least one byte needs to be written
2337
2338 // bits beyond what can fit in the queue
2339 let excess_bits = bits - available_bits;
2340
2341 match (excess_bits / 8, excess_bits % 8) {
2342 (0, excess) => {
2343 // only one byte to be written,
2344 // while the excess bits are shared
2345 // between the written byte and the bit queue
2346
2347 write_byte(
2348 writer,
2349 mem::replace(queue_value, U::to_u8(value.shr_default(available_bits)))
2350 | U::to_u8(
2351 (value << mem::replace(queue_bits, excess)) & U::from_u8(u8::ALL),
2352 ),
2353 )
2354 }
2355 (bytes, 0) => {
2356 // no excess bytes beyond what can fit the queue
2357 // so write a whole byte and
2358 // the remainder of the whole value
2359
2360 write_byte(
2361 writer.by_ref(),
2362 mem::take(queue_value)
2363 | U::to_u8((value << mem::take(queue_bits)) & U::from_u8(u8::ALL)),
2364 )?;
2365
2366 write_bytes(writer, bytes as usize, value >> available_bits)
2367 }
2368 (bytes, excess) => {
2369 // write what's in the queue along
2370 // with the head of our whole value,
2371 // write the middle section of our whole value,
2372 // while also replacing the queue with
2373 // the tail of our whole value
2374
2375 write_byte(
2376 writer.by_ref(),
2377 mem::replace(
2378 queue_value,
2379 U::to_u8(value.shr_default(available_bits + bytes * 8)),
2380 ) | U::to_u8(
2381 (value << mem::replace(queue_bits, excess)) & U::from_u8(u8::ALL),
2382 ),
2383 )?;
2384
2385 write_bytes(writer, bytes as usize, value >> available_bits)
2386 }
2387 }
2388 }
2389 }
2390}
2391
2392impl Endianness for LittleEndian {
2393 #[inline]
2394 fn push_bit_flush(queue_value: &mut u8, queue_bits: &mut u32, bit: bool) -> Option<u8> {
2395 *queue_value |= u8::from(bit) << *queue_bits;
2396 *queue_bits = (*queue_bits + 1) % 8;
2397 (*queue_bits == 0).then(|| mem::take(queue_value))
2398 }
2399
2400 #[inline]
2401 fn read_bits<const MAX: u32, R, U>(
2402 reader: &mut R,
2403 queue_value: &mut u8,
2404 queue_bits: &mut u32,
2405 count @ BitCount { bits }: BitCount<MAX>,
2406 ) -> io::Result<U>
2407 where
2408 R: io::Read,
2409 U: UnsignedInteger,
2410 {
2411 if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
2412 Self::read_bits_checked::<MAX, R, U>(reader, queue_value, queue_bits, count)
2413 } else {
2414 Err(io::Error::new(
2415 io::ErrorKind::InvalidInput,
2416 "excessive bits for type read",
2417 ))
2418 }
2419 }
2420
2421 #[inline]
2422 fn read_bits_fixed<const BITS: u32, R, U>(
2423 reader: &mut R,
2424 queue_value: &mut u8,
2425 queue_bits: &mut u32,
2426 ) -> io::Result<U>
2427 where
2428 R: io::Read,
2429 U: UnsignedInteger,
2430 {
2431 const {
2432 assert!(BITS <= U::BITS_SIZE, "excessive bits for type read");
2433 }
2434
2435 Self::read_bits_checked::<BITS, R, U>(
2436 reader,
2437 queue_value,
2438 queue_bits,
2439 BitCount::new::<BITS>(),
2440 )
2441 }
2442
2443 /// For performing bulk writes of a type to a bit sink.
2444 fn write_bits<const MAX: u32, W, U>(
2445 writer: &mut W,
2446 queue_value: &mut u8,
2447 queue_bits: &mut u32,
2448 count @ BitCount { bits }: BitCount<MAX>,
2449 value: U,
2450 ) -> io::Result<()>
2451 where
2452 W: io::Write,
2453 U: UnsignedInteger,
2454 {
2455 if MAX <= U::BITS_SIZE || bits <= U::BITS_SIZE {
2456 if bits == 0 {
2457 Ok(())
2458 } else if value <= U::ALL >> (U::BITS_SIZE - bits) {
2459 Self::write_bits_checked::<MAX, W, U>(writer, queue_value, queue_bits, count, value)
2460 } else {
2461 Err(io::Error::new(
2462 io::ErrorKind::InvalidInput,
2463 "excessive value for bits written",
2464 ))
2465 }
2466 } else {
2467 Err(io::Error::new(
2468 io::ErrorKind::InvalidInput,
2469 "excessive bits for type written",
2470 ))
2471 }
2472 }
2473
2474 /// For performing bulk writes of a type to a bit sink.
2475 fn write_bits_fixed<const BITS: u32, W, U>(
2476 writer: &mut W,
2477 queue_value: &mut u8,
2478 queue_bits: &mut u32,
2479 value: U,
2480 ) -> io::Result<()>
2481 where
2482 W: io::Write,
2483 U: UnsignedInteger,
2484 {
2485 const {
2486 assert!(BITS <= U::BITS_SIZE, "excessive bits for type written");
2487 }
2488
2489 if BITS == 0 {
2490 Ok(())
2491 } else if BITS == U::BITS_SIZE || value <= (U::ALL >> (U::BITS_SIZE - BITS)) {
2492 Self::write_bits_checked::<BITS, W, U>(
2493 writer,
2494 queue_value,
2495 queue_bits,
2496 BitCount::new::<BITS>(),
2497 value,
2498 )
2499 } else {
2500 Err(io::Error::new(
2501 io::ErrorKind::InvalidInput,
2502 "excessive value for bits written",
2503 ))
2504 }
2505 }
2506
2507 #[inline]
2508 fn pop_bit_refill<R>(
2509 reader: &mut R,
2510 queue_value: &mut u8,
2511 queue_bits: &mut u32,
2512 ) -> io::Result<bool>
2513 where
2514 R: io::Read,
2515 {
2516 Ok(if *queue_bits == 0 {
2517 let value = read_byte(reader)?;
2518 let lsb = value & u8::LSB_BIT;
2519 *queue_value = value >> 1;
2520 *queue_bits = u8::BITS_SIZE - 1;
2521 lsb
2522 } else {
2523 let lsb = *queue_value & u8::LSB_BIT;
2524 *queue_value >>= 1;
2525 *queue_bits -= 1;
2526 lsb
2527 } != 0)
2528 }
2529
2530 #[inline]
2531 fn pop_unary<const STOP_BIT: u8, R>(
2532 reader: &mut R,
2533 queue_value: &mut u8,
2534 queue_bits: &mut u32,
2535 ) -> io::Result<u32>
2536 where
2537 R: io::Read,
2538 {
2539 const {
2540 assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1");
2541 }
2542
2543 match STOP_BIT {
2544 0 => find_unary(
2545 reader,
2546 queue_value,
2547 queue_bits,
2548 |v| v.trailing_ones(),
2549 |q| *q,
2550 |v, b| v.checked_shr(b),
2551 ),
2552 1 => find_unary(
2553 reader,
2554 queue_value,
2555 queue_bits,
2556 |v| v.trailing_zeros(),
2557 |_| u8::BITS_SIZE,
2558 |v, b| v.checked_shr(b),
2559 ),
2560 _ => unreachable!(),
2561 }
2562 }
2563
2564 #[inline]
2565 fn read_signed_counted<const MAX: u32, R, S>(
2566 r: &mut R,
2567 SignedBitCount {
2568 bits: BitCount { bits },
2569 unsigned,
2570 }: SignedBitCount<MAX>,
2571 ) -> io::Result<S>
2572 where
2573 R: BitRead,
2574 S: SignedInteger,
2575 {
2576 if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2577 let unsigned = r.read_unsigned_counted::<MAX, S::Unsigned>(unsigned)?;
2578 let is_negative = r.read_bit()?;
2579 Ok(if is_negative {
2580 unsigned.as_negative(bits)
2581 } else {
2582 unsigned.as_non_negative()
2583 })
2584 } else {
2585 Err(io::Error::new(
2586 io::ErrorKind::InvalidInput,
2587 "excessive bits for type read",
2588 ))
2589 }
2590 }
2591
2592 fn write_signed_counted<const MAX: u32, W, S>(
2593 w: &mut W,
2594 SignedBitCount {
2595 bits: BitCount { bits },
2596 unsigned,
2597 }: SignedBitCount<MAX>,
2598 value: S,
2599 ) -> io::Result<()>
2600 where
2601 W: BitWrite,
2602 S: SignedInteger,
2603 {
2604 if MAX <= S::BITS_SIZE || bits <= S::BITS_SIZE {
2605 w.write_unsigned_counted(
2606 unsigned,
2607 if value.is_negative() {
2608 value.as_negative(bits)
2609 } else {
2610 value.as_non_negative()
2611 },
2612 )?;
2613 w.write_bit(value.is_negative())
2614 } else {
2615 Err(io::Error::new(
2616 io::ErrorKind::InvalidInput,
2617 "excessive bits for type written",
2618 ))
2619 }
2620 }
2621
2622 fn read_bytes<const CHUNK_SIZE: usize, R>(
2623 reader: &mut R,
2624 queue_value: &mut u8,
2625 queue_bits: u32,
2626 buf: &mut [u8],
2627 ) -> io::Result<()>
2628 where
2629 R: io::Read,
2630 {
2631 if queue_bits == 0 {
2632 reader.read_exact(buf)
2633 } else {
2634 let mut input_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
2635
2636 for output_chunk in buf.chunks_mut(CHUNK_SIZE) {
2637 let input_chunk = &mut input_chunk[0..output_chunk.len()];
2638 reader.read_exact(input_chunk)?;
2639
2640 output_chunk
2641 .iter_mut()
2642 .zip(input_chunk.iter())
2643 .for_each(|(o, i)| {
2644 *o = i << queue_bits;
2645 });
2646
2647 output_chunk[1..]
2648 .iter_mut()
2649 .zip(input_chunk.iter())
2650 .for_each(|(o, i)| {
2651 *o |= i >> (u8::BITS_SIZE - queue_bits);
2652 });
2653
2654 output_chunk[0] |= core::mem::replace(
2655 queue_value,
2656 input_chunk.last().unwrap() >> (u8::BITS_SIZE - queue_bits),
2657 );
2658 }
2659
2660 Ok(())
2661 }
2662 }
2663
2664 fn write_bytes<const CHUNK_SIZE: usize, W>(
2665 writer: &mut W,
2666 queue_value: &mut u8,
2667 queue_bits: u32,
2668 buf: &[u8],
2669 ) -> io::Result<()>
2670 where
2671 W: io::Write,
2672 {
2673 if queue_bits == 0 {
2674 writer.write_all(buf)
2675 } else {
2676 let mut output_chunk: [u8; CHUNK_SIZE] = [0; CHUNK_SIZE];
2677
2678 for input_chunk in buf.chunks(CHUNK_SIZE) {
2679 let output_chunk = &mut output_chunk[0..input_chunk.len()];
2680
2681 output_chunk
2682 .iter_mut()
2683 .zip(input_chunk.iter())
2684 .for_each(|(o, i)| {
2685 *o = i << queue_bits;
2686 });
2687
2688 output_chunk[1..]
2689 .iter_mut()
2690 .zip(input_chunk.iter())
2691 .for_each(|(o, i)| {
2692 *o |= i >> (u8::BITS_SIZE - queue_bits);
2693 });
2694
2695 output_chunk[0] |= core::mem::replace(
2696 queue_value,
2697 input_chunk.last().unwrap() >> (u8::BITS_SIZE - queue_bits),
2698 );
2699
2700 writer.write_all(output_chunk)?;
2701 }
2702
2703 Ok(())
2704 }
2705 }
2706
2707 #[inline(always)]
2708 fn bytes_to_primitive<P: Primitive>(buf: P::Bytes) -> P {
2709 P::from_le_bytes(buf)
2710 }
2711
2712 #[inline(always)]
2713 fn primitive_to_bytes<P: Primitive>(p: P) -> P::Bytes {
2714 p.to_le_bytes()
2715 }
2716}
2717
2718#[inline]
2719fn find_unary<R>(
2720 reader: &mut R,
2721 queue_value: &mut u8,
2722 queue_bits: &mut u32,
2723 leading_bits: impl Fn(u8) -> u32,
2724 max_bits: impl Fn(&mut u32) -> u32,
2725 checked_shift: impl Fn(u8, u32) -> Option<u8>,
2726) -> io::Result<u32>
2727where
2728 R: io::Read,
2729{
2730 let mut acc = 0;
2731
2732 loop {
2733 match leading_bits(*queue_value) {
2734 bits if bits == max_bits(queue_bits) => {
2735 // all bits exhausted
2736 // fetch another byte and keep going
2737 acc += *queue_bits;
2738 *queue_value = read_byte(reader.by_ref())?;
2739 *queue_bits = u8::BITS_SIZE;
2740 }
2741 bits => match checked_shift(*queue_value, bits + 1) {
2742 Some(value) => {
2743 // fetch part of source byte
2744 *queue_value = value;
2745 *queue_bits -= bits + 1;
2746 break Ok(acc + bits);
2747 }
2748 None => {
2749 // fetch all of source byte
2750 *queue_value = 0;
2751 *queue_bits = 0;
2752 break Ok(acc + bits);
2753 }
2754 },
2755 }
2756 }
2757}