diff options
author | Harald Eilertsen <haraldei@anduin.net> | 2020-12-08 23:05:37 +0100 |
---|---|---|
committer | Harald Eilertsen <haraldei@anduin.net> | 2020-12-08 23:05:37 +0100 |
commit | 4ae8aacbf6dd87ad70ae8128a866061a75c30f51 (patch) | |
tree | 9e8f9ed8f94bade0e49feaec5d535c9a15c71c31 | |
parent | 1e810adafb91a62241ecaf4dcae76f417fdd545a (diff) | |
download | cbconv-4ae8aacbf6dd87ad70ae8128a866061a75c30f51.tar.gz cbconv-4ae8aacbf6dd87ad70ae8128a866061a75c30f51.tar.bz2 cbconv-4ae8aacbf6dd87ad70ae8128a866061a75c30f51.zip |
refactor version_chunk parser.
Make it explicit what container and object tags we're expecting. Even
though we're not using that information, the parser will expect all
elements to be in place, and fail if they are not.
-rw-r--r-- | src/main.rs | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/src/main.rs b/src/main.rs index 964635a..a694739 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,8 +20,9 @@ mod cubase_project; use cubase_project::*; use nom::{ + branch::alt, bytes::complete::*, - combinator::{map, rest}, + combinator::{map, rest, value}, error::ParseError, multi::{length_data, length_value, many1}, number::complete::*, @@ -47,6 +48,18 @@ fn cmstring(input: &[u8]) -> IResult<&[u8], &str> { map(strdata, |s| std::str::from_utf8(s).unwrap())(input) } +fn cmtag<'a>(t: &'a str) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], (NodeType, u16)> { + map( + tuple(( + node_type, + length_value( + be_u32, tuple((tag(t), tag(b"\0"))) + ), + be_u16) + ), + |(nt, (_, _), v)| (nt, 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 @@ -55,13 +68,21 @@ fn cmstring(input: &[u8]) -> IResult<&[u8], &str> { * 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)] +#[derive(Clone, Debug)] enum NodeType { Container, Object, } +fn node_type<'a>(input: &'a [u8]) -> IResult<&'a [u8], NodeType> { + alt(( + value(NodeType::Container, tag(b"\xff\xff\xff\xfe")), + value(NodeType::Object, tag(b"\xff\xff\xff\xff")) + ))(input) +} + + #[derive(Debug)] struct Node<'a> { node_type: NodeType, @@ -202,17 +223,9 @@ fn cpr_file_header<'a>(input: &'a [u8]) -> IResult<&'a [u8], u32> { fn version_chunk<'a>(input: &'a [u8]) -> IResult<&'a [u8], PAppVersion> { - let (odata, c) = container_node(input)?; - println!("[*] {:?}", c); - - let (r2, o) = object_node(odata)?; - println!("[*] {:?}", o); - assert_eq!(r2.len(), 0); - - let (r2, v) = p_app_version(o.payload.unwrap())?; - assert_eq!(r2.len(), 0); - - Ok((r2, v)) + preceded( + tuple((cmtag("CmObject"), cmtag("PAppVersion"))), + length_value(be_u32, p_app_version))(input) } |