#[derive(Debug, Clone)]
pub enum XrefEntry {
Free { next_free: u32, generation: u16 },
Used { offset: u64, generation: u16 },
Compressed { container: u32, index: u32 },
}
#[derive(Debug, Clone)]
pub struct Xref {
entries: Vec<XrefEntry>,
}
impl Xref {
pub fn new() -> Self {
Self {
entries: Vec::new(),
}
}
pub fn add_entry(&mut self, entry: XrefEntry) {
self.entries.push(entry);
}
pub fn get(&self, index: usize) -> Option<&XrefEntry> {
self.entries.get(index)
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn serialize(&self) -> Vec<u8> {
let mut output = Vec::new();
output.extend_from_slice(b"xref\n");
output.extend_from_slice(format!("0 {}\n", self.entries.len() + 1).as_bytes());
output.extend_from_slice(b"0000000000 65535 f \n");
for entry in &self.entries {
match entry {
XrefEntry::Used { offset, generation } => {
output.extend_from_slice(
format!("{:010} {:05} n \n", offset, generation).as_bytes(),
);
}
XrefEntry::Free {
next_free,
generation,
} => {
output.extend_from_slice(
format!("{:010} {:05} f \n", next_free, generation).as_bytes(),
);
}
_ => {}
}
}
output
}
}
impl Default for Xref {
fn default() -> Self {
Self::new()
}
}