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 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/utils/mod.rs | 5 +++++ src/utils/read.rs | 23 ++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 src/utils/cursor.rs create mode 100644 src/utils/mod.rs create mode 100644 src/utils/read.rs (limited to 'src/utils') 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) + } +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 0000000..99a4e13 --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1,5 @@ +mod cursor; +mod read; + +pub use cursor::IoCursor; +pub use read::ReadUtils; diff --git a/src/utils/read.rs b/src/utils/read.rs new file mode 100644 index 0000000..185758a --- /dev/null +++ b/src/utils/read.rs @@ -0,0 +1,23 @@ +use std::io::{Read, Result as IOResult}; + +pub trait ReadUtils { + fn read_arr(&mut self) -> IOResult<[u8; S]>; + + fn read_vec(&mut self, size: usize) -> IOResult>; +} + +impl ReadUtils for R { + #[inline] + fn read_arr(&mut self) -> Result<[u8; S], std::io::Error> { + let mut arr = [0; S]; + self.read(&mut arr)?; + Ok(arr) + } + + #[inline] + fn read_vec(&mut self, size: usize) -> Result, std::io::Error> { + let mut vec = vec![0; size]; + self.read(&mut vec)?; + Ok(vec) + } +} -- cgit v1.2.3