blob: 2d16b315925c2fbc93aa33ec47dab42817dcbeca [file]
use std::io;
pub struct ReadRequest<'a> {
pub pos: u64,
pub buf: &'a mut [u8],
}
pub trait SeekRead: Send {
fn pread(&mut self, ranges: &mut [ReadRequest<'_>]) -> io::Result<()>;
}
pub trait SeekWrite: Send {
fn write_all(&mut self, buf: &[u8]) -> io::Result<()>;
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
pub struct PosWriter<W> {
inner: W,
}
impl<W> PosWriter<W> {
pub fn new(inner: W) -> Self {
Self { inner }
}
pub fn into_inner(self) -> W {
self.inner
}
}
impl<W: io::Write + Send> SeekWrite for PosWriter<W> {
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
io::Write::write_all(&mut self.inner, buf)
}
fn flush(&mut self) -> io::Result<()> {
io::Write::flush(&mut self.inner)
}
}
pub struct SliceReader {
data: Vec<u8>,
}
impl SliceReader {
pub fn new(data: Vec<u8>) -> Self {
Self { data }
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
}
impl SeekRead for SliceReader {
fn pread(&mut self, ranges: &mut [ReadRequest<'_>]) -> io::Result<()> {
for range in ranges {
let start = usize::try_from(range.pos)
.map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "offset overflow"))?;
let end = start
.checked_add(range.buf.len())
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "range overflow"))?;
if end > self.data.len() {
return Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
"read past end of slice",
));
}
range.buf.copy_from_slice(&self.data[start..end]);
}
Ok(())
}
}