Mes documents/Visual Studio 2005/Projects/TES4ModTranslator/TES4ModTranslator/Zip/FastZip.cs

Go to the documentation of this file.
00001 // SimpleZip.cs
00002 //
00003 // Copyright 2005 John Reilly
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 //
00019 // Linking this library statically or dynamically with other modules is
00020 // making a combined work based on this library.  Thus, the terms and
00021 // conditions of the GNU General Public License cover the whole
00022 // combination.
00023 // 
00024 // As a special exception, the copyright holders of this library give you
00025 // permission to link this library with independent modules to produce an
00026 // executable, regardless of the license terms of these independent
00027 // modules, and to copy and distribute the resulting executable under
00028 // terms of your choice, provided that you also meet, for each linked
00029 // independent module, the terms and conditions of the license of that
00030 // module.  An independent module is a module which is not derived from
00031 // or based on this library.  If you modify this library, you may extend
00032 // this exception to your version of the library, but you are not
00033 // obligated to do so.  If you do not wish to do so, delete this
00034 // exception statement from your version.
00035 
00036 
00037 using System;
00038 using System.IO;
00039 using ICSharpCode.SharpZipLib.Core;
00040 
00041 namespace ICSharpCode.SharpZipLib.Zip
00042 {
00046         public class FastZipEvents
00047         {
00051                 public ProcessDirectoryDelegate ProcessDirectory;
00052                 
00056                 public ProcessFileDelegate ProcessFile;
00057 
00061                 public DirectoryFailureDelegate DirectoryFailure;
00062                 
00066                 public FileFailureDelegate FileFailure;
00067                 
00073                 public void OnDirectoryFailure(string directory, Exception e)
00074                 {
00075                         if ( DirectoryFailure != null ) {
00076                                 ScanFailureEventArgs args = new ScanFailureEventArgs(directory, e);
00077                                 DirectoryFailure(this, args);
00078                         }
00079                 }
00080                 
00086                 public void OnFileFailure(string file, Exception e)
00087                 {
00088                         if ( FileFailure != null ) {
00089                                 ScanFailureEventArgs args = new ScanFailureEventArgs(file, e);
00090                                 FileFailure(this, args);
00091                         }
00092                 }
00093                 
00098                 public void OnProcessFile(string file)
00099                 {
00100                         if ( ProcessFile != null ) {
00101                                 ScanEventArgs args = new ScanEventArgs(file);
00102                                 ProcessFile(this, args);
00103                         }
00104                 }
00105                 
00111                 public void OnProcessDirectory(string directory, bool hasMatchingFiles)
00112                 {
00113                         if ( ProcessDirectory != null ) {
00114                                 DirectoryEventArgs args = new DirectoryEventArgs(directory, hasMatchingFiles);
00115                                 ProcessDirectory(this, args);
00116                         }
00117                 }
00118                 
00119         }
00120         
00125         public class FastZip
00126         {
00130                 public FastZip()
00131                 {
00132                         this.events = null;
00133                 }
00134                 
00139                 public FastZip(FastZipEvents events)
00140                 {
00141                         this.events = events;
00142                 }
00143                 
00147                 public enum Overwrite {
00151                         Prompt,
00155                         Never,
00159                         Always
00160                 }
00161 
00165                 public bool CreateEmptyDirectories
00166                 {
00167                         get { return createEmptyDirectories; }
00168                         set { createEmptyDirectories = value; }
00169                 }
00170 
00174                 public delegate bool ConfirmOverwriteDelegate(string fileName);
00175                 
00184                 public void CreateZip(string zipFileName, string sourceDirectory, bool recurse, string fileFilter, string directoryFilter)
00185                 {
00186                         NameTransform = new ZipNameTransform(true, sourceDirectory);
00187                         this.sourceDirectory = sourceDirectory;
00188                         
00189                         outputStream = new ZipOutputStream(File.Create(zipFileName));
00190                         try {
00191                                 FileSystemScanner scanner = new FileSystemScanner(fileFilter, directoryFilter);
00192                                 scanner.ProcessFile += new ProcessFileDelegate(ProcessFile);
00193                                 if ( this.CreateEmptyDirectories ) {
00194                                         scanner.ProcessDirectory += new ProcessDirectoryDelegate(ProcessDirectory);
00195                                 }
00196                                 scanner.Scan(sourceDirectory, recurse);
00197                         }
00198                         finally {
00199                                 outputStream.Close();
00200                         }
00201                 }
00202 
00210                 public void CreateZip(string zipFileName, string sourceDirectory, bool recurse, string fileFilter)
00211                 {
00212                         CreateZip(zipFileName, sourceDirectory, recurse, fileFilter, null);
00213                 }
00214 
00221                 public void ExtractZip(string zipFileName, string targetDirectory, string fileFilter) 
00222                 {
00223                         ExtractZip(zipFileName, targetDirectory, Overwrite.Always, null, fileFilter, null);
00224                 }
00225                 
00235                 public void ExtractZip(string zipFileName, string targetDirectory, 
00236                                        Overwrite overwrite, ConfirmOverwriteDelegate confirmDelegate, 
00237                                        string fileFilter, string directoryFilter)
00238                 {
00239                         if ((overwrite == Overwrite.Prompt) && (confirmDelegate == null)) {
00240                                 throw new ArgumentNullException("confirmDelegate");
00241                         }
00242                         this.overwrite = overwrite;
00243                         this.confirmDelegate = confirmDelegate;
00244                         this.targetDirectory = targetDirectory;
00245                         this.fileFilter = new NameFilter(fileFilter);
00246                         this.directoryFilter = new NameFilter(directoryFilter);
00247                         
00248                         inputStream = new ZipInputStream(File.OpenRead(zipFileName));
00249                         
00250                         try {
00251                                 
00252                                 if (password != null) {
00253                                         inputStream.Password = password;
00254                                 }
00255 
00256                                 ZipEntry entry;
00257                                 while ( (entry = inputStream.GetNextEntry()) != null ) {
00258                                         if ( this.directoryFilter.IsMatch(Path.GetDirectoryName(entry.Name)) && this.fileFilter.IsMatch(entry.Name) ) {
00259                                                 ExtractEntry(entry);
00260                                         }
00261                                 }
00262                         }
00263                         finally {
00264                                 inputStream.Close();
00265                         }
00266                 }
00267                 
00268                 void ProcessDirectory(object sender, DirectoryEventArgs e)
00269                 {
00270                         if ( !e.HasMatchingFiles && createEmptyDirectories ) {
00271                                 if ( events != null ) {
00272                                         events.OnProcessDirectory(e.Name, e.HasMatchingFiles);
00273                                 }
00274                                 
00275                                 if (e.Name != sourceDirectory) {
00276                                         string cleanedName = nameTransform.TransformDirectory(e.Name);
00277                                         ZipEntry entry = new ZipEntry(cleanedName);
00278                                         outputStream.PutNextEntry(entry);
00279                                 }
00280                         }
00281                 }
00282                 
00283                 void ProcessFile(object sender, ScanEventArgs e)
00284                 {
00285                         if ( events != null ) {
00286                                 events.OnProcessFile(e.Name);
00287                         }
00288                         string cleanedName = nameTransform.TransformFile(e.Name);
00289                         ZipEntry entry = new ZipEntry(cleanedName);
00290                         outputStream.PutNextEntry(entry);
00291                         AddFileContents(e.Name);
00292                 }
00293 
00294                 void AddFileContents(string name)
00295                 {
00296                         if ( buffer == null ) {
00297                                 buffer = new byte[4096];
00298                         }
00299 
00300                         FileStream stream = File.OpenRead(name);
00301                         try {
00302                                 int length;
00303                                 do {
00304                                         length = stream.Read(buffer, 0, buffer.Length);
00305                                         outputStream.Write(buffer, 0, length);
00306                                 } while ( length > 0 );
00307                         }
00308                         finally {
00309                                 stream.Close();
00310                         }
00311                 }
00312                 
00313                 void ExtractFileEntry(ZipEntry entry, string targetName)
00314                 {
00315                         bool proceed = true;
00316                         if ((overwrite == Overwrite.Prompt) && (confirmDelegate != null)) {
00317                                 if (File.Exists(targetName) == true) {
00318                                         proceed = confirmDelegate(targetName);
00319                                 }
00320                         }
00321 
00322                         if ( proceed ) {
00323                                 
00324                                 if ( events != null ) {
00325                                         events.OnProcessFile(entry.Name);
00326                                 }
00327                         
00328                                 FileStream streamWriter = File.Create(targetName);
00329                         
00330                                 try {
00331                                         if ( buffer == null ) {
00332                                                 buffer = new byte[4096];
00333                                         }
00334                                         
00335                                         int size;
00336                 
00337                                         do {
00338                                                 size = inputStream.Read(buffer, 0, buffer.Length);
00339                                                 streamWriter.Write(buffer, 0, size);
00340                                         } while (size > 0);
00341                                 }
00342                                 finally {
00343                                         streamWriter.Close();
00344                                 }
00345         
00346                                 if (restoreDateTime) {
00347                                         File.SetLastWriteTime(targetName, entry.DateTime);
00348                                 }
00349                         }
00350                 }
00351 
00352                 bool NameIsValid(string name)
00353                 {
00354                         return name != null && name.Length > 0 && name.IndexOfAny(Path.InvalidPathChars) < 0;
00355                 }
00356                 
00357                 void ExtractEntry(ZipEntry entry)
00358                 {
00359                         bool doExtraction = NameIsValid(entry.Name);
00360                         
00361                         string dirName = null;
00362                         string targetName = null;
00363                         
00364                         if ( doExtraction ) {
00365                                 string entryFileName;
00366                                 if (Path.IsPathRooted(entry.Name)) {
00367                                         string workName = Path.GetPathRoot(entry.Name);
00368                                         workName = entry.Name.Substring(workName.Length);
00369                                         entryFileName = Path.Combine(Path.GetDirectoryName(workName), Path.GetFileName(entry.Name));
00370                                 } else {
00371                                         entryFileName = entry.Name;
00372                                 }
00373                                 
00374                                 targetName = Path.Combine(targetDirectory, entryFileName);
00375                                 dirName = Path.GetDirectoryName(Path.GetFullPath(targetName));
00376         
00377                                 doExtraction = doExtraction && (entryFileName.Length > 0);
00378                         }
00379                         
00380                         if ( doExtraction && !Directory.Exists(dirName) )
00381                         {
00382                                 if ( !entry.IsDirectory || this.CreateEmptyDirectories ) {
00383                                         try {
00384                                                 Directory.CreateDirectory(dirName);
00385                                         }
00386                                         catch {
00387                                                 doExtraction = false;
00388                                         }
00389                                 }
00390                         }
00391                         
00392                         if ( doExtraction && entry.IsFile ) {
00393                                 ExtractFileEntry(entry, targetName);
00394                         }
00395                 }
00396                 
00400                 public ZipNameTransform NameTransform
00401                 {
00402                         get { return nameTransform; }
00403                         set {
00404                                 if ( value == null ) {
00405                                         nameTransform = new ZipNameTransform();
00406                                 }
00407                                 else {
00408                                         nameTransform = value;
00409                                 }
00410                         }
00411                 }
00412                 
00413                 #region Instance Fields
00414                 byte[] buffer;
00415                 ZipOutputStream outputStream;
00416                 ZipInputStream inputStream;
00417                 string password = null;
00418                 string targetDirectory;
00419                 string sourceDirectory;
00420                 NameFilter fileFilter;
00421                 NameFilter directoryFilter;
00422                 Overwrite overwrite;
00423                 ConfirmOverwriteDelegate confirmDelegate;
00424                 bool restoreDateTime = false;
00425                 bool createEmptyDirectories = false;
00426                 FastZipEvents events;
00427                 ZipNameTransform nameTransform;
00428                 #endregion
00429         }
00430 }

Generated on Fri Jun 23 21:50:05 2006 for OblivionModTranslator by  doxygen 1.4.6-NO