use std::io;
#[cfg(feature = "alloc")]
use std::vec::Vec;
use super::{
read_to_vec, skip_aligned, BitReader, Endianness, FromByteStream, FromByteStreamUsing,
FromByteStreamWith, PhantomData, Primitive,
};
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")]
#[cfg_attr(docsrs, doc(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)
}
}