use std::io::{Read, Seek, SeekFrom}; use crate::{ object::{Value, parser::FromValue}, unityfs::UnityFS, }; use anyhow::{Result, anyhow, bail}; use serde::Serialize; #[derive(Debug, Serialize)] pub struct StreamingInfo { pub offset: u64, pub path: String, pub size: u32, } impl FromValue for StreamingInfo { fn from_value(v: Value) -> Result { let mut fields = v.as_class("StreamingInfo")?; Ok(StreamingInfo { offset: fields.field("offset")?, size: fields.field("size")?, path: fields.field("path")?, }) } } impl StreamingInfo { pub fn read(&self, fs: &UnityFS) -> Result> { if !self.path.starts_with("archive:") { bail!("StreamingInfo path does not start on archive:") } let nodeinfo = fs .header .nodes() .iter() .find(|n| self.path.ends_with(&n.name)) .ok_or(anyhow!("node with path {:?} not found", self.path))? .to_owned(); let mut buf = Vec::new(); let mut node = fs.read(&nodeinfo)?; node.seek(SeekFrom::Start(self.offset))?; node.take(self.size as u64).read_to_end(&mut buf)?; Ok(buf) } }