aboutsummaryrefslogtreecommitdiffstats
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
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.
-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>>