aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2020-11-26 21:32:00 +0100
committerHarald Eilertsen <haraldei@anduin.net>2020-11-26 21:32:00 +0100
commit6392584eaadd0acdb8372de969ea84fbbb4fcc70 (patch)
tree441cab8989288d22531b655b77a773e0ff6f1f40
parent7a10cd38214bc6e244d89333ed23d0c36855bb4a (diff)
downloadcbconv-6392584eaadd0acdb8372de969ea84fbbb4fcc70.tar.gz
cbconv-6392584eaadd0acdb8372de969ea84fbbb4fcc70.tar.bz2
cbconv-6392584eaadd0acdb8372de969ea84fbbb4fcc70.zip
Return NodeValues from ARCH chunks.
-rw-r--r--src/main.rs38
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.",