Summary

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

Metrics

MethodCyclomatic ComplexitySequence CoverageBranch Coverage
OnDirectoryFailure(...)200
OnFileFailure(...)200
OnProcessFile(...)200
OnCompletedFile(...)200
OnProcessDirectory(...)200
.ctor()100

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    {
 050      bool result = false;
 051      DirectoryFailureHandler handler = DirectoryFailure;
 52
 053       if (handler != null) {
 054        var args = new ScanFailureEventArgs(directory, e);
 055        handler(this, args);
 056        result = args.ContinueRunning;
 57      }
 058      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    {
 069      FileFailureHandler handler = FileFailure;
 070      bool result = (handler != null);
 71
 072       if (result) {
 073        var args = new ScanFailureEventArgs(file, e);
 074        handler(this, args);
 075        result = args.ContinueRunning;
 76      }
 077      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    {
 087      bool result = true;
 088      ProcessFileHandler handler = ProcessFile;
 89
 090       if (handler != null) {
 091        var args = new ScanEventArgs(file);
 092        handler(this, args);
 093        result = args.ContinueRunning;
 94      }
 095      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    {
 0105      bool result = true;
 0106      CompletedFileHandler handler = CompletedFile;
 0107       if (handler != null) {
 0108        var args = new ScanEventArgs(file);
 0109        handler(this, args);
 0110        result = args.ContinueRunning;
 111      }
 0112      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    {
 0123      bool result = true;
 0124      EventHandler<DirectoryEventArgs> handler = ProcessDirectory;
 0125       if (handler != null) {
 0126        var args = new DirectoryEventArgs(directory, hasMatchingFiles);
 0127        handler(this, args);
 0128        result = args.ContinueRunning;
 129      }
 0130      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 {
 0140      get { return progressInterval_; }
 0141      set { progressInterval_ = value; }
 142    }
 143
 144    #region Instance Fields
 0145    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>
 179    public FastZip()
 180    {
 181    }
 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>
 187    public FastZip(FastZipEvents events)
 188    {
 189      events_ = events;
 190    }
 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 {
 198      get { return createEmptyDirectories_; }
 199      set { createEmptyDirectories_ = value; }
 200    }
 201
 202    /// <summary>
 203    /// Get / set the password value.
 204    /// </summary>
 205    public string Password {
 206      get { return password_; }
 207      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 {
 215      get { return entryFactory_.NameTransform; }
 216      set {
 217        entryFactory_.NameTransform = value;
 218      }
 219    }
 220
 221    /// <summary>
 222    /// Get or set the <see cref="IEntryFactory"></see> active when creating Zip files.
 223    /// </summary>
 224    public IEntryFactory EntryFactory {
 225      get { return entryFactory_; }
 226      set {
 227        if (value == null) {
 228          entryFactory_ = new ZipEntryFactory();
 229        } else {
 230          entryFactory_ = value;
 231        }
 232      }
 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 {
 247      get { return useZip64_; }
 248      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 {
 258        return restoreDateTimeOnExtract_;
 259      }
 260      set {
 261        restoreDateTimeOnExtract_ = value;
 262      }
 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 {
 270      get { return restoreAttributesOnExtract_; }
 271      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    {
 294      CreateZip(File.Create(zipFileName), sourceDirectory, recurse, fileFilter, directoryFilter);
 295    }
 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    {
 306      CreateZip(File.Create(zipFileName), sourceDirectory, recurse, fileFilter, null);
 307    }
 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    {
 320      NameTransform = new ZipNameTransform(sourceDirectory);
 321      sourceDirectory_ = sourceDirectory;
 322
 323      using (outputStream_ = new ZipOutputStream(outputStream)) {
 324
 325        if (password_ != null) {
 326          outputStream_.Password = password_;
 327        }
 328
 329        outputStream_.UseZip64 = UseZip64;
 330        var scanner = new FileSystemScanner(fileFilter, directoryFilter);
 331        scanner.ProcessFile += ProcessFile;
 332        if (this.CreateEmptyDirectories) {
 333          scanner.ProcessDirectory += ProcessDirectory;
 334        }
 335
 336        if (events_ != null) {
 337          if (events_.FileFailure != null) {
 338            scanner.FileFailure += events_.FileFailure;
 339          }
 340
 341          if (events_.DirectoryFailure != null) {
 342            scanner.DirectoryFailure += events_.DirectoryFailure;
 343          }
 344        }
 345
 346        scanner.Scan(sourceDirectory, recurse);
 347      }
 348    }
 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    {
 361      ExtractZip(zipFileName, targetDirectory, Overwrite.Always, null, fileFilter, null, restoreDateTimeOnExtract_);
 362    }
 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    {
 378      Stream inputStream = File.Open(zipFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
 379      ExtractZip(inputStream, targetDirectory, overwrite, confirmDelegate, fileFilter, directoryFilter, restoreDateTime,
 380    }
 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    {
 398      if ((overwrite == Overwrite.Prompt) && (confirmDelegate == null)) {
 399        throw new ArgumentNullException(nameof(confirmDelegate));
 400      }
 401
 402      continueRunning_ = true;
 403      overwrite_ = overwrite;
 404      confirmDelegate_ = confirmDelegate;
 405      extractNameTransform_ = new WindowsNameTransform(targetDirectory);
 406
 407      fileFilter_ = new NameFilter(fileFilter);
 408      directoryFilter_ = new NameFilter(directoryFilter);
 409      restoreDateTimeOnExtract_ = restoreDateTime;
 410
 411      using (zipFile_ = new ZipFile(inputStream)) {
 412
 413        if (password_ != null) {
 414          zipFile_.Password = password_;
 415        }
 416        zipFile_.IsStreamOwner = isStreamOwner;
 417        System.Collections.IEnumerator enumerator = zipFile_.GetEnumerator();
 418        while (continueRunning_ && enumerator.MoveNext()) {
 419          var entry = (ZipEntry)enumerator.Current;
 420          if (entry.IsFile) {
 421            // TODO Path.GetDirectory can fail here on invalid characters.
 422            if (directoryFilter_.IsMatch(Path.GetDirectoryName(entry.Name)) && fileFilter_.IsMatch(entry.Name)) {
 423              ExtractEntry(entry);
 424            }
 425          } else if (entry.IsDirectory) {
 426            if (directoryFilter_.IsMatch(entry.Name) && CreateEmptyDirectories) {
 427              ExtractEntry(entry);
 428            }
 429          } else {
 430            // Do nothing for volume labels etc...
 431          }
 432        }
 433      }
 434    }
 435    #endregion
 436
 437    #region Internal Processing
 438    void ProcessDirectory(object sender, DirectoryEventArgs e)
 439    {
 440      if (!e.HasMatchingFiles && CreateEmptyDirectories) {
 441        if (events_ != null) {
 442          events_.OnProcessDirectory(e.Name, e.HasMatchingFiles);
 443        }
 444
 445        if (e.ContinueRunning) {
 446          if (e.Name != sourceDirectory_) {
 447            ZipEntry entry = entryFactory_.MakeDirectoryEntry(e.Name);
 448            outputStream_.PutNextEntry(entry);
 449          }
 450        }
 451      }
 452    }
 453
 454    void ProcessFile(object sender, ScanEventArgs e)
 455    {
 456      if ((events_ != null) && (events_.ProcessFile != null)) {
 457        events_.ProcessFile(sender, e);
 458      }
 459
 460      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
 465          using (FileStream stream = File.Open(e.Name, FileMode.Open, FileAccess.Read, FileShare.Read)) {
 466            ZipEntry entry = entryFactory_.MakeFileEntry(e.Name);
 467            outputStream_.PutNextEntry(entry);
 468            AddFileContents(e.Name, stream);
 469          }
 470        } catch (Exception ex) {
 471          if (events_ != null) {
 472            continueRunning_ = events_.OnFileFailure(e.Name, ex);
 473          } else {
 474            continueRunning_ = false;
 475            throw;
 476          }
 477        }
 478      }
 479    }
 480
 481    void AddFileContents(string name, Stream stream)
 482    {
 483      if (stream == null) {
 484        throw new ArgumentNullException(nameof(stream));
 485      }
 486
 487      if (buffer_ == null) {
 488        buffer_ = new byte[4096];
 489      }
 490
 491      if ((events_ != null) && (events_.Progress != null)) {
 492        StreamUtils.Copy(stream, outputStream_, buffer_,
 493          events_.Progress, events_.ProgressInterval, this, name);
 494      } else {
 495        StreamUtils.Copy(stream, outputStream_, buffer_);
 496      }
 497
 498      if (events_ != null) {
 499        continueRunning_ = events_.OnCompletedFile(name);
 500      }
 501    }
 502
 503    void ExtractFileEntry(ZipEntry entry, string targetName)
 504    {
 505      bool proceed = true;
 506      if (overwrite_ != Overwrite.Always) {
 507        if (File.Exists(targetName)) {
 508          if ((overwrite_ == Overwrite.Prompt) && (confirmDelegate_ != null)) {
 509            proceed = confirmDelegate_(targetName);
 510          } else {
 511            proceed = false;
 512          }
 513        }
 514      }
 515
 516      if (proceed) {
 517        if (events_ != null) {
 518          continueRunning_ = events_.OnProcessFile(entry.Name);
 519        }
 520
 521        if (continueRunning_) {
 522          try {
 523            using (FileStream outputStream = File.Create(targetName)) {
 524              if (buffer_ == null) {
 525                buffer_ = new byte[4096];
 526              }
 527              if ((events_ != null) && (events_.Progress != null)) {
 528                StreamUtils.Copy(zipFile_.GetInputStream(entry), outputStream, buffer_,
 529                  events_.Progress, events_.ProgressInterval, this, entry.Name, entry.Size);
 530              } else {
 531                StreamUtils.Copy(zipFile_.GetInputStream(entry), outputStream, buffer_);
 532              }
 533
 534              if (events_ != null) {
 535                continueRunning_ = events_.OnCompletedFile(entry.Name);
 536              }
 537            }
 538
 539            if (restoreDateTimeOnExtract_) {
 540              File.SetLastWriteTime(targetName, entry.DateTime);
 541            }
 542
 543            if (RestoreAttributesOnExtract && entry.IsDOSEntry && (entry.ExternalFileAttributes != -1)) {
 544              var fileAttributes = (FileAttributes)entry.ExternalFileAttributes;
 545              // TODO: FastZip - Setting of other file attributes on extraction is a little trickier.
 546              fileAttributes &= (FileAttributes.Archive | FileAttributes.Normal | FileAttributes.ReadOnly | FileAttribut
 547              File.SetAttributes(targetName, fileAttributes);
 548            }
 549          } catch (Exception ex) {
 550            if (events_ != null) {
 551              continueRunning_ = events_.OnFileFailure(targetName, ex);
 552            } else {
 553              continueRunning_ = false;
 554              throw;
 555            }
 556          }
 557        }
 558      }
 559    }
 560
 561    void ExtractEntry(ZipEntry entry)
 562    {
 563      bool doExtraction = entry.IsCompressionMethodSupported();
 564      string targetName = entry.Name;
 565
 566      if (doExtraction) {
 567        if (entry.IsFile) {
 568          targetName = extractNameTransform_.TransformFile(targetName);
 569        } else if (entry.IsDirectory) {
 570          targetName = extractNameTransform_.TransformDirectory(targetName);
 571        }
 572
 573        doExtraction = !(string.IsNullOrEmpty(targetName));
 574      }
 575
 576      // TODO: Fire delegate/throw exception were compression method not supported, or name is invalid?
 577
 578      string dirName = null;
 579
 580      if (doExtraction) {
 581        if (entry.IsDirectory) {
 582          dirName = targetName;
 583        } else {
 584          dirName = Path.GetDirectoryName(Path.GetFullPath(targetName));
 585        }
 586      }
 587
 588      if (doExtraction && !Directory.Exists(dirName)) {
 589        if (!entry.IsDirectory || CreateEmptyDirectories) {
 590          try {
 591            Directory.CreateDirectory(dirName);
 592          } catch (Exception ex) {
 593            doExtraction = false;
 594            if (events_ != null) {
 595              if (entry.IsDirectory) {
 596                continueRunning_ = events_.OnDirectoryFailure(targetName, ex);
 597              } else {
 598                continueRunning_ = events_.OnFileFailure(targetName, ex);
 599              }
 600            } else {
 601              continueRunning_ = false;
 602              throw;
 603            }
 604          }
 605        }
 606      }
 607
 608      if (doExtraction && entry.IsFile) {
 609        ExtractFileEntry(entry, targetName);
 610      }
 611    }
 612
 613    static int MakeExternalAttributes(FileInfo info)
 614    {
 615      return (int)info.Attributes;
 616    }
 617
 618    static bool NameIsValid(string name)
 619    {
 620      return !string.IsNullOrEmpty(name) &&
 621        (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_;
 640    IEntryFactory entryFactory_ = new ZipEntryFactory();
 641    INameTransform extractNameTransform_;
 642    UseZip64 useZip64_ = UseZip64.Dynamic;
 643
 644    string password_;
 645
 646    #endregion
 647  }
 648}