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