Calculate file sizes easily
This commit is contained in:
parent
05acd1a519
commit
f5c296a22e
|
@ -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 psx;
|
||||||
pub mod builder;
|
pub mod builder;
|
||||||
|
|
||||||
pub type LbaCalculatorFunction = fn(&mut CDDesc);
|
pub type LengthCalculatorFunction = fn(&Layout) -> LengthInfo;
|
||||||
pub type ImageEncoderFunction = fn(&CDDesc, &mut dyn SectorWriter) -> Result<(), Error>;
|
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 struct EncodingFunctions {
|
||||||
pub lba_calculator: LbaCalculatorFunction,
|
pub length_calculator: LengthCalculatorFunction,
|
||||||
pub encoder: ImageEncoderFunction
|
pub lba_calculator: LbaCalculatorFunction,
|
||||||
|
pub encoder: ImageEncoderFunction
|
||||||
}
|
}
|
|
@ -9,9 +9,32 @@ const ROOT_DIR_NAME:&'static str = "\x00";
|
||||||
const SYSTEM_AREA_SECTOR_COUNT:usize = 16;
|
const SYSTEM_AREA_SECTOR_COUNT:usize = 16;
|
||||||
const PVD_SECTOR_COUNT:usize = 2;
|
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) {
|
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;
|
cd_desc.vol_sector_count = 0;
|
||||||
CDDesc::for_each_dir_mut(cd_desc.root.clone(), &|dir| {dir.update_content_size();});
|
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
|
cur_lba + content_sector_size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let element_size_info = calculate_psx_length_for(&element);
|
||||||
match element {
|
match element {
|
||||||
Layout::SystemArea(system_area) => {
|
Layout::SystemArea(system_area) => {
|
||||||
let mut system_area = system_area.borrow_mut();
|
let mut system_area = system_area.borrow_mut();
|
||||||
|
|
||||||
system_area.track_rel_lba = cur_lba;
|
system_area.track_rel_lba = cur_lba;
|
||||||
cur_lba += SYSTEM_AREA_SECTOR_COUNT;
|
cur_lba += element_size_info.sectors;
|
||||||
},
|
},
|
||||||
|
|
||||||
Layout::PVD(pvd) => {
|
Layout::PVD(pvd) => {
|
||||||
let mut pvd = pvd.borrow_mut();
|
let mut pvd = pvd.borrow_mut();
|
||||||
|
|
||||||
pvd.track_rel_lba = cur_lba;
|
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();
|
let mut path_table = path_table.borrow_mut();
|
||||||
|
|
||||||
path_table.track_rel_lba = cur_lba;
|
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) => {
|
Layout::Directory(dir) => {
|
||||||
let dir = dir.borrow_mut();
|
let dir = dir.borrow_mut();
|
||||||
let mut properties = dir.properties.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 {
|
if properties.is_hidden {
|
||||||
properties.track_rel_lba = 0;
|
properties.track_rel_lba = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
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) => {
|
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();
|
let mut file = file.borrow_mut();
|
||||||
|
|
||||||
cd_desc.vol_sector_count += sector_count;
|
cd_desc.vol_sector_count += element_size_info.sectors;
|
||||||
cur_lba = update_lba(&mut file.properties, cur_lba, sector_count);
|
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() {
|
for element in cd_desc.get_memory_layout() {
|
||||||
match element {
|
match element {
|
||||||
Layout::SystemArea(system_area) => process_system_area(&mut system_area.borrow_mut(), 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::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::Directory(dir) => process_directory_record(&dir.borrow(), sec_writer)?,
|
||||||
Layout::File(file) => process_file(&file.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 file_writer;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
|
use encoder::{LbaCalculatorFunction, LengthCalculatorFunction};
|
||||||
use tool_helper::{format_if_error, Output, read_file};
|
use tool_helper::{format_if_error, Output, read_file};
|
||||||
use types::{CDDesc, Directory, File, FileType, FileSystemMap, Properties, SharedPtr};
|
use types::{CDDesc, Directory, File, FileType, FileSystemMap, Properties, SharedPtr};
|
||||||
|
|
||||||
pub type CalculateLBAFunction = fn(&mut types::CDDesc);
|
|
||||||
pub type LBAEmbeddedFiles = Vec<SharedPtr<File>>;
|
pub type LBAEmbeddedFiles = Vec<SharedPtr<File>>;
|
||||||
|
|
||||||
struct ContentDumpAlignment {
|
struct ContentDumpAlignment {
|
||||||
|
@ -20,20 +20,20 @@ struct ContentDumpAlignment {
|
||||||
|
|
||||||
const DEFAULT_CONTENT_ALIGNMENT:ContentDumpAlignment = ContentDumpAlignment{name: 24, lba: 8, size: 8, ex_size: 8};
|
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)?;
|
let (mut cd_desc, lba_embedded_files) = parse_configuration(config)?;
|
||||||
|
|
||||||
calculate_lba(&mut cd_desc);
|
calculate_lba(&mut cd_desc);
|
||||||
Ok((cd_desc, lba_embedded_files))
|
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 {
|
for lba_embedded_file in lba_embedded_files {
|
||||||
let mut lba_embedded_file = lba_embedded_file.borrow_mut();
|
let mut lba_embedded_file = lba_embedded_file.borrow_mut();
|
||||||
|
|
||||||
match &mut lba_embedded_file.content {
|
match &mut lba_embedded_file.content {
|
||||||
FileType::Overlay(content, lba_names) => {
|
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 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 std::{path::PathBuf, };
|
||||||
use tool_helper::Error;
|
use tool_helper::Error;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ enum SystemType {
|
||||||
impl SystemType {
|
impl SystemType {
|
||||||
pub fn get_encoding_functions(self) -> EncodingFunctions {
|
pub fn get_encoding_functions(self) -> EncodingFunctions {
|
||||||
match self {
|
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 (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();
|
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)?;
|
write_image(&desc, encoding_functions.encoder, cmd_line.output_type, cmd_line.output_file)?;
|
||||||
|
|
||||||
if let Some(list_content_option) = cmd_line.list_content {
|
if let Some(list_content_option) = cmd_line.list_content {
|
||||||
|
|
|
@ -23,7 +23,6 @@ pub fn new_file_map(root: &Directory) -> FileSystemMap {
|
||||||
path
|
path
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("Adding: {}", path);
|
|
||||||
file_system.insert(path, file.clone());
|
file_system.insert(path, file.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ impl DefaultLayout {
|
||||||
|
|
||||||
layout.push(Layout::SystemArea(parent.system_area.clone()));
|
layout.push(Layout::SystemArea(parent.system_area.clone()));
|
||||||
layout.push(Layout::PVD(parent.pvd.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());
|
Self::add_dir_and_subdir(&mut layout, parent.root.clone());
|
||||||
layout
|
layout
|
||||||
|
@ -34,7 +34,7 @@ impl DefaultLayout {
|
||||||
pub enum Layout {
|
pub enum Layout {
|
||||||
SystemArea(SharedPtr<SystemArea>),
|
SystemArea(SharedPtr<SystemArea>),
|
||||||
PVD(SharedPtr<PrimaryVolumeDescriptor>),
|
PVD(SharedPtr<PrimaryVolumeDescriptor>),
|
||||||
PathTables(SharedPtr<PathTable>),
|
PathTables(SharedPtr<Directory>, SharedPtr<PathTable>),
|
||||||
Directory(SharedPtr<Directory>),
|
Directory(SharedPtr<Directory>),
|
||||||
File(SharedPtr<File>)
|
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 std::path::PathBuf;
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use no_comment::{IntoWithoutComments as _, languages};
|
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)?)
|
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 {
|
for mut lba_name in lba_names {
|
||||||
if lba_name.find(';').is_none() {
|
if lba_name.find(';').is_none() {
|
||||||
lba_name.push_str(";1");
|
lba_name.push_str(";1");
|
||||||
}
|
}
|
||||||
|
|
||||||
print!("Searching {}... ", lba_name);
|
if let Some(file) = file_map.get(&lba_name) {
|
||||||
if let Some(info) = file_map.get(&lba_name) {
|
let length_info = length_func(&Layout::File(file.clone()));
|
||||||
println!("found @ {}", info.borrow().get_track_rel_lba())
|
|
||||||
|
println!("Found: {} @{} ({})", lba_name, file.borrow().get_track_rel_lba(), length_info.sectors);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
println!("Not found...");
|
return Err(Error::from_text(format!("Could not locate file {} on disk", lba_name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue