1use std::io::Read;
2
3use crate::error::{ArchiveError, Result};
4
5#[repr(u8)]
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum CompressionMethod {
8 Stored,
9 Compressed,
10}
11
12const SQ_SIG: [u8; 2] = [0x76, 0xFF];
13const SQ2_SIG: [u8; 2] = [0xFA, 0xFF];
14
15#[derive(Debug, Clone)]
16pub struct Header {
17 pub name: String,
18 pub checksum: u16,
19}
20
21pub const HEADER_SIZE: usize = 21;
22impl Header {
23 pub fn load_from<T: Read>(reader: &mut T) -> Result<Self> {
24 let mut header: [u8; 2] = [0; 2];
25 reader.read_exact(&mut header)?;
26 if header == SQ_SIG {
27 Self::load_sq1_header(reader)
28 } else if header == SQ2_SIG {
29 Self::load_sq2_header(reader)
30 } else {
31 Err(ArchiveError::invalid_header("SQ"))
32 }
33 }
34
35 fn load_sq1_header<T: Read>(reader: &mut T) -> Result<Self> {
36 let mut bytes: [u8; 2] = [0; 2];
37 reader.read_exact(&mut bytes)?;
38 let checksum = u16::from_le_bytes(bytes);
39 let mut name = String::new();
40 let mut byte = [0; 1];
41 loop {
42 reader.read_exact(&mut byte)?;
43 if byte[0] == 0 {
44 break;
45 }
46 name.push(byte[0] as char);
47 }
48 Ok(Self { name, checksum })
49 }
50
51 fn load_sq2_header<T: Read>(reader: &mut T) -> Result<Self> {
52 let mut name = String::new();
53 let mut byte = [0; 1];
54 loop {
55 reader.read_exact(&mut byte)?;
56 if byte[0] == 0 {
57 break;
58 }
59 name.push(byte[0] as char);
60 }
61
62 let mut date = String::new();
63 loop {
64 reader.read_exact(&mut byte)?;
65 if byte[0] == 0 {
66 break;
67 }
68 date.push(byte[0] as char);
69 }
70
71 let mut unknown: [u8; 2] = [0; 2];
74 reader.read_exact(&mut unknown)?;
75
76 let mut bytes: [u8; 2] = [0; 2];
77 reader.read_exact(&mut bytes)?;
78 let checksum = u16::from_le_bytes(bytes);
79
80 let mut unknown: [u8; 4] = [0; 4];
81 reader.read_exact(&mut unknown)?;
82
83 Ok(Self { name, checksum })
84 }
85}