Fix SplitFileReader at file boundaries

This commit is contained in:
Luke Street 2025-08-20 08:50:19 -06:00
parent e5c1f60121
commit c219afaaff
3 changed files with 31 additions and 23 deletions

4
Cargo.lock generated
View File

@ -557,7 +557,7 @@ checksum = "cf5a574dadd7941adeaa71823ecba5e28331b8313fb2e1c6a5c7e5981ea53ad6"
[[package]] [[package]]
name = "nod" name = "nod"
version = "2.0.0-alpha.2" version = "2.0.0-alpha.3"
dependencies = [ dependencies = [
"adler", "adler",
"aes", "aes",
@ -591,7 +591,7 @@ dependencies = [
[[package]] [[package]]
name = "nodtool" name = "nodtool"
version = "2.0.0-alpha.2" version = "2.0.0-alpha.3"
dependencies = [ dependencies = [
"argp", "argp",
"crc32fast", "crc32fast",

View File

@ -12,7 +12,7 @@ strip = "debuginfo"
codegen-units = 1 codegen-units = 1
[workspace.package] [workspace.package]
version = "2.0.0-alpha.2" version = "2.0.0-alpha.3"
edition = "2024" edition = "2024"
rust-version = "1.85" rust-version = "1.85"
authors = ["Luke Street <luke@street.dev>"] authors = ["Luke Street <luke@street.dev>"]

View File

@ -105,29 +105,37 @@ impl Clone for SplitFileReader {
} }
impl DiscStream for SplitFileReader { impl DiscStream for SplitFileReader {
fn read_exact_at(&mut self, buf: &mut [u8], offset: u64) -> io::Result<()> { fn read_exact_at(&mut self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> {
let split = if self.open_file.as_ref().is_none_or(|s| !s.contains(offset)) { while !buf.is_empty() {
let split = if let Some(split) = self.files.iter().find(|f| f.contains(offset)) { let split = if self.open_file.as_ref().is_none_or(|s| !s.contains(offset)) {
let file = File::open(&split.inner)?; let split = if let Some(split) = self.files.iter().find(|f| f.contains(offset)) {
Split { inner: file, begin: split.begin, size: split.size } 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 { } else {
return Err(io::Error::from(io::ErrorKind::UnexpectedEof)); self.open_file.as_mut().unwrap()
}; };
self.open_file.insert(split) let file_offset = offset - split.begin;
} else { let len = (split.size - file_offset).min(buf.len() as u64) as usize;
self.open_file.as_mut().unwrap() let (out, remain) = buf.split_at_mut(len);
}; #[cfg(unix)]
#[cfg(unix)] {
{ use std::os::unix::fs::FileExt;
use std::os::unix::fs::FileExt; split.inner.read_exact_at(out, file_offset)?;
split.inner.read_exact_at(buf, offset) }
} #[cfg(not(unix))]
#[cfg(not(unix))] {
{ use std::io::{Read, Seek, SeekFrom};
use std::io::{Read, Seek, SeekFrom}; split.inner.seek(SeekFrom::Start(file_offset))?;
split.inner.seek(SeekFrom::Start(offset - split.begin))?; split.inner.read_exact(out)?
split.inner.read_exact(buf) }
buf = remain;
offset += len as u64;
} }
Ok(())
} }
fn stream_len(&mut self) -> io::Result<u64> { Ok(self.len()) } fn stream_len(&mut self) -> io::Result<u64> { Ok(self.len()) }