PSArc_lib/archive/
archive_table.rs

1use super::PSArchiveCompression;
2use crate::prelude::*;
3
4/// **PSArchiveTableItem** is a table of contents table for the Playstation Archive file
5#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
6#[derive(Debug, Clone, Default, PartialEq, Eq)]
7pub struct PSArchiveTableItem {
8	/// **compression_type** is the compression type of the item
9    pub compression_type: PSArchiveCompression,
10	/// **block_offset** is the offset in blocks of the item
11    pub block_offset: u32,
12	/// **uncompressed_size** is the uncompressed size of the item
13    pub uncompressed_size: u64,
14	/// **file_offset** is the file offset of the item
15    pub file_offset: u64,
16}
17
18impl PSArchiveTableItem {
19    pub fn new(compression_type: PSArchiveCompression) -> Self {
20        return Self {
21            compression_type,
22            block_offset: 0,
23            uncompressed_size: 0,
24            file_offset: 0,
25        };
26    }
27}
28
29impl ParsableContext for PSArchiveTableItem {
30    type Error = anyhow::Error;
31    fn parse(&mut self, bytes: impl ConvertAsBytes) -> Result<Self, Self::Error> {
32        let bytes = bytes.convert_as_bytes();
33        let block_offset = ((bytes[0x10] as u32) << 24)
34            + ((bytes[0x11] as u32) << 16)
35            + ((bytes[0x12] as u32) << 8)
36            + (bytes[0x13] as u32);
37        let uncompressed_size = ((bytes[0x14] as u64) << 32)
38            + ((bytes[0x15] as u64) << 24)
39            + ((bytes[0x16] as u64) << 16)
40            + ((bytes[0x17] as u64) << 8)
41            + (bytes[0x18] as u64);
42        let file_offset = ((bytes[0x19] as u64) << 32)
43            + ((bytes[0x1A] as u64) << 24)
44            + ((bytes[0x1B] as u64) << 16)
45            + ((bytes[0x1C] as u64) << 8)
46            + (bytes[0x1D] as u64);
47        return Ok(Self {
48            compression_type: self.compression_type.clone(),
49            block_offset,
50            uncompressed_size,
51            file_offset,
52        });
53    }
54}
55
56#[cfg(test)]
57#[doc(hidden)]
58mod test {
59    use super::{PSArchiveCompression, PSArchiveTableItem};
60    use crate::prelude::*;
61
62    #[test]
63    fn test_archive_table_item_parsing_manifest() {
64        let bytes = include_bytes!("../../res/test.pak")[0x20..0x3E].to_vec();
65        let mut table_item = PSArchiveTableItem::new(PSArchiveCompression::ZLIB);
66        let result = table_item.parse(bytes);
67        assert_eq!(result.is_ok(), true);
68        let result = result.unwrap();
69        assert_eq!(
70            result,
71            PSArchiveTableItem {
72                compression_type: PSArchiveCompression::ZLIB,
73                block_offset: 0,
74                uncompressed_size: 17,
75                file_offset: 96
76            }
77        );
78    }
79
80    #[test]
81    fn test_archive_table_item_parsing_item() {
82        let bytes = include_bytes!("../../res/test.pak")[0x3E..0x5C].to_vec();
83        let mut table_item = PSArchiveTableItem::new(PSArchiveCompression::ZLIB);
84        let result = table_item.parse(bytes);
85        assert_eq!(result.is_ok(), true);
86        let result = result.unwrap();
87        assert_eq!(
88            result,
89            PSArchiveTableItem {
90                compression_type: PSArchiveCompression::ZLIB,
91                block_offset: 1,
92                uncompressed_size: 115,
93                file_offset: 113,
94            }
95        );
96    }
97}