use std::io::{Read, Write, Result as IoResult};
use super::binary_format::{SectionId, HEADER_SIZE};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SectionOffset {
pub section_id: SectionId,
pub offset: i32,
pub length: i32,
}
impl SectionOffset {
pub fn new(section_id: SectionId, offset: i32, length: i32) -> Self {
SectionOffset {
section_id,
offset,
length,
}
}
pub fn validate(&self) -> Result<(), String> {
if self.offset < HEADER_SIZE as i32 {
return Err(format!("Invalid offset: {}", self.offset));
}
if self.length <= 0 {
return Err(format!("Invalid length: {}", self.length));
}
Ok(())
}
pub fn write_to<W: Write>(&self, writer: &mut W) -> IoResult<()> {
writer.write_all(&(self.section_id as u32).to_le_bytes())?; writer.write_all(&self.offset.to_le_bytes())?; writer.write_all(&self.length.to_le_bytes())?; Ok(())
}
pub fn read_from<R: Read>(reader: &mut R) -> IoResult<Self> {
let mut buf = [0u8; 4];
reader.read_exact(&mut buf)?;
let section_id_u32 = u32::from_le_bytes(buf);
let section_id = SectionId::from_u32(section_id_u32)
.ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("Invalid section ID: {}", section_id_u32),
)
})?;
reader.read_exact(&mut buf)?;
let offset = i32::from_le_bytes(buf);
reader.read_exact(&mut buf)?;
let length = i32::from_le_bytes(buf);
Ok(SectionOffset {
section_id,
offset,
length,
})
}
}
impl std::fmt::Display for SectionOffset {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}: Offset={}, Length={}",
self.section_id.name(),
self.offset,
self.length
)
}
}