From d116a1df8fe14edc8de157bf8088244261fca30f Mon Sep 17 00:00:00 2001 From: metamuffin Date: Fri, 14 Feb 2025 20:10:00 +0100 Subject: trying to read objects --- src/unityfs.rs | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'src/unityfs.rs') diff --git a/src/unityfs.rs b/src/unityfs.rs index d7659b8..bd0c7bb 100644 --- a/src/unityfs.rs +++ b/src/unityfs.rs @@ -1,7 +1,7 @@ use crate::helper::{AlignExt, ReadExt}; use anyhow::{Result, anyhow, bail}; use log::{debug, info, trace}; -use std::io::{Cursor, ErrorKind, Read, Seek, SeekFrom, Take}; +use std::io::{Cursor, Error, ErrorKind, Read, Seek, SeekFrom}; pub struct UnityFS { nodes: Vec, @@ -23,7 +23,9 @@ struct BlockInfo { } pub struct NodeReader<'a, T> { - inner: Take<&'a mut BlocksReader>, + inner: &'a mut BlocksReader, + position: u64, + offset: u64, size: u64, } @@ -131,7 +133,9 @@ impl UnityFS { self.reader.seek(SeekFrom::Start(node.offset))?; Ok(NodeReader { size: node.size, - inner: (&mut self.reader).take(node.size), + offset: node.offset, + position: 0, + inner: &mut self.reader, }) } } @@ -213,10 +217,14 @@ impl Seek for BlocksReader { let block_off = pos - decomp_off; debug!("target is block={i} offset={block_off}"); - debug!("seek comp to {comp_off}"); self.inner.seek(SeekFrom::Start(comp_off))?; - self.nblock_index = i; - self.load_next_block()?; + if self.nblock_index == i + 1 { + debug!("intra-block seek") + } else { + debug!("seek comp to {comp_off}"); + self.nblock_index = i; + self.load_next_block()?; + } self.cblock_off = block_off as usize; Ok(pos) @@ -225,7 +233,11 @@ impl Seek for BlocksReader { impl Read for NodeReader<'_, T> { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - self.inner.read(buf) + let bytes_left = self.size - self.position; + let end = buf.len().min(bytes_left as usize); + let size = self.inner.read(&mut buf[..end])?; + self.position += size as u64; + Ok(size) } } impl Seek for NodeReader<'_, T> { @@ -237,11 +249,19 @@ impl Seek for NodeReader<'_, T> { } Ok(self.stream_position()?) } + SeekFrom::Start(n) => { + debug!("seek node to {n} (off={})", self.offset); + if n > self.size { + return Err(Error::new(ErrorKind::NotSeekable, "seek out of bounds")); + } + self.position = n; + self.inner.seek(SeekFrom::Start(self.offset + n)) + } _ => unimplemented!(), } } fn stream_position(&mut self) -> std::io::Result { - Ok(self.size - self.inner.limit()) + Ok(self.position) } } -- cgit v1.2.3-70-g09d2