use core::marker::PhantomData;
use std::io::{
Read,
Result,
Seek,
SeekFrom,
};
use crate::codec::{
BigEndian,
BinaryCodec,
ByteOrder,
ByteOrderSpec,
LittleEndian,
};
use crate::stream::BufferedInput;
pub struct BufferedBinaryReader<R, O = BigEndian> {
input: BufferedInput<R>,
marker: PhantomData<fn() -> O>,
}
impl<R, O> BufferedBinaryReader<R, O>
where
O: ByteOrderSpec,
{
#[must_use]
#[inline]
pub fn new(inner: R) -> Self {
Self {
input: BufferedInput::new(inner),
marker: PhantomData,
}
}
#[must_use]
#[inline]
pub fn with_capacity(inner: R, capacity: usize) -> Self {
Self {
input: BufferedInput::with_capacity(inner, capacity),
marker: PhantomData,
}
}
#[must_use]
#[inline]
pub const fn byte_order(&self) -> ByteOrder {
O::ORDER
}
#[must_use]
#[inline]
pub const fn inner(&self) -> &R {
self.input.inner()
}
#[must_use]
#[inline]
pub fn inner_mut(&mut self) -> &mut R {
self.input.inner_mut()
}
#[must_use]
#[inline]
pub fn into_inner(self) -> R {
self.input.into_inner()
}
}
macro_rules! impl_value_read {
($order:ty, $method:ident, $ty:ty, $doc:literal) => {
#[doc = $doc]
#[inline]
pub fn $method(&mut self) -> Result<$ty> {
type Codec = BinaryCodec<$ty, $order>;
const LEN: usize = Codec::REQUIRED_MIN_BUFFER_LEN;
self.input.read_fixed::<LEN, _, _>(|bytes, index| {
unsafe { Codec::read_unchecked(bytes, index) }
})
}
};
}
macro_rules! impl_for_order {
($order:ty) => {
impl<R> BufferedBinaryReader<R, $order>
where
R: Read,
{
impl_value_read!($order, read_u8, u8, "Reads an unsigned 8-bit integer.");
impl_value_read!($order, read_i8, i8, "Reads a signed 8-bit integer.");
impl_value_read!($order, read_u16, u16, "Reads an unsigned 16-bit integer.");
impl_value_read!($order, read_u32, u32, "Reads an unsigned 32-bit integer.");
impl_value_read!($order, read_u64, u64, "Reads an unsigned 64-bit integer.");
impl_value_read!($order, read_u128, u128, "Reads an unsigned 128-bit integer.");
impl_value_read!($order, read_i16, i16, "Reads a signed 16-bit integer.");
impl_value_read!($order, read_i32, i32, "Reads a signed 32-bit integer.");
impl_value_read!($order, read_i64, i64, "Reads a signed 64-bit integer.");
impl_value_read!($order, read_i128, i128, "Reads a signed 128-bit integer.");
impl_value_read!($order, read_f32, f32, "Reads a 32-bit float.");
impl_value_read!($order, read_f64, f64, "Reads a 64-bit float.");
}
};
}
impl_for_order!(BigEndian);
impl_for_order!(LittleEndian);
impl<R, O> Read for BufferedBinaryReader<R, O>
where
R: Read,
{
#[inline]
fn read(&mut self, buffer: &mut [u8]) -> Result<usize> {
self.input.read_raw(buffer)
}
}
impl<R, O> Seek for BufferedBinaryReader<R, O>
where
R: Read + Seek,
{
#[inline]
fn seek(&mut self, position: SeekFrom) -> Result<u64> {
self.input.seek_raw(position)
}
}