@@ -15,7 +15,7 @@ use std::{
15
15
collections:: { HashMap , HashSet } ,
16
16
fs:: { create_dir_all, File } ,
17
17
io:: { self , BufWriter , Read , Result , Seek , SeekFrom , Write } ,
18
- path:: { Path , PathBuf } ,
18
+ path:: Path ,
19
19
} ;
20
20
21
21
use byteorder:: { LittleEndian , ReadBytesExt , WriteBytesExt } ;
@@ -32,7 +32,7 @@ use crate::{
32
32
33
33
// public static void CreateFromDirectory (string sourceDirectoryName, System.IO.Stream destination);
34
34
35
- /// Creates a zip archive in the specified stream that contains the files and directories from the specified directory.
35
+ /// Creates an archive in the specified stream that contains the files and directories from the specified directory.
36
36
///
37
37
/// # Errors
38
38
///
57
57
58
58
// public static void CreateFromDirectory (string sourceDirectoryName, string destinationArchiveFileName);
59
59
60
- /// Creates a zip archive that contains the files and directories from the specified directory.
60
+ /// Creates an archive that contains the files and directories from the specified directory.
61
61
///
62
62
/// # Errors
63
63
///
@@ -82,20 +82,28 @@ where
82
82
83
83
// public static void ExtractToDirectory (System.IO.Stream source, string destinationDirectoryName, bool overwriteFiles);
84
84
85
- /// Extracts all the files from the zip archive stored in the specified stream and places them in the specified destination directory on the file system, and optionally allows choosing if the files in the destination directory should be overwritten.
85
+ /// Extracts all the files from the archive stored in the specified stream and places them in the specified destination directory on the file system, and optionally allows choosing if the files in the destination directory should be overwritten.
86
86
///
87
87
/// # Errors
88
88
///
89
89
/// This function will return an error if any io fails.
90
90
pub fn extract_to_directory < R , P > (
91
- source : R ,
92
- destination_directory_name : P ,
91
+ source : & mut R ,
92
+ destination_directory_name : & P ,
93
93
overwrite_files : bool ,
94
+ hash_map : Option < HashMap < u64 , String > > ,
94
95
) -> io:: Result < ( ) >
95
96
where
96
97
P : AsRef < Path > ,
97
- R : Read ,
98
+ R : Read + Seek ,
98
99
{
100
+ let map = if let Some ( hash_map) = hash_map {
101
+ hash_map
102
+ } else {
103
+ get_red4_hashes ( )
104
+ } ;
105
+
106
+ extract_archive ( source, destination_directory_name, overwrite_files, & map)
99
107
}
100
108
101
109
// public static void ExtractToDirectory (string sourceArchiveFileName, string destinationDirectoryName, bool overwriteFiles);
@@ -106,17 +114,28 @@ where
106
114
///
107
115
/// This function will return an error if any io fails.
108
116
pub fn extract_to_directory_path < P > (
109
- source_archive_file_name : P ,
110
- destination_directory_name : P ,
117
+ source_archive_file_name : & P ,
118
+ destination_directory_name : & P ,
111
119
overwrite_files : bool ,
120
+ hash_map : Option < HashMap < u64 , String > > ,
112
121
) -> io:: Result < ( ) >
113
122
where
114
123
P : AsRef < Path > ,
115
124
{
125
+ let map = if let Some ( hash_map) = hash_map {
126
+ hash_map
127
+ } else {
128
+ get_red4_hashes ( )
129
+ } ;
130
+
131
+ let archive_file = File :: open ( source_archive_file_name) ?;
132
+ let mut archive_reader = io:: BufReader :: new ( archive_file) ;
133
+
116
134
extract_archive (
117
- source_archive_file_name ,
135
+ & mut archive_reader ,
118
136
destination_directory_name,
119
137
overwrite_files,
138
+ & map,
120
139
)
121
140
}
122
141
@@ -126,9 +145,14 @@ pub enum ArchiveMode {
126
145
Update ,
127
146
}
128
147
148
+ /*
149
+ TODO We don't support different modes for now
150
+ needs a wrapper class for archives
151
+
152
+
129
153
// public static System.IO.Compression.ZipArchive Open (string archiveFileName, System.IO.Compression.ZipArchiveMode mode);
130
154
131
- /// Opens a zip archive at the specified path and in the specified mode.
155
+ /// Opens an archive at the specified path and in the specified mode.
132
156
///
133
157
/// # Errors
134
158
///
@@ -140,9 +164,11 @@ where
140
164
todo!()
141
165
}
142
166
167
+ */
168
+
143
169
// public static System.IO.Compression.ZipArchive OpenRead (string archiveFileName);
144
170
145
- /// Opens a zip archive for reading at the specified path.
171
+ /// Opens an archive for reading at the specified path.
146
172
///
147
173
/// # Errors
148
174
///
@@ -151,7 +177,7 @@ pub fn open_read<P>(archive_file_name: P) -> io::Result<Archive>
151
177
where
152
178
P : AsRef < Path > ,
153
179
{
154
- todo ! ( )
180
+ Archive :: from_file ( archive_file_name )
155
181
}
156
182
157
183
/////////////////////////////////////////////////////////////////////////////////////////
@@ -167,15 +193,18 @@ where
167
193
/// # Errors
168
194
///
169
195
/// This function will return an error if any parsing fails
170
- fn extract_archive < P > ( in_file : & P , out_dir : & P , hash_map : & HashMap < u64 , String > ) -> io:: Result < ( ) >
196
+ fn extract_archive < P , R > (
197
+ archive_reader : & mut R ,
198
+ out_dir : & P ,
199
+ overwrite_files : bool ,
200
+ hash_map : & HashMap < u64 , String > ,
201
+ ) -> io:: Result < ( ) >
171
202
where
172
203
P : AsRef < Path > ,
204
+ R : Read + Seek ,
173
205
{
174
206
// parse archive headers
175
- let archive = Archive :: from_file ( in_file) ?;
176
-
177
- let archive_file = File :: open ( in_file) ?;
178
- let mut archive_reader = io:: BufReader :: new ( archive_file) ;
207
+ let archive = Archive :: from_reader ( archive_reader) ?;
179
208
180
209
for ( hash, file_entry) in archive. index . file_entries . iter ( ) {
181
210
// get filename
@@ -188,12 +217,21 @@ where
188
217
}
189
218
190
219
// name or hash is a relative path
191
- let mut : PathBuf
192
- let outfile = out_dir. join ( name_or_hash) ;
220
+ let outfile = out_dir. as_ref ( ) . join ( name_or_hash) ;
193
221
create_dir_all ( outfile. parent ( ) . expect ( "Could not create an out_dir" ) ) ?;
194
222
195
223
// extract to stream
196
- let mut fs = File :: create ( outfile) ?;
224
+ let mut fs = if overwrite_files {
225
+ File :: create ( outfile) ?
226
+ } else {
227
+ File :: options ( )
228
+ . read ( true )
229
+ . write ( true )
230
+ . create_new ( true )
231
+ . open ( outfile) ?
232
+ } ;
233
+
234
+ //let mut fs = File::create(outfile)?;
197
235
let mut file_writer = BufWriter :: new ( & mut fs) ;
198
236
// decompress main file
199
237
let start_index = file_entry. segments_start ;
@@ -209,7 +247,7 @@ where
209
247
archive_reader. read_exact ( & mut buffer[ ..] ) ?;
210
248
file_writer. write_all ( & buffer) ?;
211
249
} else {
212
- decompress_segment ( & mut archive_reader, segment, & mut file_writer) ?;
250
+ decompress_segment ( archive_reader, segment, & mut file_writer) ?;
213
251
}
214
252
}
215
253
0 commit comments