>> {
let (r, (_, (_, chunks))) =
tuple((
tag(b"RIFF"),
length_value(
payload_len,
tuple((tag(b"NUND"), many0(riff_chunk)))
)
))(&data)?;
Ok((r, chunks))
}
/**
* Get the correct payload length from the root chunk of the file.
*
* Cubase incorrectly specifies the chunk size four bytes less than what it really is, probably due
* to the strange inserted "NUND" tag that don't really belong anywhere. This parser fixes that by
* adding four to the size read from the file.
*/
fn payload_len<'a>(data: &'a [u8]) -> IResult<&'a [u8], u32> {
let (r, len) = be_u32(data)?;
Ok((r, len + 4))
}
pub fn parse_cubase_project(filename: P) -> Result>
where
P: AsRef
{
println!("Reading {}...", filename.as_ref().to_str().ok_or("Invalid file name")?);
let data = std::fs::read(filename)?;
let (rest, chunks) = split_chunks(&data)
.finish()
.map_err(|e| format!("{:?}", e))?;
println!("Rest: {}", rest.len());
let proj = CubaseProject::default();
for chunk in chunks {
println!("{}: {}", chunk.fourcc, chunk.payload.len());
match chunk.fourcc {
"ROOT" => {
let (r, (k, v)) = root_chunk(chunk.payload).finish().map_err(|e| format!("{:?}", e))?;
assert_eq!(r.len(), 0);
println!(" {}: {}", k, v);
},
"ARCH" => {
arch_chunk(chunk.payload).finish().map_err(|e| format!("{:?}", e))?;
},
_ => {
eprintln!("[-] Warning: ignoring unknown chunk \"{}\" of length {} bytes.",
chunk.fourcc,
chunk.payload.len());
}
};
}
Ok(proj)
}
fn main() -> Result<(), Box> {
let filename = std::env::args()
.skip(1)
.next()
.expect("You must give me a file to analyze");
parse_cubase_project(filename)?;
Ok(())
}