From b77106b526930990f51a306fd70cd00856f481e8 Mon Sep 17 00:00:00 2001 From: Igor Tolmachev Date: Fri, 12 Jul 2024 21:40:08 +0900 Subject: Add zstd compression and fix bugs --- src/utils/cursor.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/utils/cursor.rs (limited to 'src/utils/cursor.rs') diff --git a/src/utils/cursor.rs b/src/utils/cursor.rs new file mode 100644 index 0000000..c41270a --- /dev/null +++ b/src/utils/cursor.rs @@ -0,0 +1,60 @@ +use std::io::{Error, ErrorKind, Read, Result, Seek, SeekFrom, Write}; + +pub struct IoCursor { + io: Io, + cursor: u64, + bounds: (u64, u64), +} + +impl IoCursor { + pub fn new(mut io: Io, start: u64, end: u64) -> Result { + let cursor = io.seek(SeekFrom::Start(start))?; + Ok(Self { + io, + cursor, + bounds: (cursor, end), + }) + } +} + +impl Read for IoCursor { + fn read(&mut self, buf: &mut [u8]) -> Result { + let upper = buf.len().min((self.bounds.1 - self.cursor) as usize); + let bytes = self.io.read(&mut buf[..upper])?; + self.cursor += bytes as u64; + Ok(bytes) + } +} + +impl Write for IoCursor { + fn write(&mut self, buf: &[u8]) -> Result { + let upper = buf.len().min((self.bounds.1 - self.cursor) as usize); + let bytes = self.io.write(&buf[..upper])?; + self.cursor += bytes as u64; + Ok(bytes) + } + + #[inline] + fn flush(&mut self) -> Result<()> { + self.io.flush() + } +} + +impl Seek for IoCursor { + fn seek(&mut self, pos: SeekFrom) -> Result { + self.cursor = match pos { + SeekFrom::Start(0) => return Ok(self.cursor - self.bounds.0), + SeekFrom::Start(offset) => self.bounds.0.checked_add(offset), + SeekFrom::End(offset) => self.bounds.1.checked_add_signed(offset), + SeekFrom::Current(offset) => self.cursor.checked_add_signed(offset), + } + .filter(|v| *v >= self.bounds.0) + .ok_or(Error::new( + ErrorKind::InvalidInput, + "Invalid seek to a negative or overflowing position", + ))? + .min(self.bounds.1); + + Ok(self.io.seek(SeekFrom::Start(self.cursor))? - self.bounds.0) + } +} -- cgit v1.2.3