Coverage Report

Created: 2026-09-06 06:29

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