Prepare new LBA representation

This commit is contained in:
2023-04-12 21:59:36 +02:00
parent 1a0d175779
commit 320fa8934c
8 changed files with 114 additions and 50 deletions

View File

@@ -0,0 +1,42 @@
pub struct BitRange {
start: usize,
length: usize
}
impl BitRange {
pub const fn from_to(start_bit: usize, end_bit: usize) -> Self {
Self{start: start_bit, length: (end_bit - start_bit) + 1}
}
pub const fn get_mask(&self) -> usize {
self.max_value()
}
pub const fn max_value(&self) -> usize {
(1 << self.length) - 1
}
pub const fn or_value(&self, dst_value: usize, value: usize) -> usize {
dst_value | ((value & self.get_mask()) << self.start)
}
}
pub struct Bit {
pos: usize
}
impl Bit {
pub const fn at(pos: usize) -> Self {
Bit{pos}
}
pub const fn or_value(&self, dst_value: usize, is_set: bool) -> usize {
if is_set {
dst_value | (1 << self.pos)
}
else {
dst_value
}
}
}

View File

@@ -1,3 +1,4 @@
pub mod bits;
pub (super) mod helper;
pub mod layout;
pub mod file_map;

View File

@@ -1,4 +1,4 @@
use super::{layout::Layout, File, FileSystemMap};
use super::{bits::{Bit, BitRange}, layout::Layout, File, FileSystemMap};
use super::super::encoder::LengthCalculatorFunction;
use std::path::PathBuf;
use no_comment::{IntoWithoutComments as _, languages};
@@ -8,32 +8,39 @@ pub type LBANameVec = Vec<String>;
mod main;
/*
Size in sectors [22, 31];
Is LZ4 compressed [19];
LBA value [0, 18]
*/
#[repr(packed)]
struct LBAEntry {
lba: u16,
size_words: u16,
raw: u32,
}
impl LBAEntry {
pub fn write_entry(&mut self, lba: u16, mut size_bytes: usize) -> Result<(), Error> {
const WORD_SIZE:usize = std::mem::size_of::<u32>();
const SIZE_IN_SECTOR_RANGE:BitRange = BitRange::from_to(22, 31);
const _IS_LZ4_COMPRESSED:Bit = Bit::at(19);
const LBA_VALUE_RANGE:BitRange = BitRange::from_to(0, 18);
if self.lba != 0 || self.size_words != 0 {
pub fn write_entry(&mut self, lba: usize, size_bytes: usize) -> Result<(), Error> {
if lba > Self::LBA_VALUE_RANGE.max_value() {
return Err(Error::from_text(format!("LBA of value {} is impossible and can not be encoded! Maximum LBA value is: {}", lba, Self::LBA_VALUE_RANGE.max_value())));
}
let size_in_sectors = cdtypes::types::helper::sector_count_mode2_form1(size_bytes);
if size_in_sectors > Self::SIZE_IN_SECTOR_RANGE.max_value() {
return Err(Error::from_text(format!("{} sectors can not be encoded into 10bit", size_in_sectors)));
}
let lba = usize::from_ne_bytes(lba.to_le_bytes());
let size_in_sectors = usize::from_ne_bytes(size_in_sectors.to_le_bytes());
if self.raw != 0 {
return Err(Error::from_str("LBA Entry will overwrite non-zero value!\nIs no space allocated for the LBA Entries?"));
}
size_bytes = (size_bytes + (WORD_SIZE - 1))/WORD_SIZE;
if (size_bytes as u16) as usize != size_bytes {
return Err(Error::from_text(format!("{} words can not be encoded into 16bit", size_bytes)));
}
let lba = lba.to_le_bytes();
let size_bytes = (size_bytes as u16).to_le_bytes();
self.lba = u16::from_ne_bytes(lba);
self.size_words = u16::from_ne_bytes(size_bytes);
self.raw = Self::SIZE_IN_SECTOR_RANGE.or_value(Self::LBA_VALUE_RANGE.or_value(0, lba), size_in_sectors) as u32;
Ok(())
}
}
@@ -71,13 +78,13 @@ pub fn update_content_for_main(content: &mut Vec<u8>, lba_names: &LBANameVec, fi
Ok(content.clone())
}
fn for_each_lba_name<F: FnMut(usize, (u16, usize)) -> Result<(), Error>>(lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction, mut functor: F) -> Result<(), Error> {
fn for_each_lba_name<F: FnMut(usize, (usize, usize)) -> Result<(), Error>>(lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction, mut functor: F) -> Result<(), Error> {
let mut idx = 0;
for lba_name in lba_names {
if let Some(file) = file_map.get(lba_name) {
let (lba, bytes) = (format_if_error_drop_cause!(file.try_borrow(), "Failed accessing file \"{}\" for writing LBA information.\nNote: You can not inject the LBA information of a file into itself.", lba_name)?.get_absolute_lba(), length_func(&Layout::File(file.clone())).bytes);
functor(idx, (lba as u16, bytes.ok_or(Error::from_text(format!("{} does not contain a size!", lba_name)))?))?;
functor(idx, (lba, bytes.ok_or(Error::from_text(format!("{} does not contain a size!", lba_name)))?))?;
idx += 1;
}