1pub mod types;
8
9pub mod header;
10pub mod offsets;
11
12pub mod reader;
13pub mod writer;
14
15mod internal;
16
17pub use reader::PsbReader;
18pub use writer::PsbWriter;
19
20use header::PsbHeader;
21use io::Seek;
22use offsets::{PsbOffsets, PsbResourcesOffset};
23use types::{PsbValue, collection::PsbObject};
24
25use std::{error::Error, io::{self, Read, SeekFrom}};
26
27pub const PSB_SIGNATURE: u32 = 0x425350;
29
30pub const PSB_MDF_SIGNATURE: u32 = 0x66646D;
32
33#[derive(Debug)]
34pub struct PsbError {
35
36 kind: PsbErrorKind,
37 err: Option<Box<dyn Error>>
38
39}
40
41impl PsbError {
42
43 pub fn new(kind: PsbErrorKind, err: Option<Box<dyn Error>>) -> Self {
44 Self { kind, err }
45 }
46
47 pub fn kind(&self) -> &PsbErrorKind {
48 &self.kind
49 }
50
51 pub fn source(&self) -> &Option<Box<dyn Error>> {
52 &self.err
53 }
54
55}
56
57#[derive(Debug)]
58pub enum PsbErrorKind {
59
60 Io(io::Error),
61 InvalidFile,
62 InvalidHeader,
63 UnknownHeaderVersion,
64 InvalidIndex,
65 InvalidPSBValue,
66 InvalidPSBRoot,
67 InvalidOffsetTable,
68 Custom
69
70}
71
72impl From<io::Error> for PsbError {
73
74 fn from(err: io::Error) -> Self {
75 PsbError::new(PsbErrorKind::Io(err), None)
76 }
77
78}
79
80#[derive(Debug, Clone)]
81pub struct PsbRefs {
82
83 names: Vec<String>,
84
85 strings: Vec<String>,
86
87}
88
89impl PsbRefs {
90
91 pub fn new(names: Vec<String>, strings: Vec<String>) -> Self {
92 Self {
93 names, strings
94 }
95 }
96
97 pub fn names(&self) -> &Vec<String> {
98 &self.names
99 }
100
101 pub fn names_mut(&mut self) -> &mut Vec<String> {
102 &mut self.names
103 }
104
105 pub fn names_len(&self) -> usize {
106 self.names.len()
107 }
108
109 pub fn get_name(&self, index: usize) -> Option<&String> {
110 self.names.get(index)
111 }
112
113 pub fn get_name_mut(&mut self, index: usize) -> Option<&mut String> {
114 self.names.get_mut(index)
115 }
116
117 pub fn find_name_index(&self, name: &String) -> Option<u64> {
118 for (i, nm) in self.names.iter().enumerate() {
119 if nm == name {
120 return Some(i as u64)
121 }
122 }
123
124 None
125 }
126
127 pub fn strings(&self) -> &Vec<String> {
128 &self.strings
129 }
130
131 pub fn strings_mut(&mut self) -> &mut Vec<String> {
132 &mut self.strings
133 }
134
135 pub fn strings_len(&self) -> usize {
136 self.strings.len()
137 }
138
139 pub fn get_string(&self, index: usize) -> Option<&String> {
140 self.strings.get(index)
141 }
142
143 pub fn get_string_mut(&mut self, index: usize) -> Option<&mut String> {
144 self.strings.get_mut(index)
145 }
146
147 pub fn find_string_index(&self, string: &String) -> Option<u64> {
148 for (i, st) in self.strings.iter().enumerate() {
149 if st == string {
150 return Some(i as u64)
151 }
152 }
153
154 None
155 }
156}
157
158#[derive(Debug)]
159pub struct VirtualPsb {
160
161 header: PsbHeader,
162
163 resources: Vec<Vec<u8>>,
164 extra: Vec<Vec<u8>>,
165
166 root: PsbObject
167
168}
169
170impl VirtualPsb {
171
172 pub fn new(
173 header: PsbHeader,
174 resources: Vec<Vec<u8>>,
175 extra: Vec<Vec<u8>>,
176 root: PsbObject
177 ) -> Self {
178 Self {
179 header,
180 resources,
181 extra,
182 root
183 }
184 }
185
186 pub fn header(&self) -> PsbHeader {
187 self.header
188 }
189
190 pub fn resources(&self) -> &Vec<Vec<u8>> {
191 &self.resources
192 }
193
194 pub fn resources_mut(&mut self) -> &mut Vec<Vec<u8>> {
195 &mut self.resources
196 }
197
198 pub fn extra(&self) -> &Vec<Vec<u8>> {
199 &self.extra
200 }
201
202 pub fn extra_mut(&mut self) -> &mut Vec<Vec<u8>> {
203 &mut self.extra
204 }
205
206 pub fn root(&self) -> &PsbObject {
207 &self.root
208 }
209
210 pub fn root_mut(&mut self) -> &mut PsbObject {
211 &mut self.root
212 }
213
214 pub fn set_root(&mut self, root: PsbObject) {
215 self.root = root;
216 }
217
218 pub fn unwrap(self) -> (PsbHeader, Vec<Vec<u8>>, Vec<Vec<u8>>, PsbObject) {
219 (
220 self.header,
221 self.resources,
222 self.extra,
223 self.root
224 )
225 }
226
227}
228
229#[derive(Debug)]
230pub struct PsbFile<T: Read + Seek> {
231
232 header: PsbHeader,
233
234 refs: PsbRefs,
235 offsets: PsbOffsets,
236
237 stream: T
238
239}
240
241impl<T: Read + Seek> PsbFile<T> {
242
243 pub fn new(header: PsbHeader, refs: PsbRefs, offsets: PsbOffsets, stream: T) -> Self {
244 Self {
245 header,
246 refs,
247 offsets,
248 stream
249 }
250 }
251
252 pub fn header(&self) -> PsbHeader {
253 self.header
254 }
255
256 pub fn refs(&self) -> &PsbRefs {
257 &self.refs
258 }
259
260 pub fn offsets(&self) -> PsbOffsets {
261 self.offsets
262 }
263
264 pub fn entry_point(&self) -> u32 {
265 self.offsets.entry_point as u32
266 }
267
268 pub fn load_root(&mut self) -> Result<PsbObject, PsbError> {
269 self.stream.seek(SeekFrom::Start(self.entry_point() as u64))?;
270 let (_, root) = PsbValue::from_bytes_refs(&mut self.stream, &self.refs)?;
271
272 if let PsbValue::Object(root_obj) = root {
273 Ok(root_obj)
274 } else {
275 Err(PsbError::new(PsbErrorKind::InvalidPSBRoot, None))
276 }
277 }
278
279 pub fn load_resources(&mut self) -> Result<Vec<Vec<u8>>, PsbError> {
280 Self::load_from_table(&mut self.stream, self.offsets.resources)
281 }
282
283 pub fn load_extra(&mut self) -> Result<Vec<Vec<u8>>, PsbError> {
284 if self.offsets.extra.is_none() {
285 Ok(Vec::new())
286 } else {
287 Self::load_from_table(&mut self.stream, self.offsets.extra.unwrap())
288 }
289 }
290
291 fn load_from_table<R: Read + Seek>(stream: &mut R, table: PsbResourcesOffset) -> Result<Vec<Vec<u8>>, PsbError> {
292 stream.seek(SeekFrom::Start(table.offset_pos as u64))?;
293 let (_, resource_offsets) = match PsbValue::from_bytes(stream)? {
294
295 (read, PsbValue::IntArray(array)) => Ok((read, array)),
296
297 _ => Err(PsbError::new(PsbErrorKind::InvalidOffsetTable, None))
298
299 }?;
300
301 stream.seek(SeekFrom::Start(table.lengths_pos as u64))?;
302 let (_, resource_lengths) = match PsbValue::from_bytes(stream)? {
303
304 (read, PsbValue::IntArray(array)) => Ok((read, array)),
305
306 _ => Err(PsbError::new(PsbErrorKind::InvalidOffsetTable, None))
307
308 }?;
309
310 if resource_offsets.len() < resource_lengths.len() {
311 return Err(PsbError::new(PsbErrorKind::InvalidOffsetTable, None));
312 }
313
314 let mut resources = Vec::new();
315
316 let resource_offsets = resource_offsets.unwrap();
317 let resource_lengths = resource_lengths.unwrap();
318
319 for i in 0..resource_offsets.len() {
320 let mut buffer = Vec::new();
321
322 stream.seek(SeekFrom::Start(table.data_pos as u64 + resource_offsets[i] as u64))?;
323 stream.take(resource_lengths[i] as u64).read_to_end(&mut buffer)?;
324
325 resources.push(buffer);
326 }
327
328 Ok(resources)
329 }
330
331 pub fn load(&mut self) -> Result<VirtualPsb, PsbError> {
334 let root = self.load_root()?;
335 let res = self.load_resources()?;
336 let extra = self.load_extra()?;
337
338 Ok(VirtualPsb::new(self.header, res, extra, root))
339 }
340
341 pub fn unwrap(self) -> T {
343 self.stream
344 }
345
346}