diff options
author | Harald Eilertsen <haraldei@anduin.net> | 2020-11-26 21:32:00 +0100 |
---|---|---|
committer | Harald Eilertsen <haraldei@anduin.net> | 2020-11-26 21:32:00 +0100 |
commit | 6392584eaadd0acdb8372de969ea84fbbb4fcc70 (patch) | |
tree | 441cab8989288d22531b655b77a773e0ff6f1f40 | |
parent | 7a10cd38214bc6e244d89333ed23d0c36855bb4a (diff) | |
download | cbconv-6392584eaadd0acdb8372de969ea84fbbb4fcc70.tar.gz cbconv-6392584eaadd0acdb8372de969ea84fbbb4fcc70.tar.bz2 cbconv-6392584eaadd0acdb8372de969ea84fbbb4fcc70.zip |
Return NodeValues from ARCH chunks.
-rw-r--r-- | src/main.rs | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/src/main.rs b/src/main.rs index 5a3bf36..8617896 100644 --- a/src/main.rs +++ b/src/main.rs @@ -64,6 +64,7 @@ impl From<u32> for NodeType { #[derive(Debug)] enum NodeValue<'a> { Unknown, + Container(&'a str, u16), //List(Vec<Node<'a>>), Raw(Vec<u32>), Arrangement(PArrangement), @@ -263,7 +264,7 @@ fn fourcc<'a>(data: &'a [u8]) -> IResult<&'a [u8], &'a str> { } /** - * Root chunks allways have the same layout, two length prefixed strings. + * Root chunks always have the same layout, two length prefixed strings. * * These seem to be a mapping between a field name, and the data type the field contains. * The actual data follows in the ARCH chunk following this ROOT chunk. @@ -278,10 +279,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], ()> { +fn container_node<'a>(data: &'a [u8]) -> IResult<&'a [u8], NodeValue> { let (r, (_, name, num)) = tuple((tag(b"\xff\xff\xff\xfe"), cmstring, be_u16))(data)?; - println!(" Container: {}, {}", name, num); - Ok((r, ())) + Ok((r, NodeValue::Container(name, num))) } /** @@ -289,22 +289,19 @@ fn container_node<'a>(data: &'a [u8]) -> IResult<&'a [u8], ()> { * * It has a size, as well as a payload containing the actual serialized data. */ -fn object_node<'a>(data: &'a [u8]) -> IResult<&'a [u8], ()> { - let (r, (_, name, num, payload)) = tuple((tag(b"\xff\xff\xff\xff"), cmstring, be_u16, length_data(be_u32)))(data)?; - println!(" Object: {}, {}, {}", name, num, payload.len()); - +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)?; let (_, nv) = node_value(name, payload)?; - println!(" {:?}", nv); - Ok((r, ())) + Ok((r, 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], ()> { - let (rest, _nodes) = many0(alt((container_node, object_node)))(data)?; - Ok((rest, ())) +fn arch_chunk<'a>(data: &'a [u8]) -> IResult<&'a [u8], Vec<NodeValue>> { + let (rest, nodes) = many0(alt((container_node, object_node)))(data)?; + Ok((rest, nodes)) } struct RiffChunk<'a> { @@ -380,7 +377,20 @@ where println!(" {}: {}", k, v); }, "ARCH" => { - arch_chunk(chunk.payload).finish().map_err(|e| format!("{:?}", e))?; + let (r, nodes) = arch_chunk(chunk.payload).finish().map_err(|e| format!("{:?}", e))?; + assert_eq!(r.len(), 0); + let mut indent = 2; + for node in nodes { + match node { + NodeValue::Container(name, v) => { + println!("{1:0$}{2}, {3}", indent, " ", name, v); + indent += 2; + }, + _ => { + println!("{1:0$}{2:?}", indent, " ", node); + }, + } + } }, _ => { eprintln!("[-] Warning: ignoring unknown chunk \"{}\" of length {} bytes.", |