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