diff options
| author | Igor Tolmachev <me@igorek.dev> | 2024-06-25 23:23:19 +0900 |
|---|---|---|
| committer | Igor Tolmachev <me@igorek.dev> | 2024-06-25 23:23:19 +0900 |
| commit | 3c6dffa5ccfc72804a76f2090738721b90b10ce8 (patch) | |
| tree | 1026d7ea77f938aaf22470741eae3f01eced7ce9 /src | |
| parent | a4e92ed9bec1f5879eb1c20dfe281c4d25ed5f89 (diff) | |
| download | archivator-3c6dffa5ccfc72804a76f2090738721b90b10ce8.tar.gz archivator-3c6dffa5ccfc72804a76f2090738721b90b10ce8.zip | |
Add bit flag logic
Diffstat (limited to 'src')
| -rw-r--r-- | src/zip/driver.rs | 3 | ||||
| -rw-r--r-- | src/zip/file.rs | 94 | ||||
| -rw-r--r-- | src/zip/mod.rs | 3 | ||||
| -rw-r--r-- | src/zip/tests.rs | 42 |
4 files changed, 141 insertions, 1 deletions
diff --git a/src/zip/driver.rs b/src/zip/driver.rs index 8e8c27c..c9a5155 100644 --- a/src/zip/driver.rs +++ b/src/zip/driver.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use crate::driver::{ArchiveRead, ArchiveWrite, Driver}; | 1 | use crate::driver::{ArchiveRead, ArchiveWrite, Driver}; |
| 2 | use crate::zip::file::CompressionMethod; | 2 | use crate::zip::file::{BitFlag, CompressionMethod}; |
| 3 | use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, EOCDR64}; | 3 | use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, EOCDR64}; |
| 4 | use crate::zip::{ZipError, ZipFile, ZipResult}; | 4 | use crate::zip::{ZipError, ZipFile, ZipResult}; |
| 5 | use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime}; | 5 | use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime}; |
| @@ -138,6 +138,7 @@ impl<IO: Read + Seek> ArchiveRead for Zip<IO> { | |||
| 138 | name.clone(), | 138 | name.clone(), |
| 139 | ZipFile::new( | 139 | ZipFile::new( |
| 140 | CompressionMethod::from_struct_id(cdr.compression_method)?, | 140 | CompressionMethod::from_struct_id(cdr.compression_method)?, |
| 141 | BitFlag::new(cdr.bit_flag), | ||
| 141 | NaiveDateTime::new( | 142 | NaiveDateTime::new( |
| 142 | NaiveDate::from_ymd_opt( | 143 | NaiveDate::from_ymd_opt( |
| 143 | (cdr.dos_date as i32 >> 9 & 0x7F) + 1980, | 144 | (cdr.dos_date as i32 >> 9 & 0x7F) + 1980, |
diff --git a/src/zip/file.rs b/src/zip/file.rs index f735d65..b4f2d7c 100644 --- a/src/zip/file.rs +++ b/src/zip/file.rs | |||
| @@ -28,8 +28,100 @@ impl CompressionMethod { | |||
| 28 | } | 28 | } |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | pub struct BitFlag { | ||
| 32 | pub flag: u16, | ||
| 33 | } | ||
| 34 | |||
| 35 | pub mod bit { | ||
| 36 | #[derive(Debug, PartialEq, Eq)] | ||
| 37 | pub enum DeflateMode { | ||
| 38 | Normal, | ||
| 39 | Maximum, | ||
| 40 | Fast, | ||
| 41 | SuperFast, | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | macro_rules! get_set_bit_flag { | ||
| 46 | {$($get:ident $set:ident $bit:expr)+} => { | ||
| 47 | $( | ||
| 48 | pub fn $get(&self) -> bool { | ||
| 49 | self.get_bit($bit) | ||
| 50 | } | ||
| 51 | |||
| 52 | pub fn $set(&mut self, enable: bool) { | ||
| 53 | self.set_bit($bit, enable); | ||
| 54 | } | ||
| 55 | )* | ||
| 56 | }; | ||
| 57 | } | ||
| 58 | |||
| 59 | impl BitFlag { | ||
| 60 | pub fn new(flag: u16) -> Self { | ||
| 61 | Self { flag } | ||
| 62 | } | ||
| 63 | |||
| 64 | #[inline] | ||
| 65 | fn get_bit(&self, bit: u32) -> bool { | ||
| 66 | (self.flag & 2u16.pow(bit)) > 0 | ||
| 67 | } | ||
| 68 | |||
| 69 | #[inline] | ||
| 70 | fn set_bit(&mut self, bit: u32, enable: bool) { | ||
| 71 | if enable { | ||
| 72 | self.flag |= 2u16.pow(bit); | ||
| 73 | } else { | ||
| 74 | self.flag &= !2u16.pow(bit); | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | pub fn deflate_mode(&self) -> bit::DeflateMode { | ||
| 79 | match self.flag & 6 { | ||
| 80 | 0 => bit::DeflateMode::Normal, | ||
| 81 | 2 => bit::DeflateMode::Maximum, | ||
| 82 | 4 => bit::DeflateMode::Fast, | ||
| 83 | 6 => bit::DeflateMode::SuperFast, | ||
| 84 | _ => panic!("impossible"), | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | pub fn set_deflate_mode(&mut self, mode: bit::DeflateMode) { | ||
| 89 | match mode { | ||
| 90 | bit::DeflateMode::Normal => { | ||
| 91 | self.set_bit(1, false); | ||
| 92 | self.set_bit(2, false); | ||
| 93 | } | ||
| 94 | bit::DeflateMode::Maximum => { | ||
| 95 | self.set_bit(1, true); | ||
| 96 | self.set_bit(2, false); | ||
| 97 | } | ||
| 98 | bit::DeflateMode::Fast => { | ||
| 99 | self.set_bit(1, false); | ||
| 100 | self.set_bit(2, true); | ||
| 101 | } | ||
| 102 | bit::DeflateMode::SuperFast => { | ||
| 103 | self.set_bit(1, true); | ||
| 104 | self.set_bit(2, true); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | get_set_bit_flag! { | ||
| 110 | is_encrypted set_encrypted 0 | ||
| 111 | is_imploding_8k set_imploding_8k 1 | ||
| 112 | is_imploding_3sf_trees set_imploding_3sf_trees 2 | ||
| 113 | is_lzma_has_eos_marker set_lzma_has_eos_marker 1 | ||
| 114 | is_has_data_descriptor set_has_data_descriptor 3 | ||
| 115 | is_patched_data set_patched_data 5 | ||
| 116 | is_strong_encryption set_strong_encryption 6 | ||
| 117 | is_utf8 set_utf8 11 | ||
| 118 | is_cd_encryption set_cd_encryption 13 | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 31 | pub struct ZipFile { | 122 | pub struct ZipFile { |
| 32 | pub compression_method: CompressionMethod, | 123 | pub compression_method: CompressionMethod, |
| 124 | pub bit_flag: BitFlag, | ||
| 33 | pub datetime: DateTime<Local>, | 125 | pub datetime: DateTime<Local>, |
| 34 | pub crc: u32, | 126 | pub crc: u32, |
| 35 | pub compressed_size: u64, | 127 | pub compressed_size: u64, |
| @@ -42,6 +134,7 @@ pub struct ZipFile { | |||
| 42 | impl ZipFile { | 134 | impl ZipFile { |
| 43 | pub fn new( | 135 | pub fn new( |
| 44 | compression_method: CompressionMethod, | 136 | compression_method: CompressionMethod, |
| 137 | bit_flag: BitFlag, | ||
| 45 | datetime: DateTime<Local>, | 138 | datetime: DateTime<Local>, |
| 46 | crc: u32, | 139 | crc: u32, |
| 47 | compressed_size: u64, | 140 | compressed_size: u64, |
| @@ -52,6 +145,7 @@ impl ZipFile { | |||
| 52 | ) -> Self { | 145 | ) -> Self { |
| 53 | Self { | 146 | Self { |
| 54 | compression_method, | 147 | compression_method, |
| 148 | bit_flag, | ||
| 55 | datetime, | 149 | datetime, |
| 56 | crc, | 150 | crc, |
| 57 | compressed_size, | 151 | compressed_size, |
diff --git a/src/zip/mod.rs b/src/zip/mod.rs index 8601526..23cadb9 100644 --- a/src/zip/mod.rs +++ b/src/zip/mod.rs | |||
| @@ -6,3 +6,6 @@ mod structs; | |||
| 6 | pub use driver::Zip; | 6 | pub use driver::Zip; |
| 7 | pub use error::{ZipError, ZipResult}; | 7 | pub use error::{ZipError, ZipResult}; |
| 8 | pub use file::ZipFile; | 8 | pub use file::ZipFile; |
| 9 | |||
| 10 | #[cfg(test)] | ||
| 11 | mod tests; | ||
diff --git a/src/zip/tests.rs b/src/zip/tests.rs new file mode 100644 index 0000000..d64e626 --- /dev/null +++ b/src/zip/tests.rs | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | use crate::zip::file::{bit::DeflateMode, BitFlag}; | ||
| 2 | |||
| 3 | #[test] | ||
| 4 | fn test_bit_flag() { | ||
| 5 | macro_rules! bit_flag { | ||
| 6 | ($($get:ident $set:ident)+) => { | ||
| 7 | $( | ||
| 8 | let mut bit_flag = BitFlag::new(0); | ||
| 9 | |||
| 10 | assert_eq!(bit_flag.$get(), false); | ||
| 11 | bit_flag.$set(true); | ||
| 12 | assert_eq!(bit_flag.$get(), true); | ||
| 13 | bit_flag.$set(false); | ||
| 14 | assert_eq!(bit_flag.$get(), false); | ||
| 15 | )+ | ||
| 16 | }; | ||
| 17 | } | ||
| 18 | |||
| 19 | bit_flag!( | ||
| 20 | is_encrypted set_encrypted | ||
| 21 | is_imploding_8k set_imploding_8k | ||
| 22 | is_imploding_3sf_trees set_imploding_3sf_trees | ||
| 23 | is_lzma_has_eos_marker set_lzma_has_eos_marker | ||
| 24 | is_has_data_descriptor set_has_data_descriptor | ||
| 25 | is_patched_data set_patched_data | ||
| 26 | is_strong_encryption set_strong_encryption | ||
| 27 | is_utf8 set_utf8 | ||
| 28 | is_cd_encryption set_cd_encryption | ||
| 29 | ); | ||
| 30 | |||
| 31 | let mut bit_flag = BitFlag::new(0); | ||
| 32 | |||
| 33 | assert_eq!(bit_flag.deflate_mode(), DeflateMode::Normal); | ||
| 34 | bit_flag.set_deflate_mode(DeflateMode::Maximum); | ||
| 35 | assert_eq!(bit_flag.deflate_mode(), DeflateMode::Maximum); | ||
| 36 | bit_flag.set_deflate_mode(DeflateMode::Fast); | ||
| 37 | assert_eq!(bit_flag.deflate_mode(), DeflateMode::Fast); | ||
| 38 | bit_flag.set_deflate_mode(DeflateMode::SuperFast); | ||
| 39 | assert_eq!(bit_flag.deflate_mode(), DeflateMode::SuperFast); | ||
| 40 | bit_flag.set_deflate_mode(DeflateMode::Normal); | ||
| 41 | assert_eq!(bit_flag.deflate_mode(), DeflateMode::Normal); | ||
| 42 | } | ||
