use std::io;
use std::io::Seek as _;
use crate::Error;
pub struct ForkReader<R> {
inner: R,
position: u64,
end: u64,
}
impl<R> ForkReader<R> {
pub(crate) fn new(inner: R, position: u64, end: u64) -> Self {
Self {
inner,
position,
end,
}
}
}
impl<R: io::Read + io::Seek> io::Read for ForkReader<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let pos = self.stream_position()?;
if pos + buf.len() as u64 > self.end {
if pos >= self.end {
Ok(0)
} else {
let len = self.end - pos;
self.inner.read(&mut buf[0..(len as usize)])
}
} else {
self.inner.read(buf)
}
}
}
impl<R: io::Read + io::Seek> io::Seek for ForkReader<R> {
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
match pos {
io::SeekFrom::Start(x) => {
Ok(self.inner.seek(io::SeekFrom::Start(self.position + x))? - self.position)
}
io::SeekFrom::End(mode) => {
eprintln!("Unsupported seek {mode:?}");
Err(Error::UnsupportedSeek.into())
}
io::SeekFrom::Current(x) => {
Ok(self.inner.seek(io::SeekFrom::Current(x))? - self.position)
}
}
}
}