Improve psxcdread
This commit is contained in:
parent
7dd98d5762
commit
4cb6e05e62
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "cdtypes"
|
||||
version = "0.7.1"
|
||||
version = "0.7.2"
|
||||
edition = "2021"
|
||||
|
||||
[profile.release]
|
||||
|
|
|
@ -2,7 +2,7 @@ pub mod reader;
|
|||
pub mod sector;
|
||||
|
||||
use sector::*;
|
||||
use reader::Reader as CDReader;
|
||||
use reader::{UnknownSectorBehavior, Reader as CDReader};
|
||||
use super::{Error, types as types};
|
||||
use types::{cue::{Specifier, DataType, DataTypeEnd}, lsb_msb::ReadWriteEndian, pvd::PrimaryVolumeDescriptor, sector::{Mode2Form1, SubHeaderForm}};
|
||||
use std::fs::File;
|
||||
|
@ -191,7 +191,7 @@ pub struct CD {
|
|||
}
|
||||
|
||||
impl CD {
|
||||
pub fn from_file(file: File, specifier: Option<Vec<Specifier>>) -> Result<CD, Error> {
|
||||
pub fn from_file(file: File, specifier: Option<Vec<Specifier>>, unk_sector_behav: UnknownSectorBehavior) -> Result<CD, Error> {
|
||||
let data_type_ends = {
|
||||
if let Some(specifier) = specifier {
|
||||
DataTypeEnd::parse_cue_specifier(specifier)?
|
||||
|
@ -201,7 +201,7 @@ impl CD {
|
|||
Vec::new()
|
||||
}
|
||||
};
|
||||
let reader = CDReader::new(file, &data_type_ends)?;
|
||||
let reader = CDReader::new(file, &data_type_ends, unk_sector_behav)?;
|
||||
let mut sectors = Vec::new();
|
||||
|
||||
for sector in reader {
|
||||
|
|
|
@ -2,17 +2,27 @@ use super::{sector::Sector, types::time::Time};
|
|||
use super::super::{Error, types::{cue::{DataType, DataTypeEnd}, sector::*}};
|
||||
use std::io::Read;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum UnknownSectorBehavior {
|
||||
CauseError,
|
||||
CauseWarningAddEmpty,
|
||||
TreatAsAudio,
|
||||
}
|
||||
|
||||
pub struct Reader<'a> {
|
||||
file: std::fs::File,
|
||||
data_type_guide: &'a Vec<DataTypeEnd>,
|
||||
lba: usize,
|
||||
unk_sector_behav: UnknownSectorBehavior,
|
||||
active: bool
|
||||
}
|
||||
|
||||
impl<'a> Reader<'a> {
|
||||
pub fn new(file: std::fs::File, data_type_guide: &'a Vec<DataTypeEnd>) -> Result<Reader, Error> {
|
||||
const CD_PREGAP_SECTORS:usize = Time::cd_pregap().as_sectors();
|
||||
|
||||
pub fn new(file: std::fs::File, data_type_guide: &'a Vec<DataTypeEnd>, unk_sector_behav: UnknownSectorBehavior) -> Result<Reader, Error> {
|
||||
Ok(Reader{
|
||||
file, data_type_guide, lba: Time::cd_pregap().as_sectors(), active: true
|
||||
file, data_type_guide, unk_sector_behav, lba: Self::CD_PREGAP_SECTORS, active: true
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -23,11 +33,10 @@ impl<'a> Reader<'a> {
|
|||
return Some(data_type.r#type.clone());
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn process_audio_sector(&mut self, _force: bool) -> Result<Option<Sector>, Error> {
|
||||
fn process_audio_sector(&mut self, _unk_sector_behav: UnknownSectorBehavior) -> Result<Option<Sector>, Error> {
|
||||
let mut buffer = [0;std::mem::size_of::<Audio>()];
|
||||
let bytes = self.file.read(&mut buffer)?;
|
||||
|
||||
|
@ -42,18 +51,23 @@ impl<'a> Reader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn process_binary_sector(&mut self, force: bool) -> Result<Option<Sector>, Error> {
|
||||
fn process_binary_sector(&mut self, unk_sector_behav: UnknownSectorBehavior) -> Result<Option<Sector>, Error> {
|
||||
fn make_ok_some(sector: Sector) -> Result<Option<Sector>, Error> {
|
||||
Ok(Some(sector))
|
||||
}
|
||||
|
||||
let mut buffer = [0;std::mem::size_of::<Mode2Form1>()];
|
||||
let bytes = self.file.read(&mut buffer)?;
|
||||
let mut buffer = [0;SECTOR_SIZE];
|
||||
let bytes = self.file.read(&mut buffer)?;
|
||||
let sector_id = self.lba - 1 - Self::CD_PREGAP_SECTORS;
|
||||
|
||||
if bytes == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
if bytes != SECTOR_SIZE {
|
||||
return Err(Error::GenericError(format!("Failed to read in a complete sector for sector: {}", sector_id)));
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let sector = &*(buffer.as_ptr() as *const Mode0);
|
||||
let mode = sector.header.get_mode();
|
||||
|
@ -69,14 +83,18 @@ impl<'a> Reader<'a> {
|
|||
}
|
||||
}
|
||||
Err(mode) => {
|
||||
let error_str = format!("Unknown Mode: {} @LBA: {}", mode, self.lba - 1);
|
||||
if force {
|
||||
println!("Warning: {}", error_str);
|
||||
return make_ok_some(Sector::Empty(Mode0::new()));
|
||||
}
|
||||
|
||||
else {
|
||||
return Err(Error::TypeError(error_str));
|
||||
let error_str = format!("Unknown Mode: {} @Sector: {}", mode, sector_id);
|
||||
match unk_sector_behav {
|
||||
UnknownSectorBehavior::CauseError => {
|
||||
return Err(Error::TypeError(error_str));
|
||||
},
|
||||
UnknownSectorBehavior::CauseWarningAddEmpty => {
|
||||
println!("Warning: {}", error_str);
|
||||
return make_ok_some(Sector::Empty(Mode0::new()));
|
||||
}
|
||||
UnknownSectorBehavior::TreatAsAudio => {
|
||||
return make_ok_some(Sector::Audio(std::mem::transmute::<[u8; std::mem::size_of::<Audio>()], Audio>(buffer)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +116,7 @@ impl<'a> std::iter::Iterator for Reader<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
match function(self, true) {
|
||||
match function(self, self.unk_sector_behav) {
|
||||
Ok(sector) => {
|
||||
if let Some(sector) = sector {
|
||||
Some(Ok(sector))
|
||||
|
|
|
@ -76,7 +76,7 @@ impl Time {
|
|||
Time{sector, second, minute}
|
||||
}
|
||||
|
||||
pub fn as_sectors(&self) -> usize {
|
||||
pub const fn as_sectors(&self) -> usize {
|
||||
self.sector as usize + self.second as usize*Self::MAX_SECTORS + self.minute as usize*Self::MAX_SECONDS*Self::MAX_SECTORS
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "psxcdread"
|
||||
version = "0.5.0"
|
||||
version = "0.7.0"
|
||||
edition = "2021"
|
||||
|
||||
[profile.release]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use psxcdread::{*};
|
||||
use cdtypes::{Error, cd::CD, types::{cue, sector::SECTOR_SIZE}};
|
||||
use cdtypes::{cd::{reader::UnknownSectorBehavior, CD}, types::{cue, sector::SECTOR_SIZE}, Error};
|
||||
use std::{fs::OpenOptions, io::{stdin, stdout, Write}, path::{Path, PathBuf}};
|
||||
|
||||
fn open_file(path: &Path, write_access: bool) -> Result<std::fs::File, Error> {
|
||||
|
@ -48,7 +48,7 @@ fn open_cue(file: std::fs::File, cue_path: &Path) -> Result<CD, Error> {
|
|||
}
|
||||
let specifier = cue::read::read(file)?;
|
||||
if let Some(bin_path) = get_bin_path(&specifier, cue_path)? {
|
||||
Ok(CD::from_file(open_file(bin_path.as_path(), false)?, Some(specifier))?)
|
||||
Ok(CD::from_file(open_file(bin_path.as_path(), false)?, Some(specifier), UnknownSectorBehavior::CauseError)?)
|
||||
}
|
||||
|
||||
else {
|
||||
|
@ -74,7 +74,7 @@ fn open_cd(path: &str) -> Result<CD, Error> {
|
|||
}
|
||||
|
||||
else {
|
||||
Ok(CD::from_file(file, None)?)
|
||||
Ok(CD::from_file(file, None, UnknownSectorBehavior::TreatAsAudio)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue