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,7 +105,8 @@ 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<()> {
while !buf.is_empty() {
let split = if self.open_file.as_ref().is_none_or(|s| !s.contains(offset)) { 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 split = if let Some(split) = self.files.iter().find(|f| f.contains(offset)) {
let file = File::open(&split.inner)?; let file = File::open(&split.inner)?;
@ -117,17 +118,24 @@ impl DiscStream for SplitFileReader {
} else { } else {
self.open_file.as_mut().unwrap() self.open_file.as_mut().unwrap()
}; };
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)] #[cfg(unix)]
{ {
use std::os::unix::fs::FileExt; use std::os::unix::fs::FileExt;
split.inner.read_exact_at(buf, offset) split.inner.read_exact_at(out, file_offset)?;
} }
#[cfg(not(unix))] #[cfg(not(unix))]
{ {
use std::io::{Read, Seek, SeekFrom}; use std::io::{Read, Seek, SeekFrom};
split.inner.seek(SeekFrom::Start(offset - split.begin))?; split.inner.seek(SeekFrom::Start(file_offset))?;
split.inner.read_exact(buf) split.inner.read_exact(out)?
} }
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()) }