aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2020-12-07 22:13:56 +0100
committerHarald Eilertsen <haraldei@anduin.net>2020-12-07 22:13:56 +0100
commit1e810adafb91a62241ecaf4dcae76f417fdd545a (patch)
treef3363c38f2c57815fcf4225beeb656cce5ec4bac /src
parent40a44631b56de9343946fe29b0172184e4efc62b (diff)
downloadcbconv-1e810adafb91a62241ecaf4dcae76f417fdd545a.tar.gz
cbconv-1e810adafb91a62241ecaf4dcae76f417fdd545a.tar.bz2
cbconv-1e810adafb91a62241ecaf4dcae76f417fdd545a.zip
refactor: arch_chunk now takes sub parser as arg.
The sub parser is applied to the chunk payload, and the returned output is the output of the sub parser.
Diffstat (limited to 'src')
-rw-r--r--src/main.rs30
1 files changed, 16 insertions, 14 deletions
diff --git a/src/main.rs b/src/main.rs
index c5f1e46..964635a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -21,12 +21,14 @@ use cubase_project::*;
use nom::{
bytes::complete::*,
- combinator::map,
+ combinator::{map, rest},
+ error::ParseError,
multi::{length_data, length_value, many1},
number::complete::*,
sequence::{preceded, terminated, tuple},
Finish,
IResult,
+ Parser,
};
use std::{
error::Error,
@@ -110,10 +112,14 @@ fn root_chunk<'a>(input: &'a [u8]) -> IResult<&'a [u8], (&str, &str)> {
length_value(be_u32, tuple((cmstring, cmstring))))(input)
}
-fn arch_chunk<'a>(input: &'a [u8]) -> IResult<&'a [u8], &'a [u8]> {
+fn arch_chunk<'a, O, E, F>(subparser: F) -> impl FnMut(&'a [u8]) -> IResult<&'a [u8], O, E>
+where
+ E: ParseError<&'a [u8]>,
+ F: Parser<&'a [u8], O, E>,
+{
preceded(
tag(b"ARCH"),
- length_data(be_u32))(input)
+ length_value(be_u32, subparser))
}
/**
@@ -152,18 +158,18 @@ fn cpr_file<'a>(input: &'a [u8]) -> IResult<&'a [u8], CubaseProject> {
match k {
"Version" => {
- let (r2, v) = version_chunk(r)?;
+ let (r2, v) = arch_chunk(version_chunk)(r)?;
println!("[*] {:?}", v);
proj.app_version = v;
payload = r2;
},
"Arrangement1" => {
- let (r2, a) = arrangement_chunk(r)?;
+ let (r2, a) = arch_chunk(arrangement_chunk)(r)?;
println!("[*] {:?}", a);
payload = r2;
},
_ => {
- let (r2, _) = arch_chunk(r)?;
+ let (r2, _) = arch_chunk(rest)(r)?;
payload = r2;
}
}
@@ -196,9 +202,7 @@ fn cpr_file_header<'a>(input: &'a [u8]) -> IResult<&'a [u8], u32> {
fn version_chunk<'a>(input: &'a [u8]) -> IResult<&'a [u8], PAppVersion> {
- let (r, chunk) = arch_chunk(input)?;
-
- let (odata, c) = container_node(chunk)?;
+ let (odata, c) = container_node(input)?;
println!("[*] {:?}", c);
let (r2, o) = object_node(odata)?;
@@ -208,13 +212,11 @@ fn version_chunk<'a>(input: &'a [u8]) -> IResult<&'a [u8], PAppVersion> {
let (r2, v) = p_app_version(o.payload.unwrap())?;
assert_eq!(r2.len(), 0);
- Ok((r, v))
+ Ok((r2, v))
}
fn arrangement_chunk<'a>(input: &'a [u8]) -> IResult<&'a [u8], PArrangement> {
- let (r, chunk) = arch_chunk(input)?;
-
// It varies a bit how many levels deep the actual PArrangement object is.
//
// File created with Cubase 4.5.x (file version 310?) seems to have this
@@ -224,7 +226,7 @@ fn arrangement_chunk<'a>(input: &'a [u8]) -> IResult<&'a [u8], PArrangement> {
//
// While Cubase version 5.x (file version 400?) seems to have the CmObject
// directly under the GDocument container.
- let (odata, c) = many1(container_node)(chunk)?;
+ let (odata, c) = many1(container_node)(input)?;
println!("[*] {:?}", c);
// This is the actual PArrangeent object
@@ -235,7 +237,7 @@ fn arrangement_chunk<'a>(input: &'a [u8]) -> IResult<&'a [u8], PArrangement> {
let (r2, v) = p_arrangement(o.payload.unwrap())?;
// assert_eq!(r2.len(), 0);
- Ok((r, PArrangement::default()))
+ Ok((r2, PArrangement::default()))
}
pub fn parse_cubase_project<P>(filename: P) -> Result<CubaseProject, Box<dyn Error>>