Implement writing LBA header

This commit is contained in:
jaby 2022-12-09 04:08:29 +01:00
parent 3867b3f885
commit 396f6da113
3 changed files with 46 additions and 26 deletions

View File

@ -6,7 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
byteorder = "*"
cdtypes = {path = "../cdtypes"} cdtypes = {path = "../cdtypes"}
clap = {version = "*", features = ["derive"]} clap = {version = "*", features = ["derive"]}
no-comment = "*" no-comment = "*"

View File

@ -30,9 +30,9 @@ pub fn process(config: config_reader::Configuration, calculate_lba: LbaCalculato
pub fn process_files(file_map: FileSystemMap, lba_embedded_files: LBAEmbeddedFiles, length_func: LengthCalculatorFunction) -> Result<(), Error> { pub fn process_files(file_map: FileSystemMap, lba_embedded_files: LBAEmbeddedFiles, length_func: LengthCalculatorFunction) -> Result<(), Error> {
for lba_embedded_file_raw in lba_embedded_files { for lba_embedded_file_raw in lba_embedded_files {
let new_content_info = { let new_content_info = {
let lba_embedded_file = lba_embedded_file_raw.borrow(); let mut lba_embedded_file = lba_embedded_file_raw.borrow_mut();
match &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(content, lba_names, &file_map, length_func)?; let new_content = types::overlay::update_content(content, lba_names, &file_map, length_func)?;

View File

@ -1,7 +1,6 @@
use super::{layout::Layout, File, FileSystemMap}; use super::{layout::Layout, File, FileSystemMap};
use super::super::encoder::LengthCalculatorFunction; use super::super::encoder::LengthCalculatorFunction;
use std::path::PathBuf; use std::path::PathBuf;
use byteorder::{ByteOrder, LittleEndian};
use no_comment::{IntoWithoutComments as _, languages}; use no_comment::{IntoWithoutComments as _, languages};
use tool_helper::{Error, format_if_error, read_file}; use tool_helper::{Error, format_if_error, read_file};
@ -11,14 +10,29 @@ const COMPRESSION_LEVEL:u32 = 16;
#[repr(packed)] #[repr(packed)]
struct OverlayHeader { struct OverlayHeader {
pub start_adr: u32, _start_adr: u32,
pub _lba_count: u16, lba_count: u16,
} }
impl OverlayHeader { impl OverlayHeader {
pub fn lba_count_offset() -> usize { pub fn read_lba_count(&self) -> usize {
let dummy = OverlayHeader{start_adr: 0, _lba_count: 0}.start_adr; u16::from_le(self.lba_count) as usize
std::mem::size_of_val(&dummy) }
}
#[repr(packed)]
struct LBAEntry {
lba: u16,
sectors: u16,
}
impl LBAEntry {
pub fn write_entry(&mut self, lba: u16, sectors: u16) {
let lba = lba.to_le_bytes();
let sectors = sectors.to_le_bytes();
self.lba = u16::from_ne_bytes(lba);
self.sectors = u16::from_ne_bytes(sectors);
} }
} }
@ -30,12 +44,21 @@ 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, length_func: LengthCalculatorFunction) -> Result<Vec<u8>, Error> { pub fn update_content(content: &mut Vec<u8>, lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction) -> Result<Vec<u8>, Error> {
let (lba_header, lba_count) = skip_to_lba_header(content);
let lba_header = unsafe{std::slice::from_raw_parts_mut(lba_header.as_mut_ptr() as *mut LBAEntry, lba_count)};
let mut idx = 0;
for lba_name in lba_names { for lba_name in lba_names {
if let Some(file) = file_map.get(lba_name) { if let Some(file) = file_map.get(lba_name) {
let (lba, sector_count) = (file.borrow().get_track_rel_lba(), length_func(&Layout::File(file.clone())).sectors); let (lba, sector_count) = (file.borrow().get_track_rel_lba(), length_func(&Layout::File(file.clone())).sectors);
println!("Totally writing: {} with @{} ({})", lba_name, lba, sector_count); if idx >= lba_count {
return Err(Error::from_text(format!("Trying to write more LBAs then there is space!")));
}
lba_header[idx].write_entry(lba as u16, sector_count as u16);
idx += 1;
} }
else { else {
@ -43,28 +66,17 @@ pub fn update_content(content: &Vec<u8>, lba_names: &LBANameVec, file_map: &File
} }
} }
//Ok(tool_helper::compress::lz4(content, COMPRESSION_LEVEL)?) Ok(tool_helper::compress::lz4(content, COMPRESSION_LEVEL)?)
//^ real code - v to make it fail (hopefully)
let mut new_content = content.clone();
for _ in 0..2048 {
new_content.push(0x0);
}
Ok(new_content)
} }
fn load_content(file_path: &PathBuf) -> Result<Vec<u8>, Error> { fn load_content(file_path: &PathBuf) -> Result<Vec<u8>, Error> {
let overlay_header_size = std::mem::size_of::<OverlayHeader>(); let mut content = read_file(&file_path)?;
let mut content = read_file(&file_path)?;
if content.len() < overlay_header_size { if content.len() < std::mem::size_of::<OverlayHeader>() {
return Err(Error::from_text(format!("Overlay {} has no header!", file_path.to_string_lossy()))); return Err(Error::from_text(format!("Overlay {} has no header!", file_path.to_string_lossy())));
} }
let lba_count = LittleEndian::read_u16(&content[OverlayHeader::lba_count_offset()..]) as usize; let (lba_header, lba_count) = skip_to_lba_header(&mut content);
let lba_header_size = lba_count*std::mem::size_of::<u32>();
let lba_header = &mut content[overlay_header_size..(overlay_header_size+lba_header_size)];
if lba_header.is_empty() { if lba_header.is_empty() {
return Err(Error::from_text(format!("LBA header of overlay {} is smaller then {} elements", file_path.to_string_lossy(), lba_count))); return Err(Error::from_text(format!("LBA header of overlay {} is smaller then {} elements", file_path.to_string_lossy(), lba_count)));
} }
@ -78,6 +90,15 @@ fn load_content(file_path: &PathBuf) -> Result<Vec<u8>, Error> {
Ok(content) Ok(content)
} }
fn skip_to_lba_header(content: &mut Vec<u8>) -> (&mut [u8], usize) {
let overlay_header_size = std::mem::size_of::<OverlayHeader>();
let lba_count = unsafe{std::mem::transmute::<&u8, &OverlayHeader>(&content[0])}.read_lba_count();
let lba_header_size = lba_count*std::mem::size_of::<LBAEntry>();
(&mut content[overlay_header_size..(overlay_header_size+lba_header_size)], lba_count)
}
fn load_lba_names(lba_source: PathBuf) -> Result<LBANameVec, Error> { fn load_lba_names(lba_source: PathBuf) -> Result<LBANameVec, Error> {
const LBA_DECLARATION:&'static str = "__jabyengine_request_lba_for"; const LBA_DECLARATION:&'static str = "__jabyengine_request_lba_for";
fn get_part_of_interest(file: String, lba_source: &PathBuf) -> Result<String, Error> { fn get_part_of_interest(file: String, lba_source: &PathBuf) -> Result<String, Error> {