aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/zip/driver.rs3
-rw-r--r--src/zip/file.rs94
-rw-r--r--src/zip/mod.rs3
-rw-r--r--src/zip/tests.rs42
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 @@
1use crate::driver::{ArchiveRead, ArchiveWrite, Driver}; 1use crate::driver::{ArchiveRead, ArchiveWrite, Driver};
2use crate::zip::file::CompressionMethod; 2use crate::zip::file::{BitFlag, CompressionMethod};
3use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, EOCDR64}; 3use crate::zip::structs::{deserialize, EOCDR64Locator, ExtraHeader, CDR, EOCDR, EOCDR64};
4use crate::zip::{ZipError, ZipFile, ZipResult}; 4use crate::zip::{ZipError, ZipFile, ZipResult};
5use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime}; 5use 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
31pub struct BitFlag {
32 pub flag: u16,
33}
34
35pub mod bit {
36 #[derive(Debug, PartialEq, Eq)]
37 pub enum DeflateMode {
38 Normal,
39 Maximum,
40 Fast,
41 SuperFast,
42 }
43}
44
45macro_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
59impl 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
31pub struct ZipFile { 122pub 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 {
42impl ZipFile { 134impl 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;
6pub use driver::Zip; 6pub use driver::Zip;
7pub use error::{ZipError, ZipResult}; 7pub use error::{ZipError, ZipResult};
8pub use file::ZipFile; 8pub use file::ZipFile;
9
10#[cfg(test)]
11mod 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 @@
1use crate::zip::file::{bit::DeflateMode, BitFlag};
2
3#[test]
4fn 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}