aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2020-12-08 23:05:37 +0100
committerHarald Eilertsen <haraldei@anduin.net>2020-12-08 23:05:37 +0100
commit4ae8aacbf6dd87ad70ae8128a866061a75c30f51 (patch)
tree9e8f9ed8f94bade0e49feaec5d535c9a15c71c31
parent1e810adafb91a62241ecaf4dcae76f417fdd545a (diff)
downloadcbconv-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.rs39
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)
}