From 1e810adafb91a62241ecaf4dcae76f417fdd545a Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Mon, 7 Dec 2020 22:13:56 +0100 Subject: 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. --- src/main.rs | 30 ++++++++++++++++-------------- 1 file 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

(filename: P) -> Result> -- cgit v1.2.3