Create raw path table
This commit is contained in:
parent
e2750b105e
commit
da329e4395
|
@ -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)};
|
||||||
|
|
||||||
|
@ -163,3 +183,24 @@ fn update_dir_record(dir_record: &mut DirectoryRecord, dir: &Directory) -> Resul
|
||||||
|
|
||||||
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())
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue