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