1use std::io::Read;
2
3use crate::date_time::DosDateTime;
4use crate::error::{ArchiveError, Result};
5
6const COMPRESSED: u16 = 0x5048; const STORED: u16 = 0x5453; #[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}