Calculate file sizes easily

This commit is contained in:
Jaby 2022-12-08 03:10:02 +01:00 committed by Jaby
parent a3c4c12c21
commit 4b46ae0c19
7 changed files with 69 additions and 45 deletions

View File

@ -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 LbaCalculatorFunction = fn(&mut CDDesc);
pub type ImageEncoderFunction = fn(&CDDesc, &mut dyn SectorWriter) -> Result<(), Error>;
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 lba_calculator: LbaCalculatorFunction,
pub encoder: ImageEncoderFunction
pub length_calculator: LengthCalculatorFunction,
pub lba_calculator: LbaCalculatorFunction,
pub encoder: ImageEncoderFunction
}

View File

@ -9,9 +9,32 @@ 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;
let mut cur_lba = 0;
cd_desc.vol_sector_count = 0;
CDDesc::for_each_dir_mut(cd_desc.root.clone(), &|dir| {dir.update_content_size();});
@ -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);
}
}
}
@ -83,11 +99,11 @@ pub fn encode_psx_image(cd_desc: &CDDesc, sec_writer: &mut dyn SectorWriter) ->
for element in cd_desc.get_memory_layout() {
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::Directory(dir) => process_directory_record(&dir.borrow(), sec_writer)?,
Layout::File(file) => process_file(&file.borrow(), sec_writer)?,
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(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)?,
}
}

View File

@ -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)?;
},
_ =>()
}

View File

@ -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 {

View File

@ -23,7 +23,6 @@ pub fn new_file_map(root: &Directory) -> FileSystemMap {
path
};
println!("Adding: {}", path);
file_system.insert(path, file.clone());
}
}

View File

@ -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>)
}

View 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)));
}
}