use std::io::{self, Read, Seek, SeekFrom};
pub struct ReverseRead<R> {
input: R,
offset: u64,
ptr: u64,
}
impl<R: Seek + Read> Read for ReverseRead<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let buff_size = buf.len() as u64;
if self.ptr == self.offset {
return Ok(0);
}
if self.offset + buff_size > self.ptr {
let e = (self.ptr - self.offset) as usize;
self.input.seek(SeekFrom::Start(self.offset))?;
self.input.read_exact(&mut buf[0..e])?;
buf[0..e].reverse();
self.ptr = self.offset;
Ok(e)
} else {
let new_position = self.ptr - buff_size;
self.input.seek(SeekFrom::Start(new_position))?;
self.input.read_exact(buf)?;
buf.reverse();
self.ptr -= buff_size;
Ok(buff_size as usize)
}
}
}
impl<R: Seek + Read> ReverseRead<R> {
pub fn new(input: R, filesize: u64, offset: u64) -> Self {
Self {
input,
offset,
ptr: filesize,
}
}
}