use std::io::{
BufRead,
Read,
Result,
Seek,
SeekFrom,
};
use crate::{
Leb128ReadExt,
StringReadExt,
};
pub struct Leb128Reader<R> {
inner: R,
strict: bool,
}
impl<R> Leb128Reader<R> {
#[inline]
pub fn new(inner: R) -> Self {
Self::with_strict(inner, false)
}
#[inline]
pub fn with_strict(inner: R, strict: bool) -> Self {
Self { inner, strict }
}
#[inline]
pub fn is_strict(&self) -> bool {
self.strict
}
#[inline]
pub fn set_strict(&mut self, strict: bool) {
self.strict = strict;
}
#[inline]
pub fn get_ref(&self) -> &R {
&self.inner
}
#[inline]
pub fn get_mut(&mut self) -> &mut R {
&mut self.inner
}
#[inline]
pub fn into_inner(self) -> R {
self.inner
}
}
macro_rules! delegate_read {
($name:ident, $read:ident, $read_strict:ident, $value:ty) => {
#[doc = concat!("Reads a LEB128 `", stringify!($value), "`.")]
#[inline]
pub fn $name(&mut self) -> Result<$value> {
if self.strict {
self.inner.$read_strict()
} else {
self.inner.$read()
}
}
};
}
impl<R> Leb128Reader<R>
where
R: Read,
{
delegate_read!(read_u8, read_uleb_u8, read_uleb_u8_strict, u8);
delegate_read!(read_u16, read_uleb_u16, read_uleb_u16_strict, u16);
delegate_read!(read_u32, read_uleb_u32, read_uleb_u32_strict, u32);
delegate_read!(read_u64, read_uleb_u64, read_uleb_u64_strict, u64);
delegate_read!(read_u128, read_uleb_u128, read_uleb_u128_strict, u128);
delegate_read!(read_usize, read_uleb_usize, read_uleb_usize_strict, usize);
delegate_read!(read_i8, read_sleb_i8, read_sleb_i8_strict, i8);
delegate_read!(read_i16, read_sleb_i16, read_sleb_i16_strict, i16);
delegate_read!(read_i32, read_sleb_i32, read_sleb_i32_strict, i32);
delegate_read!(read_i64, read_sleb_i64, read_sleb_i64_strict, i64);
delegate_read!(read_i128, read_sleb_i128, read_sleb_i128_strict, i128);
delegate_read!(read_isize, read_sleb_isize, read_sleb_isize_strict, isize);
#[inline]
pub fn read_utf8_string(&mut self, max_len: usize) -> Result<String> {
if self.strict {
self.inner.read_utf8_string_uleb_strict(max_len)
} else {
self.inner.read_utf8_string_uleb(max_len)
}
}
}
impl<R> Read for Leb128Reader<R>
where
R: Read,
{
#[inline]
fn read(&mut self, buffer: &mut [u8]) -> Result<usize> {
self.inner.read(buffer)
}
}
impl<R> BufRead for Leb128Reader<R>
where
R: BufRead,
{
#[inline]
fn fill_buf(&mut self) -> Result<&[u8]> {
self.inner.fill_buf()
}
#[inline]
fn consume(&mut self, amount: usize) {
self.inner.consume(amount);
}
}
impl<R> Seek for Leb128Reader<R>
where
R: Seek,
{
#[inline]
fn seek(&mut self, position: SeekFrom) -> Result<u64> {
self.inner.seek(position)
}
}