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