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