Skip to main content

paperforge_pdf/
xref.rs

1#[derive(Debug, Clone)]
2pub enum XrefEntry {
3    Free { next_free: u32, generation: u16 },
4    Used { offset: u64, generation: u16 },
5    Compressed { container: u32, index: u32 },
6}
7
8#[derive(Debug, Clone)]
9pub struct Xref {
10    entries: Vec<XrefEntry>,
11}
12
13impl Xref {
14    pub fn new() -> Self {
15        Self {
16            entries: Vec::new(),
17        }
18    }
19
20    pub fn add_entry(&mut self, entry: XrefEntry) {
21        self.entries.push(entry);
22    }
23
24    pub fn get(&self, index: usize) -> Option<&XrefEntry> {
25        self.entries.get(index)
26    }
27
28    pub fn len(&self) -> usize {
29        self.entries.len()
30    }
31
32    pub fn is_empty(&self) -> bool {
33        self.entries.is_empty()
34    }
35
36    pub fn serialize(&self) -> Vec<u8> {
37        let mut output = Vec::new();
38        output.extend_from_slice(b"xref\n");
39        output.extend_from_slice(format!("0 {}\n", self.entries.len() + 1).as_bytes());
40        output.extend_from_slice(b"0000000000 65535 f \n");
41        for entry in &self.entries {
42            match entry {
43                XrefEntry::Used { offset, generation } => {
44                    output.extend_from_slice(
45                        format!("{:010} {:05} n \n", offset, generation).as_bytes(),
46                    );
47                }
48                XrefEntry::Free {
49                    next_free,
50                    generation,
51                } => {
52                    output.extend_from_slice(
53                        format!("{:010} {:05} f \n", next_free, generation).as_bytes(),
54                    );
55                }
56                _ => {}
57            }
58        }
59        output
60    }
61}
62
63impl Default for Xref {
64    fn default() -> Self {
65        Self::new()
66    }
67}