PSArc_lib/archive/
table_of_content.rs

1use super::PSArchiveFlags;
2use crate::prelude::*;
3
4/// **PSArchiveTOC** contains the table of content and details about each resource
5#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
6#[derive(Debug, Clone, Default, PartialEq, Eq)]
7pub struct PSArchiveTOC {
8	/// **length** is the total length of the table of contents
9	pub length: u32,
10	/// **entry_size** contains each entries size
11	pub entry_size: u32,
12	/// **entry_count** is the amount of entries in the Playstation Archive file
13	pub entry_count: u32,
14	// **flags** is the flags of the Playstation Archive file
15	pub flags: PSArchiveFlags
16}
17
18impl Parsable for PSArchiveTOC {
19    type Error = anyhow::Error;
20    fn parse(bytes: impl ConvertAsBytes) -> Result<Self, Self::Error> {
21		let bytes = bytes.convert_as_bytes();
22		let length = (((bytes[0] as u32) << 24) + ((bytes[1] as u32) << 16) + ((bytes[2] as u32) << 8) + (bytes[3] as u32)) - 32;
23		let entry_size = ((bytes[4] as u32) << 24) + ((bytes[5] as u32) << 16) + ((bytes[6] as u32) << 8) + (bytes[7] as u32);
24		let entry_count = (((bytes[8] as u32) << 24) + ((bytes[9] as u32) << 16) + ((bytes[10] as u32) << 8) + (bytes[11] as u32)) - 1;
25		let flags = PSArchiveFlags::parse(&[bytes[16], bytes[17], bytes[18], bytes[19]] as &[u8])?;
26		return Ok(Self {
27			length,
28			entry_size,
29			entry_count,
30			flags
31		});
32	}
33}
34
35#[cfg(test)]
36#[doc(hidden)]
37mod test {
38	use crate::prelude::*;
39	use super::{PSArchiveTOC, PSArchiveFlags};
40
41	#[test]
42	fn test_toc_parsing() {
43		let bytes = include_bytes!("../../res/test.pak")[0xC..].to_vec();
44		let result = PSArchiveTOC::parse(bytes);
45		assert_eq!(result.is_ok(), true);
46		let result = result.unwrap();
47		assert_eq!(result.length, 64);
48		assert_eq!(result.entry_size, 30);
49		assert_eq!(result.entry_count, 1);
50		assert_eq!(result.flags, PSArchiveFlags::ABSOLUTE);
51	}
52}