use super::super::utils::f32_to_half;
#[derive(Debug, Clone)]
pub struct Fixup {
pub offset_in_section: u32,
pub target_section: u32,
pub target_offset: u32,
}
pub struct Section {
pub data: Vec<u8>,
pub fixups: Vec<Fixup>,
}
impl Section {
pub fn new() -> Self {
Self {
data: Vec::new(),
fixups: Vec::new(),
}
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn pos(&self) -> u32 {
self.data.len() as u32
}
pub fn align(&mut self, alignment: usize) {
let padding = (alignment - (self.data.len() % alignment)) % alignment;
self.data.extend(std::iter::repeat_n(0u8, padding));
}
pub fn write_u8(&mut self, v: u8) {
self.data.push(v);
}
pub fn write_u16(&mut self, v: u16) {
self.data.extend_from_slice(&v.to_le_bytes());
}
pub fn write_i16(&mut self, v: i16) {
self.data.extend_from_slice(&v.to_le_bytes());
}
pub fn write_u32(&mut self, v: u32) {
self.data.extend_from_slice(&v.to_le_bytes());
}
pub fn write_i32(&mut self, v: i32) {
self.data.extend_from_slice(&v.to_le_bytes());
}
pub fn write_u64(&mut self, v: u64) {
self.data.extend_from_slice(&v.to_le_bytes());
}
pub fn write_f32(&mut self, v: f32) {
self.data.extend_from_slice(&v.to_le_bytes());
}
pub fn write_f16(&mut self, v: f32) {
self.data.extend_from_slice(&f32_to_half(v).to_le_bytes());
}
pub fn write_ptr(&mut self, target_section: u32, target_offset: u32) {
let offset = self.pos();
self.fixups.push(Fixup {
offset_in_section: offset,
target_section,
target_offset,
});
self.write_u64(0);
}
pub fn write_array_ref(&mut self, count: u32, target_section: u32, target_offset: u32) {
self.write_u32(count);
self.write_ptr(target_section, target_offset);
}
pub fn write_null_ptr(&mut self) {
self.write_u64(0);
}
pub fn write_null_array(&mut self) {
self.write_u32(0);
self.write_u64(0);
}
pub fn write_string(&mut self, s: &str) -> u32 {
let offset = self.pos();
self.data.extend_from_slice(s.as_bytes());
self.data.push(0); offset
}
}