rar_stream/formats/
mod.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum Signature {
8 Rar15,
10 Rar50,
12}
13
14impl Signature {
15 pub const RAR15: &[u8; 7] = b"Rar!\x1a\x07\x00";
16 pub const RAR50: &[u8; 8] = b"Rar!\x1a\x07\x01\x00";
17
18 pub fn size(&self) -> u64 {
19 match self {
20 Self::Rar15 => 7,
21 Self::Rar50 => 8,
22 }
23 }
24
25 pub fn from_bytes(data: &[u8]) -> Option<Self> {
26 if data.len() >= 8 && data.starts_with(Self::RAR50) {
27 Some(Self::Rar50)
28 } else if data.len() >= 7 && data.starts_with(Self::RAR15) {
29 Some(Self::Rar15)
30 } else {
31 None
32 }
33 }
34}
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
38pub struct RawTimestamp {
39 pub nanos: i64,
40}
41
42impl RawTimestamp {
43 pub fn from_unix_nanos(nanos: i64) -> Self {
44 Self { nanos }
45 }
46
47 pub fn from_dos(dos_time: u32) -> Self {
48 let second = ((dos_time & 0x1f) * 2) as i64;
49 let minute = ((dos_time >> 5) & 0x3f) as i64;
50 let hour = ((dos_time >> 11) & 0x1f) as i64;
51 let day = ((dos_time >> 16) & 0x1f) as i64;
52 let month = ((dos_time >> 21) & 0x0f) as i64;
53 let year = ((dos_time >> 25) + 1980) as i64;
54
55 let days = (year - 1970) * 365 + (month - 1) * 30 + day;
56 let secs = days * 86400 + hour * 3600 + minute * 60 + second;
57 Self { nanos: secs * 1_000_000_000 }
58 }
59
60 pub fn saturating_add(self, add_nanos: i64) -> Self {
61 Self { nanos: self.nanos.saturating_add(add_nanos) }
62 }
63}
64
65pub fn parse_dos_datetime(dos_time: u32) -> RawTimestamp {
66 RawTimestamp::from_dos(dos_time)
67}
68
69pub fn parse_windows_filetime(filetime: u64) -> RawTimestamp {
70 const WINDOWS_TICK_NS: i128 = 100;
71 const EPOCH_DIFF: i128 = 11_644_473_600_000_000_000;
72 let unix_ns = (filetime as i128) * WINDOWS_TICK_NS - EPOCH_DIFF;
73 RawTimestamp::from_unix_nanos(unix_ns as i64)
74}