use std::convert::TryInto;
use std::io::{self, BufRead, Read};
use std::str;
use crate::*;
pub trait Source<'de, S: Str<'de>> {
fn offset(&self) -> usize;
fn limit(&self) -> usize;
fn read_u8_char(&mut self) -> IoResult<u8>;
fn read_str(&mut self, n: usize) -> IoResult<S>;
unsafe fn read_until(&mut self, byte: u8) -> IoResult<S>;
}
impl<'t, 'de, S, T> Source<'de, S> for &'t mut T
where
S: Str<'de>,
T: Source<'de, S>,
{
fn offset(&self) -> usize {
<T as Source<'de, S>>::offset(&**self)
}
fn limit(&self) -> usize {
<T as Source<'de, S>>::limit(&**self)
}
fn read_u8_char(&mut self) -> IoResult<u8> {
<T as Source<'de, S>>::read_u8_char(&mut **self)
}
fn read_str(&mut self, n: usize) -> IoResult<S> {
<T as Source<'de, S>>::read_str(&mut **self, n)
}
unsafe fn read_until(&mut self, byte: u8) -> IoResult<S> {
<T as Source<'de, S>>::read_until(&mut **self, byte)
}
}
pub struct ByteReader<R: Read> {
read: io::BufReader<io::Take<R>>,
offset: usize,
limit: usize,
}
impl<R: Read> ByteReader<R> {
pub fn new(read: R, limit: usize) -> Self {
Self {
read: io::BufReader::new(
read.take(
limit
.try_into()
.expect("Limit greater than u64::MAX_VALUE is not supported"),
),
),
offset: 0,
limit,
}
}
}
impl<'de, R: Read> Source<'de, Vec<u8>> for ByteReader<R> {
fn offset(&self) -> usize {
self.offset
}
fn limit(&self) -> usize {
self.limit
}
fn read_u8_char(&mut self) -> IoResult<u8> {
let mut buf = [0u8];
self.read.read_exact(&mut buf)?;
Ok(buf[0])
}
fn read_str(&mut self, n: usize) -> IoResult<Vec<u8>> {
if n > self.limit {
return Err(Error::UnexpectedEof.into());
}
let mut buf = vec![0u8; n];
self.read.read_exact(&mut buf)?;
Ok(buf)
}
unsafe fn read_until(&mut self, byte: u8) -> IoResult<Vec<u8>> {
let mut vec = vec![];
let _ = self.read.read_until(byte, &mut vec)?;
Ok(vec)
}
}
pub struct StringReader<R: Read> {
read: io::BufReader<io::Take<R>>,
offset: usize,
limit: usize,
}
impl<R: Read> StringReader<R> {
pub fn new(read: R, limit: usize) -> Self {
Self {
read: io::BufReader::new(
read.take(
limit
.try_into()
.expect("Limit greater than u64::MAX_VALUE is not supported"),
),
),
offset: 0,
limit,
}
}
}
impl<'de, R: Read> Source<'de, String> for StringReader<R> {
fn offset(&self) -> usize {
self.offset
}
fn limit(&self) -> usize {
self.limit
}
fn read_u8_char(&mut self) -> IoResult<u8> {
let mut buf = [0u8];
self.read.read_exact(&mut buf)?;
let _ = str::from_utf8(&buf).map_err(|_| Error::BadEncoding(self.offset))?;
Ok(buf[0])
}
fn read_str(&mut self, n: usize) -> IoResult<String> {
if n > self.limit {
return Err(Error::UnexpectedEof.into());
}
let mut buf = vec![0u8; n];
self.read.read_exact(&mut buf)?;
let string = String::from_utf8(buf).map_err(|_| Error::BadEncoding(self.offset))?;
Ok(string)
}
unsafe fn read_until(&mut self, byte: u8) -> IoResult<String> {
let mut vec = vec![];
let _ = self.read.read_until(byte, &mut vec)?;
let string = String::from_utf8(vec).map_err(|_| Error::BadEncoding(self.offset))?;
Ok(string)
}
}