33using System . IO ;
44using System . IO . Compression ;
55using System . Linq ;
6- using Fallout . Common . Utilities . Collections ;
7- using ICSharpCode . SharpZipLib . BZip2 ;
8- using ICSharpCode . SharpZipLib . GZip ;
9- using ICSharpCode . SharpZipLib . Tar ;
10- using ICSharpCode . SharpZipLib . Zip ;
116using SharpCompress . Common ;
127using SharpCompress . Readers ;
13- using ZipFile = ICSharpCode . SharpZipLib . Zip . ZipFile ;
8+ using SharpCompress . Writers ;
9+ using SharpCompress . Writers . Zip ;
10+ using Fallout . Common . Utilities . Collections ;
1411
1512namespace Fallout . Common . IO ;
1613
@@ -110,14 +107,16 @@ public static void ZipTo(
110107 filter ??= _ => true ;
111108 List < AbsolutePath > files = directory . GetFiles ( depth : int . MaxValue ) . Where ( filter ) . ToList ( ) ;
112109
113- using FileStream fileStream = File . Open ( archiveFile , fileMode , FileAccess . ReadWrite ) ;
114- using ZipArchive zipArchive = new ( fileStream , ZipArchiveMode . Create ) ;
110+ using var fileStream = File . Open ( archiveFile , fileMode , FileAccess . ReadWrite ) ;
111+ using var writer = WriterFactory . OpenWriter (
112+ fileStream ,
113+ ArchiveType . Zip ,
114+ new ZipWriterOptions ( CompressionType . Deflate , compressionLevel . ToSharpCompressCompressionLevel ( ) ) ) ;
115115
116116 void AddFile ( AbsolutePath file )
117117 {
118- RelativePath relativePath = directory . GetRelativePathTo ( file ) ;
119- string entryName = ZipEntry . CleanName ( relativePath ) ;
120- zipArchive . CreateEntryFromFile ( file , entryName , compressionLevel ) ;
118+ var entryName = directory . GetUnixRelativePathTo ( file ) ;
119+ writer . Write ( entryName , file ) ;
121120 }
122121
123122 files . ForEach ( AddFile ) ;
@@ -131,22 +130,7 @@ void AddFile(AbsolutePath file)
131130 /// <param name="directory">The directory into which the archive's contents are extracted.</param>
132131 public static void UnZipTo ( this AbsolutePath archiveFile , AbsolutePath directory )
133132 {
134- using FileStream fileStream = File . OpenRead ( archiveFile ) ;
135- using ZipFile zipFile = new ( fileStream ) ;
136-
137- IEnumerable < ZipEntry > entries = zipFile . Cast < ZipEntry > ( ) . Where ( x => ! x . IsDirectory ) ;
138-
139- void HandleEntry ( ZipEntry entry )
140- {
141- AbsolutePath file = directory / entry . Name ;
142- Directory . CreateDirectory ( file . Parent . NotNull ( ) ) ;
143-
144- using Stream entryStream = zipFile . GetInputStream ( entry ) ;
145- using FileStream outputStream = File . Open ( file , FileMode . Create ) ;
146- entryStream . CopyTo ( outputStream ) ;
147- }
148-
149- entries . ForEach ( HandleEntry ) ;
133+ UncompressArchive ( archiveFile , directory ) ;
150134 }
151135
152136 /// <summary>
@@ -160,8 +144,10 @@ public static void TarGZipTo(
160144 this AbsolutePath baseDirectory ,
161145 AbsolutePath archiveFile ,
162146 IEnumerable < AbsolutePath > files ,
163- FileMode fileMode = FileMode . CreateNew ) =>
164- CompressTar ( baseDirectory , archiveFile , files . ToList ( ) , fileMode , x => new GZipOutputStream ( x ) ) ;
147+ FileMode fileMode = FileMode . CreateNew )
148+ {
149+ CompressTar ( baseDirectory , archiveFile , files . ToList ( ) , fileMode , CompressionType . GZip ) ;
150+ }
165151
166152 /// <summary>
167153 /// Compresses <paramref name="directory" /> into a gzip-compressed tar archive at <paramref name="archiveFile" />.
@@ -195,8 +181,10 @@ public static void TarBZip2To(
195181 this AbsolutePath directory ,
196182 AbsolutePath archiveFile ,
197183 IEnumerable < AbsolutePath > files ,
198- FileMode fileMode = FileMode . CreateNew ) =>
199- CompressTar ( directory , archiveFile , files . ToList ( ) , fileMode , x => new BZip2OutputStream ( x ) ) ;
184+ FileMode fileMode = FileMode . CreateNew )
185+ {
186+ CompressTar ( directory , archiveFile , files . ToList ( ) , fileMode , CompressionType . BZip2 ) ;
187+ }
200188
201189 /// <summary>
202190 /// Compresses <paramref name="directory" /> into a bzip2-compressed tar archive at <paramref name="archiveFile" />.
@@ -219,98 +207,103 @@ public static void TarBZip2To(
219207 directory . TarBZip2To ( archiveFile , files , fileMode ) ;
220208 }
221209
222- /// <summary>
210+ /// <summary>
223211 /// Extracts the contents of a gzip-compressed tar archive at <paramref name="archiveFile" /> into <paramref name="directory" />.
224212 /// Destination directory is created, and conflicting files are overwritten.
225213 /// </summary>
226214 /// <param name="archiveFile">The tar.gz archive file to extract.</param>
227215 /// <param name="directory">The directory into which the archive's contents are extracted.</param>
228- public static void UnTarGZipTo ( this AbsolutePath archiveFile , AbsolutePath directory ) =>
229- UncompressTar ( archiveFile , directory , x => new GZipInputStream ( x ) ) ;
216+ public static void UnTarGZipTo ( this AbsolutePath archiveFile , AbsolutePath directory )
217+ {
218+ UncompressArchive ( archiveFile , directory ) ;
219+ }
230220
231- /// <summary>
221+ /// <summary>
232222 /// Extracts the contents of a bzip2-compressed tar archive at <paramref name="archiveFile" /> into <paramref name="directory" />.
233223 /// Destination directory is created, and conflicting files are overwritten.
234224 /// </summary>
235225 /// <param name="archiveFile">The tar.bz2 archive file to extract.</param>
236226 /// <param name="directory">The directory into which the archive's contents are extracted.</param>
237- public static void UnTarBZip2To ( this AbsolutePath archiveFile , AbsolutePath directory ) =>
238- UncompressTar ( archiveFile , directory , x => new BZip2InputStream ( x ) ) ;
227+ public static void UnTarBZip2To ( this AbsolutePath archiveFile , AbsolutePath directory )
228+ {
229+ UncompressArchive ( archiveFile , directory ) ;
230+ }
239231
240- /// <summary>
241- /// Extracts the contents of an xz-compressed tar archive at <paramref name="archive " /> into <paramref name="directory" />.
232+ /// <summary>
233+ /// Extracts the contents of an xz-compressed tar archive at <paramref name="archiveFile " /> into <paramref name="directory" />.
242234 /// Destination directory is created, and conflicting files are skipped.
243235 /// </summary>
244- /// <param name="archive ">The tar.xz archive file to extract.</param>
236+ /// <param name="archiveFile ">The tar.xz archive file to extract.</param>
245237 /// <param name="directory">The directory into which the archive's contents are extracted.</param>
246- public static void UnTarXzTo ( this AbsolutePath archive , AbsolutePath directory )
238+ public static void UnTarXzTo ( this AbsolutePath archiveFile , AbsolutePath directory )
247239 {
248- using Stream stream = File . OpenRead ( archive ) ;
249- using IReader reader = ReaderFactory . OpenReader ( stream ) ;
250-
251- while ( reader . MoveToNextEntry ( ) )
252- {
253- if ( reader . Entry . IsDirectory )
254- {
255- continue ;
256- }
257-
258- reader . WriteEntryToDirectory ( directory , new ExtractionOptions
259- {
260- ExtractFullPath = true ,
261- Overwrite = true
262- } ) ;
263- }
240+ UncompressArchive ( archiveFile , directory ) ;
264241 }
265242
266243 /// <summary>
267- /// Compresses the given <paramref name="files" /> into a tar archive at <paramref name="archiveFile" />, wrapping the underlying
268- /// file stream with the compression stream produced by <paramref name="outputStreamFactory " />.
244+ /// Compresses the given <paramref name="files" /> into a tar archive at <paramref name="archiveFile" /> using
245+ /// <paramref name="compressionType " />.
269246 /// </summary>
270247 /// <param name="baseDirectory">The base directory used to compute the relative entry names of the archived files.</param>
271248 /// <param name="archiveFile">The archive file to create.</param>
272249 /// <param name="files">The files to add to the archive.</param>
273250 /// <param name="fileMode">The <see cref="FileMode" /> used to open the archive file.</param>
274- /// <param name="outputStreamFactory">A factory that wraps the raw archive file stream with the desired compression stream .</param>
251+ /// <param name="compressionType">The compression type to use for the archive .</param>
275252 private static void CompressTar (
276253 AbsolutePath baseDirectory ,
277254 AbsolutePath archiveFile ,
278255 IReadOnlyCollection < AbsolutePath > files ,
279256 FileMode fileMode ,
280- Func < Stream , Stream > outputStreamFactory )
257+ CompressionType compressionType )
281258 {
282259 archiveFile . Parent . CreateDirectory ( ) ;
283-
284- using FileStream fileStream = File . Open ( archiveFile , fileMode , FileAccess . ReadWrite ) ;
285- using Stream outputStream = outputStreamFactory ( fileStream ) ;
286- using TarArchive tarArchive = TarArchive . CreateOutputTarArchive ( outputStream ) ;
260+ using var fileStream = File . Open ( archiveFile , fileMode , FileAccess . ReadWrite ) ;
261+ using var writer = WriterFactory . OpenWriter ( fileStream , ArchiveType . Tar , new WriterOptions ( compressionType ) ) ;
287262
288263 void AddFile ( AbsolutePath file )
289264 {
290- TarEntry entry = TarEntry . CreateEntryFromFile ( file ) ;
291- entry . Name = baseDirectory . GetUnixRelativePathTo ( file ) ;
292-
293- tarArchive . WriteEntry ( entry , false ) ;
265+ var entryName = baseDirectory . GetUnixRelativePathTo ( file ) ;
266+ // ReSharper disable once AccessToDisposedClosure
267+ writer . Write ( entryName , file ) ;
294268 }
295269
296270 files . ForEach ( AddFile ) ;
297271 }
298272
299- /// <summary>
300- /// Extracts the contents of a tar archive at <paramref name="archiveFile" /> into <paramref name="directory" />, wrapping the
301- /// underlying file stream with the decompression stream produced by <paramref name="inputStreamFactory" />.
273+ private static SharpCompress . Compressors . Deflate . CompressionLevel ToSharpCompressCompressionLevel (
274+ this CompressionLevel compressionLevel )
275+ {
276+ return compressionLevel switch
277+ {
278+ CompressionLevel . NoCompression => SharpCompress . Compressors . Deflate . CompressionLevel . None ,
279+ CompressionLevel . Fastest => SharpCompress . Compressors . Deflate . CompressionLevel . BestSpeed ,
280+ CompressionLevel . Optimal => SharpCompress . Compressors . Deflate . CompressionLevel . Default ,
281+ _ => SharpCompress . Compressors . Deflate . CompressionLevel . BestCompression
282+ } ;
283+ }
284+
285+ /// <summary>
286+ /// Extracts the contents of an archive at <paramref name="archiveFile" /> into <paramref name="directory" />.
302287 /// </summary>
303288 /// <param name="archiveFile">The archive file to extract.</param>
304289 /// <param name="directory">The directory into which the archive's contents are extracted.</param>
305- /// <param name="inputStreamFactory">A factory that wraps the raw archive file stream with the desired decompression stream.</param>
306- private static void UncompressTar ( AbsolutePath archiveFile , AbsolutePath directory , Func < Stream , Stream > inputStreamFactory )
290+ private static void UncompressArchive ( AbsolutePath archiveFile , AbsolutePath directory )
307291 {
308- using FileStream fileStream = File . OpenRead ( archiveFile ) ;
309- using Stream inputStream = inputStreamFactory ( fileStream ) ;
310- using TarArchive tarArchive = TarArchive . CreateInputTarArchive ( inputStream , null ) ;
292+ using var fileStream = File . OpenRead ( archiveFile ) ;
293+ using var reader = ReaderFactory . OpenReader ( fileStream ) ;
311294
312295 directory . CreateDirectory ( ) ;
313296
314- tarArchive . ExtractContents ( directory ) ;
297+ while ( reader . MoveToNextEntry ( ) )
298+ {
299+ if ( reader . Entry . IsDirectory )
300+ continue ;
301+
302+ reader . WriteEntryToDirectory ( directory , new ExtractionOptions
303+ {
304+ ExtractFullPath = true ,
305+ Overwrite = true
306+ } ) ;
307+ }
315308 }
316309}
0 commit comments