aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
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/main.rs
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/main.rs')
-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>>