diff --git a/maraiah/shp.rs b/maraiah/shp.rs index 5c7df2d..4e72f7a 100644 --- a/maraiah/shp.rs +++ b/maraiah/shp.rs @@ -7,6 +7,7 @@ pub mod fram; pub mod sequ; use crate::{bin::usize_from_u32, err::*}; +use std::io::prelude::*; /// Reads a collection at an offset provided by the Shapes header. pub fn read_coll_at_offset(b: &[u8], @@ -23,14 +24,17 @@ pub fn read_coll_at_offset(b: &[u8], } /// Read all of the collections in a Shapes file. -pub fn read(b: &[u8]) -> ResultS> +pub fn read(fp: &mut impl Read) -> ResultS { - let mut cl = Vec::with_capacity(32); - let mut p = 0; + let mut b = Vec::new(); + fp.read_to_end(&mut b)?; - for _ in 0..32 { + // hush little rustc, don't say a word... + let mut collections: Collections = unsafe {std::mem::uninitialized()}; + + for (i, co) in collections.iter_mut().enumerate() { read_data! { - endian: BIG, buf: b, size: 32, start: p, data { + endian: BIG, buf: &b, size: 32, start: i * 32, data { let lo_ofs = u32[4]; let lo_len = u32[8] usize; let hi_ofs = u32[12]; @@ -38,18 +42,19 @@ pub fn read(b: &[u8]) -> ResultS> } } - let lo = read_coll_at_offset(b, lo_ofs, lo_len)?; - let hi = read_coll_at_offset(b, hi_ofs, hi_len)?; + let lo = read_coll_at_offset(&b, lo_ofs, lo_len)?; + let hi = read_coll_at_offset(&b, hi_ofs, hi_len)?; - cl.push((lo, hi)); - - p += 32; + *co = (lo, hi); } - Ok(cl) + Ok(collections) } /// A collection, which may have low- and high-definition variations, or none. pub type CollectionDef = (Option, Option); +/// The set of all collections in a Shapes file. +pub type Collections = [CollectionDef; 32]; + // EOF diff --git a/tests/shp.rs b/tests/shp.rs index 1e82ff2..ed86a54 100644 --- a/tests/shp.rs +++ b/tests/shp.rs @@ -10,7 +10,9 @@ fn shp_must_not_process() assert!(shp::coll::read(inp).is_err()); assert!(shp::fram::read(inp).is_err()); assert!(shp::sequ::read(inp).is_err()); - assert!(shp::read(inp).is_err()); + + let mut inp = std::io::BufReader::new(&inp[..]); + assert!(shp::read(&mut inp).is_err()); } }