Skip to main content

unarc_rs/hyp/
header.rs

1use std::io::Read;
2
3use crate::date_time::DosDateTime;
4use crate::error::{ArchiveError, Result};
5
6const COMPRESSED: u16 = 0x5048; // "HP"
7const STORED: u16 = 0x5453; // "ST"
8
9#[repr(u8)]
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum CompressionMethod {
12    Stored,
13    Compressed,
14}
15
16#[derive(Debug, Clone)]
17pub struct Header {
18    pub compression_method: CompressionMethod,
19    pub version: u8,
20    pub compressed_size: u32,
21    pub original_size: u32,
22    pub date_time: DosDateTime,
23    pub checksum: u32,
24    pub attribute: u8,
25    pub name: String,
26}
27pub const HEADER_SIZE: usize = 21;
28impl Header {
29    pub fn load_from<T: Read>(mut header_bytes: &[u8], reader: &mut T) -> Result<Self> {
30        convert_u16!(compression_method, header_bytes);
31        convert_u8!(version, header_bytes);
32        convert_u32!(compressed_size, header_bytes);
33        convert_u32!(original_size, header_bytes);
34        convert_u32!(date_time, header_bytes);
35        convert_u32!(checksum, header_bytes);
36        convert_u8!(attribute, header_bytes);
37        convert_u8!(name_length, header_bytes);
38        let mut name_buffer = vec![0; name_length as usize];
39        reader.read_exact(&mut name_buffer)?;
40        let name = String::from_utf8_lossy(&name_buffer).to_string();
41        Ok(Header {
42            compression_method: match compression_method {
43                STORED => CompressionMethod::Stored,
44                COMPRESSED => CompressionMethod::Compressed,
45                _ => return Err(ArchiveError::unsupported_method("HYP", format!("0x{:04X}", compression_method))),
46            },
47            version,
48            compressed_size,
49            original_size,
50            date_time: DosDateTime::new(date_time),
51            checksum,
52            attribute,
53            name,
54        })
55    }
56}