Summary

Class:ICSharpCode.SharpZipLib.Zip.FastZip
Assembly:ICSharpCode.SharpZipLib
File(s):C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Zip\FastZip.cs
Covered lines:85
Uncovered lines:99
Coverable lines:184
Total lines:648
Line coverage:46.1%
Branch coverage:28.3%

Metrics

MethodCyclomatic ComplexitySequence CoverageBranch Coverage
.ctor()1100100
.ctor(...)100
CreateZip(...)100
CreateZip(...)100
CreateZip(...)772.2245.45
ExtractZip(...)1100100
ExtractZip(...)1100100
ExtractZip(...)138047.83
ProcessDirectory(...)600
ProcessFile(...)652.9444.44
AddFileContents(...)663.6454.55
ExtractFileEntry(...)1800
ExtractEntry(...)1454.5544.44
MakeExternalAttributes(...)100
NameIsValid(...)200

File(s)

C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Zip\FastZip.cs

#LineLine coverage
 1using System;
 2using System.IO;
 3using ICSharpCode.SharpZipLib.Core;
 4
 5namespace ICSharpCode.SharpZipLib.Zip
 6{
 7  /// <summary>
 8  /// FastZipEvents supports all events applicable to <see cref="FastZip">FastZip</see> operations.
 9  /// </summary>
 10  public class FastZipEvents
 11  {
 12    /// <summary>
 13    /// Delegate to invoke when processing directories.
 14    /// </summary>
 15    public event EventHandler<DirectoryEventArgs> ProcessDirectory;
 16
 17    /// <summary>
 18    /// Delegate to invoke when processing files.
 19    /// </summary>
 20    public ProcessFileHandler ProcessFile;
 21
 22    /// <summary>
 23    /// Delegate to invoke during processing of files.
 24    /// </summary>
 25    public ProgressHandler Progress;
 26
 27    /// <summary>
 28    /// Delegate to invoke when processing for a file has been completed.
 29    /// </summary>
 30    public CompletedFileHandler CompletedFile;
 31
 32    /// <summary>
 33    /// Delegate to invoke when processing directory failures.
 34    /// </summary>
 35    public DirectoryFailureHandler DirectoryFailure;
 36
 37    /// <summary>
 38    /// Delegate to invoke when processing file failures.
 39    /// </summary>
 40    public FileFailureHandler FileFailure;
 41
 42    /// <summary>
 43    /// Raise the <see cref="DirectoryFailure">directory failure</see> event.
 44    /// </summary>
 45    /// <param name="directory">The directory causing the failure.</param>
 46    /// <param name="e">The exception for this event.</param>
 47    /// <returns>A boolean indicating if execution should continue or not.</returns>
 48    public bool OnDirectoryFailure(string directory, Exception e)
 49    {
 50      bool result = false;
 51      DirectoryFailureHandler handler = DirectoryFailure;
 52
 53      if (handler != null) {
 54        var args = new ScanFailureEventArgs(directory, e);
 55        handler(this, args);
 56        result = args.ContinueRunning;
 57      }
 58      return result;
 59    }
 60
 61    /// <summary>
 62    /// Fires the <see cref="FileFailure"> file failure handler delegate</see>.
 63    /// </summary>
 64    /// <param name="file">The file causing the failure.</param>
 65    /// <param name="e">The exception for this failure.</param>
 66    /// <returns>A boolean indicating if execution should continue or not.</returns>
 67    public bool OnFileFailure(string file, Exception e)
 68    {
 69      FileFailureHandler handler = FileFailure;
 70      bool result = (handler != null);
 71
 72      if (result) {
 73        var args = new ScanFailureEventArgs(file, e);
 74        handler(this, args);
 75        result = args.ContinueRunning;
 76      }
 77      return result;
 78    }
 79
 80    /// <summary>
 81    /// Fires the <see cref="ProcessFile">ProcessFile delegate</see>.
 82    /// </summary>
 83    /// <param name="file">The file being processed.</param>
 84    /// <returns>A boolean indicating if execution should continue or not.</returns>
 85    public bool OnProcessFile(string file)
 86    {
 87      bool result = true;
 88      ProcessFileHandler handler = ProcessFile;
 89
 90      if (handler != null) {
 91        var args = new ScanEventArgs(file);
 92        handler(this, args);
 93        result = args.ContinueRunning;
 94      }
 95      return result;
 96    }
 97
 98    /// <summary>
 99    /// Fires the <see cref="CompletedFile"/> delegate
 100    /// </summary>
 101    /// <param name="file">The file whose processing has been completed.</param>
 102    /// <returns>A boolean indicating if execution should continue or not.</returns>
 103    public bool OnCompletedFile(string file)
 104    {
 105      bool result = true;
 106      CompletedFileHandler handler = CompletedFile;
 107      if (handler != null) {
 108        var args = new ScanEventArgs(file);
 109        handler(this, args);
 110        result = args.ContinueRunning;
 111      }
 112      return result;
 113    }
 114
 115    /// <summary>
 116    /// Fires the <see cref="ProcessDirectory">process directory</see> delegate.
 117    /// </summary>
 118    /// <param name="directory">The directory being processed.</param>
 119    /// <param name="hasMatchingFiles">Flag indicating if the directory has matching files as determined by the current 
 120    /// <returns>A <see cref="bool"/> of true if the operation should continue; false otherwise.</returns>
 121    public bool OnProcessDirectory(string directory, bool hasMatchingFiles)
 122    {
 123      bool result = true;
 124      EventHandler<DirectoryEventArgs> handler = ProcessDirectory;
 125      if (handler != null) {
 126        var args = new DirectoryEventArgs(directory, hasMatchingFiles);
 127        handler(this, args);
 128        result = args.ContinueRunning;
 129      }
 130      return result;
 131    }
 132
 133    /// <summary>
 134    /// The minimum timespan between <see cref="Progress"/> events.
 135    /// </summary>
 136    /// <value>The minimum period of time between <see cref="Progress"/> events.</value>
 137    /// <seealso cref="Progress"/>
 138    /// <remarks>The default interval is three seconds.</remarks>
 139    public TimeSpan ProgressInterval {
 140      get { return progressInterval_; }
 141      set { progressInterval_ = value; }
 142    }
 143
 144    #region Instance Fields
 145    TimeSpan progressInterval_ = TimeSpan.FromSeconds(3);
 146    #endregion
 147  }
 148
 149  /// <summary>
 150  /// FastZip provides facilities for creating and extracting zip files.
 151  /// </summary>
 152  public class FastZip
 153  {
 154    #region Enumerations
 155    /// <summary>
 156    /// Defines the desired handling when overwriting files during extraction.
 157    /// </summary>
 158    public enum Overwrite
 159    {
 160      /// <summary>
 161      /// Prompt the user to confirm overwriting
 162      /// </summary>
 163      Prompt,
 164      /// <summary>
 165      /// Never overwrite files.
 166      /// </summary>
 167      Never,
 168      /// <summary>
 169      /// Always overwrite files.
 170      /// </summary>
 171      Always
 172    }
 173    #endregion
 174
 175    #region Constructors
 176    /// <summary>
 177    /// Initialise a default instance of <see cref="FastZip"/>.
 178    /// </summary>
 5179    public FastZip()
 180    {
 5181    }
 182
 183    /// <summary>
 184    /// Initialise a new instance of <see cref="FastZip"/>
 185    /// </summary>
 186    /// <param name="events">The <see cref="FastZipEvents">events</see> to use during operations.</param>
 0187    public FastZip(FastZipEvents events)
 188    {
 0189      events_ = events;
 0190    }
 191    #endregion
 192
 193    #region Properties
 194    /// <summary>
 195    /// Get/set a value indicating wether empty directories should be created.
 196    /// </summary>
 197    public bool CreateEmptyDirectories {
 6198      get { return createEmptyDirectories_; }
 2199      set { createEmptyDirectories_ = value; }
 200    }
 201
 202    /// <summary>
 203    /// Get / set the password value.
 204    /// </summary>
 205    public string Password {
 0206      get { return password_; }
 4207      set { password_ = value; }
 208    }
 209
 210    /// <summary>
 211    /// Get or set the <see cref="INameTransform"></see> active when creating Zip files.
 212    /// </summary>
 213    /// <seealso cref="EntryFactory"></seealso>
 214    public INameTransform NameTransform {
 0215      get { return entryFactory_.NameTransform; }
 216      set {
 4217        entryFactory_.NameTransform = value;
 4218      }
 219    }
 220
 221    /// <summary>
 222    /// Get or set the <see cref="IEntryFactory"></see> active when creating Zip files.
 223    /// </summary>
 224    public IEntryFactory EntryFactory {
 0225      get { return entryFactory_; }
 226      set {
 1227         if (value == null) {
 0228          entryFactory_ = new ZipEntryFactory();
 0229        } else {
 1230          entryFactory_ = value;
 231        }
 1232      }
 233    }
 234
 235    /// <summary>
 236    /// Gets or sets the setting for <see cref="UseZip64">Zip64 handling when writing.</see>
 237    /// </summary>
 238    /// <remarks>
 239    /// The default value is dynamic which is not backwards compatible with old
 240    /// programs and can cause problems with XP's built in compression which cant
 241    /// read Zip64 archives. However it does avoid the situation were a large file
 242    /// is added and cannot be completed correctly.
 243    /// NOTE: Setting the size for entries before they are added is the best solution!
 244    /// By default the EntryFactory used by FastZip will set fhe file size.
 245    /// </remarks>
 246    public UseZip64 UseZip64 {
 4247      get { return useZip64_; }
 0248      set { useZip64_ = value; }
 249    }
 250
 251    /// <summary>
 252    /// Get/set a value indicating wether file dates and times should
 253    /// be restored when extracting files from an archive.
 254    /// </summary>
 255    /// <remarks>The default value is false.</remarks>
 256    public bool RestoreDateTimeOnExtract {
 257      get {
 0258        return restoreDateTimeOnExtract_;
 259      }
 260      set {
 0261        restoreDateTimeOnExtract_ = value;
 0262      }
 263    }
 264
 265    /// <summary>
 266    /// Get/set a value indicating wether file attributes should
 267    /// be restored during extract operations
 268    /// </summary>
 269    public bool RestoreAttributesOnExtract {
 0270      get { return restoreAttributesOnExtract_; }
 0271      set { restoreAttributesOnExtract_ = value; }
 272    }
 273    #endregion
 274
 275    #region Delegates
 276    /// <summary>
 277    /// Delegate called when confirming overwriting of files.
 278    /// </summary>
 279    public delegate bool ConfirmOverwriteDelegate(string fileName);
 280    #endregion
 281
 282    #region CreateZip
 283    /// <summary>
 284    /// Create a zip file.
 285    /// </summary>
 286    /// <param name="zipFileName">The name of the zip file to create.</param>
 287    /// <param name="sourceDirectory">The directory to source files from.</param>
 288    /// <param name="recurse">True to recurse directories, false for no recursion.</param>
 289    /// <param name="fileFilter">The <see cref="PathFilter">file filter</see> to apply.</param>
 290    /// <param name="directoryFilter">The <see cref="PathFilter">directory filter</see> to apply.</param>
 291    public void CreateZip(string zipFileName, string sourceDirectory,
 292      bool recurse, string fileFilter, string directoryFilter)
 293    {
 0294      CreateZip(File.Create(zipFileName), sourceDirectory, recurse, fileFilter, directoryFilter);
 0295    }
 296
 297    /// <summary>
 298    /// Create a zip file/archive.
 299    /// </summary>
 300    /// <param name="zipFileName">The name of the zip file to create.</param>
 301    /// <param name="sourceDirectory">The directory to obtain files and directories from.</param>
 302    /// <param name="recurse">True to recurse directories, false for no recursion.</param>
 303    /// <param name="fileFilter">The file filter to apply.</param>
 304    public void CreateZip(string zipFileName, string sourceDirectory, bool recurse, string fileFilter)
 305    {
 0306      CreateZip(File.Create(zipFileName), sourceDirectory, recurse, fileFilter, null);
 0307    }
 308
 309    /// <summary>
 310    /// Create a zip archive sending output to the <paramref name="outputStream"/> passed.
 311    /// </summary>
 312    /// <param name="outputStream">The stream to write archive data to.</param>
 313    /// <param name="sourceDirectory">The directory to source files from.</param>
 314    /// <param name="recurse">True to recurse directories, false for no recursion.</param>
 315    /// <param name="fileFilter">The <see cref="PathFilter">file filter</see> to apply.</param>
 316    /// <param name="directoryFilter">The <see cref="PathFilter">directory filter</see> to apply.</param>
 317    /// <remarks>The <paramref name="outputStream"/> is closed after creation.</remarks>
 318    public void CreateZip(Stream outputStream, string sourceDirectory, bool recurse, string fileFilter, string directory
 319    {
 4320      NameTransform = new ZipNameTransform(sourceDirectory);
 4321      sourceDirectory_ = sourceDirectory;
 322
 4323      using (outputStream_ = new ZipOutputStream(outputStream)) {
 324
 4325         if (password_ != null) {
 2326          outputStream_.Password = password_;
 327        }
 328
 4329        outputStream_.UseZip64 = UseZip64;
 4330        var scanner = new FileSystemScanner(fileFilter, directoryFilter);
 4331        scanner.ProcessFile += ProcessFile;
 4332         if (this.CreateEmptyDirectories) {
 0333          scanner.ProcessDirectory += ProcessDirectory;
 334        }
 335
 4336         if (events_ != null) {
 0337           if (events_.FileFailure != null) {
 0338            scanner.FileFailure += events_.FileFailure;
 339          }
 340
 0341           if (events_.DirectoryFailure != null) {
 0342            scanner.DirectoryFailure += events_.DirectoryFailure;
 343          }
 344        }
 345
 4346        scanner.Scan(sourceDirectory, recurse);
 4347      }
 4348    }
 349
 350    #endregion
 351
 352    #region ExtractZip
 353    /// <summary>
 354    /// Extract the contents of a zip file.
 355    /// </summary>
 356    /// <param name="zipFileName">The zip file to extract from.</param>
 357    /// <param name="targetDirectory">The directory to save extracted information in.</param>
 358    /// <param name="fileFilter">A filter to apply to files.</param>
 359    public void ExtractZip(string zipFileName, string targetDirectory, string fileFilter)
 360    {
 1361      ExtractZip(zipFileName, targetDirectory, Overwrite.Always, null, fileFilter, null, restoreDateTimeOnExtract_);
 1362    }
 363
 364    /// <summary>
 365    /// Extract the contents of a zip file.
 366    /// </summary>
 367    /// <param name="zipFileName">The zip file to extract from.</param>
 368    /// <param name="targetDirectory">The directory to save extracted information in.</param>
 369    /// <param name="overwrite">The style of <see cref="Overwrite">overwriting</see> to apply.</param>
 370    /// <param name="confirmDelegate">A delegate to invoke when confirming overwriting.</param>
 371    /// <param name="fileFilter">A filter to apply to files.</param>
 372    /// <param name="directoryFilter">A filter to apply to directories.</param>
 373    /// <param name="restoreDateTime">Flag indicating whether to restore the date and time for extracted files.</param>
 374    public void ExtractZip(string zipFileName, string targetDirectory,
 375                 Overwrite overwrite, ConfirmOverwriteDelegate confirmDelegate,
 376                 string fileFilter, string directoryFilter, bool restoreDateTime)
 377    {
 1378      Stream inputStream = File.Open(zipFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
 1379      ExtractZip(inputStream, targetDirectory, overwrite, confirmDelegate, fileFilter, directoryFilter, restoreDateTime,
 1380    }
 381
 382    /// <summary>
 383    /// Extract the contents of a zip file held in a stream.
 384    /// </summary>
 385    /// <param name="inputStream">The seekable input stream containing the zip to extract from.</param>
 386    /// <param name="targetDirectory">The directory to save extracted information in.</param>
 387    /// <param name="overwrite">The style of <see cref="Overwrite">overwriting</see> to apply.</param>
 388    /// <param name="confirmDelegate">A delegate to invoke when confirming overwriting.</param>
 389    /// <param name="fileFilter">A filter to apply to files.</param>
 390    /// <param name="directoryFilter">A filter to apply to directories.</param>
 391    /// <param name="restoreDateTime">Flag indicating whether to restore the date and time for extracted files.</param>
 392    /// <param name="isStreamOwner">Flag indicating whether the inputStream will be closed by this method.</param>
 393    public void ExtractZip(Stream inputStream, string targetDirectory,
 394             Overwrite overwrite, ConfirmOverwriteDelegate confirmDelegate,
 395             string fileFilter, string directoryFilter, bool restoreDateTime,
 396             bool isStreamOwner)
 397    {
 1398       if ((overwrite == Overwrite.Prompt) && (confirmDelegate == null)) {
 0399        throw new ArgumentNullException(nameof(confirmDelegate));
 400      }
 401
 1402      continueRunning_ = true;
 1403      overwrite_ = overwrite;
 1404      confirmDelegate_ = confirmDelegate;
 1405      extractNameTransform_ = new WindowsNameTransform(targetDirectory);
 406
 1407      fileFilter_ = new NameFilter(fileFilter);
 1408      directoryFilter_ = new NameFilter(directoryFilter);
 1409      restoreDateTimeOnExtract_ = restoreDateTime;
 410
 1411      using (zipFile_ = new ZipFile(inputStream)) {
 412
 1413         if (password_ != null) {
 0414          zipFile_.Password = password_;
 415        }
 1416        zipFile_.IsStreamOwner = isStreamOwner;
 1417        System.Collections.IEnumerator enumerator = zipFile_.GetEnumerator();
 2418         while (continueRunning_ && enumerator.MoveNext()) {
 1419          var entry = (ZipEntry)enumerator.Current;
 1420           if (entry.IsFile) {
 421            // TODO Path.GetDirectory can fail here on invalid characters.
 0422             if (directoryFilter_.IsMatch(Path.GetDirectoryName(entry.Name)) && fileFilter_.IsMatch(entry.Name)) {
 0423              ExtractEntry(entry);
 424            }
 1425           } else if (entry.IsDirectory) {
 1426             if (directoryFilter_.IsMatch(entry.Name) && CreateEmptyDirectories) {
 1427              ExtractEntry(entry);
 428            }
 429          } else {
 430            // Do nothing for volume labels etc...
 431          }
 432        }
 1433      }
 1434    }
 435    #endregion
 436
 437    #region Internal Processing
 438    void ProcessDirectory(object sender, DirectoryEventArgs e)
 439    {
 0440       if (!e.HasMatchingFiles && CreateEmptyDirectories) {
 0441         if (events_ != null) {
 0442          events_.OnProcessDirectory(e.Name, e.HasMatchingFiles);
 443        }
 444
 0445         if (e.ContinueRunning) {
 0446           if (e.Name != sourceDirectory_) {
 0447            ZipEntry entry = entryFactory_.MakeDirectoryEntry(e.Name);
 0448            outputStream_.PutNextEntry(entry);
 449          }
 450        }
 451      }
 0452    }
 453
 454    void ProcessFile(object sender, ScanEventArgs e)
 455    {
 4456       if ((events_ != null) && (events_.ProcessFile != null)) {
 0457        events_.ProcessFile(sender, e);
 458      }
 459
 4460       if (e.ContinueRunning) {
 461        try {
 462          // The open below is equivalent to OpenRead which gaurantees that if opened the
 463          // file will not be changed by subsequent openers, but precludes opening in some cases
 464          // were it could succeed. ie the open may fail as its already open for writing and the share mode should refle
 4465          using (FileStream stream = File.Open(e.Name, FileMode.Open, FileAccess.Read, FileShare.Read)) {
 4466            ZipEntry entry = entryFactory_.MakeFileEntry(e.Name);
 4467            outputStream_.PutNextEntry(entry);
 4468            AddFileContents(e.Name, stream);
 4469          }
 4470        } catch (Exception ex) {
 0471           if (events_ != null) {
 0472            continueRunning_ = events_.OnFileFailure(e.Name, ex);
 0473          } else {
 0474            continueRunning_ = false;
 0475            throw;
 476          }
 0477        }
 478      }
 4479    }
 480
 481    void AddFileContents(string name, Stream stream)
 482    {
 4483       if (stream == null) {
 0484        throw new ArgumentNullException(nameof(stream));
 485      }
 486
 4487       if (buffer_ == null) {
 4488        buffer_ = new byte[4096];
 489      }
 490
 4491       if ((events_ != null) && (events_.Progress != null)) {
 0492        StreamUtils.Copy(stream, outputStream_, buffer_,
 0493          events_.Progress, events_.ProgressInterval, this, name);
 0494      } else {
 4495        StreamUtils.Copy(stream, outputStream_, buffer_);
 496      }
 497
 4498       if (events_ != null) {
 0499        continueRunning_ = events_.OnCompletedFile(name);
 500      }
 4501    }
 502
 503    void ExtractFileEntry(ZipEntry entry, string targetName)
 504    {
 0505      bool proceed = true;
 0506       if (overwrite_ != Overwrite.Always) {
 0507         if (File.Exists(targetName)) {
 0508           if ((overwrite_ == Overwrite.Prompt) && (confirmDelegate_ != null)) {
 0509            proceed = confirmDelegate_(targetName);
 0510          } else {
 0511            proceed = false;
 512          }
 513        }
 514      }
 515
 0516       if (proceed) {
 0517         if (events_ != null) {
 0518          continueRunning_ = events_.OnProcessFile(entry.Name);
 519        }
 520
 0521         if (continueRunning_) {
 522          try {
 0523            using (FileStream outputStream = File.Create(targetName)) {
 0524               if (buffer_ == null) {
 0525                buffer_ = new byte[4096];
 526              }
 0527               if ((events_ != null) && (events_.Progress != null)) {
 0528                StreamUtils.Copy(zipFile_.GetInputStream(entry), outputStream, buffer_,
 0529                  events_.Progress, events_.ProgressInterval, this, entry.Name, entry.Size);
 0530              } else {
 0531                StreamUtils.Copy(zipFile_.GetInputStream(entry), outputStream, buffer_);
 532              }
 533
 0534               if (events_ != null) {
 0535                continueRunning_ = events_.OnCompletedFile(entry.Name);
 536              }
 0537            }
 538
 0539             if (restoreDateTimeOnExtract_) {
 0540              File.SetLastWriteTime(targetName, entry.DateTime);
 541            }
 542
 0543             if (RestoreAttributesOnExtract && entry.IsDOSEntry && (entry.ExternalFileAttributes != -1)) {
 0544              var fileAttributes = (FileAttributes)entry.ExternalFileAttributes;
 545              // TODO: FastZip - Setting of other file attributes on extraction is a little trickier.
 0546              fileAttributes &= (FileAttributes.Archive | FileAttributes.Normal | FileAttributes.ReadOnly | FileAttribut
 0547              File.SetAttributes(targetName, fileAttributes);
 548            }
 0549          } catch (Exception ex) {
 0550             if (events_ != null) {
 0551              continueRunning_ = events_.OnFileFailure(targetName, ex);
 0552            } else {
 0553              continueRunning_ = false;
 0554              throw;
 555            }
 0556          }
 557        }
 558      }
 0559    }
 560
 561    void ExtractEntry(ZipEntry entry)
 562    {
 1563      bool doExtraction = entry.IsCompressionMethodSupported();
 1564      string targetName = entry.Name;
 565
 1566       if (doExtraction) {
 1567         if (entry.IsFile) {
 0568          targetName = extractNameTransform_.TransformFile(targetName);
 1569         } else if (entry.IsDirectory) {
 1570          targetName = extractNameTransform_.TransformDirectory(targetName);
 571        }
 572
 1573        doExtraction = !(string.IsNullOrEmpty(targetName));
 574      }
 575
 576      // TODO: Fire delegate/throw exception were compression method not supported, or name is invalid?
 577
 1578      string dirName = null;
 579
 1580       if (doExtraction) {
 1581         if (entry.IsDirectory) {
 1582          dirName = targetName;
 1583        } else {
 0584          dirName = Path.GetDirectoryName(Path.GetFullPath(targetName));
 585        }
 586      }
 587
 1588       if (doExtraction && !Directory.Exists(dirName)) {
 1589         if (!entry.IsDirectory || CreateEmptyDirectories) {
 590          try {
 1591            Directory.CreateDirectory(dirName);
 1592          } catch (Exception ex) {
 0593            doExtraction = false;
 0594             if (events_ != null) {
 0595               if (entry.IsDirectory) {
 0596                continueRunning_ = events_.OnDirectoryFailure(targetName, ex);
 0597              } else {
 0598                continueRunning_ = events_.OnFileFailure(targetName, ex);
 599              }
 0600            } else {
 0601              continueRunning_ = false;
 0602              throw;
 603            }
 0604          }
 605        }
 606      }
 607
 1608       if (doExtraction && entry.IsFile) {
 0609        ExtractFileEntry(entry, targetName);
 610      }
 1611    }
 612
 613    static int MakeExternalAttributes(FileInfo info)
 614    {
 0615      return (int)info.Attributes;
 616    }
 617
 618    static bool NameIsValid(string name)
 619    {
 0620      return !string.IsNullOrEmpty(name) &&
 0621        (name.IndexOfAny(Path.GetInvalidPathChars()) < 0);
 622    }
 623    #endregion
 624
 625    #region Instance Fields
 626    bool continueRunning_;
 627    byte[] buffer_;
 628    ZipOutputStream outputStream_;
 629    ZipFile zipFile_;
 630    string sourceDirectory_;
 631    NameFilter fileFilter_;
 632    NameFilter directoryFilter_;
 633    Overwrite overwrite_;
 634    ConfirmOverwriteDelegate confirmDelegate_;
 635
 636    bool restoreDateTimeOnExtract_;
 637    bool restoreAttributesOnExtract_;
 638    bool createEmptyDirectories_;
 639    FastZipEvents events_;
 5640    IEntryFactory entryFactory_ = new ZipEntryFactory();
 641    INameTransform extractNameTransform_;
 5642    UseZip64 useZip64_ = UseZip64.Dynamic;
 643
 644    string password_;
 645
 646    #endregion
 647  }
 648}