aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2020-11-25 14:14:45 +0100
committerHarald Eilertsen <haraldei@anduin.net>2020-11-25 14:14:45 +0100
commit1b1fca8138485920590d04b04ba699e78a418934 (patch)
treeb36b3a6801993b14da08ac9c75b7da906343f2d0
parent763c77283c1f9cf22475f4b6cd38073a9e96c832 (diff)
downloadcbconv-1b1fca8138485920590d04b04ba699e78a418934.tar.gz
cbconv-1b1fca8138485920590d04b04ba699e78a418934.tar.bz2
cbconv-1b1fca8138485920590d04b04ba699e78a418934.zip
Refactor parsing of ARCH chunks and add docs.
-rw-r--r--src/main.rs54
1 files changed, 38 insertions, 16 deletions
diff --git a/src/main.rs b/src/main.rs
index 52a8d3f..7546df8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -16,6 +16,7 @@
*/
use nom::{
+ branch::alt,
bytes::complete::*,
multi::{count, length_data, many0},
number::complete::*,
@@ -101,7 +102,6 @@ fn bytevec<'a>(data: &'a[u8]) -> IResult<&'a [u8], &'a [u8]> {
/// Version information about the app that created the file.
#[derive(Debug)]
struct PAppVersion<'a> {
- num1: u32,
appname: &'a str,
appversion: &'a str,
appdate: &'a str,
@@ -113,11 +113,10 @@ struct PAppVersion<'a> {
}
fn p_appversion<'a>(data: &'a [u8]) -> IResult<&'a [u8], PAppVersion<'a>> {
- let (r, (num1, appname, appversion, appdate, num2, apparch, num3, appencoding, applocale)) =
- tuple((be_u32, cmstring, cmstring, cmstring, be_u32, cmstring, be_u32, cmstring, cmstring))(&data)?;
+ let (r, (appname, appversion, appdate, num2, apparch, num3, appencoding, applocale)) =
+ tuple((cmstring, cmstring, cmstring, be_u32, cmstring, be_u32, cmstring, cmstring))(&data)?;
Ok((r, PAppVersion {
- num1,
appname,
appversion,
appdate,
@@ -271,20 +270,35 @@ fn root_chunk<'a>(data: &'a [u8]) -> IResult<&'a [u8], ()> {
Ok((rest, ()))
}
-fn arch_chunk<'a>(data: &'a [u8]) -> IResult<&'a [u8], ()> {
- let (rest, (nt, t, x)) = tuple((nodetype, cmstring, be_u16))(data)?;
- println!(" {:?}: {}, {}", nt, t, x);
- match nt {
- NodeType::Container => {
- arch_chunk(rest)?;
- },
- NodeType::Leaf => {
- let (_, nodeval) = node_value(t, rest)?;
- println!(" {:?}", nodeval);
- }
- };
+/**
+ * A container node does not contain any data of it's own, but contains
+ * 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], ()> {
+ let (r, (_, name, num)) = tuple((tag(b"\xff\xff\xff\xfe"), cmstring, be_u16))(data)?;
+ println!(" Container: {}, {}", name, num);
+ Ok((r, ()))
+}
+
+/**
+ * An object node contains serialized structured data.
+ *
+ * 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());
+ Ok((r, ()))
+}
+/**
+ * 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, ()))
}
@@ -302,6 +316,14 @@ fn chunk<'a>(data: &'a [u8]) -> IResult<&'a [u8], ()> {
Ok((rest, ()))
}
+/**
+ * Parse the Cubase project file header.
+ *
+ * A Cubase project file is almost a standard RIFF file, with the exception of an
+ * extra fourcc (NUND) following the global RIFF header. The extra (NUND) fourcc
+ * is _not_ followed by the length of the chunk, but rather immediately followed by
+ * the next chunk.
+ */
fn file_hdr<'a>(data: &'a [u8]) -> IResult<&'a [u8], ()> {
let (rest, (_, len, _)) = tuple((tag("RIFF"), be_u32, tag("NUND")))(data)?;
println!("RIFF: {}, NUND", len);