unarc_rs/arc/
local_file_header.rs1use crate::date_time::DosDateTime;
2
3#[repr(u8)]
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum FileType {
6 Binary = 0,
7 Text7Bit = 1,
8 CommentHeader = 2,
9 Directory = 3,
10 VolumeLabel = 4,
11 ChapterLabel = 5,
12 Unknown(u8),
13}
14
15impl From<u8> for FileType {
16 fn from(value: u8) -> Self {
17 match value {
18 0 => FileType::Binary,
19 1 => FileType::Text7Bit,
20 2 => FileType::CommentHeader,
21 3 => FileType::Directory,
22 4 => FileType::VolumeLabel,
23 5 => FileType::ChapterLabel,
24 _ => FileType::Unknown(value),
25 }
26 }
27}
28
29#[repr(u8)]
30#[derive(Debug, Clone, Copy, PartialEq, Eq)]
31pub enum CompressionMethod {
32 Unpacked(u8),
33 RLE90,
35 Squeezed,
37 Crunched(u8),
39 Squashed,
40 Crushed,
41 Distilled,
42 Unknown(u8),
43}
44
45impl From<u8> for CompressionMethod {
46 fn from(value: u8) -> Self {
47 match value {
48 1 => CompressionMethod::Unpacked(1),
49 2 => CompressionMethod::Unpacked(2),
50 3 => CompressionMethod::RLE90,
51 4 => CompressionMethod::Squeezed,
52 5 => CompressionMethod::Crunched(5),
53 6 => CompressionMethod::Crunched(6),
54 7 => CompressionMethod::Crunched(7),
55 8 => CompressionMethod::Crunched(8),
56 9 => CompressionMethod::Squashed,
57 10 => CompressionMethod::Crushed,
58 11 => CompressionMethod::Distilled,
59 _ => CompressionMethod::Unknown(value),
60 }
61 }
62}
63
64#[derive(Debug, Clone)]
65pub struct LocalFileHeader {
66 pub compression_method: CompressionMethod,
67 pub name: String,
68 pub compressed_size: u32,
69 pub date_time: DosDateTime,
70 pub crc16: u16,
71 pub original_size: u32,
72}
73
74impl LocalFileHeader {
75 pub fn load_from(mut header_bytes: &[u8]) -> Option<Self> {
76 convert_u8!(compression_method, header_bytes);
77 if compression_method == 0 {
78 return None;
79 }
80 let idx = header_bytes.iter().position(|&x| x == 0).unwrap_or(13);
81 let name = String::from_utf8_lossy(&header_bytes[0..idx]).to_string();
82 header_bytes = &header_bytes[13..];
83 convert_u32!(compressed_size, header_bytes);
84 convert_u32!(date_time, header_bytes);
85 convert_u16!(crc16, header_bytes);
86 convert_u32!(original_size, header_bytes);
87
88 Some(LocalFileHeader {
89 compression_method: compression_method.into(),
90 name,
91 compressed_size,
92 date_time: DosDateTime::new(date_time),
93 crc16,
94 original_size,
95 })
96 }
97}