/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 | | } |