diff --git a/src/cue_sheet/mod.rs b/src/cue_sheet/mod.rs index c625757..c23852d 100644 --- a/src/cue_sheet/mod.rs +++ b/src/cue_sheet/mod.rs @@ -1,51 +1,30 @@ //! Module to extract the cue sheet from the NRG metadata. +use std::io::Write; +use std::fs::File; + use ::error::NrgError; use ::metadata::metadata::NrgMetadata; +use ::metadata::cuex::NrgCuexTrack; -pub fn write_cue_sheet(image_name: &String, nm: &NrgMetadata) +/// Writes the cue sheet for `image_name` into a file. +/// +/// `metadata` is the metadata extracted from `image_name` by nrgrip::metadata. +/// The output file's name is derived from `image_name`. +pub fn write_cue_sheet(image_name: &String, metadata: &NrgMetadata) -> Result<(), NrgError> { - if nm.cuex_chunk.is_none() { + if metadata.cuex_chunk.is_none() { return Err(NrgError::NoNrgCue); } - let cuex_tracks = &nm.cuex_chunk.as_ref().unwrap().tracks; + let cuex_tracks = &metadata.cuex_chunk.as_ref().unwrap().tracks; - let file_name = try!(make_cue_sheet_name(image_name)); + let file_name = make_cue_sheet_name(image_name); + let mut fd = try!(File::create(file_name)); - println!("FILE \"{}\" RAW", image_name); - - let mut index0_pos = -1; - for track in cuex_tracks { - // Ignore lead-in and lead-out areas - if track.track_number == 0 || track.track_number == 0xAA { - continue; - } - - // Ignore negative positions - if track.position_sectors < 0 { - continue; - } - - // Store/skip index0 - if track.index_number == 0 { - index0_pos = track.position_sectors; - continue; - } - - // Write track info - println!(" TRACK {:02} AUDIO", track.track_number); - - // Write index0 if we stored it and it's before the current index's - // position (i.e., it indicates a pre-gap) - if index0_pos >= 0 && index0_pos < track.position_sectors { - try!(write_cue_index(0, index0_pos)); - index0_pos = -1; - } - - // Write current index - try!(write_cue_index(track.index_number, track.position_sectors)); - } + // Write cue sheet + try!(writeln!(fd, "FILE \"{}\" RAW", image_name)); + try!(write_cue_tracks(&mut fd, cuex_tracks)); Ok(()) } @@ -56,12 +35,66 @@ pub fn write_cue_sheet(image_name: &String, nm: &NrgMetadata) /// If `image_name`'s extension is `.nrg` (case-insensitive), the cue sheet's /// name will be the same as `image_name` with a `.cue` extension instead of /// `.nrg`. Otherwise, the cue sheet's name will be `image_name.cue`. -fn make_cue_sheet_name(image_name: &String) -> Result { - Ok("image.cue".to_string()) +fn make_cue_sheet_name(image_name: &String) -> String { + let mut name = image_name.clone(); + if name.to_lowercase().ends_with(".nrg") { + let newlen = name.len() - 4; + name.truncate(newlen); + } + name.push_str(".cue"); + name } -fn write_cue_index(index: u8, position_sectors: i32) +/// Writes a list of cue tracks to `fd`. +fn write_cue_tracks(fd: &mut File, cuex_tracks: &Vec) + -> Result<(), NrgError> { + let mut index0_pos = -1; // position of the last index #0 encountered + for track in cuex_tracks { + try!(write_cue_track(fd, track, &mut index0_pos)); + } + Ok(()) +} + + +/// Writes a cue track's info to `fd`. +/// +/// `index0_pos` should be negative when this function is first called. +fn write_cue_track(fd: &mut File, track: &NrgCuexTrack, index0_pos: &mut i32) + -> Result<(), NrgError> { + // Ignore lead-in and lead-out areas + if track.track_number == 0 || track.track_number == 0xAA { + return Ok(()); + } + + // Ignore negative positions + if track.position_sectors < 0 { + return Ok(()); + } + + // Store/skip index0 + if track.index_number == 0 { + *index0_pos = track.position_sectors; + return Ok(()); + } + + // Write track info + try!(writeln!(fd, " TRACK {:02} AUDIO", track.track_number)); + + // Write index0 if we stored it and it's before the current index's + // position (i.e., it indicates a pre-gap) + if *index0_pos >= 0 && *index0_pos < track.position_sectors { + try!(write_cue_index(fd, 0, *index0_pos)); + *index0_pos = -1; + } + + // Write current index + write_cue_index(fd, track.index_number, track.position_sectors) +} + + +/// Writes a cue index's info to `fd`. +fn write_cue_index(fd: &mut File, index: u8, position_sectors: i32) -> Result<(), NrgError> { assert!(position_sectors >= 0); @@ -71,8 +104,8 @@ fn write_cue_index(index: u8, position_sectors: i32) let minutes = seconds / 60; seconds %= 60; - println!(" INDEX {:02} {:02}:{:02}:{:02}", - index, minutes, seconds, remaining_sectors); + try!(writeln!(fd, " INDEX {:02} {:02}:{:02}:{:02}", + index, minutes, seconds, remaining_sectors)); Ok(()) } diff --git a/src/metadata/mod.rs b/src/metadata/mod.rs index 19403b7..9922dc5 100644 --- a/src/metadata/mod.rs +++ b/src/metadata/mod.rs @@ -6,7 +6,7 @@ use std::io::{Seek, SeekFrom}; use ::error::NrgError; pub mod metadata; -mod cuex; +pub mod cuex; mod daox; mod sinf; mod mtyp;