#![warn(missing_docs)]
#[cfg(not(feature = "std"))]
use no_std_io2::io;
#[cfg(feature = "alloc")]
use alloc::{vec, vec::Vec};
#[cfg(feature = "std")]
use std::io;
use super::{
BitCount, CheckablePrimitive, Endianness, Integer, PhantomData, Primitive, SignedBitCount,
SignedInteger, UnsignedInteger, VBRInteger,
};
use core::convert::TryInto;
#[derive(Copy, Clone, Debug)]
pub(crate) struct VariableWidthOverflow;
impl core::fmt::Display for VariableWidthOverflow {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
"variable bit rate overflowed".fmt(f)
}
}
impl core::error::Error for VariableWidthOverflow {}
impl From<VariableWidthOverflow> for io::Error {
fn from(VariableWidthOverflow: VariableWidthOverflow) -> Self {
io::Error::new(
#[cfg(feature = "std")]
{
io::ErrorKind::StorageFull
},
#[cfg(not(feature = "std"))]
{
io::ErrorKind::Other
},
"variable bit rate overflow",
)
}
}
pub trait BitRead {
fn read_bit(&mut self) -> io::Result<bool> {
self.read_unsigned::<1, u8>().map(|b| b == 1)
}
#[inline]
fn read<const BITS: u32, I>(&mut self) -> io::Result<I>
where
I: Integer,
{
I::read::<BITS, _>(self)
}
#[inline]
fn read_var<I>(&mut self, bits: u32) -> io::Result<I>
where
I: Integer + Sized,
{
I::read_var(self, BitCount::unknown(bits))
}
fn read_count<const MAX: u32>(&mut self) -> io::Result<BitCount<MAX>> {
const {
assert!(MAX > 0, "MAX value must be > 0");
assert!(
MAX == u32::MAX || (MAX + 1).is_power_of_two(),
"MAX should fill some whole number of bits ('0b111', '0b1111', etc.)"
)
}
self.read_unsigned_var(if MAX < u32::MAX {
(MAX + 1).ilog2()
} else {
32
})
.map(|bits| BitCount { bits })
}
#[inline(always)]
fn read_counted<const MAX: u32, I>(&mut self, bits: BitCount<MAX>) -> io::Result<I>
where
I: Integer + Sized,
{
I::read_var(self, bits)
}
fn read_unsigned<const BITS: u32, U>(&mut self) -> io::Result<U>
where
U: UnsignedInteger,
{
self.read_unsigned_var(BITS)
}
#[inline(always)]
fn read_unsigned_var<U>(&mut self, bits: u32) -> io::Result<U>
where
U: UnsignedInteger,
{
self.read_unsigned_counted(BitCount::unknown(bits))
}
fn read_unsigned_counted<const MAX: u32, U>(&mut self, bits: BitCount<MAX>) -> io::Result<U>
where
U: UnsignedInteger;
fn read_signed<const BITS: u32, S>(&mut self) -> io::Result<S>
where
S: SignedInteger,
{
self.read_signed_var(BITS)
}
fn read_signed_var<S>(&mut self, bits: u32) -> io::Result<S>
where
S: SignedInteger,
{
self.read_signed_counted(BitCount::unknown(bits))
}
fn read_signed_counted<const MAX: u32, S>(
&mut self,
bits: impl TryInto<SignedBitCount<MAX>>,
) -> io::Result<S>
where
S: SignedInteger;
#[inline]
fn read_const<const BITS: u32, const VALUE: u32, E>(&mut self, err: E) -> Result<(), E>
where
E: From<io::Error>,
{
use super::Numeric;
const {
assert!(
BITS == 0 || VALUE <= (u32::ALL >> (u32::BITS_SIZE - BITS)),
"excessive value for bits read"
);
}
(self.read::<BITS, u32>()? == VALUE)
.then_some(())
.ok_or(err)
}
fn read_to<V>(&mut self) -> io::Result<V>
where
V: Primitive;
fn read_as_to<F, V>(&mut self) -> io::Result<V>
where
F: Endianness,
V: Primitive;
fn skip(&mut self, bits: u32) -> io::Result<()> {
(0..bits).try_for_each(|_| self.read_bit().map(|_| ()))
}
fn read_bytes(&mut self, buf: &mut [u8]) -> io::Result<()> {
for b in buf.iter_mut() {
*b = self.read_unsigned::<8, _>()?;
}
Ok(())
}
#[inline(always)]
#[deprecated(since = "1.8.0", note = "use read_to() method instead")]
fn read_to_bytes<const SIZE: usize>(&mut self) -> io::Result<[u8; SIZE]> {
self.read_to()
}
#[cfg(feature = "alloc")]
fn read_to_vec(&mut self, bytes: usize) -> io::Result<Vec<u8>> {
read_to_vec(|buf| self.read_bytes(buf), bytes)
}
fn read_unary<const STOP_BIT: u8>(&mut self) -> io::Result<u32> {
const {
assert!(matches!(STOP_BIT, 0 | 1), "stop bit must be 0 or 1");
}
let mut unary = 0;
while self.read::<1, u8>()? != STOP_BIT {
unary += 1;
}
Ok(unary)
}
#[inline]
fn read_checked<C>(&mut self, count: C::CountType) -> io::Result<C>
where
C: CheckablePrimitive,
{
C::read(self, count)
}
fn parse<F: FromBitStream>(&mut self) -> Result<F, F::Error> {
F::from_reader(self)
}
fn parse_with<'a, F: FromBitStreamWith<'a>>(
&mut self,
context: &F::Context,
) -> Result<F, F::Error> {
F::from_reader(self, context)
}
fn parse_using<F: FromBitStreamUsing>(&mut self, context: F::Context) -> Result<F, F::Error> {
F::from_reader(self, context)
}
fn byte_aligned(&self) -> bool;
fn byte_align(&mut self);
#[inline]
fn read_huffman<T>(&mut self) -> io::Result<T::Symbol>
where
T: crate::huffman::FromBits,
{
T::from_bits(|| self.read_bit())
}
fn read_unsigned_vbr<const FIELD_SIZE: u32, U: UnsignedInteger>(&mut self) -> io::Result<U> {
const { assert!(FIELD_SIZE >= 2 && FIELD_SIZE < U::BITS_SIZE) };
let payload_bits = FIELD_SIZE - 1;
let mut value = U::ZERO;
let mut shift = 0u32;
loop {
let (data, continuation) = self.read_unsigned::<FIELD_SIZE, U>().map(|item| {
(
item & ((U::ONE << payload_bits) - U::ONE),
(item >> payload_bits) != U::ZERO,
)
})?;
let shifted = data << shift;
value |= shifted;
if !continuation {
if (data << shift) >> shift == data {
break Ok(value);
} else {
break Err(VariableWidthOverflow {}.into());
}
}
shift += payload_bits;
if shift >= U::BITS_SIZE {
break Err(VariableWidthOverflow {}.into());
}
}
}
fn read_signed_vbr<const FIELD_SIZE: u32, I: SignedInteger>(&mut self) -> io::Result<I> {
self.read_unsigned_vbr::<FIELD_SIZE, I::Unsigned>()
.map(|zig_zag| {
let shifted = zig_zag >> 1;
let complimented = zig_zag & <I::Unsigned as crate::Numeric>::ONE;
let neg = I::ZERO - complimented.as_non_negative();
shifted.as_non_negative() ^ neg
})
}
#[inline]
fn read_vbr<const FIELD_SIZE: u32, I: VBRInteger>(&mut self) -> io::Result<I> {
I::read_vbr::<FIELD_SIZE, _>(self)
}
#[inline]
fn by_ref(&mut self) -> &mut Self {
self
}
}
impl<R: BitRead + ?Sized> BitRead for &mut R {
#[inline]
fn read_bit(&mut self) -> io::Result<bool> {
(**self).read_bit()
}
#[inline]
fn read<const BITS: u32, I>(&mut self) -> io::Result<I>
where
I: Integer,
{
(**self).read::<BITS, I>()
}
#[inline]
fn read_var<I>(&mut self, bits: u32) -> io::Result<I>
where
I: Integer + Sized,
{
(**self).read_var(bits)
}
#[inline]
fn read_count<const MAX: u32>(&mut self) -> io::Result<BitCount<MAX>> {
(**self).read_count::<MAX>()
}
#[inline]
fn read_counted<const MAX: u32, I>(&mut self, bits: BitCount<MAX>) -> io::Result<I>
where
I: Integer + Sized,
{
(**self).read_counted::<MAX, I>(bits)
}
#[inline]
fn read_unsigned<const BITS: u32, U>(&mut self) -> io::Result<U>
where
U: UnsignedInteger,
{
(**self).read_unsigned::<BITS, U>()
}
#[inline]
fn read_unsigned_var<U>(&mut self, bits: u32) -> io::Result<U>
where
U: UnsignedInteger,
{
(**self).read_unsigned_var(bits)
}
#[inline]
fn read_unsigned_counted<const MAX: u32, U>(&mut self, bits: BitCount<MAX>) -> io::Result<U>
where
U: UnsignedInteger,
{
(**self).read_unsigned_counted::<MAX, U>(bits)
}
#[inline]
fn read_signed<const BITS: u32, S>(&mut self) -> io::Result<S>
where
S: SignedInteger,
{
(**self).read_signed::<BITS, S>()
}
#[inline]
fn read_signed_var<S>(&mut self, bits: u32) -> io::Result<S>
where
S: SignedInteger,
{
(**self).read_signed_var(bits)
}
#[inline]
fn read_signed_counted<const MAX: u32, S>(
&mut self,
bits: impl TryInto<SignedBitCount<MAX>>,
) -> io::Result<S>
where
S: SignedInteger,
{
(**self).read_signed_counted::<MAX, S>(bits)
}
#[inline]
fn read_to<V>(&mut self) -> io::Result<V>
where
V: Primitive,
{
(**self).read_to::<V>()
}
#[inline]
fn read_as_to<F, V>(&mut self) -> io::Result<V>
where
F: Endianness,
V: Primitive,
{
(**self).read_as_to::<F, V>()
}
#[inline]
fn skip(&mut self, bits: u32) -> io::Result<()> {
(**self).skip(bits)
}
#[inline]
fn read_bytes(&mut self, buf: &mut [u8]) -> io::Result<()> {
(**self).read_bytes(buf)
}
#[inline]
#[cfg(feature = "alloc")]
fn read_to_vec(&mut self, bytes: usize) -> io::Result<Vec<u8>> {
(**self).read_to_vec(bytes)
}
#[inline]
fn read_unary<const STOP_BIT: u8>(&mut self) -> io::Result<u32> {
(**self).read_unary::<STOP_BIT>()
}
#[inline]
fn parse<F: FromBitStream>(&mut self) -> Result<F, F::Error> {
(**self).parse::<F>()
}
#[inline]
fn parse_with<'a, F: FromBitStreamWith<'a>>(
&mut self,
context: &F::Context,
) -> Result<F, F::Error> {
(**self).parse_with::<F>(context)
}
#[inline]
fn byte_aligned(&self) -> bool {
(**self).byte_aligned()
}
#[inline]
fn byte_align(&mut self) {
(**self).byte_align()
}
#[inline]
fn read_huffman<T>(&mut self) -> io::Result<T::Symbol>
where
T: crate::huffman::FromBits,
{
(**self).read_huffman::<T>()
}
}
pub trait BitRead2 {
fn read_bit(&mut self) -> io::Result<bool>;
fn read<I>(&mut self, bits: u32) -> io::Result<I>
where
I: Integer + Sized;
fn read_in<const BITS: u32, I>(&mut self) -> io::Result<I>
where
I: Integer,
{
self.read(BITS)
}
fn read_signed<S>(&mut self, bits: u32) -> io::Result<S>
where
S: SignedInteger;
fn read_signed_in<const BITS: u32, S>(&mut self) -> io::Result<S>
where
S: SignedInteger,
{
self.read_signed(BITS)
}
fn read_to<V>(&mut self) -> io::Result<V>
where
V: Primitive;
fn read_as_to<F, V>(&mut self) -> io::Result<V>
where
F: Endianness,
V: Primitive;
fn skip(&mut self, bits: u32) -> io::Result<()>;
fn read_bytes(&mut self, buf: &mut [u8]) -> io::Result<()> {
for b in buf.iter_mut() {
*b = self.read_in::<8, _>()?;
}
Ok(())
}
#[inline(always)]
#[deprecated(since = "1.8.0", note = "use read_to() method instead")]
fn read_to_bytes<const SIZE: usize>(&mut self) -> io::Result<[u8; SIZE]> {
self.read_to()
}
#[cfg(feature = "alloc")]
fn read_to_vec(&mut self, bytes: usize) -> io::Result<Vec<u8>> {
read_to_vec(|buf| self.read_bytes(buf), bytes)
}
fn read_unary0(&mut self) -> io::Result<u32> {
let mut unary = 0;
while self.read_bit()? {
unary += 1;
}
Ok(unary)
}
fn read_unary1(&mut self) -> io::Result<u32> {
let mut unary = 0;
while !(self.read_bit()?) {
unary += 1;
}
Ok(unary)
}
fn parse<F: FromBitStream>(&mut self) -> Result<F, F::Error>
where
Self: BitRead,
{
F::from_reader(self)
}
fn parse_with<'a, F: FromBitStreamWith<'a>>(
&mut self,
context: &F::Context,
) -> Result<F, F::Error>
where
Self: BitRead,
{
F::from_reader(self, context)
}
fn byte_aligned(&self) -> bool;
fn byte_align(&mut self);
#[inline]
fn read_huffman<T>(&mut self) -> io::Result<T::Symbol>
where
T: crate::huffman::FromBits,
{
T::from_bits(|| self.read_bit())
}
}
impl<R: BitRead> BitRead2 for R {
#[inline(always)]
fn read_bit(&mut self) -> io::Result<bool> {
BitRead::read_bit(self)
}
#[inline(always)]
fn read<I>(&mut self, bits: u32) -> io::Result<I>
where
I: Integer + Sized,
{
self.read_var(bits)
}
#[inline(always)]
fn read_in<const BITS: u32, I>(&mut self) -> io::Result<I>
where
I: Integer,
{
BitRead::read::<BITS, I>(self)
}
#[inline(always)]
fn read_signed<S>(&mut self, bits: u32) -> io::Result<S>
where
S: SignedInteger,
{
self.read_signed_var(bits)
}
#[inline(always)]
fn read_signed_in<const BITS: u32, S>(&mut self) -> io::Result<S>
where
S: SignedInteger,
{
BitRead::read_signed::<BITS, S>(self)
}
#[inline(always)]
fn read_to<V>(&mut self) -> io::Result<V>
where
V: Primitive,
{
BitRead::read_to::<V>(self)
}
#[inline(always)]
fn read_as_to<F, V>(&mut self) -> io::Result<V>
where
F: Endianness,
V: Primitive,
{
BitRead::read_as_to::<F, V>(self)
}
#[inline(always)]
fn skip(&mut self, bits: u32) -> io::Result<()> {
BitRead::skip(self, bits)
}
#[inline(always)]
fn read_bytes(&mut self, buf: &mut [u8]) -> io::Result<()> {
BitRead::read_bytes(self, buf)
}
#[inline(always)]
fn read_unary0(&mut self) -> io::Result<u32> {
self.read_unary::<0>()
}
#[inline(always)]
fn read_unary1(&mut self) -> io::Result<u32> {
self.read_unary::<1>()
}
#[inline(always)]
fn byte_aligned(&self) -> bool {
BitRead::byte_aligned(self)
}
#[inline(always)]
fn byte_align(&mut self) {
BitRead::byte_align(self)
}
}
#[derive(Clone, Debug)]
pub struct BitReader<R, E: Endianness> {
reader: R,
value: u8,
bits: u32,
phantom: PhantomData<E>,
}
impl<R, E: Endianness> BitReader<R, E> {
pub fn new(reader: R) -> BitReader<R, E> {
BitReader {
reader,
value: 0,
bits: 0,
phantom: PhantomData,
}
}
pub fn endian(reader: R, _endian: E) -> BitReader<R, E> {
BitReader {
reader,
value: 0,
bits: 0,
phantom: PhantomData,
}
}
#[inline]
pub fn into_reader(self) -> R {
self.reader
}
}
impl<R: io::Read, E: Endianness> BitReader<R, E> {
#[inline]
pub fn reader(&mut self) -> Option<&mut R> {
if BitRead::byte_aligned(self) {
Some(&mut self.reader)
} else {
None
}
}
#[inline]
pub fn aligned_reader(&mut self) -> &mut R {
BitRead::byte_align(self);
&mut self.reader
}
#[inline]
pub fn into_bytereader(self) -> ByteReader<R, E> {
ByteReader::new(self.into_reader())
}
#[inline]
pub fn bytereader(&mut self) -> Option<ByteReader<&mut R, E>> {
self.reader().map(ByteReader::new)
}
}
impl<R: io::Read, E: Endianness> BitRead for BitReader<R, E> {
#[inline(always)]
fn read_bit(&mut self) -> io::Result<bool> {
let Self {
value,
bits,
reader,
..
} = self;
E::pop_bit_refill(reader, value, bits)
}
#[inline(always)]
fn read_unsigned_counted<const BITS: u32, U>(&mut self, bits: BitCount<BITS>) -> io::Result<U>
where
U: UnsignedInteger,
{
let Self {
value: queue_value,
bits: queue_bits,
reader,
..
} = self;
E::read_bits(reader, queue_value, queue_bits, bits)
}
#[inline]
fn read_unsigned<const BITS: u32, U>(&mut self) -> io::Result<U>
where
U: UnsignedInteger,
{
let Self {
value,
bits,
reader,
..
} = self;
E::read_bits_fixed::<BITS, R, U>(reader, value, bits)
}
#[inline(always)]
fn read_signed_counted<const MAX: u32, S>(
&mut self,
bits: impl TryInto<SignedBitCount<MAX>>,
) -> io::Result<S>
where
S: SignedInteger,
{
E::read_signed_counted(
self,
bits.try_into().map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidInput,
"signed reads need at least 1 bit for sign",
)
})?,
)
}
#[inline]
fn read_signed<const BITS: u32, S>(&mut self) -> io::Result<S>
where
S: SignedInteger,
{
let count = const {
assert!(BITS <= S::BITS_SIZE, "excessive bits for type read");
let count = BitCount::<BITS>::new::<BITS>().signed_count();
assert!(count.is_some(), "signed reads need at least 1 bit for sign");
count.unwrap()
};
E::read_signed_counted(self, count)
}
#[inline]
fn read_to<V>(&mut self) -> io::Result<V>
where
V: Primitive,
{
let mut buffer = V::buffer();
E::read_bytes::<8, _>(
&mut self.reader,
&mut self.value,
self.bits,
buffer.as_mut(),
)?;
Ok(E::bytes_to_primitive(buffer))
}
#[inline]
fn read_as_to<F, V>(&mut self) -> io::Result<V>
where
F: Endianness,
V: Primitive,
{
let mut buffer = V::buffer();
F::read_bytes::<8, _>(
&mut self.reader,
&mut self.value,
self.bits,
buffer.as_mut(),
)?;
Ok(F::bytes_to_primitive(buffer))
}
fn skip(&mut self, mut bits: u32) -> io::Result<()> {
if BitRead::byte_aligned(self) && bits % 8 == 0 {
skip_aligned(self.reader.by_ref(), bits / 8)
} else {
loop {
match bits {
0 => break Ok(()),
bits @ 1..64 => break self.read_var(bits).map(|_: u64| ()),
_ => {
let _ = BitRead::read::<64, u64>(self)?;
bits -= 64;
}
}
}
}
}
#[inline]
fn read_bytes(&mut self, buf: &mut [u8]) -> io::Result<()> {
E::read_bytes::<1024, _>(&mut self.reader, &mut self.value, self.bits, buf)
}
fn read_unary<const STOP_BIT: u8>(&mut self) -> io::Result<u32> {
let Self {
value,
bits,
reader,
..
} = self;
E::pop_unary::<STOP_BIT, R>(reader, value, bits)
}
#[inline]
fn byte_aligned(&self) -> bool {
self.bits == 0
}
#[inline]
fn byte_align(&mut self) {
self.value = 0;
self.bits = 0;
}
}
impl<R, E> BitReader<R, E>
where
E: Endianness,
R: io::Read + io::Seek,
{
pub fn seek_bits(&mut self, from: io::SeekFrom) -> io::Result<u64> {
match from {
io::SeekFrom::Start(from_start_pos) => {
let (bytes, bits) = (from_start_pos / 8, (from_start_pos % 8) as u32);
BitRead::byte_align(self);
self.reader.seek(io::SeekFrom::Start(bytes))?;
BitRead::skip(self, bits)?;
Ok(from_start_pos)
}
io::SeekFrom::End(from_end_pos) => {
let reader_end = self.reader.seek(io::SeekFrom::End(0))?;
let new_pos = (reader_end * 8) as i64 - from_end_pos;
assert!(new_pos >= 0, "The final position should be greater than 0");
self.seek_bits(io::SeekFrom::Start(new_pos as u64))
}
io::SeekFrom::Current(offset) => {
let new_pos = self.position_in_bits()? as i64 + offset;
assert!(new_pos >= 0, "The final position should be greater than 0");
self.seek_bits(io::SeekFrom::Start(new_pos as u64))
}
}
}
#[inline]
#[allow(clippy::seek_from_current)]
pub fn position_in_bits(&mut self) -> io::Result<u64> {
let bytes = self.reader.seek(io::SeekFrom::Current(0))?;
Ok(bytes * 8 - (self.bits as u64))
}
}
fn skip_aligned<R>(reader: R, bytes: u32) -> io::Result<()>
where
R: io::Read,
{
fn skip_chunks<const SIZE: usize, R>(mut reader: R, mut bytes: usize) -> io::Result<()>
where
R: io::Read,
{
let mut buf = [0; SIZE];
while bytes > 0 {
let to_read = bytes.min(SIZE);
reader.read_exact(&mut buf[0..to_read])?;
bytes -= to_read;
}
Ok(())
}
match bytes {
0..256 => skip_chunks::<8, R>(reader, bytes as usize),
256..1024 => skip_chunks::<256, R>(reader, bytes as usize),
1024..4096 => skip_chunks::<1024, R>(reader, bytes as usize),
_ => skip_chunks::<4096, R>(reader, bytes as usize),
}
}
pub trait ByteRead {
fn read<V>(&mut self) -> Result<V, io::Error>
where
V: Primitive;
fn read_as<F, V>(&mut self) -> Result<V, io::Error>
where
F: Endianness,
V: Primitive;
fn read_bytes(&mut self, buf: &mut [u8]) -> io::Result<()> {
for b in buf.iter_mut() {
*b = self.read()?;
}
Ok(())
}
#[inline(always)]
#[deprecated(since = "1.8.0", note = "use read() method instead")]
fn read_to_bytes<const SIZE: usize>(&mut self) -> io::Result<[u8; SIZE]> {
self.read()
}
#[cfg(feature = "alloc")]
fn read_to_vec(&mut self, bytes: usize) -> io::Result<Vec<u8>> {
read_to_vec(|buf| self.read_bytes(buf), bytes)
}
fn skip(&mut self, bytes: u32) -> io::Result<()>;
fn parse<F: FromByteStream>(&mut self) -> Result<F, F::Error> {
F::from_reader(self)
}
fn parse_with<'a, F: FromByteStreamWith<'a>>(
&mut self,
context: &F::Context,
) -> Result<F, F::Error> {
F::from_reader(self, context)
}
fn parse_using<F: FromByteStreamUsing>(&mut self, context: F::Context) -> Result<F, F::Error> {
F::from_reader(self, context)
}
fn reader_ref(&mut self) -> &mut dyn io::Read;
}
#[derive(Debug)]
pub struct ByteReader<R: io::Read, E: Endianness> {
phantom: PhantomData<E>,
reader: R,
}
impl<R: io::Read, E: Endianness> ByteReader<R, E> {
pub fn new(reader: R) -> ByteReader<R, E> {
ByteReader {
phantom: PhantomData,
reader,
}
}
pub fn endian(reader: R, _endian: E) -> ByteReader<R, E> {
ByteReader {
phantom: PhantomData,
reader,
}
}
#[inline]
pub fn into_reader(self) -> R {
self.reader
}
#[inline]
pub fn reader(&mut self) -> &mut R {
&mut self.reader
}
#[inline]
pub fn into_bitreader(self) -> BitReader<R, E> {
BitReader::new(self.into_reader())
}
#[inline]
pub fn bitreader(&mut self) -> BitReader<&mut R, E> {
BitReader::new(self.reader())
}
}
impl<R: io::Read, E: Endianness> ByteRead for ByteReader<R, E> {
#[inline]
fn read<V>(&mut self) -> Result<V, io::Error>
where
V: Primitive,
{
let mut buf = V::buffer();
self.read_bytes(buf.as_mut())?;
Ok(E::bytes_to_primitive(buf))
}
#[inline]
fn read_as<F, V>(&mut self) -> Result<V, io::Error>
where
F: Endianness,
V: Primitive,
{
let mut buf = V::buffer();
self.read_bytes(buf.as_mut())?;
Ok(F::bytes_to_primitive(buf))
}
#[inline]
fn read_bytes(&mut self, buf: &mut [u8]) -> io::Result<()> {
self.reader.read_exact(buf)
}
#[inline]
fn skip(&mut self, bytes: u32) -> io::Result<()> {
skip_aligned(&mut self.reader, bytes)
}
#[inline]
fn reader_ref(&mut self) -> &mut dyn io::Read {
&mut self.reader
}
}
impl<R: io::Read + io::Seek, E: Endianness> io::Seek for ByteReader<R, E> {
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
self.reader().seek(pos)
}
}
pub trait FromBitStream {
type Error;
fn from_reader<R: BitRead + ?Sized>(r: &mut R) -> Result<Self, Self::Error>
where
Self: Sized;
}
pub trait FromBitStreamWith<'a> {
type Context: 'a;
type Error;
fn from_reader<R: BitRead + ?Sized>(
r: &mut R,
context: &Self::Context,
) -> Result<Self, Self::Error>
where
Self: Sized;
}
pub trait FromBitStreamUsing {
type Context;
type Error;
fn from_reader<R: BitRead + ?Sized>(
r: &mut R,
context: Self::Context,
) -> Result<Self, Self::Error>
where
Self: Sized;
}
pub trait FromByteStream {
type Error;
fn from_reader<R: ByteRead + ?Sized>(r: &mut R) -> Result<Self, Self::Error>
where
Self: Sized;
}
pub trait FromByteStreamWith<'a> {
type Context: 'a;
type Error;
fn from_reader<R: ByteRead + ?Sized>(
r: &mut R,
context: &Self::Context,
) -> Result<Self, Self::Error>
where
Self: Sized;
}
pub trait FromByteStreamUsing {
type Context;
type Error;
fn from_reader<R: ByteRead + ?Sized>(
r: &mut R,
context: Self::Context,
) -> Result<Self, Self::Error>
where
Self: Sized;
}
#[cfg(feature = "alloc")]
fn read_to_vec(
mut read: impl FnMut(&mut [u8]) -> io::Result<()>,
bytes: usize,
) -> io::Result<Vec<u8>> {
const MAX_CHUNK: usize = 4096;
match bytes {
0 => Ok(Vec::new()),
bytes if bytes <= MAX_CHUNK => {
let mut buf = vec![0; bytes];
read(&mut buf)?;
Ok(buf)
}
mut bytes => {
let mut whole = Vec::with_capacity(MAX_CHUNK);
let mut chunk: [u8; MAX_CHUNK] = [0; MAX_CHUNK];
while bytes > 0 {
let chunk_size = bytes.min(MAX_CHUNK);
let chunk = &mut chunk[0..chunk_size];
read(chunk)?;
whole.extend_from_slice(chunk);
bytes -= chunk_size;
}
Ok(whole)
}
}
}