diff options
| author | Igor Tolmachev <me@igorek.dev> | 2024-07-01 19:12:40 +0900 |
|---|---|---|
| committer | Igor Tolmachev <me@igorek.dev> | 2024-07-02 18:59:00 +0900 |
| commit | 5d3d32ded672b67471d9d7c85ebbe691129cc51c (patch) | |
| tree | 1f9a82196d69cfec34af595a659e4d74a80b0c92 /src/zip/file_info.rs | |
| parent | 6d5f8f046b3b24e50cb1a0e7751c6bc9170ed9d1 (diff) | |
| download | archivator-5d3d32ded672b67471d9d7c85ebbe691129cc51c.tar.gz archivator-5d3d32ded672b67471d9d7c85ebbe691129cc51c.zip | |
Add compression support (lzma and xz are broken)
Diffstat (limited to 'src/zip/file_info.rs')
| -rw-r--r-- | src/zip/file_info.rs | 163 |
1 files changed, 0 insertions, 163 deletions
diff --git a/src/zip/file_info.rs b/src/zip/file_info.rs deleted file mode 100644 index 92d52f7..0000000 --- a/src/zip/file_info.rs +++ /dev/null | |||
| @@ -1,163 +0,0 @@ | |||
| 1 | use crate::driver::ArchiveFileInfo; | ||
| 2 | use crate::zip::{ZipError, ZipResult}; | ||
| 3 | use chrono::{DateTime, Local}; | ||
| 4 | |||
| 5 | #[derive(Debug, Clone)] | ||
| 6 | pub enum CompressionMethod { | ||
| 7 | Store, | ||
| 8 | Deflate, | ||
| 9 | BZIP2, | ||
| 10 | LZMA, | ||
| 11 | ZStd, | ||
| 12 | XZ, | ||
| 13 | } | ||
| 14 | |||
| 15 | impl CompressionMethod { | ||
| 16 | pub(crate) fn from_struct_id(id: u16) -> ZipResult<Self> { | ||
| 17 | match id { | ||
| 18 | 0 => Ok(Self::Store), | ||
| 19 | 8 => Ok(Self::Deflate), | ||
| 20 | 12 => Ok(Self::BZIP2), | ||
| 21 | 14 => Ok(Self::LZMA), | ||
| 22 | 93 => Ok(Self::ZStd), | ||
| 23 | 95 => Ok(Self::XZ), | ||
| 24 | 1..=7 | 9..=11 | 13 | 15..=20 | 94 | 96..=99 => { | ||
| 25 | Err(ZipError::UnsupportedCompressionMethod.into()) | ||
| 26 | } | ||
| 27 | 21..=92 | 100.. => Err(ZipError::InvalidCompressionMethod.into()), | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | #[derive(Debug, Clone)] | ||
| 33 | pub struct BitFlag { | ||
| 34 | flag: u16, | ||
| 35 | } | ||
| 36 | |||
| 37 | pub mod bit { | ||
| 38 | #[derive(Debug, PartialEq, Eq)] | ||
| 39 | pub enum DeflateMode { | ||
| 40 | Normal, | ||
| 41 | Maximum, | ||
| 42 | Fast, | ||
| 43 | SuperFast, | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | macro_rules! get_set_bit_flag { | ||
| 48 | {$($get:ident $set:ident $bit:expr)+} => { | ||
| 49 | $( | ||
| 50 | pub fn $get(&self) -> bool { | ||
| 51 | self.get_bit($bit) | ||
| 52 | } | ||
| 53 | |||
| 54 | pub fn $set(&mut self, enable: bool) { | ||
| 55 | self.set_bit($bit, enable); | ||
| 56 | } | ||
| 57 | )* | ||
| 58 | }; | ||
| 59 | } | ||
| 60 | |||
| 61 | impl BitFlag { | ||
| 62 | pub fn new(flag: u16) -> Self { | ||
| 63 | Self { flag } | ||
| 64 | } | ||
| 65 | |||
| 66 | #[inline] | ||
| 67 | fn get_bit(&self, bit: u32) -> bool { | ||
| 68 | (self.flag & 2u16.pow(bit)) > 0 | ||
| 69 | } | ||
| 70 | |||
| 71 | #[inline] | ||
| 72 | fn set_bit(&mut self, bit: u32, enable: bool) { | ||
| 73 | if enable { | ||
| 74 | self.flag |= 2u16.pow(bit); | ||
| 75 | } else { | ||
| 76 | self.flag &= !2u16.pow(bit); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | pub fn deflate_mode(&self) -> bit::DeflateMode { | ||
| 81 | match self.flag & 6 { | ||
| 82 | 0 => bit::DeflateMode::Normal, | ||
| 83 | 2 => bit::DeflateMode::Maximum, | ||
| 84 | 4 => bit::DeflateMode::Fast, | ||
| 85 | 6 => bit::DeflateMode::SuperFast, | ||
| 86 | _ => panic!("impossible"), | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | pub fn set_deflate_mode(&mut self, mode: bit::DeflateMode) { | ||
| 91 | match mode { | ||
| 92 | bit::DeflateMode::Normal => { | ||
| 93 | self.set_bit(1, false); | ||
| 94 | self.set_bit(2, false); | ||
| 95 | } | ||
| 96 | bit::DeflateMode::Maximum => { | ||
| 97 | self.set_bit(1, true); | ||
| 98 | self.set_bit(2, false); | ||
| 99 | } | ||
| 100 | bit::DeflateMode::Fast => { | ||
| 101 | self.set_bit(1, false); | ||
| 102 | self.set_bit(2, true); | ||
| 103 | } | ||
| 104 | bit::DeflateMode::SuperFast => { | ||
| 105 | self.set_bit(1, true); | ||
| 106 | self.set_bit(2, true); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | get_set_bit_flag! { | ||
| 112 | is_encrypted set_encrypted 0 | ||
| 113 | is_imploding_8k set_imploding_8k 1 | ||
| 114 | is_imploding_3sf_trees set_imploding_3sf_trees 2 | ||
| 115 | is_lzma_has_eos_marker set_lzma_has_eos_marker 1 | ||
| 116 | is_has_data_descriptor set_has_data_descriptor 3 | ||
| 117 | is_patched_data set_patched_data 5 | ||
| 118 | is_strong_encryption set_strong_encryption 6 | ||
| 119 | is_utf8 set_utf8 11 | ||
| 120 | is_cd_encryption set_cd_encryption 13 | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | #[derive(Debug, Clone)] | ||
| 125 | pub struct ZipFileInfo { | ||
| 126 | pub compression_method: CompressionMethod, | ||
| 127 | pub bit_flag: BitFlag, | ||
| 128 | pub datetime: DateTime<Local>, | ||
| 129 | pub crc: u32, | ||
| 130 | pub compressed_size: u64, | ||
| 131 | pub size: u64, | ||
| 132 | pub header_pointer: u64, | ||
| 133 | pub name: String, | ||
| 134 | pub comment: String, | ||
| 135 | } | ||
| 136 | |||
| 137 | impl ZipFileInfo { | ||
| 138 | pub fn new( | ||
| 139 | compression_method: CompressionMethod, | ||
| 140 | bit_flag: BitFlag, | ||
| 141 | datetime: DateTime<Local>, | ||
| 142 | crc: u32, | ||
| 143 | compressed_size: u64, | ||
| 144 | size: u64, | ||
| 145 | header_pointer: u64, | ||
| 146 | name: String, | ||
| 147 | comment: String, | ||
| 148 | ) -> Self { | ||
| 149 | Self { | ||
| 150 | compression_method, | ||
| 151 | bit_flag, | ||
| 152 | datetime, | ||
| 153 | crc, | ||
| 154 | compressed_size, | ||
| 155 | size, | ||
| 156 | header_pointer, | ||
| 157 | name, | ||
| 158 | comment, | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | impl ArchiveFileInfo for ZipFileInfo {} | ||
