From 0a11e6d5e64121b94f4e0c8637a4ceab80804623 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Thu, 26 Nov 2020 22:32:47 +0100 Subject: Rename NodeType to Node, and give it some data. This way I can pass the node name and the mysterious number up to the parent parsers. --- src/main.rs | 55 ++++++++++++++++++++++--------------------------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8617896..bf5c2d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,7 +29,6 @@ use nom::{ IResult, }; use std::{ - convert::From, error::Error, path::Path, }; @@ -45,26 +44,23 @@ fn cmstring(data: &[u8]) -> IResult<&[u8], &str> { Ok((r, std::str::from_utf8(&s[0..end]).unwrap())) } -#[derive(Debug, PartialEq)] -enum NodeType { - Container, - Leaf, -} - -impl From for NodeType { - fn from(v: u32) -> NodeType { - match v { - 0xffffffff => NodeType::Leaf, - 0xfffffffe => NodeType::Container, - _ => panic!(format!("Unexpected node type: {:#x} found.", v)), - } - } +/** + * The data chunks in the file is split into what seems like a structure of containers and leaf + * nodes. Where the containers don't contain any data of themselves, but leaf nodes may contain + * data and also be a container for further sub nodes. + * + * Each node regardless of type has a name, and a 16 bit number which meaning I'm not sure about. + * Leaf nodes also has a data payload prefixed by a 32 bit length (be). + */ +#[derive(Debug)] +enum Node<'a> { + Container(&'a str, u16), + Leaf(&'a str, u16, NodeValue<'a>), } #[derive(Debug)] enum NodeValue<'a> { Unknown, - Container(&'a str, u16), //List(Vec>), Raw(Vec), Arrangement(PArrangement), @@ -85,14 +81,6 @@ enum NodeValue<'a> { Version(PAppVersion<'a>), } -#[derive(Debug)] -struct Node<'a> { - nodetype: NodeType, - nodeclass: &'a str, - num: u16, - value: Box>, -} - /// A vector of 32bit words preceeded by a 16 bit count. fn counted_vec(data: &[u8]) -> IResult<&[u8], Vec> { let (r, len) = be_u16(data)?; @@ -279,9 +267,9 @@ fn root_chunk<'a>(data: &'a [u8]) -> IResult<&'a [u8], (&str, &str)> { * one or more sub elements. These can be either other containers, or * object/leaf nodes. */ -fn container_node<'a>(data: &'a [u8]) -> IResult<&'a [u8], NodeValue> { +fn container_node<'a>(data: &'a [u8]) -> IResult<&'a [u8], Node> { let (r, (_, name, num)) = tuple((tag(b"\xff\xff\xff\xfe"), cmstring, be_u16))(data)?; - Ok((r, NodeValue::Container(name, num))) + Ok((r, Node::Container(name, num))) } /** @@ -289,17 +277,17 @@ fn container_node<'a>(data: &'a [u8]) -> IResult<&'a [u8], NodeValue> { * * It has a size, as well as a payload containing the actual serialized data. */ -fn object_node<'a>(data: &'a [u8]) -> IResult<&'a [u8], NodeValue> { - let (r, (_, name, _num, payload)) = tuple((tag(b"\xff\xff\xff\xff"), cmstring, be_u16, length_data(be_u32)))(data)?; +fn object_node<'a>(data: &'a [u8]) -> IResult<&'a [u8], Node> { + let (r, (_, name, num, payload)) = tuple((tag(b"\xff\xff\xff\xff"), cmstring, be_u16, length_data(be_u32)))(data)?; let (_, nv) = node_value(name, payload)?; - Ok((r, nv)) + Ok((r, Node::Leaf(name, num, nv))) } /** * ARCH chunks contains one or more structured data elements that can be * either container nodes or object/leaf nodes.. */ -fn arch_chunk<'a>(data: &'a [u8]) -> IResult<&'a [u8], Vec> { +fn arch_chunk<'a>(data: &'a [u8]) -> IResult<&'a [u8], Vec> { let (rest, nodes) = many0(alt((container_node, object_node)))(data)?; Ok((rest, nodes)) } @@ -382,12 +370,13 @@ where let mut indent = 2; for node in nodes { match node { - NodeValue::Container(name, v) => { + Node::Container(name, v) => { println!("{1:0$}{2}, {3}", indent, " ", name, v); indent += 2; }, - _ => { - println!("{1:0$}{2:?}", indent, " ", node); + Node::Leaf(name, v, nv) => { + println!("{1:0$}{2}, {3}", indent, " ", name, v); + println!("{1:0$}{2:?}", indent + 2, " ", nv); }, } } -- cgit v1.2.3