Create raw path table

This commit is contained in:
Jaby 2022-10-23 16:31:07 +02:00 committed by Jaby
parent 7335e933c7
commit 684fd6598e
3 changed files with 61 additions and 12 deletions

View File

@ -1,7 +1,7 @@
use super::{*, Sector, SectorWriter, {CDDesc, Error}}; use super::{*, Sector, SectorWriter, {CDDesc, Error}};
use super::super::types::{layout::Layout, *}; use super::super::types::{helper::PathTableMember, layout::Layout, *};
use builder::SubModeBuilder; use builder::SubModeBuilder;
use cdtypes::types::{cdstring::{AString, DString}, date::*, dir_record::DirectoryRecord, helper::sector_count_mode2_form1, pvd as cd_pvd, lsb_msb::*, sector::Mode2Form1}; use cdtypes::types::{cdstring::{AString, DString}, date::*, dir_record::DirectoryRecord, helper::sector_count_mode2_form1, path_table::*, pvd as cd_pvd, lsb_msb::*, sector::Mode2Form1};
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;
@ -77,6 +77,7 @@ pub fn encode_psx_image(cd_desc: CDDesc, sec_writer: &mut dyn SectorWriter) -> R
match element { match element {
Layout::SystemArea(system_area) => process_system_area(&system_area.borrow(), sec_writer)?, Layout::SystemArea(system_area) => process_system_area(&system_area.borrow(), 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)?,
_ => () _ => ()
} }
} }
@ -100,7 +101,7 @@ fn process_system_area(system_area: &SystemArea, sec_writer: &mut dyn SectorWrit
fn process_pvd(pvd: &PrimaryVolumeDescriptor, path_table: SharedPtr<PathTable>, root_dir: SharedPtr<Directory>, vol_sector_count: usize, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> { fn process_pvd(pvd: &PrimaryVolumeDescriptor, path_table: SharedPtr<PathTable>, root_dir: SharedPtr<Directory>, vol_sector_count: usize, sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
const PLAYSATATION_STR:&'static str = "PLAYSTATION"; const PLAYSATATION_STR:&'static str = "PLAYSTATION";
let path_table = validate_path_table(&path_table)?; let path_table = validate_and_unwrap_path_table(&path_table)?;
let root_dir = root_dir.borrow(); let root_dir = root_dir.borrow();
let pvd_lba = pvd.track_rel_lba; let pvd_lba = pvd.track_rel_lba;
@ -142,17 +143,36 @@ fn process_pvd(pvd: &PrimaryVolumeDescriptor, path_table: SharedPtr<PathTable>,
Ok(()) Ok(())
} }
fn validate_path_table(path_table: &SharedPtr<PathTable>) -> Result<std::cell::Ref<PathTable>, Error> { fn process_path_table(path_table: &PathTable, root_dir: SharedPtr<Directory>, _sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
let path_table = path_table.borrow(); let mut bytes_used = 0;
let mut path_table_raw_l = vec![0u8; path_table.size_bytes];
let mut path_table_raw_b = vec![0u8; path_table.size_bytes];
let path_table = PathTable::collect_member(root_dir);
for entry in path_table {
bytes_used += unsafe{update_path_table_entry(std::mem::transmute::<&mut u8, &mut PathTableL>(&mut path_table_raw_l[bytes_used]), std::mem::transmute::<&mut u8, &mut PathTableB>(&mut path_table_raw_b[bytes_used]), entry)?};
}
Err(Error::not_implemented("process_path_table"))
}
fn validate_path_table(path_table: &PathTable) -> Result<(), Error> {
if path_table.size_bytes > Mode2Form1::DATA_SIZE { if path_table.size_bytes > Mode2Form1::DATA_SIZE {
Err(Error::from_text(format!("Path Tables are not allowed to be bigger then {} bytes - Path Table has {} bytes", Mode2Form1::DATA_SIZE, path_table.size_bytes))) Err(Error::from_text(format!("Path Tables are not allowed to be bigger then {} bytes - Path Table has {} bytes", Mode2Form1::DATA_SIZE, path_table.size_bytes)))
} }
else { else {
Ok(path_table) Ok(())
} }
} }
fn validate_and_unwrap_path_table(path_table: &SharedPtr<PathTable>) -> Result<std::cell::Ref<PathTable>, Error> {
let path_table = path_table.borrow();
validate_path_table(&path_table)?;
Ok(path_table)
}
fn update_dir_record(dir_record: &mut DirectoryRecord, dir: &Directory) -> Result<(), Error> { fn update_dir_record(dir_record: &mut DirectoryRecord, dir: &Directory) -> Result<(), Error> {
unsafe{dir_record.new(dir.name.as_str().unwrap_or("\x00"), false)}; unsafe{dir_record.new(dir.name.as_str().unwrap_or("\x00"), false)};
@ -162,4 +182,25 @@ fn update_dir_record(dir_record: &mut DirectoryRecord, dir: &Directory) -> Resul
dir_record.set_directory(); dir_record.set_directory();
Ok(()) Ok(())
}
fn update_path_table_entry(path_table_l: &mut PathTableL, path_table_b: &mut PathTableB, entry: PathTableMember) -> Result<usize, Error> {
let name_len = entry.name.len();
if name_len > 8 {
return Err(Error::from_text(format!("Directory name can not exceed size of 8 characters but folder {} has {} characters", entry.name, name_len)));
}
unsafe{
let name = entry.name.as_str();
path_table_l.new(name);
path_table_b.new(name);
}
path_table_l.directory_logical_block.write(entry.track_rel_lba as u32);
path_table_b.directory_logical_block.write(entry.track_rel_lba as u32);
path_table_l.parent_table_id.write(entry.parent_table_id as u16);
path_table_b.parent_table_id.write(entry.parent_table_id as u16);
Ok(path_table_l.get_size())
} }

View File

@ -1,10 +1,11 @@
use super::*; use super::*;
const CURRENT_DIR_NAME:&'static str = "/x00"; const CURRENT_DIR_NAME:&'static str = "\x00";
const PARENT_DIR_NAME:&'static str = "/x01"; const PARENT_DIR_NAME:&'static str = "\x01";
pub struct PathTableMember { pub struct PathTableMember {
pub name: String, pub name: String,
pub track_rel_lba: usize,
pub parent_table_id: usize, pub parent_table_id: usize,
} }
@ -27,7 +28,10 @@ pub fn collect_path_table_member(root: SharedPtr<Directory>) -> Vec<PathTableMem
let mut cur_dirs = Vec::new(); let mut cur_dirs = Vec::new();
for dir in dirs { for dir in dirs {
cur_dirs.push(PathTableMember{name: dir.borrow().name.as_string().unwrap_or("".to_owned()), parent_table_id: parent_id}); let dir = dir.borrow();
if !dir.properties.is_hidden {
cur_dirs.push(PathTableMember{name: dir.name.as_string().unwrap_or("".to_owned()), track_rel_lba: dir.get_track_rel_lba(), parent_table_id: parent_id});
}
} }
cur_dirs.sort_by(|a, b| { cur_dirs.sort_by(|a, b| {
@ -43,7 +47,7 @@ pub fn collect_path_table_member(root: SharedPtr<Directory>) -> Vec<PathTableMem
let mut collection = Vec::new(); let mut collection = Vec::new();
let root = root.borrow(); let root = root.borrow();
collection.push(PathTableMember{name: CURRENT_DIR_NAME.to_owned(), parent_table_id: 1}); collection.push(PathTableMember{name: CURRENT_DIR_NAME.to_owned(), track_rel_lba: root.get_track_rel_lba(), parent_table_id: 1});
collect_path_table_for(&mut collection, &root.dirs, 1); collect_path_table_for(&mut collection, &root.dirs, 1);
collection collection
} }

View File

@ -1,4 +1,4 @@
mod helper; pub (super) mod helper;
pub mod layout; pub mod layout;
pub mod file_map; pub mod file_map;
@ -75,10 +75,14 @@ impl PathTable {
PathTable{track_rel_lba: 0, size_bytes: 0} PathTable{track_rel_lba: 0, size_bytes: 0}
} }
pub fn collect_member(root: SharedPtr<Directory>) -> Vec<helper::PathTableMember> {
helper::collect_path_table_member(root)
}
pub fn calculate_size_for(root: SharedPtr<Directory>) -> usize { pub fn calculate_size_for(root: SharedPtr<Directory>) -> usize {
let mut size_bytes = 0; let mut size_bytes = 0;
helper::collect_path_table_member(root).into_iter().for_each(|element| { Self::collect_member(root).into_iter().for_each(|element| {
println!("PT: {} ^{}", element.name, element.parent_table_id); println!("PT: {} ^{}", element.name, element.parent_table_id);
size_bytes += PathTableL::calculate_size_for(element.name.as_ref()); size_bytes += PathTableL::calculate_size_for(element.name.as_ref());
}); });