From c219afaaff57ea626b0fca53fc026371f7d1c0ef Mon Sep 17 00:00:00 2001 From: Luke Street Date: Wed, 20 Aug 2025 08:50:19 -0600 Subject: [PATCH] Fix SplitFileReader at file boundaries --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- nod/src/io/split.rs | 48 ++++++++++++++++++++++++++------------------- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca43204..8efd4ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -557,7 +557,7 @@ checksum = "cf5a574dadd7941adeaa71823ecba5e28331b8313fb2e1c6a5c7e5981ea53ad6" [[package]] name = "nod" -version = "2.0.0-alpha.2" +version = "2.0.0-alpha.3" dependencies = [ "adler", "aes", @@ -591,7 +591,7 @@ dependencies = [ [[package]] name = "nodtool" -version = "2.0.0-alpha.2" +version = "2.0.0-alpha.3" dependencies = [ "argp", "crc32fast", diff --git a/Cargo.toml b/Cargo.toml index 5ee75cd..71d16b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ strip = "debuginfo" codegen-units = 1 [workspace.package] -version = "2.0.0-alpha.2" +version = "2.0.0-alpha.3" edition = "2024" rust-version = "1.85" authors = ["Luke Street "] diff --git a/nod/src/io/split.rs b/nod/src/io/split.rs index 6d07298..d0cb85a 100644 --- a/nod/src/io/split.rs +++ b/nod/src/io/split.rs @@ -105,29 +105,37 @@ impl Clone for SplitFileReader { } impl DiscStream for SplitFileReader { - fn read_exact_at(&mut self, buf: &mut [u8], offset: u64) -> io::Result<()> { - let split = if self.open_file.as_ref().is_none_or(|s| !s.contains(offset)) { - let split = if let Some(split) = self.files.iter().find(|f| f.contains(offset)) { - let file = File::open(&split.inner)?; - Split { inner: file, begin: split.begin, size: split.size } + fn read_exact_at(&mut self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> { + while !buf.is_empty() { + let split = if self.open_file.as_ref().is_none_or(|s| !s.contains(offset)) { + let split = if let Some(split) = self.files.iter().find(|f| f.contains(offset)) { + let file = File::open(&split.inner)?; + Split { inner: file, begin: split.begin, size: split.size } + } else { + return Err(io::Error::from(io::ErrorKind::UnexpectedEof)); + }; + self.open_file.insert(split) } else { - return Err(io::Error::from(io::ErrorKind::UnexpectedEof)); + self.open_file.as_mut().unwrap() }; - self.open_file.insert(split) - } else { - self.open_file.as_mut().unwrap() - }; - #[cfg(unix)] - { - use std::os::unix::fs::FileExt; - split.inner.read_exact_at(buf, offset) - } - #[cfg(not(unix))] - { - use std::io::{Read, Seek, SeekFrom}; - split.inner.seek(SeekFrom::Start(offset - split.begin))?; - split.inner.read_exact(buf) + let file_offset = offset - split.begin; + let len = (split.size - file_offset).min(buf.len() as u64) as usize; + let (out, remain) = buf.split_at_mut(len); + #[cfg(unix)] + { + use std::os::unix::fs::FileExt; + split.inner.read_exact_at(out, file_offset)?; + } + #[cfg(not(unix))] + { + use std::io::{Read, Seek, SeekFrom}; + split.inner.seek(SeekFrom::Start(file_offset))?; + split.inner.read_exact(out)? + } + buf = remain; + offset += len as u64; } + Ok(()) } fn stream_len(&mut self) -> io::Result { Ok(self.len()) }