Create raw path table

This commit is contained in:
jaby 2022-10-23 16:31:07 +02:00
parent fbeaa392be
commit 29e328aca5
3 changed files with 61 additions and 12 deletions

View File

@ -1,7 +1,7 @@
use super::{*, Sector, SectorWriter, {CDDesc, Error}};
use super::super::types::{layout::Layout, *};
use super::super::types::{helper::PathTableMember, layout::Layout, *};
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 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 {
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::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> {
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 pvd_lba = pvd.track_rel_lba;
@ -142,17 +143,36 @@ fn process_pvd(pvd: &PrimaryVolumeDescriptor, path_table: SharedPtr<PathTable>,
Ok(())
}
fn validate_path_table(path_table: &SharedPtr<PathTable>) -> Result<std::cell::Ref<PathTable>, Error> {
let path_table = path_table.borrow();
fn process_path_table(path_table: &PathTable, root_dir: SharedPtr<Directory>, _sec_writer: &mut dyn SectorWriter) -> Result<(), Error> {
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 {
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 {
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> {
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();
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::*;
const CURRENT_DIR_NAME:&'static str = "/x00";
const PARENT_DIR_NAME:&'static str = "/x01";
const CURRENT_DIR_NAME:&'static str = "\x00";
const PARENT_DIR_NAME:&'static str = "\x01";
pub struct PathTableMember {
pub name: String,
pub track_rel_lba: 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();
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| {
@ -43,7 +47,7 @@ pub fn collect_path_table_member(root: SharedPtr<Directory>) -> Vec<PathTableMem
let mut collection = Vec::new();
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);
collection
}

View File

@ -1,4 +1,4 @@
mod helper;
pub (super) mod helper;
pub mod layout;
pub mod file_map;
@ -75,10 +75,14 @@ impl PathTable {
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 {
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);
size_bytes += PathTableL::calculate_size_for(element.name.as_ref());
});