Skip to main content

gzip/
types.rs

1use std::fmt::Debug;
2use std::convert::TryFrom;
3use enumflags2::BitFlags;
4use crate::error::*;
5
6pub type Id = [u8; 2];
7pub type SubfieldId = [u8; 2];
8pub type Name = String;
9pub type Comment = String;
10pub type Crc16 = u16;
11pub type Crc32 = u32;
12
13#[derive(BitFlags, Debug, Copy, Clone, PartialEq)]
14#[repr(u8)]
15pub enum Flags {
16    Text = 1,
17    HeaderCrc = 2,
18    Extra = 4,
19    Name = 8,
20    Comment = 16,
21    Reserved0 = 32,
22    Reserved1 = 64,
23    Reserved2 = 128,
24}
25
26#[derive(BitFlags, Debug, Copy, Clone, PartialEq)]
27#[repr(u8)]
28pub enum CompressionFlags {
29    BestCompression = 2,
30    FastestCompression = 4,
31}
32
33#[derive(Debug, Copy, Clone, PartialEq)]
34#[repr(u8)]
35pub enum CompressionMethod {
36    Reserved0 = 0,
37    Reserved1 = 1,
38    Reserved2 = 2,
39    Reserved3 = 3,
40    Reserved4 = 4,
41    Reserved5 = 5,
42    Reserved6 = 6,
43    Reserved7 = 7,
44    Deflate = 8,
45}
46
47impl TryFrom<u8> for CompressionMethod {
48    type Error = Error;
49    fn try_from(byte: u8) -> std::result::Result<Self, Self::Error> {
50        use CompressionMethod::*;
51        match byte {
52            0 => Ok(Reserved0),
53            1 => Ok(Reserved1),
54            2 => Ok(Reserved2),
55            3 => Ok(Reserved3),
56            4 => Ok(Reserved4),
57            5 => Ok(Reserved5),
58            6 => Ok(Reserved6),
59            7 => Ok(Reserved7),
60            8 => Ok(Deflate),
61            _ => Err(Error(ErrorKind::InvalidCompressionMethod, None)),
62        }
63    }
64}
65
66impl Default for CompressionMethod {
67    fn default() -> Self { CompressionMethod::Deflate }
68}
69
70#[derive(Debug, Copy, Clone, PartialEq)]
71#[repr(u8)]
72pub enum OperatingSystem {
73    Fat = 0,
74    Amiga = 1,
75    Vms = 2,
76    Unix = 3,
77    VmCms = 4,
78    Atari = 5,
79    Hpfs = 6,
80    Macintosh = 7,
81    ZSystem = 8,
82    Cpm = 9,
83    Tops = 10,
84    Ntfs = 11,
85    Qdos = 12,
86    Acorn = 13,
87    Unknown = 255,
88}
89
90impl Default for OperatingSystem {
91    fn default() -> Self { OperatingSystem::Unknown }
92}
93
94impl TryFrom<u8> for OperatingSystem {
95    type Error = Error;
96    fn try_from(byte: u8) -> std::result::Result<Self, Self::Error> {
97        use OperatingSystem::*;
98        match byte {
99            0 => Ok(Fat),
100            1 => Ok(Amiga),
101            2 => Ok(Vms),
102            3 => Ok(Unix),
103            4 => Ok(VmCms),
104            5 => Ok(Atari),
105            6 => Ok(Hpfs),
106            7 => Ok(Macintosh),
107            8 => Ok(ZSystem),
108            9 => Ok(Cpm),
109            10 => Ok(Tops),
110            11 => Ok(Ntfs),
111            12 => Ok(Qdos),
112            13 => Ok(Acorn),
113            155 => Ok(Unknown),
114            _ => Err(Error(ErrorKind::InvalidCompressionMethod, None)),
115        }
116    }
117}
118
119#[derive(Debug, Copy, Clone, PartialEq)]
120pub enum SubFieldType {
121    ApolloFileTypeInformation,
122}
123
124impl From<SubFieldType> for [u8; 2] {
125    fn from(t: SubFieldType) -> Self {
126        use SubFieldType::*;
127        match t {
128            ApolloFileTypeInformation => [0x41, 0x70], // AP
129        }
130    }
131}
132
133impl Header {
134    pub const GZIP_ID: [u8; 2] = [0x1f, 0x8b];
135}
136
137#[derive(Default, Debug, Clone)]
138pub struct Extra {
139    pub length: u16,
140    pub subfield_id: SubfieldId,
141    pub data_length: u16,
142    pub data: Vec<u8>,
143}
144
145#[derive(Default, Debug, Clone)]
146pub struct Header {
147    pub id: Id,
148    pub compression_method: CompressionMethod,
149    pub flags: BitFlags<Flags>,
150    pub modification_time: u32,
151    pub compression_flags: BitFlags<CompressionFlags>,
152    pub operating_system: OperatingSystem,
153    pub extra: Option<Extra>,
154    pub name: Option<Name>,
155    pub comment: Option<Comment>,
156    pub crc: Option<Crc16>,
157}
158
159#[derive(Default, Clone)]
160pub struct Member {
161    pub header: Header,
162    pub data: Vec<u8>,
163    pub crc: Crc32,
164    pub input_size: u32,
165}
166
167impl Debug for Member {
168    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
169        f.debug_struct("GZIP Member")
170            .field("Header", &self.header)
171            .field("Read Data Size", &self.data.len())
172            .field("Input Size", &self.input_size)
173            .field("CRC32", &self.crc)
174            .finish()
175    }
176}