diff --git a/src/lib.rs b/src/lib.rs index 7388df6..220f59e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,15 +3,15 @@ extern crate iota; use std::convert::TryInto; use std::io::Cursor; -use std::mem::size_of; -use byteorder::{ByteOrder, LittleEndian, ReadBytesExt}; +use byteorder::{LittleEndian, ReadBytesExt}; pub mod names; pub mod zero_copy; pub use crate::names::consts; pub use crate::names::types; +pub use zero_copy::Error; #[derive (Debug, Default)] pub struct Mesh { @@ -47,36 +47,20 @@ pub struct Model <'a> { vertexarrays: Vec , } -#[derive (Debug)] -pub enum ModelLoadErr { - BadMagic, - UnsupportedVersion, - ParseMeshFailed, - ParseVertexArrayFailed, -} - -use crate::names::MAGIC; - impl Header { - pub fn from_slice (input: &[u8]) -> Result { - if &input [0..MAGIC.len ()] != MAGIC { - return Err (ModelLoadErr::BadMagic); - } - let input = &input [MAGIC.len ()..]; - + pub fn from_zc (zc: &zero_copy::Model) -> Header { let mut header = Header::default (); - LittleEndian::read_u32_into (&input [0..header.fields.len () * size_of:: ()], &mut header.fields); - if header.fields [consts::VERSION] != 2 { - return Err (ModelLoadErr::UnsupportedVersion); + for (i, value) in zc.header_fields ().enumerate () { + header.fields [i] = value; } - Ok (header) + header } } impl Mesh { - pub fn from_slice (input: &[u8]) -> Result { + pub fn from_slice (input: &[u8]) -> Result { let mut mesh = Mesh::default (); let mut rdr = Cursor::new (input); @@ -89,7 +73,7 @@ impl Mesh { &mut mesh.first_triangle, &mut mesh.num_triangles, ].iter_mut () { - **field = rdr.read_u32:: ().map_err (|_| ModelLoadErr::ParseMeshFailed)?; + **field = rdr.read_u32:: ().map_err (|_| Error::ParseMeshFailed)?; } Ok (mesh) @@ -97,7 +81,7 @@ impl Mesh { } impl VertexArray { - pub fn from_slice (input: &[u8]) -> Result { + pub fn from_slice (input: &[u8]) -> Result { let mut va = VertexArray::default (); let mut rdr = Cursor::new (input); @@ -109,7 +93,7 @@ impl VertexArray { &mut va.va_size, &mut va.va_offset, ].iter_mut () { - **field = rdr.read_u32:: ().map_err (|_| ModelLoadErr::ParseVertexArrayFailed)?; + **field = rdr.read_u32:: ().map_err (|_| Error::ParseVertexArrayFailed)?; } Ok (va) @@ -117,8 +101,10 @@ impl VertexArray { } impl <'a> Model <'a> { - pub fn from_slice (data: &'a [u8]) -> Result , ModelLoadErr> { - let header = Header::from_slice (data)?; + pub fn from_slice (data: &'a [u8]) -> Result , Error> { + let zc = zero_copy::Model::get_root (data)?; + + let header = Header::from_zc (&zc); let text = { let offset: usize = header.fields [consts::OFS_TEXT].try_into ().unwrap (); diff --git a/src/zero_copy.rs b/src/zero_copy.rs index a548adb..2722cb8 100644 --- a/src/zero_copy.rs +++ b/src/zero_copy.rs @@ -17,6 +17,11 @@ pub struct Mesh <'data> { ofs: usize, } +pub struct HeaderFields <'data> { + model: &'data Model <'data>, + idx: usize, +} + pub struct VertexArrays <'data> { model: &'data Model <'data>, idx: usize, @@ -49,6 +54,21 @@ fn usize_from (x: u32) -> usize { usize::try_from (x).unwrap () } +impl <'data> Iterator for HeaderFields <'data> { + type Item = u32; + + fn next (&mut self) -> Option { + if self.idx >= HEADER_FIELD_COUNT { + return None; + } + + let result = self.model.header_field (self.idx); + + self.idx += 1; + Some (result) + } +} + impl <'data> Iterator for VertexArrays <'data> { type Item = VertexArray <'data>; @@ -128,6 +148,13 @@ impl <'data> Model <'data> { } } + pub fn header_fields (&self) -> HeaderFields { + HeaderFields { + model: self, + idx: 0, + } + } + pub fn vertexarrays (&self) -> VertexArrays { VertexArrays { model: self,