aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main.rs43
1 files changed, 24 insertions, 19 deletions
diff --git a/src/main.rs b/src/main.rs
index 414f1c0..5a3bf36 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -26,7 +26,6 @@ use nom::{
number::complete::*,
sequence::tuple,
Finish,
- InputTake,
IResult,
};
use std::{
@@ -263,10 +262,14 @@ fn fourcc<'a>(data: &'a [u8]) -> IResult<&'a [u8], &'a str> {
Ok((rest, std::str::from_utf8(tag).unwrap()))
}
-fn root_chunk<'a>(data: &'a [u8]) -> IResult<&'a [u8], ()> {
- let (rest, (key, val)) = tuple((cmstring, cmstring))(data)?;
- println!(" {}: {}", key, val);
- Ok((rest, ()))
+/**
+ * Root chunks allways 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.
+ */
+fn root_chunk<'a>(data: &'a [u8]) -> IResult<&'a [u8], (&str, &str)> {
+ tuple((cmstring, cmstring))(data)
}
@@ -304,20 +307,6 @@ fn arch_chunk<'a>(data: &'a [u8]) -> IResult<&'a [u8], ()> {
Ok((rest, ()))
}
-fn chunk<'a>(data: &'a [u8]) -> IResult<&'a [u8], ()> {
- let (rest, (tag, payload)) = tuple((fourcc, length_data(be_u32)))(data)?;
-
- println!(" {}: {}", tag, payload.len());
-
- match tag {
- "ROOT" => root_chunk(payload)?,
- "ARCH" => arch_chunk(payload)?,
- &_ => (payload, ())
- };
-
- Ok((rest, ()))
-}
-
struct RiffChunk<'a> {
fourcc: &'a str,
payload: &'a [u8],
@@ -383,6 +372,22 @@ where
for chunk in chunks {
println!("{}: {}", chunk.fourcc, chunk.payload.len());
+
+ match chunk.fourcc {
+ "ROOT" => {
+ let (r, (k, v)) = root_chunk(chunk.payload).finish().map_err(|e| format!("{:?}", e))?;
+ assert_eq!(r.len(), 0);
+ println!(" {}: {}", k, v);
+ },
+ "ARCH" => {
+ arch_chunk(chunk.payload).finish().map_err(|e| format!("{:?}", e))?;
+ },
+ _ => {
+ eprintln!("[-] Warning: ignoring unknown chunk \"{}\" of length {} bytes.",
+ chunk.fourcc,
+ chunk.payload.len());
+ }
+ };
}
Ok(proj)