Calculate file sizes easily
This commit is contained in:
parent
a3c4c12c21
commit
4b46ae0c19
|
@ -1,12 +1,19 @@
|
|||
use super::{file_writer::{SectorWriter}, types::{CDDesc, Error}};
|
||||
use super::{file_writer::{SectorWriter}, types::{CDDesc, Error, layout::Layout}};
|
||||
|
||||
pub mod psx;
|
||||
pub mod builder;
|
||||
|
||||
pub type LengthCalculatorFunction = fn(&Layout) -> LengthInfo;
|
||||
pub type LbaCalculatorFunction = fn(&mut CDDesc);
|
||||
pub type ImageEncoderFunction = fn(&CDDesc, &mut dyn SectorWriter) -> Result<(), Error>;
|
||||
|
||||
pub struct LengthInfo {
|
||||
pub bytes: Option<usize>,
|
||||
pub sectors: usize,
|
||||
}
|
||||
|
||||
pub struct EncodingFunctions {
|
||||
pub length_calculator: LengthCalculatorFunction,
|
||||
pub lba_calculator: LbaCalculatorFunction,
|
||||
pub encoder: ImageEncoderFunction
|
||||
}
|
|
@ -9,8 +9,31 @@ const ROOT_DIR_NAME:&'static str = "\x00";
|
|||
const SYSTEM_AREA_SECTOR_COUNT:usize = 16;
|
||||
const PVD_SECTOR_COUNT:usize = 2;
|
||||
|
||||
pub fn calculate_psx_length_for(element: &Layout) -> LengthInfo {
|
||||
match element {
|
||||
Layout::SystemArea(_) => LengthInfo{bytes: None, sectors: SYSTEM_AREA_SECTOR_COUNT},
|
||||
Layout::PVD(_) => LengthInfo{bytes: None, sectors: PVD_SECTOR_COUNT},
|
||||
Layout::PathTables(root, _) => {
|
||||
let path_table_size = PathTable::calculate_size_for(root.clone());
|
||||
LengthInfo{bytes: Some(path_table_size), sectors: sector_count_mode2_form1(path_table_size)}
|
||||
},
|
||||
Layout::Directory(dir) => {
|
||||
let dir = dir.borrow();
|
||||
let properties = dir.properties.borrow_mut();
|
||||
let size_bytes = properties.get_padded_size();
|
||||
|
||||
return LengthInfo{bytes: Some(size_bytes), sectors: sector_count_mode2_form1(size_bytes)};
|
||||
},
|
||||
Layout::File(file) => {
|
||||
let file = file.borrow();
|
||||
let fake_size = file.properties.get_padded_size();
|
||||
|
||||
return LengthInfo{bytes: Some(fake_size), sectors: sector_count_mode2_form1(fake_size)};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn calculate_psx_lbas(cd_desc: &mut CDDesc) {
|
||||
let path_table_size = PathTable::calculate_size_for(cd_desc.root.clone());
|
||||
let mut cur_lba = 0;
|
||||
|
||||
cd_desc.vol_sector_count = 0;
|
||||
|
@ -22,57 +45,50 @@ pub fn calculate_psx_lbas(cd_desc: &mut CDDesc) {
|
|||
cur_lba + content_sector_size
|
||||
}
|
||||
|
||||
let element_size_info = calculate_psx_length_for(&element);
|
||||
match element {
|
||||
Layout::SystemArea(system_area) => {
|
||||
let mut system_area = system_area.borrow_mut();
|
||||
|
||||
system_area.track_rel_lba = cur_lba;
|
||||
cur_lba += SYSTEM_AREA_SECTOR_COUNT;
|
||||
cur_lba += element_size_info.sectors;
|
||||
},
|
||||
|
||||
Layout::PVD(pvd) => {
|
||||
let mut pvd = pvd.borrow_mut();
|
||||
|
||||
pvd.track_rel_lba = cur_lba;
|
||||
cur_lba += PVD_SECTOR_COUNT;
|
||||
cur_lba += element_size_info.sectors;
|
||||
},
|
||||
|
||||
Layout::PathTables(path_table) => {
|
||||
Layout::PathTables(_, path_table) => {
|
||||
let mut path_table = path_table.borrow_mut();
|
||||
|
||||
path_table.track_rel_lba = cur_lba;
|
||||
path_table.size_bytes = path_table_size;
|
||||
path_table.size_bytes = element_size_info.bytes.unwrap_or(0);
|
||||
|
||||
cur_lba += sector_count_mode2_form1(path_table.size_bytes)*4;
|
||||
cur_lba += element_size_info.sectors*4;
|
||||
},
|
||||
|
||||
Layout::Directory(dir) => {
|
||||
let dir = dir.borrow_mut();
|
||||
let mut properties = dir.properties.borrow_mut();
|
||||
let sector_count = sector_count_mode2_form1(properties.get_padded_size());
|
||||
|
||||
cd_desc.vol_sector_count += sector_count;
|
||||
cd_desc.vol_sector_count += element_size_info.sectors;
|
||||
if properties.is_hidden {
|
||||
properties.track_rel_lba = 0;
|
||||
}
|
||||
|
||||
else {
|
||||
cur_lba = update_lba(&mut properties, cur_lba, sector_count);
|
||||
cur_lba = update_lba(&mut properties, cur_lba, element_size_info.sectors);
|
||||
}
|
||||
},
|
||||
|
||||
Layout::File(file) => {
|
||||
let sector_count = {
|
||||
let file = file.borrow();
|
||||
let fake_size = file.properties.get_padded_size();
|
||||
|
||||
sector_count_mode2_form1(fake_size)
|
||||
};
|
||||
|
||||
let mut file = file.borrow_mut();
|
||||
|
||||
cd_desc.vol_sector_count += sector_count;
|
||||
cur_lba = update_lba(&mut file.properties, cur_lba, sector_count);
|
||||
cd_desc.vol_sector_count += element_size_info.sectors;
|
||||
cur_lba = update_lba(&mut file.properties, cur_lba, element_size_info.sectors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +101,7 @@ pub fn encode_psx_image(cd_desc: &CDDesc, sec_writer: &mut dyn SectorWriter) ->
|
|||
match element {
|
||||
Layout::SystemArea(system_area) => process_system_area(&mut system_area.borrow_mut(), sec_writer)?,
|
||||
Layout::PVD(pvd) => process_pvd(&pvd.borrow(), cd_desc.path_table.clone(), cd_desc.root.clone(), vol_sector_count, sec_writer)?,
|
||||
Layout::PathTables(path_table) => process_path_table(&path_table.borrow(), cd_desc.root.clone(), sec_writer)?,
|
||||
Layout::PathTables(root, path_table) => process_path_table(&path_table.borrow(), root, sec_writer)?,
|
||||
Layout::Directory(dir) => process_directory_record(&dir.borrow(), sec_writer)?,
|
||||
Layout::File(file) => process_file(&file.borrow(), sec_writer)?,
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ pub mod encoder;
|
|||
pub mod file_writer;
|
||||
pub mod types;
|
||||
|
||||
use encoder::{LbaCalculatorFunction, LengthCalculatorFunction};
|
||||
use tool_helper::{format_if_error, Output, read_file};
|
||||
use types::{CDDesc, Directory, File, FileType, FileSystemMap, Properties, SharedPtr};
|
||||
|
||||
pub type CalculateLBAFunction = fn(&mut types::CDDesc);
|
||||
pub type LBAEmbeddedFiles = Vec<SharedPtr<File>>;
|
||||
|
||||
struct ContentDumpAlignment {
|
||||
|
@ -20,20 +20,20 @@ struct ContentDumpAlignment {
|
|||
|
||||
const DEFAULT_CONTENT_ALIGNMENT:ContentDumpAlignment = ContentDumpAlignment{name: 24, lba: 8, size: 8, ex_size: 8};
|
||||
|
||||
pub fn process(config: config_reader::Configuration, calculate_lba: CalculateLBAFunction) -> Result<(CDDesc, LBAEmbeddedFiles), Error> {
|
||||
pub fn process(config: config_reader::Configuration, calculate_lba: LbaCalculatorFunction) -> Result<(CDDesc, LBAEmbeddedFiles), Error> {
|
||||
let (mut cd_desc, lba_embedded_files) = parse_configuration(config)?;
|
||||
|
||||
calculate_lba(&mut cd_desc);
|
||||
Ok((cd_desc, lba_embedded_files))
|
||||
}
|
||||
|
||||
pub fn process_files(file_map: FileSystemMap, lba_embedded_files: LBAEmbeddedFiles) -> Result<(), Error> {
|
||||
pub fn process_files(file_map: FileSystemMap, lba_embedded_files: LBAEmbeddedFiles, length_func: LengthCalculatorFunction) -> Result<(), Error> {
|
||||
for lba_embedded_file in lba_embedded_files {
|
||||
let mut lba_embedded_file = lba_embedded_file.borrow_mut();
|
||||
|
||||
match &mut lba_embedded_file.content {
|
||||
FileType::Overlay(content, lba_names) => {
|
||||
let _new_content = types::overlay::update_content(std::mem::take(content), std::mem::take(lba_names), &file_map)?;
|
||||
let _new_content = types::overlay::update_content(std::mem::take(content), std::mem::take(lba_names), &file_map, length_func)?;
|
||||
},
|
||||
_ =>()
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use clap::{Parser, ValueEnum};
|
||||
use psxcdgen_ex::{encoder::{EncodingFunctions, psx::{encode_psx_image, calculate_psx_lbas}}, file_writer::{ImageType, write_image}, config_reader};
|
||||
use psxcdgen_ex::{encoder::{EncodingFunctions, psx::{calculate_psx_lbas, calculate_psx_length_for, encode_psx_image}}, file_writer::{ImageType, write_image}, config_reader};
|
||||
use std::{path::PathBuf, };
|
||||
use tool_helper::Error;
|
||||
|
||||
|
@ -30,7 +30,7 @@ enum SystemType {
|
|||
impl SystemType {
|
||||
pub fn get_encoding_functions(self) -> EncodingFunctions {
|
||||
match self {
|
||||
SystemType::Psx => EncodingFunctions{lba_calculator: calculate_psx_lbas, encoder: encode_psx_image}
|
||||
SystemType::Psx => EncodingFunctions{length_calculator: calculate_psx_length_for, lba_calculator: calculate_psx_lbas, encoder: encode_psx_image}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ fn run_main(cmd_line: CommandLine) -> Result<(), Error> {
|
|||
let (desc, lba_embedded_files) = psxcdgen_ex::process(config_reader::parse_xml(std::fs::read_to_string(cmd_line.input_file)?)?, encoding_functions.lba_calculator)?;
|
||||
let file_map = desc.create_file_map();
|
||||
|
||||
psxcdgen_ex::process_files(file_map, lba_embedded_files)?;
|
||||
psxcdgen_ex::process_files(file_map, lba_embedded_files, encoding_functions.length_calculator)?;
|
||||
write_image(&desc, encoding_functions.encoder, cmd_line.output_type, cmd_line.output_file)?;
|
||||
|
||||
if let Some(list_content_option) = cmd_line.list_content {
|
||||
|
|
|
@ -23,7 +23,6 @@ pub fn new_file_map(root: &Directory) -> FileSystemMap {
|
|||
path
|
||||
};
|
||||
|
||||
println!("Adding: {}", path);
|
||||
file_system.insert(path, file.clone());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ impl DefaultLayout {
|
|||
|
||||
layout.push(Layout::SystemArea(parent.system_area.clone()));
|
||||
layout.push(Layout::PVD(parent.pvd.clone()));
|
||||
layout.push(Layout::PathTables(parent.path_table.clone()));
|
||||
layout.push(Layout::PathTables(parent.root.clone(), parent.path_table.clone()));
|
||||
|
||||
Self::add_dir_and_subdir(&mut layout, parent.root.clone());
|
||||
layout
|
||||
|
@ -34,7 +34,7 @@ impl DefaultLayout {
|
|||
pub enum Layout {
|
||||
SystemArea(SharedPtr<SystemArea>),
|
||||
PVD(SharedPtr<PrimaryVolumeDescriptor>),
|
||||
PathTables(SharedPtr<PathTable>),
|
||||
PathTables(SharedPtr<Directory>, SharedPtr<PathTable>),
|
||||
Directory(SharedPtr<Directory>),
|
||||
File(SharedPtr<File>)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::{File, FileSystemMap};
|
||||
use super::{layout::Layout, File, FileSystemMap};
|
||||
use super::super::encoder::LengthCalculatorFunction;
|
||||
use std::path::PathBuf;
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use no_comment::{IntoWithoutComments as _, languages};
|
||||
|
@ -27,19 +28,20 @@ pub fn load_from(file_name: &str, file_path: PathBuf, lba_source: PathBuf) -> Re
|
|||
Ok(File::new_overlay(file_name, content, lba_names, content_size)?)
|
||||
}
|
||||
|
||||
pub fn update_content(_content: Vec<u8>, lba_names: LBANameVec, file_map: &FileSystemMap) -> Result<Vec<u8>, Error> {
|
||||
pub fn update_content(_content: Vec<u8>, lba_names: LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction) -> Result<Vec<u8>, Error> {
|
||||
for mut lba_name in lba_names {
|
||||
if lba_name.find(';').is_none() {
|
||||
lba_name.push_str(";1");
|
||||
}
|
||||
|
||||
print!("Searching {}... ", lba_name);
|
||||
if let Some(info) = file_map.get(&lba_name) {
|
||||
println!("found @ {}", info.borrow().get_track_rel_lba())
|
||||
if let Some(file) = file_map.get(&lba_name) {
|
||||
let length_info = length_func(&Layout::File(file.clone()));
|
||||
|
||||
println!("Found: {} @{} ({})", lba_name, file.borrow().get_track_rel_lba(), length_info.sectors);
|
||||
}
|
||||
|
||||
else {
|
||||
println!("Not found...");
|
||||
return Err(Error::from_text(format!("Could not locate file {} on disk", lba_name)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue