Coverage Report

Created: 2025-07-11 07:25

/rust/registry/src/index.crates.io-6f17d22bba15001f/bitstream-io-2.6.0/src/lib.rs
Line
Count
Source (jump to first uncovered line)
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 `Read` trait, and the only requirement
20
//! for writer streams is that they must implement the `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(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,ignore
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_in::<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
//! # Migrating From Pre 1.0.0
67
//!
68
//! There are now `BitRead` and `BitWrite` traits for bitstream
69
//! reading and writing (analogous to the standard library's
70
//! `Read` and `Write` traits) which you will also need to import.
71
//! The upside to this approach is that library consumers
72
//! can now make functions and methods generic over any sort
73
//! of bit reader or bit writer, regardless of the underlying
74
//! stream byte source or endianness.
75
76
#![warn(missing_docs)]
77
#![forbid(unsafe_code)]
78
#![cfg_attr(feature = "alloc", no_std)]
79
80
#[cfg(feature = "alloc")]
81
extern crate alloc;
82
use core::fmt::Debug;
83
use core::marker::PhantomData;
84
use core::mem;
85
use core::ops::{BitOrAssign, BitXor, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub};
86
#[cfg(feature = "alloc")]
87
use core2::io;
88
#[cfg(not(feature = "alloc"))]
89
use std::io;
90
91
pub mod huffman;
92
pub mod read;
93
pub mod write;
94
pub use read::{
95
    BitRead, BitReader, ByteRead, ByteReader, FromBitStream, FromBitStreamWith, FromByteStream,
96
    FromByteStreamWith, HuffmanRead,
97
};
98
pub use write::{
99
    BitCounter, BitRecorder, BitWrite, BitWriter, ByteWrite, ByteWriter, HuffmanWrite, ToBitStream,
100
    ToBitStreamWith, ToByteStream, ToByteStreamWith,
101
};
102
103
/// A trait intended for simple fixed-length primitives (such as ints and floats)
104
/// which allows them to be read and written to streams of
105
/// different endiannesses verbatim.
106
pub trait Primitive {
107
    /// The raw byte representation of this numeric type
108
    type Bytes: AsRef<[u8]> + AsMut<[u8]>;
109
110
    /// An empty buffer of this type's size
111
    fn buffer() -> Self::Bytes;
112
113
    /// Our value in big-endian bytes
114
    fn to_be_bytes(self) -> Self::Bytes;
115
116
    /// Our value in little-endian bytes
117
    fn to_le_bytes(self) -> Self::Bytes;
118
119
    /// Convert big-endian bytes to our value
120
    fn from_be_bytes(bytes: Self::Bytes) -> Self;
121
122
    /// Convert little-endian bytes to our value
123
    fn from_le_bytes(bytes: Self::Bytes) -> Self;
124
}
125
126
macro_rules! define_primitive_numeric {
127
    ($t:ty) => {
128
        impl Primitive for $t {
129
            type Bytes = [u8; mem::size_of::<$t>()];
130
131
            #[inline(always)]
132
0
            fn buffer() -> Self::Bytes {
133
0
                [0; mem::size_of::<$t>()]
134
0
            }
Unexecuted instantiation: <u8 as bitstream_io::Primitive>::buffer
Unexecuted instantiation: <i8 as bitstream_io::Primitive>::buffer
Unexecuted instantiation: <u16 as bitstream_io::Primitive>::buffer
Unexecuted instantiation: <i16 as bitstream_io::Primitive>::buffer
Unexecuted instantiation: <u32 as bitstream_io::Primitive>::buffer
Unexecuted instantiation: <i32 as bitstream_io::Primitive>::buffer
Unexecuted instantiation: <u64 as bitstream_io::Primitive>::buffer
135
            #[inline(always)]
136
0
            fn to_be_bytes(self) -> Self::Bytes {
137
0
                self.to_be_bytes()
138
0
            }
Unexecuted instantiation: <i8 as bitstream_io::Primitive>::to_be_bytes
Unexecuted instantiation: <i16 as bitstream_io::Primitive>::to_be_bytes
139
            #[inline(always)]
140
            fn to_le_bytes(self) -> Self::Bytes {
141
                self.to_le_bytes()
142
            }
143
            #[inline(always)]
144
            fn from_be_bytes(bytes: Self::Bytes) -> Self {
145
                <$t>::from_be_bytes(bytes)
146
            }
147
            #[inline(always)]
148
            fn from_le_bytes(bytes: Self::Bytes) -> Self {
149
                <$t>::from_le_bytes(bytes)
150
            }
151
        }
152
    };
153
}
154
155
impl<const N: usize> Primitive for [u8; N] {
156
    type Bytes = [u8; N];
157
158
    #[inline(always)]
159
    fn buffer() -> Self::Bytes {
160
        [0; N]
161
    }
162
163
    #[inline(always)]
164
    fn to_be_bytes(self) -> Self::Bytes {
165
        self
166
    }
167
168
    #[inline(always)]
169
    fn to_le_bytes(self) -> Self::Bytes {
170
        self
171
    }
172
173
    #[inline(always)]
174
    fn from_be_bytes(bytes: Self::Bytes) -> Self {
175
        bytes
176
    }
177
178
    #[inline(always)]
179
    fn from_le_bytes(bytes: Self::Bytes) -> Self {
180
        bytes
181
    }
182
}
183
184
/// This trait extends many common integer types (both unsigned and signed)
185
/// with a few trivial methods so that they can be used
186
/// with the bitstream handling traits.
187
pub trait Numeric:
188
    Primitive
189
    + Sized
190
    + Copy
191
    + Default
192
    + Debug
193
    + PartialOrd
194
    + Shl<u32, Output = Self>
195
    + ShlAssign<u32>
196
    + Shr<u32, Output = Self>
197
    + ShrAssign<u32>
198
    + Rem<Self, Output = Self>
199
    + RemAssign<Self>
200
    + BitOrAssign<Self>
201
    + BitXor<Self, Output = Self>
202
    + Not<Output = Self>
203
    + Sub<Self, Output = Self>
204
{
205
    /// Size of type in bits
206
    const BITS_SIZE: u32;
207
208
    /// The value of 1 in this type
209
    const ONE: Self;
210
211
    /// Returns true if this value is 0, in its type
212
    fn is_zero(self) -> bool;
213
214
    /// Returns a `u8` value in this type
215
    fn from_u8(u: u8) -> Self;
216
217
    /// Assuming 0 <= value < 256, returns this value as a `u8` type
218
    fn to_u8(self) -> u8;
219
220
    /// Counts the number of 1 bits
221
    fn count_ones(self) -> u32;
222
223
    /// Counts the number of leading zeros
224
    fn leading_zeros(self) -> u32;
225
226
    /// Counts the number of trailing zeros
227
    fn trailing_zeros(self) -> u32;
228
229
    /// Convert to a generic unsigned write value for stream recording purposes
230
    fn unsigned_value(self) -> write::UnsignedValue;
231
}
232
233
macro_rules! define_numeric {
234
    ($t:ty) => {
235
        define_primitive_numeric!($t);
236
237
        impl Numeric for $t {
238
            const BITS_SIZE: u32 = mem::size_of::<$t>() as u32 * 8;
239
240
            const ONE: Self = 1;
241
242
            #[inline(always)]
243
0
            fn is_zero(self) -> bool {
244
0
                self == 0
245
0
            }
246
            #[inline(always)]
247
            fn from_u8(u: u8) -> Self {
248
                u as $t
249
            }
250
            #[inline(always)]
251
0
            fn to_u8(self) -> u8 {
252
0
                self as u8
253
0
            }
Unexecuted instantiation: <u8 as bitstream_io::Numeric>::to_u8
Unexecuted instantiation: <i8 as bitstream_io::Numeric>::to_u8
Unexecuted instantiation: <u16 as bitstream_io::Numeric>::to_u8
Unexecuted instantiation: <i16 as bitstream_io::Numeric>::to_u8
Unexecuted instantiation: <u32 as bitstream_io::Numeric>::to_u8
Unexecuted instantiation: <i32 as bitstream_io::Numeric>::to_u8
Unexecuted instantiation: <u64 as bitstream_io::Numeric>::to_u8
254
            #[inline(always)]
255
            fn count_ones(self) -> u32 {
256
                self.count_ones()
257
            }
258
            #[inline(always)]
259
            fn leading_zeros(self) -> u32 {
260
                self.leading_zeros()
261
            }
262
            #[inline(always)]
263
            fn trailing_zeros(self) -> u32 {
264
                self.trailing_zeros()
265
            }
266
            #[inline(always)]
267
            fn unsigned_value(self) -> write::UnsignedValue {
268
                self.into()
269
            }
270
        }
271
    };
272
}
273
274
/// This trait extends many common signed integer types
275
/// so that they can be used with the bitstream handling traits.
276
pub trait SignedNumeric: Numeric {
277
    /// Returns true if this value is negative
278
    fn is_negative(self) -> bool;
279
280
    /// Given a two-complement positive value and certain number of bits,
281
    /// returns this value as a negative number.
282
    fn as_negative(self, bits: u32) -> Self;
283
284
    /// Given a two-complement positive value and certain number of bits,
285
    /// returns this value as a negative number.
286
    fn as_negative_fixed<const BITS: u32>(self) -> Self;
287
288
    /// Given a negative value and a certain number of bits,
289
    /// returns this value as a twos-complement positive number.
290
    fn as_unsigned(self, bits: u32) -> Self;
291
292
    /// Given a negative value and a certain number of bits,
293
    /// returns this value as a twos-complement positive number.
294
    fn as_unsigned_fixed<const BITS: u32>(self) -> Self;
295
296
    /// Converts to a generic signed value for stream recording purposes.
297
    fn signed_value(self) -> write::SignedValue;
298
}
299
300
macro_rules! define_signed_numeric {
301
    ($t:ty) => {
302
        impl SignedNumeric for $t {
303
            #[inline(always)]
304
0
            fn is_negative(self) -> bool {
305
0
                self < 0
306
0
            }
Unexecuted instantiation: <i8 as bitstream_io::SignedNumeric>::is_negative
Unexecuted instantiation: <i16 as bitstream_io::SignedNumeric>::is_negative
307
            #[inline(always)]
308
            fn as_negative(self, bits: u32) -> Self {
309
                self + (-1 << (bits - 1))
310
            }
311
            #[inline(always)]
312
            fn as_negative_fixed<const BITS: u32>(self) -> Self {
313
                self + (-1 << (BITS - 1))
314
            }
315
            #[inline(always)]
316
0
            fn as_unsigned(self, bits: u32) -> Self {
317
0
                self - (-1 << (bits - 1))
318
0
            }
Unexecuted instantiation: <i8 as bitstream_io::SignedNumeric>::as_unsigned
Unexecuted instantiation: <i16 as bitstream_io::SignedNumeric>::as_unsigned
319
            #[inline(always)]
320
            fn as_unsigned_fixed<const BITS: u32>(self) -> Self {
321
                self - (-1 << (BITS - 1))
322
            }
323
            #[inline(always)]
324
            fn signed_value(self) -> write::SignedValue {
325
                self.into()
326
            }
327
        }
328
    };
329
}
330
331
define_numeric!(u8);
332
define_numeric!(i8);
333
define_numeric!(u16);
334
define_numeric!(i16);
335
define_numeric!(u32);
336
define_numeric!(i32);
337
define_numeric!(u64);
338
define_numeric!(i64);
339
define_numeric!(u128);
340
define_numeric!(i128);
341
342
define_signed_numeric!(i8);
343
define_signed_numeric!(i16);
344
define_signed_numeric!(i32);
345
define_signed_numeric!(i64);
346
define_signed_numeric!(i128);
347
348
define_primitive_numeric!(f32);
349
define_primitive_numeric!(f64);
350
351
/// A stream's endianness, or byte order, for determining
352
/// how bits should be read.
353
///
354
/// It comes in `BigEndian` and `LittleEndian` varieties
355
/// (which may be shortened to `BE` and `LE`)
356
/// and is not something programmers should have to implement
357
/// in most cases.
358
pub trait Endianness: Sized {
359
    /// Pushes the given bits and value onto an accumulator
360
    /// with the given bits and value.
361
    fn push<N>(queue: &mut BitQueue<Self, N>, bits: u32, value: N)
362
    where
363
        N: Numeric;
364
365
    /// Pushes the given constant number of bits and value onto an accumulator
366
    /// with the given bits and value.
367
    fn push_fixed<const B: u32, N>(queue: &mut BitQueue<Self, N>, value: N)
368
    where
369
        N: Numeric;
370
371
    /// Pops a value with the given number of bits from an accumulator
372
    /// with the given bits and value.
373
    fn pop<N>(queue: &mut BitQueue<Self, N>, bits: u32) -> N
374
    where
375
        N: Numeric;
376
377
    /// Pops a value with the given number of constant bits
378
    /// from an accumulator with the given bits and value.
379
    fn pop_fixed<const B: u32, N>(queue: &mut BitQueue<Self, N>) -> N
380
    where
381
        N: Numeric;
382
383
    /// Drops the given number of bits from an accumulator
384
    /// with the given bits and value.
385
    fn drop<N>(queue: &mut BitQueue<Self, N>, bits: u32)
386
    where
387
        N: Numeric;
388
389
    /// Returns the next number of 0 bits from an accumulator
390
    /// with the given bits and value.
391
    fn next_zeros<N>(queue: &BitQueue<Self, N>) -> u32
392
    where
393
        N: Numeric;
394
395
    /// Returns the next number of 1 bits from an accumulator
396
    /// with the given bits and value.
397
    fn next_ones<N>(queue: &BitQueue<Self, N>) -> u32
398
    where
399
        N: Numeric;
400
401
    /// Reads signed value from reader in this endianness
402
    fn read_signed<R, S>(r: &mut R, bits: u32) -> io::Result<S>
403
    where
404
        R: BitRead,
405
        S: SignedNumeric;
406
407
    /// Reads signed value from reader in this endianness
408
    fn read_signed_fixed<R, const B: u32, S>(r: &mut R) -> io::Result<S>
409
    where
410
        R: BitRead,
411
        S: SignedNumeric;
412
413
    /// Writes signed value to writer in this endianness
414
    fn write_signed<W, S>(w: &mut W, bits: u32, value: S) -> io::Result<()>
415
    where
416
        W: BitWrite,
417
        S: SignedNumeric;
418
419
    /// Writes signed value to writer in this endianness
420
    fn write_signed_fixed<W, const B: u32, S>(w: &mut W, value: S) -> io::Result<()>
421
    where
422
        W: BitWrite,
423
        S: SignedNumeric;
424
425
    /// Reads convertable numeric value from reader in this endianness
426
    fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
427
    where
428
        R: BitRead,
429
        V: Primitive;
430
431
    /// Writes convertable numeric value to writer in this endianness
432
    fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
433
    where
434
        W: BitWrite,
435
        V: Primitive;
436
437
    /// Reads entire numeric value from reader in this endianness
438
    fn read_numeric<R, V>(r: R) -> io::Result<V>
439
    where
440
        R: io::Read,
441
        V: Primitive;
442
443
    /// Writes entire numeric value to writer in this endianness
444
    fn write_numeric<W, V>(w: W, value: V) -> io::Result<()>
445
    where
446
        W: io::Write,
447
        V: Primitive;
448
}
449
450
/// Big-endian, or most significant bits first
451
#[derive(Copy, Clone, Debug)]
452
pub struct BigEndian;
453
454
/// Big-endian, or most significant bits first
455
pub type BE = BigEndian;
456
457
impl Endianness for BigEndian {
458
    #[inline]
459
0
    fn push<N>(queue: &mut BitQueue<Self, N>, bits: u32, value: N)
460
0
    where
461
0
        N: Numeric,
462
0
    {
463
0
        if !queue.value.is_zero() {
464
0
            queue.value <<= bits;
465
0
        }
466
0
        queue.value |= value;
467
0
        queue.bits += bits;
468
0
    }
469
470
    #[inline]
471
0
    fn push_fixed<const B: u32, N>(queue: &mut BitQueue<Self, N>, value: N)
472
0
    where
473
0
        N: Numeric,
474
0
    {
475
0
        if !queue.value.is_zero() {
476
0
            queue.value <<= B;
477
0
        }
478
0
        queue.value |= value;
479
0
        queue.bits += B;
480
0
    }
481
482
    #[inline]
483
0
    fn pop<N>(queue: &mut BitQueue<Self, N>, bits: u32) -> N
484
0
    where
485
0
        N: Numeric,
486
0
    {
487
0
        if bits < queue.bits {
488
0
            let offset = queue.bits - bits;
489
0
            let to_return = queue.value >> offset;
490
0
            queue.value %= N::ONE << offset;
491
0
            queue.bits -= bits;
492
0
            to_return
493
        } else {
494
0
            let to_return = queue.value;
495
0
            queue.value = N::default();
496
0
            queue.bits = 0;
497
0
            to_return
498
        }
499
0
    }
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop::<i8>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop::<u8>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop::<i32>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop::<u32>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop::<i16>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop::<u16>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop::<u64>
500
501
    #[inline]
502
0
    fn pop_fixed<const B: u32, N>(queue: &mut BitQueue<Self, N>) -> N
503
0
    where
504
0
        N: Numeric,
505
0
    {
506
0
        if B < queue.bits {
507
0
            let offset = queue.bits - B;
508
0
            let to_return = queue.value >> offset;
509
0
            queue.value %= N::ONE << offset;
510
0
            queue.bits -= B;
511
0
            to_return
512
        } else {
513
0
            let to_return = queue.value;
514
0
            queue.value = N::default();
515
0
            queue.bits = 0;
516
0
            to_return
517
        }
518
0
    }
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop_fixed::<8, i8>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop_fixed::<8, u8>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop_fixed::<8, i32>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop_fixed::<8, u32>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop_fixed::<8, i16>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop_fixed::<8, u16>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::pop_fixed::<8, u64>
519
520
    #[inline]
521
    fn drop<N>(queue: &mut BitQueue<Self, N>, bits: u32)
522
    where
523
        N: Numeric,
524
    {
525
        if bits < queue.bits {
526
            queue.value %= N::ONE << (queue.bits - bits);
527
            queue.bits -= bits;
528
        } else {
529
            queue.value = N::default();
530
            queue.bits = 0;
531
        }
532
    }
533
534
    #[inline]
535
    fn next_zeros<N>(queue: &BitQueue<Self, N>) -> u32
536
    where
537
        N: Numeric,
538
    {
539
        queue.value.leading_zeros() - (N::BITS_SIZE - queue.bits)
540
    }
541
542
    #[inline]
543
    fn next_ones<N>(queue: &BitQueue<Self, N>) -> u32
544
    where
545
        N: Numeric,
546
    {
547
        if queue.bits < N::BITS_SIZE {
548
            (queue.value ^ ((N::ONE << queue.bits) - N::ONE)).leading_zeros()
549
                - (N::BITS_SIZE - queue.bits)
550
        } else {
551
            (!queue.value).leading_zeros()
552
        }
553
    }
554
555
    fn read_signed<R, S>(r: &mut R, bits: u32) -> io::Result<S>
556
    where
557
        R: BitRead,
558
        S: SignedNumeric,
559
    {
560
        let is_negative = r.read_bit()?;
561
        let unsigned = r.read::<S>(bits - 1)?;
562
        Ok(if is_negative {
563
            unsigned.as_negative(bits)
564
        } else {
565
            unsigned
566
        })
567
    }
568
569
    fn read_signed_fixed<R, const B: u32, S>(r: &mut R) -> io::Result<S>
570
    where
571
        R: BitRead,
572
        S: SignedNumeric,
573
    {
574
        let is_negative = r.read_bit()?;
575
        let unsigned = r.read::<S>(B - 1)?;
576
        Ok(if is_negative {
577
            unsigned.as_negative_fixed::<B>()
578
        } else {
579
            unsigned
580
        })
581
    }
582
583
0
    fn write_signed<W, S>(w: &mut W, bits: u32, value: S) -> io::Result<()>
584
0
    where
585
0
        W: BitWrite,
586
0
        S: SignedNumeric,
587
0
    {
588
0
        if bits == S::BITS_SIZE {
589
0
            w.write_bytes(value.to_be_bytes().as_ref())
590
0
        } else if value.is_negative() {
591
0
            w.write_bit(true)
592
0
                .and_then(|()| w.write(bits - 1, value.as_unsigned(bits)))
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::write_signed::<bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian>, i8>::{closure#0}
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::write_signed::<bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian>, i16>::{closure#0}
593
        } else {
594
0
            w.write_bit(false).and_then(|()| w.write(bits - 1, value))
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::write_signed::<bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian>, i8>::{closure#1}
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::write_signed::<bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian>, i16>::{closure#1}
595
        }
596
0
    }
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::write_signed::<bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian>, i8>
Unexecuted instantiation: <bitstream_io::BigEndian as bitstream_io::Endianness>::write_signed::<bitstream_io::write::BitWriter<&mut alloc::vec::Vec<u8>, bitstream_io::BigEndian>, i16>
597
598
    fn write_signed_fixed<W, const B: u32, S>(w: &mut W, value: S) -> io::Result<()>
599
    where
600
        W: BitWrite,
601
        S: SignedNumeric,
602
    {
603
        if B == S::BITS_SIZE {
604
            w.write_bytes(value.to_be_bytes().as_ref())
605
        } else if value.is_negative() {
606
            w.write_bit(true)
607
                .and_then(|()| w.write(B - 1, value.as_unsigned(B)))
608
        } else {
609
            w.write_bit(false).and_then(|()| w.write(B - 1, value))
610
        }
611
    }
612
613
    #[inline]
614
    fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
615
    where
616
        R: BitRead,
617
        V: Primitive,
618
    {
619
        let mut buffer = V::buffer();
620
        r.read_bytes(buffer.as_mut())?;
621
        Ok(V::from_be_bytes(buffer))
622
    }
623
624
    #[inline]
625
    fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
626
    where
627
        W: BitWrite,
628
        V: Primitive,
629
    {
630
        w.write_bytes(value.to_be_bytes().as_ref())
631
    }
632
633
    #[inline]
634
    fn read_numeric<R, V>(mut r: R) -> io::Result<V>
635
    where
636
        R: io::Read,
637
        V: Primitive,
638
    {
639
        let mut buffer = V::buffer();
640
        r.read_exact(buffer.as_mut())?;
641
        Ok(V::from_be_bytes(buffer))
642
    }
643
644
    #[inline]
645
    fn write_numeric<W, V>(mut w: W, value: V) -> io::Result<()>
646
    where
647
        W: io::Write,
648
        V: Primitive,
649
    {
650
        w.write_all(value.to_be_bytes().as_ref())
651
    }
652
}
653
654
/// Little-endian, or least significant bits first
655
#[derive(Copy, Clone, Debug)]
656
pub struct LittleEndian;
657
658
/// Little-endian, or least significant bits first
659
pub type LE = LittleEndian;
660
661
impl Endianness for LittleEndian {
662
    #[inline]
663
0
    fn push<N>(queue: &mut BitQueue<Self, N>, bits: u32, mut value: N)
664
0
    where
665
0
        N: Numeric,
666
0
    {
667
0
        if !value.is_zero() {
668
0
            value <<= queue.bits;
669
0
            queue.value |= value;
670
0
        }
671
0
        queue.bits += bits;
672
0
    }
673
674
    #[inline]
675
    fn push_fixed<const B: u32, N>(queue: &mut BitQueue<Self, N>, mut value: N)
676
    where
677
        N: Numeric,
678
    {
679
        if !value.is_zero() {
680
            value <<= queue.bits;
681
            queue.value |= value;
682
        }
683
        queue.bits += B;
684
    }
685
686
    #[inline]
687
0
    fn pop<N>(queue: &mut BitQueue<Self, N>, bits: u32) -> N
688
0
    where
689
0
        N: Numeric,
690
0
    {
691
0
        if bits < queue.bits {
692
0
            let to_return = queue.value % (N::ONE << bits);
693
0
            queue.value >>= bits;
694
0
            queue.bits -= bits;
695
0
            to_return
696
        } else {
697
0
            let to_return = queue.value;
698
0
            queue.value = N::default();
699
0
            queue.bits = 0;
700
0
            to_return
701
        }
702
0
    }
Unexecuted instantiation: <bitstream_io::LittleEndian as bitstream_io::Endianness>::pop::<u8>
Unexecuted instantiation: <bitstream_io::LittleEndian as bitstream_io::Endianness>::pop::<u64>
703
704
0
    fn pop_fixed<const B: u32, N>(queue: &mut BitQueue<Self, N>) -> N
705
0
    where
706
0
        N: Numeric,
707
0
    {
708
0
        if B < queue.bits {
709
0
            let to_return = queue.value % (N::ONE << B);
710
0
            queue.value >>= B;
711
0
            queue.bits -= B;
712
0
            to_return
713
        } else {
714
0
            let to_return = queue.value;
715
0
            queue.value = N::default();
716
0
            queue.bits = 0;
717
0
            to_return
718
        }
719
0
    }
720
721
    #[inline]
722
    fn drop<N>(queue: &mut BitQueue<Self, N>, bits: u32)
723
    where
724
        N: Numeric,
725
    {
726
        if bits < queue.bits {
727
            queue.value >>= bits;
728
            queue.bits -= bits;
729
        } else {
730
            queue.value = N::default();
731
            queue.bits = 0;
732
        }
733
    }
734
735
    #[inline(always)]
736
    fn next_zeros<N>(queue: &BitQueue<Self, N>) -> u32
737
    where
738
        N: Numeric,
739
    {
740
        queue.value.trailing_zeros()
741
    }
742
743
    #[inline]
744
    fn next_ones<N>(queue: &BitQueue<Self, N>) -> u32
745
    where
746
        N: Numeric,
747
    {
748
        (queue.value ^ !N::default()).trailing_zeros()
749
    }
750
751
    fn read_signed<R, S>(r: &mut R, bits: u32) -> io::Result<S>
752
    where
753
        R: BitRead,
754
        S: SignedNumeric,
755
    {
756
        let unsigned = r.read::<S>(bits - 1)?;
757
        let is_negative = r.read_bit()?;
758
        Ok(if is_negative {
759
            unsigned.as_negative(bits)
760
        } else {
761
            unsigned
762
        })
763
    }
764
765
    fn read_signed_fixed<R, const B: u32, S>(r: &mut R) -> io::Result<S>
766
    where
767
        R: BitRead,
768
        S: SignedNumeric,
769
    {
770
        let unsigned = r.read::<S>(B - 1)?;
771
        let is_negative = r.read_bit()?;
772
        Ok(if is_negative {
773
            unsigned.as_negative_fixed::<B>()
774
        } else {
775
            unsigned
776
        })
777
    }
778
779
    fn write_signed<W, S>(w: &mut W, bits: u32, value: S) -> io::Result<()>
780
    where
781
        W: BitWrite,
782
        S: SignedNumeric,
783
    {
784
        if bits == S::BITS_SIZE {
785
            w.write_bytes(value.to_le_bytes().as_ref())
786
        } else if value.is_negative() {
787
            w.write(bits - 1, value.as_unsigned(bits))
788
                .and_then(|()| w.write_bit(true))
789
        } else {
790
            w.write(bits - 1, value).and_then(|()| w.write_bit(false))
791
        }
792
    }
793
794
    fn write_signed_fixed<W, const B: u32, S>(w: &mut W, value: S) -> io::Result<()>
795
    where
796
        W: BitWrite,
797
        S: SignedNumeric,
798
    {
799
        if B == S::BITS_SIZE {
800
            w.write_bytes(value.to_le_bytes().as_ref())
801
        } else if value.is_negative() {
802
            w.write(B - 1, value.as_unsigned_fixed::<B>())
803
                .and_then(|()| w.write_bit(true))
804
        } else {
805
            w.write(B - 1, value).and_then(|()| w.write_bit(false))
806
        }
807
    }
808
809
    #[inline]
810
    fn read_primitive<R, V>(r: &mut R) -> io::Result<V>
811
    where
812
        R: BitRead,
813
        V: Primitive,
814
    {
815
        let mut buffer = V::buffer();
816
        r.read_bytes(buffer.as_mut())?;
817
        Ok(V::from_le_bytes(buffer))
818
    }
819
820
    #[inline]
821
    fn write_primitive<W, V>(w: &mut W, value: V) -> io::Result<()>
822
    where
823
        W: BitWrite,
824
        V: Primitive,
825
    {
826
        w.write_bytes(value.to_le_bytes().as_ref())
827
    }
828
829
    fn read_numeric<R, V>(mut r: R) -> io::Result<V>
830
    where
831
        R: io::Read,
832
        V: Primitive,
833
    {
834
        let mut buffer = V::buffer();
835
        r.read_exact(buffer.as_mut())?;
836
        Ok(V::from_le_bytes(buffer))
837
    }
838
839
    #[inline]
840
    fn write_numeric<W, V>(mut w: W, value: V) -> io::Result<()>
841
    where
842
        W: io::Write,
843
        V: Primitive,
844
    {
845
        w.write_all(value.to_le_bytes().as_ref())
846
    }
847
}
848
849
/// A queue for efficiently pushing bits onto a value
850
/// and popping them off a value.
851
#[derive(Clone, Debug, Default)]
852
pub struct BitQueue<E: Endianness, N: Numeric> {
853
    phantom: PhantomData<E>,
854
    value: N,
855
    bits: u32,
856
}
857
858
impl<E: Endianness, N: Numeric> BitQueue<E, N> {
859
    /// Returns a new empty queue
860
    #[inline]
861
0
    pub fn new() -> BitQueue<E, N> {
862
0
        BitQueue {
863
0
            phantom: PhantomData,
864
0
            value: N::default(),
865
0
            bits: 0,
866
0
        }
867
0
    }
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u8>>::new
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u8>>::new
868
869
    /// Creates a new queue from the given value with the given size
870
    /// Panics if the value is larger than the given number of bits.
871
    #[inline]
872
0
    pub fn from_value(value: N, bits: u32) -> BitQueue<E, N> {
873
0
        assert!(if bits < N::BITS_SIZE {
874
0
            value < (N::ONE << bits)
875
        } else {
876
0
            bits <= N::BITS_SIZE
877
        });
878
0
        BitQueue {
879
0
            phantom: PhantomData,
880
0
            value,
881
0
            bits,
882
0
        }
883
0
    }
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u64>>::from_value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i8>>::from_value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u8>>::from_value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i32>>::from_value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u32>>::from_value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i16>>::from_value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u16>>::from_value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u64>>::from_value
884
885
    /// Sets the queue to a given value with the given number of bits
886
    /// Panics if the value is larger than the given number of bits
887
    #[inline]
888
    pub fn set(&mut self, value: N, bits: u32) {
889
        assert!(if bits < N::BITS_SIZE {
890
            value < (N::ONE << bits)
891
        } else {
892
            bits <= N::BITS_SIZE
893
        });
894
        self.value = value;
895
        self.bits = bits;
896
    }
897
898
    /// Consumes the queue and returns its current value
899
    #[inline(always)]
900
0
    pub fn value(self) -> N {
901
0
        self.value
902
0
    }
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u64>>::value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i8>>::value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u8>>::value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i32>>::value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u32>>::value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i16>>::value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u16>>::value
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u64>>::value
903
904
    /// Returns the total bits in the queue
905
    #[inline(always)]
906
0
    pub fn len(&self) -> u32 {
907
0
        self.bits
908
0
    }
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u8>>::len
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u64>>::len
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i8>>::len
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u8>>::len
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i32>>::len
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u32>>::len
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i16>>::len
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u16>>::len
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u64>>::len
909
910
    /// Returns the maximum bits the queue can hold
911
    #[inline(always)]
912
0
    pub fn max_len(&self) -> u32 {
913
0
        N::BITS_SIZE
914
0
    }
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u8>>::max_len
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u8>>::max_len
915
916
    /// Returns the remaining bits the queue can hold
917
    #[inline(always)]
918
0
    pub fn remaining_len(&self) -> u32 {
919
0
        self.max_len() - self.len()
920
0
    }
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u8>>::remaining_len
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u8>>::remaining_len
921
922
    /// Returns true if the queue is empty
923
    #[inline(always)]
924
0
    pub fn is_empty(&self) -> bool {
925
0
        self.bits == 0
926
0
    }
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u8>>::is_empty
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u8>>::is_empty
927
928
    /// Returns true if the queue is full
929
    #[inline(always)]
930
0
    pub fn is_full(&self) -> bool {
931
0
        self.bits == N::BITS_SIZE
932
0
    }
933
934
    /// Drops all values in the queue
935
    #[inline(always)]
936
    pub fn clear(&mut self) {
937
        self.set(N::default(), 0)
938
    }
939
940
    /// Returns true if all bits remaining in the queue are 0
941
    #[inline(always)]
942
    pub fn all_0(&self) -> bool {
943
        self.value.count_ones() == 0
944
    }
945
946
    /// Returns true if all bits remaining in the queue are 1
947
    #[inline(always)]
948
    pub fn all_1(&self) -> bool {
949
        self.value.count_ones() == self.bits
950
    }
951
952
    /// Pushes a value with the given number of bits onto the tail of the queue
953
    /// Panics if the number of bits pushed is larger than the queue can hold.
954
    #[inline(always)]
955
0
    pub fn push(&mut self, bits: u32, value: N) {
956
0
        assert!(bits <= self.remaining_len()); // check for overflow
957
0
        E::push(self, bits, value)
958
0
    }
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u8>>::push
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u8>>::push
959
960
    /// Pushes a value with the given number of bits onto the tail of the queue
961
    /// Panics if the number of bits pushed is larger than the queue can hold.
962
    #[inline(always)]
963
0
    pub fn push_fixed<const B: u32>(&mut self, value: N) {
964
0
        assert!(B <= self.remaining_len()); // check for overflow
965
0
        E::push_fixed::<B, N>(self, value)
966
0
    }
967
968
    /// Pops a value with the given number of bits from the head of the queue
969
    /// Panics if the number of bits popped is larger than the number
970
    /// of bits in the queue.
971
    #[inline(always)]
972
0
    pub fn pop(&mut self, bits: u32) -> N {
973
0
        assert!(bits <= self.len()); // check for underflow
974
0
        E::pop(self, bits)
975
0
    }
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u8>>::pop
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u64>>::pop
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i8>>::pop
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u8>>::pop
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i32>>::pop
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u32>>::pop
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i16>>::pop
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u16>>::pop
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u64>>::pop
976
977
    /// Pops a value with the given number of bits from the head of the queue
978
0
    pub fn pop_fixed<const B: u32>(&mut self) -> N {
979
0
        assert!(B <= self.len()); // check for underflow
980
0
        E::pop_fixed::<B, N>(self)
981
0
    }
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::LittleEndian, u64>>::pop_fixed::<8>
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i8>>::pop_fixed::<8>
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u8>>::pop_fixed::<8>
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i32>>::pop_fixed::<8>
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u32>>::pop_fixed::<8>
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, i16>>::pop_fixed::<8>
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u16>>::pop_fixed::<8>
Unexecuted instantiation: <bitstream_io::BitQueue<bitstream_io::BigEndian, u64>>::pop_fixed::<8>
982
983
    /// Pops all the current bits from the queue
984
    /// and resets it to an empty state.
985
    #[inline]
986
    pub fn pop_all(&mut self) -> N {
987
        let to_return = self.value;
988
        self.value = N::default();
989
        self.bits = 0;
990
        to_return
991
    }
992
993
    /// Drops the given number of bits from the head of the queue
994
    /// without returning them.
995
    /// Panics if the number of bits dropped is larger than the
996
    /// number of bits in the queue.
997
    #[inline(always)]
998
    pub fn drop(&mut self, bits: u32) {
999
        assert!(bits <= self.len()); // check for underflow
1000
        E::drop(self, bits)
1001
    }
1002
1003
    /// Pops all 0 bits up to and including the next 1 bit
1004
    /// and returns the amount of 0 bits popped
1005
    #[inline]
1006
    pub fn pop_0(&mut self) -> u32 {
1007
        let zeros = E::next_zeros(self);
1008
        self.drop(zeros + 1);
1009
        zeros
1010
    }
1011
1012
    /// Pops all 1 bits up to and including the next 0 bit
1013
    /// and returns the amount of 1 bits popped
1014
    #[inline]
1015
    pub fn pop_1(&mut self) -> u32 {
1016
        let ones = E::next_ones(self);
1017
        self.drop(ones + 1);
1018
        ones
1019
    }
1020
}
1021
1022
impl<E: Endianness> BitQueue<E, u8> {
1023
    /// Returns the state of the queue as a single value
1024
    /// which can be used to perform lookups.
1025
    #[inline(always)]
1026
    pub fn to_state(&self) -> usize {
1027
        (1 << self.bits) | (self.value as usize)
1028
    }
1029
}