Skip to main content

unarc_rs/sq/
header.rs

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        // Maybe it's something connected to the checksum, seems that the checksum is larger in sq2
72        // but doesn't seem to be u32 -> for now just skip the extra info.
73        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}