use std::io::{self, ErrorKind};
use std::io::{Read, Seek, SeekFrom, Write};
use crate::Error;
use crate::layers::traits::{InnerWriterTrait, LayerReader, LayerTruncatedReader, LayerWriter};
use super::traits::InnerReaderTrait;
pub struct RawLayerWriter<W: InnerWriterTrait> {
inner: W,
}
impl<W: InnerWriterTrait> RawLayerWriter<W> {
pub fn new(inner: W) -> Self {
Self { inner }
}
}
impl<W: InnerWriterTrait> LayerWriter<'_, W> for RawLayerWriter<W> {
fn finalize(self: Box<Self>) -> Result<W, Error> {
Ok(self.inner)
}
}
impl<W: InnerWriterTrait> Write for RawLayerWriter<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}
pub struct RawLayerReader<R: InnerReaderTrait> {
inner: R,
offset_pos: u64,
}
impl<R: InnerReaderTrait> RawLayerReader<R> {
pub fn new(inner: R) -> Self {
Self {
inner,
offset_pos: 0,
}
}
pub fn reset_position(&mut self) -> io::Result<()> {
self.offset_pos = self.inner.stream_position()?;
Ok(())
}
}
impl<R: InnerReaderTrait> LayerReader<'_, R> for RawLayerReader<R> {
fn into_raw(self: Box<Self>) -> R {
self.inner
}
fn initialize(&mut self) -> Result<(), Error> {
Ok(())
}
}
impl<R: InnerReaderTrait> Seek for RawLayerReader<R> {
fn seek(&mut self, ask_pos: SeekFrom) -> io::Result<u64> {
let e = || io::Error::from(ErrorKind::InvalidInput);
match ask_pos {
SeekFrom::Start(pos) => {
self.inner.seek(SeekFrom::Start(
self.offset_pos.checked_add(pos).ok_or_else(e)?,
))?;
Ok(pos)
}
SeekFrom::Current(_pos) => {
let inner_pos = self.inner.seek(ask_pos)?;
if inner_pos < self.offset_pos {
self.inner.seek(SeekFrom::Start(self.offset_pos))?;
Ok(0)
} else {
Ok(inner_pos.checked_sub(self.offset_pos).ok_or_else(e)?)
}
}
SeekFrom::End(_pos) => {
let inner_pos = self.inner.seek(ask_pos)?;
if inner_pos < self.offset_pos {
self.inner.seek(SeekFrom::Start(self.offset_pos))?;
Ok(0)
} else {
Ok(inner_pos.checked_sub(self.offset_pos).ok_or_else(e)?)
}
}
}
}
}
impl<R: InnerReaderTrait> Read for RawLayerReader<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
self.inner.read(into)
}
}
pub struct RawLayerTruncatedReader<R: Read> {
inner: R,
}
impl<R: Read> RawLayerTruncatedReader<R> {
pub fn new(inner: R) -> Self {
Self { inner }
}
}
impl<R: Read> Read for RawLayerTruncatedReader<R> {
fn read(&mut self, into: &mut [u8]) -> io::Result<usize> {
self.inner.read(into)
}
}
impl<R: Read> LayerTruncatedReader<'_, R> for RawLayerTruncatedReader<R> {}
#[cfg(test)]
mod tests {
use super::*;
use crate::layers::traits::{LayerReader, LayerWriter};
use std::io::{Cursor, Read, Seek, SeekFrom, Write};
static DATA: [u8; 4] = [1, 2, 3, 4];
#[test]
fn basic_ops() {
let buf = Vec::new();
let mut raw_w = Box::new(RawLayerWriter::new(buf));
raw_w.write_all(&DATA).unwrap();
let dest = raw_w.finalize().unwrap();
let buf = Cursor::new(dest);
let mut raw_r = Box::new(RawLayerReader::new(buf));
raw_r.initialize().unwrap();
let mut output = Vec::new();
raw_r.read_to_end(&mut output).unwrap();
assert_eq!(output.as_slice(), &DATA);
raw_r.seek(SeekFrom::Start(2)).unwrap();
let mut output = Vec::new();
raw_r.read_to_end(&mut output).unwrap();
assert_eq!(output.as_slice(), &DATA[2..]);
}
#[test]
fn relative_seek() {
let buf = Vec::new();
let mut raw_w = Box::new(RawLayerWriter::new(buf));
raw_w.write_all(&DATA).unwrap();
let data2 = b"abcdef";
raw_w.write_all(data2).unwrap();
let dest = raw_w.finalize().unwrap();
let buf = Cursor::new(dest);
let mut raw_r = Box::new(RawLayerReader::new(buf));
raw_r.initialize().unwrap();
let mut output = [0u8; 4];
raw_r.read_exact(&mut output).unwrap();
assert_eq!(&output, &DATA);
raw_r.reset_position().unwrap();
assert_eq!(raw_r.stream_position().unwrap(), 0);
assert_eq!(raw_r.seek(SeekFrom::Current(-1)).unwrap(), 0);
assert_eq!(raw_r.seek(SeekFrom::Current(1)).unwrap(), 1);
let mut buf = Vec::new();
raw_r.read_to_end(&mut buf).unwrap();
assert_eq!(buf.as_slice(), b"bcdef");
assert_eq!(raw_r.stream_position().unwrap(), data2.len() as u64);
raw_r.rewind().unwrap();
assert_eq!(raw_r.seek(SeekFrom::Start(3)).unwrap(), 3);
let mut buf = Vec::new();
raw_r.read_to_end(&mut buf).unwrap();
assert_eq!(buf.as_slice(), b"def");
assert_eq!(raw_r.stream_position().unwrap(), data2.len() as u64);
assert_eq!(raw_r.seek(SeekFrom::End(0)).unwrap(), data2.len() as u64);
assert_eq!(raw_r.seek(SeekFrom::End(-6)).unwrap(), 0);
assert_eq!(raw_r.seek(SeekFrom::End(-10)).unwrap(), 0);
assert_eq!(raw_r.seek(SeekFrom::End(-4)).unwrap(), 2);
let mut buf = Vec::new();
raw_r.read_to_end(&mut buf).unwrap();
assert_eq!(buf.as_slice(), b"cdef");
assert_eq!(raw_r.stream_position().unwrap(), data2.len() as u64);
}
#[test]
fn basic_truncated_ops() {
let buf = Vec::new();
let mut raw_w = Box::new(RawLayerWriter::new(buf));
raw_w.write_all(&DATA).unwrap();
let buf = raw_w.finalize().unwrap();
let mut raw_r = Box::new(RawLayerTruncatedReader::new(buf.as_slice()));
let mut output = Vec::new();
raw_r.read_to_end(&mut output).unwrap();
assert_eq!(output.as_slice(), &DATA);
}
#[test]
fn basic_truncated_truncated() {
let buf = Vec::new();
let mut raw_w = Box::new(RawLayerWriter::new(buf));
raw_w.write_all(&DATA).unwrap();
let buf = raw_w.finalize().unwrap();
let stop = buf.len() / 2;
let mut raw_r = Box::new(RawLayerTruncatedReader::new(&buf[..stop]));
let mut output = Vec::new();
raw_r.read_to_end(&mut output).unwrap();
assert_eq!(output.as_slice(), &DATA[..stop]);
}
}