diff options
author | Harald Eilertsen <haraldei@anduin.net> | 2020-12-07 22:13:56 +0100 |
---|---|---|
committer | Harald Eilertsen <haraldei@anduin.net> | 2020-12-07 22:13:56 +0100 |
commit | 1e810adafb91a62241ecaf4dcae76f417fdd545a (patch) | |
tree | f3363c38f2c57815fcf4225beeb656cce5ec4bac /src | |
parent | 40a44631b56de9343946fe29b0172184e4efc62b (diff) | |
download | cbconv-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.rs | 30 |
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>> |