oxidize_pdf/parser/
xref_types.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum XRefEntryType {
11 Free,
13 Uncompressed,
15 Compressed,
17 Custom(u8),
20}
21
22impl XRefEntryType {
23 pub fn from_value(value: u64) -> Self {
25 match value {
26 0 => XRefEntryType::Free,
27 1 => XRefEntryType::Uncompressed,
28 2 => XRefEntryType::Compressed,
29 n if n <= 255 => XRefEntryType::Custom(n as u8),
30 _ => XRefEntryType::Free, }
32 }
33
34 pub fn is_in_use(&self) -> bool {
36 match self {
37 XRefEntryType::Free => false,
38 XRefEntryType::Uncompressed => true,
39 XRefEntryType::Compressed => true,
40 XRefEntryType::Custom(_) => true,
43 }
44 }
45
46 pub fn to_value(&self) -> u8 {
48 match self {
49 XRefEntryType::Free => 0,
50 XRefEntryType::Uncompressed => 1,
51 XRefEntryType::Compressed => 2,
52 XRefEntryType::Custom(n) => *n,
53 }
54 }
55}
56
57#[derive(Debug, Clone, PartialEq)]
59pub struct XRefEntryInfo {
60 pub entry_type: XRefEntryType,
62 pub field2: u64,
67 pub field3: u64,
72}
73
74impl XRefEntryInfo {
75 pub fn new(entry_type: XRefEntryType, field2: u64, field3: u64) -> Self {
77 Self {
78 entry_type,
79 field2,
80 field3,
81 }
82 }
83
84 pub fn get_offset(&self) -> Option<u64> {
86 match self.entry_type {
87 XRefEntryType::Uncompressed => Some(self.field2),
88 _ => None,
89 }
90 }
91
92 pub fn get_generation(&self) -> u16 {
94 match self.entry_type {
95 XRefEntryType::Free | XRefEntryType::Uncompressed => self.field3 as u16,
96 _ => 0,
97 }
98 }
99
100 pub fn get_compressed_info(&self) -> Option<(u32, u32)> {
102 match self.entry_type {
103 XRefEntryType::Compressed => Some((self.field2 as u32, self.field3 as u32)),
104 _ => None,
105 }
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn test_xref_entry_type_from_value() {
115 assert_eq!(XRefEntryType::from_value(0), XRefEntryType::Free);
116 assert_eq!(XRefEntryType::from_value(1), XRefEntryType::Uncompressed);
117 assert_eq!(XRefEntryType::from_value(2), XRefEntryType::Compressed);
118 assert_eq!(XRefEntryType::from_value(53), XRefEntryType::Custom(53));
119 assert_eq!(XRefEntryType::from_value(255), XRefEntryType::Custom(255));
120 assert_eq!(XRefEntryType::from_value(256), XRefEntryType::Free);
122 }
123
124 #[test]
125 fn test_is_in_use() {
126 assert!(!XRefEntryType::Free.is_in_use());
127 assert!(XRefEntryType::Uncompressed.is_in_use());
128 assert!(XRefEntryType::Compressed.is_in_use());
129 assert!(XRefEntryType::Custom(53).is_in_use());
130 }
131
132 #[test]
133 fn test_entry_info() {
134 let info = XRefEntryInfo::new(XRefEntryType::Uncompressed, 1234, 5);
135 assert_eq!(info.get_offset(), Some(1234));
136 assert_eq!(info.get_generation(), 5);
137 assert_eq!(info.get_compressed_info(), None);
138
139 let compressed = XRefEntryInfo::new(XRefEntryType::Compressed, 10, 20);
140 assert_eq!(compressed.get_offset(), None);
141 assert_eq!(compressed.get_generation(), 0);
142 assert_eq!(compressed.get_compressed_info(), Some((10, 20)));
143 }
144
145 #[test]
146 fn test_to_value() {
147 assert_eq!(XRefEntryType::Free.to_value(), 0);
148 assert_eq!(XRefEntryType::Uncompressed.to_value(), 1);
149 assert_eq!(XRefEntryType::Compressed.to_value(), 2);
150 assert_eq!(XRefEntryType::Custom(53).to_value(), 53);
151 assert_eq!(XRefEntryType::Custom(255).to_value(), 255);
152 }
153
154 #[test]
155 fn test_free_entry_info() {
156 let free = XRefEntryInfo::new(XRefEntryType::Free, 100, 65535);
157 assert_eq!(free.get_offset(), None);
158 assert_eq!(free.get_generation(), 65535);
159 assert_eq!(free.get_compressed_info(), None);
160 }
161
162 #[test]
163 fn test_custom_entry_info() {
164 let custom = XRefEntryInfo::new(XRefEntryType::Custom(99), 500, 10);
165 assert_eq!(custom.get_offset(), None);
166 assert_eq!(custom.get_generation(), 0);
167 assert_eq!(custom.get_compressed_info(), None);
168 }
169}