rar_stream/parsing/
archive_header.rs1use crate::error::{RarError, Result};
7
8#[derive(Debug, Clone)]
9pub struct ArchiveHeader {
10 pub crc: u16,
11 pub header_type: u8,
12 pub flags: u16,
13 pub size: u16,
14 pub reserved1: u16,
15 pub reserved2: u32,
16 pub has_volume_attributes: bool,
18 pub has_comment: bool,
19 pub is_locked: bool,
20 pub has_solid_attributes: bool,
21 pub is_new_name_scheme: bool,
22 pub has_auth_info: bool,
23 pub has_recovery: bool,
24 pub is_block_encoded: bool,
25 pub is_first_volume: bool,
26}
27
28pub struct ArchiveHeaderParser;
29
30impl ArchiveHeaderParser {
31 pub const HEADER_SIZE: usize = 13;
32
33 pub fn parse(buffer: &[u8]) -> Result<ArchiveHeader> {
34 if buffer.len() < Self::HEADER_SIZE {
35 return Err(RarError::BufferTooSmall {
36 needed: Self::HEADER_SIZE,
37 have: buffer.len(),
38 });
39 }
40
41 let crc = u16::from_le_bytes([buffer[0], buffer[1]]);
42 let header_type = buffer[2];
43 let flags = u16::from_le_bytes([buffer[3], buffer[4]]);
44 let size = u16::from_le_bytes([buffer[5], buffer[6]]);
45 let reserved1 = u16::from_le_bytes([buffer[7], buffer[8]]);
46 let reserved2 = u32::from_le_bytes([buffer[9], buffer[10], buffer[11], buffer[12]]);
47
48 Ok(ArchiveHeader {
49 crc,
50 header_type,
51 flags,
52 size,
53 reserved1,
54 reserved2,
55 has_volume_attributes: (flags & 0x0001) != 0,
56 has_comment: (flags & 0x0002) != 0,
57 is_locked: (flags & 0x0004) != 0,
58 has_solid_attributes: (flags & 0x0008) != 0,
59 is_new_name_scheme: (flags & 0x0010) != 0,
60 has_auth_info: (flags & 0x0020) != 0,
61 has_recovery: (flags & 0x0040) != 0,
62 is_block_encoded: (flags & 0x0080) != 0,
63 is_first_volume: (flags & 0x0100) != 0,
64 })
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn test_parse_archive_header() {
74 let buffer = [
75 0x00, 0x00, 0x73, 0x01, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
82 let header = ArchiveHeaderParser::parse(&buffer).unwrap();
83 assert_eq!(header.header_type, 0x73);
84 assert!(header.has_volume_attributes);
85 assert!(!header.has_comment);
86 }
87}