Free cookie consent management tool by TermsFeed Policy Generator

source: tags/3.3.12/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/Packaging/DotNetZip/ZipFile.Events.cs @ 13398

Last change on this file since 13398 was 12074, checked in by sraggl, 10 years ago

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 49.3 KB
Line 
1// ZipFile.Events.cs
2// ------------------------------------------------------------------
3//
4// Copyright (c) 2008, 2009, 2011 Dino Chiesa .
5// All rights reserved.
6//
7// This code module is part of DotNetZip, a zipfile class library.
8//
9// ------------------------------------------------------------------
10//
11// This code is licensed under the Microsoft Public License.
12// See the file License.txt for the license details.
13// More info on: http://dotnetzip.codeplex.com
14//
15// ------------------------------------------------------------------
16//
17// last saved (in emacs):
18// Time-stamp: <2011-July-09 08:42:35>
19//
20// ------------------------------------------------------------------
21//
22// This module defines the methods for issuing events from the ZipFile class.
23//
24// ------------------------------------------------------------------
25//
26
27using System;
28using System.IO;
29
30namespace OfficeOpenXml.Packaging.Ionic.Zip
31{
32    internal partial class ZipFile
33    {
34        private string ArchiveNameForEvent
35        {
36            get
37            {
38                return (_name != null) ? _name : "(stream)";
39            }
40        }
41
42        #region Save
43
44        /// <summary>
45        ///   An event handler invoked when a Save() starts, before and after each
46        ///   entry has been written to the archive, when a Save() completes, and
47        ///   during other Save events.
48        /// </summary>
49        ///
50        /// <remarks>
51        /// <para>
52        ///   Depending on the particular event, different properties on the <see
53        ///   cref="SaveProgressEventArgs"/> parameter are set.  The following
54        ///   table summarizes the available EventTypes and the conditions under
55        ///   which this event handler is invoked with a
56        ///   <c>SaveProgressEventArgs</c> with the given EventType.
57        /// </para>
58        ///
59        /// <list type="table">
60        /// <listheader>
61        /// <term>value of EntryType</term>
62        /// <description>Meaning and conditions</description>
63        /// </listheader>
64        ///
65        /// <item>
66        /// <term>ZipProgressEventType.Saving_Started</term>
67        /// <description>Fired when ZipFile.Save() begins.
68        /// </description>
69        /// </item>
70        ///
71        /// <item>
72        /// <term>ZipProgressEventType.Saving_BeforeSaveEntry</term>
73        /// <description>
74        ///   Fired within ZipFile.Save(), just before writing data for each
75        ///   particular entry.
76        /// </description>
77        /// </item>
78        ///
79        /// <item>
80        /// <term>ZipProgressEventType.Saving_AfterSaveEntry</term>
81        /// <description>
82        ///   Fired within ZipFile.Save(), just after having finished writing data
83        ///   for each particular entry.
84        /// </description>
85        /// </item>
86        ///
87        /// <item>
88        /// <term>ZipProgressEventType.Saving_Completed</term>
89        /// <description>Fired when ZipFile.Save() has completed.
90        /// </description>
91        /// </item>
92        ///
93        /// <item>
94        /// <term>ZipProgressEventType.Saving_AfterSaveTempArchive</term>
95        /// <description>
96        ///   Fired after the temporary file has been created.  This happens only
97        ///   when saving to a disk file.  This event will not be invoked when
98        ///   saving to a stream.
99        /// </description>
100        /// </item>
101        ///
102        /// <item>
103        /// <term>ZipProgressEventType.Saving_BeforeRenameTempArchive</term>
104        /// <description>
105        ///   Fired just before renaming the temporary file to the permanent
106        ///   location.  This happens only when saving to a disk file.  This event
107        ///   will not be invoked when saving to a stream.
108        /// </description>
109        /// </item>
110        ///
111        /// <item>
112        /// <term>ZipProgressEventType.Saving_AfterRenameTempArchive</term>
113        /// <description>
114        ///   Fired just after renaming the temporary file to the permanent
115        ///   location.  This happens only when saving to a disk file.  This event
116        ///   will not be invoked when saving to a stream.
117        /// </description>
118        /// </item>
119        ///
120        /// <item>
121        /// <term>ZipProgressEventType.Saving_AfterCompileSelfExtractor</term>
122        /// <description>
123        ///   Fired after a self-extracting archive has finished compiling.  This
124        ///   EventType is used only within SaveSelfExtractor().
125        /// </description>
126        /// </item>
127        ///
128        /// <item>
129        /// <term>ZipProgressEventType.Saving_BytesRead</term>
130        /// <description>
131        ///   Set during the save of a particular entry, to update progress of the
132        ///   Save().  When this EventType is set, the BytesTransferred is the
133        ///   number of bytes that have been read from the source stream.  The
134        ///   TotalBytesToTransfer is the number of bytes in the uncompressed
135        ///   file.
136        /// </description>
137        /// </item>
138        ///
139        /// </list>
140        /// </remarks>
141        ///
142        /// <example>
143        ///
144        ///    This example uses an anonymous method to handle the
145        ///    SaveProgress event, by updating a progress bar.
146        ///
147        /// <code lang="C#">
148        /// progressBar1.Value = 0;
149        /// progressBar1.Max = listbox1.Items.Count;
150        /// using (ZipFile zip = new ZipFile())
151        /// {
152        ///    // listbox1 contains a list of filenames
153        ///    zip.AddFiles(listbox1.Items);
154        ///
155        ///    // do the progress bar:
156        ///    zip.SaveProgress += (sender, e) => {
157        ///       if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry) {
158        ///          progressBar1.PerformStep();
159        ///       }
160        ///    };
161        ///
162        ///    zip.Save(fs);
163        /// }
164        /// </code>
165        /// </example>
166        ///
167        /// <example>
168        ///   This example uses a named method as the
169        ///   <c>SaveProgress</c> event handler, to update the user, in a
170        ///   console-based application.
171        ///
172        /// <code lang="C#">
173        /// static bool justHadByteUpdate= false;
174        /// public static void SaveProgress(object sender, SaveProgressEventArgs e)
175        /// {
176        ///     if (e.EventType == ZipProgressEventType.Saving_Started)
177        ///         Console.WriteLine("Saving: {0}", e.ArchiveName);
178        ///
179        ///     else if (e.EventType == ZipProgressEventType.Saving_Completed)
180        ///     {
181        ///         justHadByteUpdate= false;
182        ///         Console.WriteLine();
183        ///         Console.WriteLine("Done: {0}", e.ArchiveName);
184        ///     }
185        ///
186        ///     else if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry)
187        ///     {
188        ///         if (justHadByteUpdate)
189        ///             Console.WriteLine();
190        ///         Console.WriteLine("  Writing: {0} ({1}/{2})",
191        ///                           e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal);
192        ///         justHadByteUpdate= false;
193        ///     }
194        ///
195        ///     else if (e.EventType == ZipProgressEventType.Saving_EntryBytesRead)
196        ///     {
197        ///         if (justHadByteUpdate)
198        ///             Console.SetCursorPosition(0, Console.CursorTop);
199        ///          Console.Write("     {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer,
200        ///                       e.BytesTransferred / (0.01 * e.TotalBytesToTransfer ));
201        ///         justHadByteUpdate= true;
202        ///     }
203        /// }
204        ///
205        /// public static ZipUp(string targetZip, string directory)
206        /// {
207        ///   using (var zip = new ZipFile()) {
208        ///     zip.SaveProgress += SaveProgress;
209        ///     zip.AddDirectory(directory);
210        ///     zip.Save(targetZip);
211        ///   }
212        /// }
213        ///
214        /// </code>
215        ///
216        /// <code lang="VB">
217        /// Public Sub ZipUp(ByVal targetZip As String, ByVal directory As String)
218        ///     Using zip As ZipFile = New ZipFile
219        ///         AddHandler zip.SaveProgress, AddressOf MySaveProgress
220        ///         zip.AddDirectory(directory)
221        ///         zip.Save(targetZip)
222        ///     End Using
223        /// End Sub
224        ///
225        /// Private Shared justHadByteUpdate As Boolean = False
226        ///
227        /// Public Shared Sub MySaveProgress(ByVal sender As Object, ByVal e As SaveProgressEventArgs)
228        ///     If (e.EventType Is ZipProgressEventType.Saving_Started) Then
229        ///         Console.WriteLine("Saving: {0}", e.ArchiveName)
230        ///
231        ///     ElseIf (e.EventType Is ZipProgressEventType.Saving_Completed) Then
232        ///         justHadByteUpdate = False
233        ///         Console.WriteLine
234        ///         Console.WriteLine("Done: {0}", e.ArchiveName)
235        ///
236        ///     ElseIf (e.EventType Is ZipProgressEventType.Saving_BeforeWriteEntry) Then
237        ///         If justHadByteUpdate Then
238        ///             Console.WriteLine
239        ///         End If
240        ///         Console.WriteLine("  Writing: {0} ({1}/{2})", e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal)
241        ///         justHadByteUpdate = False
242        ///
243        ///     ElseIf (e.EventType Is ZipProgressEventType.Saving_EntryBytesRead) Then
244        ///         If justHadByteUpdate Then
245        ///             Console.SetCursorPosition(0, Console.CursorTop)
246        ///         End If
247        ///         Console.Write("     {0}/{1} ({2:N0}%)", e.BytesTransferred, _
248        ///                       e.TotalBytesToTransfer, _
249        ///                       (CDbl(e.BytesTransferred) / (0.01 * e.TotalBytesToTransfer)))
250        ///         justHadByteUpdate = True
251        ///     End If
252        /// End Sub
253        /// </code>
254        /// </example>
255        ///
256        /// <example>
257        ///
258        /// This is a more complete example of using the SaveProgress
259        /// events in a Windows Forms application, with a
260        /// Thread object.
261        ///
262        /// <code lang="C#">
263        /// delegate void SaveEntryProgress(SaveProgressEventArgs e);
264        /// delegate void ButtonClick(object sender, EventArgs e);
265        ///
266        /// internal class WorkerOptions
267        /// {
268        ///     public string ZipName;
269        ///     public string Folder;
270        ///     public string Encoding;
271        ///     public string Comment;
272        ///     public int ZipFlavor;
273        ///     public Zip64Option Zip64;
274        /// }
275        ///
276        /// private int _progress2MaxFactor;
277        /// private bool _saveCanceled;
278        /// private long _totalBytesBeforeCompress;
279        /// private long _totalBytesAfterCompress;
280        /// private Thread _workerThread;
281        ///
282        ///
283        /// private void btnZipup_Click(object sender, EventArgs e)
284        /// {
285        ///     KickoffZipup();
286        /// }
287        ///
288        /// private void btnCancel_Click(object sender, EventArgs e)
289        /// {
290        ///     if (this.lblStatus.InvokeRequired)
291        ///     {
292        ///         this.lblStatus.Invoke(new ButtonClick(this.btnCancel_Click), new object[] { sender, e });
293        ///     }
294        ///     else
295        ///     {
296        ///         _saveCanceled = true;
297        ///         lblStatus.Text = "Canceled...";
298        ///         ResetState();
299        ///     }
300        /// }
301        ///
302        /// private void KickoffZipup()
303        /// {
304        ///     _folderName = tbDirName.Text;
305        ///
306        ///     if (_folderName == null || _folderName == "") return;
307        ///     if (this.tbZipName.Text == null || this.tbZipName.Text == "") return;
308        ///
309        ///     // check for existence of the zip file:
310        ///     if (System.IO.File.Exists(this.tbZipName.Text))
311        ///     {
312        ///         var dlgResult = MessageBox.Show(String.Format("The file you have specified ({0}) already exists." +
313        ///                                                       "  Do you want to overwrite this file?", this.tbZipName.Text),
314        ///                                         "Confirmation is Required", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
315        ///         if (dlgResult != DialogResult.Yes) return;
316        ///         System.IO.File.Delete(this.tbZipName.Text);
317        ///     }
318        ///
319        ///      _saveCanceled = false;
320        ///     _nFilesCompleted = 0;
321        ///     _totalBytesAfterCompress = 0;
322        ///     _totalBytesBeforeCompress = 0;
323        ///     this.btnOk.Enabled = false;
324        ///     this.btnOk.Text = "Zipping...";
325        ///     this.btnCancel.Enabled = true;
326        ///     lblStatus.Text = "Zipping...";
327        ///
328        ///     var options = new WorkerOptions
329        ///     {
330        ///         ZipName = this.tbZipName.Text,
331        ///         Folder = _folderName,
332        ///         Encoding = "ibm437"
333        ///     };
334        ///
335        ///     if (this.comboBox1.SelectedIndex != 0)
336        ///     {
337        ///         options.Encoding = this.comboBox1.SelectedItem.ToString();
338        ///     }
339        ///
340        ///     if (this.radioFlavorSfxCmd.Checked)
341        ///         options.ZipFlavor = 2;
342        ///     else if (this.radioFlavorSfxGui.Checked)
343        ///         options.ZipFlavor = 1;
344        ///     else options.ZipFlavor = 0;
345        ///
346        ///     if (this.radioZip64AsNecessary.Checked)
347        ///         options.Zip64 = Zip64Option.AsNecessary;
348        ///     else if (this.radioZip64Always.Checked)
349        ///         options.Zip64 = Zip64Option.Always;
350        ///     else options.Zip64 = Zip64Option.Never;
351        ///
352        ///     options.Comment = String.Format("Encoding:{0} || Flavor:{1} || ZIP64:{2}\r\nCreated at {3} || {4}\r\n",
353        ///                 options.Encoding,
354        ///                 FlavorToString(options.ZipFlavor),
355        ///                 options.Zip64.ToString(),
356        ///                 System.DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss"),
357        ///                 this.Text);
358        ///
359        ///     if (this.tbComment.Text != TB_COMMENT_NOTE)
360        ///         options.Comment += this.tbComment.Text;
361        ///
362        ///     _workerThread = new Thread(this.DoSave);
363        ///     _workerThread.Name = "Zip Saver thread";
364        ///     _workerThread.Start(options);
365        ///     this.Cursor = Cursors.WaitCursor;
366        ///  }
367        ///
368        ///
369        /// private void DoSave(Object p)
370        /// {
371        ///     WorkerOptions options = p as WorkerOptions;
372        ///     try
373        ///     {
374        ///         using (var zip1 = new ZipFile())
375        ///         {
376        ///             zip1.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding(options.Encoding);
377        ///             zip1.Comment = options.Comment;
378        ///             zip1.AddDirectory(options.Folder);
379        ///             _entriesToZip = zip1.EntryFileNames.Count;
380        ///             SetProgressBars();
381        ///             zip1.SaveProgress += this.zip1_SaveProgress;
382        ///
383        ///             zip1.UseZip64WhenSaving = options.Zip64;
384        ///
385        ///             if (options.ZipFlavor == 1)
386        ///                 zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.WinFormsApplication);
387        ///             else if (options.ZipFlavor == 2)
388        ///                 zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.ConsoleApplication);
389        ///             else
390        ///                 zip1.Save(options.ZipName);
391        ///         }
392        ///     }
393        ///     catch (System.Exception exc1)
394        ///     {
395        ///         MessageBox.Show(String.Format("Exception while zipping: {0}", exc1.Message));
396        ///         btnCancel_Click(null, null);
397        ///     }
398        /// }
399        ///
400        ///
401        ///
402        /// void zip1_SaveProgress(object sender, SaveProgressEventArgs e)
403        /// {
404        ///     switch (e.EventType)
405        ///     {
406        ///         case ZipProgressEventType.Saving_AfterWriteEntry:
407        ///             StepArchiveProgress(e);
408        ///             break;
409        ///         case ZipProgressEventType.Saving_EntryBytesRead:
410        ///             StepEntryProgress(e);
411        ///             break;
412        ///         case ZipProgressEventType.Saving_Completed:
413        ///             SaveCompleted();
414        ///             break;
415        ///         case ZipProgressEventType.Saving_AfterSaveTempArchive:
416        ///             // this event only occurs when saving an SFX file
417        ///             TempArchiveSaved();
418        ///             break;
419        ///     }
420        ///     if (_saveCanceled)
421        ///         e.Cancel = true;
422        /// }
423        ///
424        ///
425        ///
426        /// private void StepArchiveProgress(SaveProgressEventArgs e)
427        /// {
428        ///     if (this.progressBar1.InvokeRequired)
429        ///     {
430        ///         this.progressBar1.Invoke(new SaveEntryProgress(this.StepArchiveProgress), new object[] { e });
431        ///     }
432        ///     else
433        ///     {
434        ///         if (!_saveCanceled)
435        ///         {
436        ///             _nFilesCompleted++;
437        ///             this.progressBar1.PerformStep();
438        ///             _totalBytesAfterCompress += e.CurrentEntry.CompressedSize;
439        ///             _totalBytesBeforeCompress += e.CurrentEntry.UncompressedSize;
440        ///
441        ///             // reset the progress bar for the entry:
442        ///             this.progressBar2.Value = this.progressBar2.Maximum = 1;
443        ///
444        ///             this.Update();
445        ///         }
446        ///     }
447        /// }
448        ///
449        ///
450        /// private void StepEntryProgress(SaveProgressEventArgs e)
451        /// {
452        ///     if (this.progressBar2.InvokeRequired)
453        ///     {
454        ///         this.progressBar2.Invoke(new SaveEntryProgress(this.StepEntryProgress), new object[] { e });
455        ///     }
456        ///     else
457        ///     {
458        ///         if (!_saveCanceled)
459        ///         {
460        ///             if (this.progressBar2.Maximum == 1)
461        ///             {
462        ///                 // reset
463        ///                 Int64 max = e.TotalBytesToTransfer;
464        ///                 _progress2MaxFactor = 0;
465        ///                 while (max > System.Int32.MaxValue)
466        ///                 {
467        ///                     max /= 2;
468        ///                     _progress2MaxFactor++;
469        ///                 }
470        ///                 this.progressBar2.Maximum = (int)max;
471        ///                 lblStatus.Text = String.Format("{0} of {1} files...({2})",
472        ///                     _nFilesCompleted + 1, _entriesToZip, e.CurrentEntry.FileName);
473        ///             }
474        ///
475        ///              int xferred = e.BytesTransferred >> _progress2MaxFactor;
476        ///
477        ///              this.progressBar2.Value = (xferred >= this.progressBar2.Maximum)
478        ///                 ? this.progressBar2.Maximum
479        ///                 : xferred;
480        ///
481        ///              this.Update();
482        ///         }
483        ///     }
484        /// }
485        ///
486        /// private void SaveCompleted()
487        /// {
488        ///     if (this.lblStatus.InvokeRequired)
489        ///     {
490        ///         this.lblStatus.Invoke(new MethodInvoker(this.SaveCompleted));
491        ///     }
492        ///     else
493        ///     {
494        ///         lblStatus.Text = String.Format("Done, Compressed {0} files, {1:N0}% of original.",
495        ///             _nFilesCompleted, (100.00 * _totalBytesAfterCompress) / _totalBytesBeforeCompress);
496        ///          ResetState();
497        ///     }
498        /// }
499        ///
500        /// private void ResetState()
501        /// {
502        ///     this.btnCancel.Enabled = false;
503        ///     this.btnOk.Enabled = true;
504        ///     this.btnOk.Text = "Zip it!";
505        ///     this.progressBar1.Value = 0;
506        ///     this.progressBar2.Value = 0;
507        ///     this.Cursor = Cursors.Default;
508        ///     if (!_workerThread.IsAlive)
509        ///         _workerThread.Join();
510        /// }
511        /// </code>
512        ///
513        /// </example>
514        ///
515        /// <seealso cref="Ionic.Zip.ZipFile.ReadProgress"/>
516        /// <seealso cref="Ionic.Zip.ZipFile.AddProgress"/>
517        /// <seealso cref="Ionic.Zip.ZipFile.ExtractProgress"/>
518        internal event EventHandler<SaveProgressEventArgs> SaveProgress;
519
520
521        internal bool OnSaveBlock(ZipEntry entry, Int64 bytesXferred, Int64 totalBytesToXfer)
522        {
523            EventHandler<SaveProgressEventArgs> sp = SaveProgress;
524            if (sp != null)
525            {
526                var e = SaveProgressEventArgs.ByteUpdate(ArchiveNameForEvent, entry,
527                                                         bytesXferred, totalBytesToXfer);
528                sp(this, e);
529                if (e.Cancel)
530                    _saveOperationCanceled = true;
531            }
532            return _saveOperationCanceled;
533        }
534
535        private void OnSaveEntry(int current, ZipEntry entry, bool before)
536        {
537            EventHandler<SaveProgressEventArgs> sp = SaveProgress;
538            if (sp != null)
539            {
540                var e = new SaveProgressEventArgs(ArchiveNameForEvent, before, _entries.Count, current, entry);
541                sp(this, e);
542                if (e.Cancel)
543                    _saveOperationCanceled = true;
544            }
545        }
546
547        private void OnSaveEvent(ZipProgressEventType eventFlavor)
548        {
549            EventHandler<SaveProgressEventArgs> sp = SaveProgress;
550            if (sp != null)
551            {
552                var e = new SaveProgressEventArgs(ArchiveNameForEvent, eventFlavor);
553                sp(this, e);
554                if (e.Cancel)
555                    _saveOperationCanceled = true;
556            }
557        }
558
559        private void OnSaveStarted()
560        {
561            EventHandler<SaveProgressEventArgs> sp = SaveProgress;
562            if (sp != null)
563            {
564                var e = SaveProgressEventArgs.Started(ArchiveNameForEvent);
565                sp(this, e);
566                if (e.Cancel)
567                    _saveOperationCanceled = true;
568            }
569        }
570        private void OnSaveCompleted()
571        {
572            EventHandler<SaveProgressEventArgs> sp = SaveProgress;
573            if (sp != null)
574            {
575                var e = SaveProgressEventArgs.Completed(ArchiveNameForEvent);
576                sp(this, e);
577            }
578        }
579        #endregion
580
581
582        #region Read
583        /// <summary>
584        /// An event handler invoked before, during, and after the reading of a zip archive.
585        /// </summary>
586        ///
587        /// <remarks>
588        /// <para>
589        /// Depending on the particular event being signaled, different properties on the
590        /// <see cref="ReadProgressEventArgs"/> parameter are set.  The following table
591        /// summarizes the available EventTypes and the conditions under which this
592        /// event handler is invoked with a <c>ReadProgressEventArgs</c> with the given EventType.
593        /// </para>
594        ///
595        /// <list type="table">
596        /// <listheader>
597        /// <term>value of EntryType</term>
598        /// <description>Meaning and conditions</description>
599        /// </listheader>
600        ///
601        /// <item>
602        /// <term>ZipProgressEventType.Reading_Started</term>
603        /// <description>Fired just as ZipFile.Read() begins. Meaningful properties: ArchiveName.
604        /// </description>
605        /// </item>
606        ///
607        /// <item>
608        /// <term>ZipProgressEventType.Reading_Completed</term>
609        /// <description>Fired when ZipFile.Read() has completed. Meaningful properties: ArchiveName.
610        /// </description>
611        /// </item>
612        ///
613        /// <item>
614        /// <term>ZipProgressEventType.Reading_ArchiveBytesRead</term>
615        /// <description>Fired while reading, updates the number of bytes read for the entire archive.
616        /// Meaningful properties: ArchiveName, CurrentEntry, BytesTransferred, TotalBytesToTransfer.
617        /// </description>
618        /// </item>
619        ///
620        /// <item>
621        /// <term>ZipProgressEventType.Reading_BeforeReadEntry</term>
622        /// <description>Indicates an entry is about to be read from the archive.
623        /// Meaningful properties: ArchiveName, EntriesTotal.
624        /// </description>
625        /// </item>
626        ///
627        /// <item>
628        /// <term>ZipProgressEventType.Reading_AfterReadEntry</term>
629        /// <description>Indicates an entry has just been read from the archive.
630        /// Meaningful properties: ArchiveName, EntriesTotal, CurrentEntry.
631        /// </description>
632        /// </item>
633        ///
634        /// </list>
635        /// </remarks>
636        ///
637        /// <seealso cref="Ionic.Zip.ZipFile.SaveProgress"/>
638        /// <seealso cref="Ionic.Zip.ZipFile.AddProgress"/>
639        /// <seealso cref="Ionic.Zip.ZipFile.ExtractProgress"/>
640        internal event EventHandler<ReadProgressEventArgs> ReadProgress;
641
642        private void OnReadStarted()
643        {
644            EventHandler<ReadProgressEventArgs> rp = ReadProgress;
645            if (rp != null)
646            {
647                    var e = ReadProgressEventArgs.Started(ArchiveNameForEvent);
648                    rp(this, e);
649            }
650        }
651
652        private void OnReadCompleted()
653        {
654            EventHandler<ReadProgressEventArgs> rp = ReadProgress;
655            if (rp != null)
656            {
657                    var e = ReadProgressEventArgs.Completed(ArchiveNameForEvent);
658                    rp(this, e);
659            }
660        }
661
662        internal void OnReadBytes(ZipEntry entry)
663        {
664            EventHandler<ReadProgressEventArgs> rp = ReadProgress;
665            if (rp != null)
666            {
667                    var e = ReadProgressEventArgs.ByteUpdate(ArchiveNameForEvent,
668                                        entry,
669                                        ReadStream.Position,
670                                        LengthOfReadStream);
671                    rp(this, e);
672            }
673        }
674
675        internal void OnReadEntry(bool before, ZipEntry entry)
676        {
677            EventHandler<ReadProgressEventArgs> rp = ReadProgress;
678            if (rp != null)
679            {
680                ReadProgressEventArgs e = (before)
681                    ? ReadProgressEventArgs.Before(ArchiveNameForEvent, _entries.Count)
682                    : ReadProgressEventArgs.After(ArchiveNameForEvent, entry, _entries.Count);
683                rp(this, e);
684            }
685        }
686
687        private Int64 _lengthOfReadStream = -99;
688        private Int64 LengthOfReadStream
689        {
690            get
691            {
692                if (_lengthOfReadStream == -99)
693                {
694                    _lengthOfReadStream = (_ReadStreamIsOurs)
695                        ? SharedUtilities.GetFileLength(_name)
696                        : -1L;
697                }
698                return _lengthOfReadStream;
699            }
700        }
701        #endregion
702
703
704        #region Extract
705        /// <summary>
706        ///   An event handler invoked before, during, and after extraction of
707        ///   entries in the zip archive.
708        /// </summary>
709        ///
710        /// <remarks>
711        /// <para>
712        ///   Depending on the particular event, different properties on the <see
713        ///   cref="ExtractProgressEventArgs"/> parameter are set.  The following
714        ///   table summarizes the available EventTypes and the conditions under
715        ///   which this event handler is invoked with a
716        ///   <c>ExtractProgressEventArgs</c> with the given EventType.
717        /// </para>
718        ///
719        /// <list type="table">
720        /// <listheader>
721        /// <term>value of EntryType</term>
722        /// <description>Meaning and conditions</description>
723        /// </listheader>
724        ///
725        /// <item>
726        /// <term>ZipProgressEventType.Extracting_BeforeExtractAll</term>
727        /// <description>
728        ///   Set when ExtractAll() begins. The ArchiveName, Overwrite, and
729        ///   ExtractLocation properties are meaningful.</description>
730        /// </item>
731        ///
732        /// <item>
733        /// <term>ZipProgressEventType.Extracting_AfterExtractAll</term>
734        /// <description>
735        ///   Set when ExtractAll() has completed.  The ArchiveName, Overwrite,
736        ///   and ExtractLocation properties are meaningful.
737        /// </description>
738        /// </item>
739        ///
740        /// <item>
741        /// <term>ZipProgressEventType.Extracting_BeforeExtractEntry</term>
742        /// <description>
743        ///   Set when an Extract() on an entry in the ZipFile has begun.
744        ///   Properties that are meaningful: ArchiveName, EntriesTotal,
745        ///   CurrentEntry, Overwrite, ExtractLocation, EntriesExtracted.
746        /// </description>
747        /// </item>
748        ///
749        /// <item>
750        /// <term>ZipProgressEventType.Extracting_AfterExtractEntry</term>
751        /// <description>
752        ///   Set when an Extract() on an entry in the ZipFile has completed.
753        ///   Properties that are meaningful: ArchiveName, EntriesTotal,
754        ///   CurrentEntry, Overwrite, ExtractLocation, EntriesExtracted.
755        /// </description>
756        /// </item>
757        ///
758        /// <item>
759        /// <term>ZipProgressEventType.Extracting_EntryBytesWritten</term>
760        /// <description>
761        ///   Set within a call to Extract() on an entry in the ZipFile, as data
762        ///   is extracted for the entry.  Properties that are meaningful:
763        ///   ArchiveName, CurrentEntry, BytesTransferred, TotalBytesToTransfer.
764        /// </description>
765        /// </item>
766        ///
767        /// <item>
768        /// <term>ZipProgressEventType.Extracting_ExtractEntryWouldOverwrite</term>
769        /// <description>
770        ///   Set within a call to Extract() on an entry in the ZipFile, when the
771        ///   extraction would overwrite an existing file. This event type is used
772        ///   only when <c>ExtractExistingFileAction</c> on the <c>ZipFile</c> or
773        ///   <c>ZipEntry</c> is set to <c>InvokeExtractProgressEvent</c>.
774        /// </description>
775        /// </item>
776        ///
777        /// </list>
778        ///
779        /// </remarks>
780        ///
781        /// <example>
782        /// <code>
783        /// private static bool justHadByteUpdate = false;
784        /// public static void ExtractProgress(object sender, ExtractProgressEventArgs e)
785        /// {
786        ///   if(e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten)
787        ///   {
788        ///     if (justHadByteUpdate)
789        ///       Console.SetCursorPosition(0, Console.CursorTop);
790        ///
791        ///     Console.Write("   {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer,
792        ///                   e.BytesTransferred / (0.01 * e.TotalBytesToTransfer ));
793        ///     justHadByteUpdate = true;
794        ///   }
795        ///   else if(e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry)
796        ///   {
797        ///     if (justHadByteUpdate)
798        ///       Console.WriteLine();
799        ///     Console.WriteLine("Extracting: {0}", e.CurrentEntry.FileName);
800        ///     justHadByteUpdate= false;
801        ///   }
802        /// }
803        ///
804        /// public static ExtractZip(string zipToExtract, string directory)
805        /// {
806        ///   string TargetDirectory= "extract";
807        ///   using (var zip = ZipFile.Read(zipToExtract)) {
808        ///     zip.ExtractProgress += ExtractProgress;
809        ///     foreach (var e in zip1)
810        ///     {
811        ///       e.Extract(TargetDirectory, true);
812        ///     }
813        ///   }
814        /// }
815        ///
816        /// </code>
817        /// <code lang="VB">
818        /// Public Shared Sub Main(ByVal args As String())
819        ///     Dim ZipToUnpack As String = "C1P3SML.zip"
820        ///     Dim TargetDir As String = "ExtractTest_Extract"
821        ///     Console.WriteLine("Extracting file {0} to {1}", ZipToUnpack, TargetDir)
822        ///     Using zip1 As ZipFile = ZipFile.Read(ZipToUnpack)
823        ///         AddHandler zip1.ExtractProgress, AddressOf MyExtractProgress
824        ///         Dim e As ZipEntry
825        ///         For Each e In zip1
826        ///             e.Extract(TargetDir, True)
827        ///         Next
828        ///     End Using
829        /// End Sub
830        ///
831        /// Private Shared justHadByteUpdate As Boolean = False
832        ///
833        /// Public Shared Sub MyExtractProgress(ByVal sender As Object, ByVal e As ExtractProgressEventArgs)
834        ///     If (e.EventType = ZipProgressEventType.Extracting_EntryBytesWritten) Then
835        ///         If ExtractTest.justHadByteUpdate Then
836        ///             Console.SetCursorPosition(0, Console.CursorTop)
837        ///         End If
838        ///         Console.Write("   {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer, (CDbl(e.BytesTransferred) / (0.01 * e.TotalBytesToTransfer)))
839        ///         ExtractTest.justHadByteUpdate = True
840        ///     ElseIf (e.EventType = ZipProgressEventType.Extracting_BeforeExtractEntry) Then
841        ///         If ExtractTest.justHadByteUpdate Then
842        ///             Console.WriteLine
843        ///         End If
844        ///         Console.WriteLine("Extracting: {0}", e.CurrentEntry.FileName)
845        ///         ExtractTest.justHadByteUpdate = False
846        ///     End If
847        /// End Sub
848        /// </code>
849        /// </example>
850        ///
851        /// <seealso cref="Ionic.Zip.ZipFile.SaveProgress"/>
852        /// <seealso cref="Ionic.Zip.ZipFile.ReadProgress"/>
853        /// <seealso cref="Ionic.Zip.ZipFile.AddProgress"/>
854        internal event EventHandler<ExtractProgressEventArgs> ExtractProgress;
855
856
857
858        private void OnExtractEntry(int current, bool before, ZipEntry currentEntry, string path)
859        {
860            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
861            if (ep != null)
862            {
863                var e = new ExtractProgressEventArgs(ArchiveNameForEvent, before, _entries.Count, current, currentEntry, path);
864                ep(this, e);
865                if (e.Cancel)
866                    _extractOperationCanceled = true;
867            }
868        }
869
870
871        // Can be called from within ZipEntry._ExtractOne.
872        internal bool OnExtractBlock(ZipEntry entry, Int64 bytesWritten, Int64 totalBytesToWrite)
873        {
874            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
875            if (ep != null)
876            {
877                var e = ExtractProgressEventArgs.ByteUpdate(ArchiveNameForEvent, entry,
878                                                            bytesWritten, totalBytesToWrite);
879                ep(this, e);
880                if (e.Cancel)
881                    _extractOperationCanceled = true;
882            }
883            return _extractOperationCanceled;
884        }
885
886
887        // Can be called from within ZipEntry.InternalExtract.
888        internal bool OnSingleEntryExtract(ZipEntry entry, string path, bool before)
889        {
890            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
891            if (ep != null)
892            {
893                var e = (before)
894                    ? ExtractProgressEventArgs.BeforeExtractEntry(ArchiveNameForEvent, entry, path)
895                    : ExtractProgressEventArgs.AfterExtractEntry(ArchiveNameForEvent, entry, path);
896                ep(this, e);
897                if (e.Cancel)
898                    _extractOperationCanceled = true;
899            }
900            return _extractOperationCanceled;
901        }
902
903        internal bool OnExtractExisting(ZipEntry entry, string path)
904        {
905            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
906            if (ep != null)
907            {
908                var e = ExtractProgressEventArgs.ExtractExisting(ArchiveNameForEvent, entry, path);
909                ep(this, e);
910                if (e.Cancel)
911                    _extractOperationCanceled = true;
912            }
913            return _extractOperationCanceled;
914        }
915
916
917        private void OnExtractAllCompleted(string path)
918        {
919            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
920            if (ep != null)
921            {
922                var e = ExtractProgressEventArgs.ExtractAllCompleted(ArchiveNameForEvent,
923                                                                     path );
924                ep(this, e);
925            }
926        }
927
928
929        private void OnExtractAllStarted(string path)
930        {
931            EventHandler<ExtractProgressEventArgs> ep = ExtractProgress;
932            if (ep != null)
933            {
934                var e = ExtractProgressEventArgs.ExtractAllStarted(ArchiveNameForEvent,
935                                                                   path );
936                ep(this, e);
937            }
938        }
939
940
941        #endregion
942
943
944
945        #region Add
946        /// <summary>
947        /// An event handler invoked before, during, and after Adding entries to a zip archive.
948        /// </summary>
949        ///
950        /// <remarks>
951        ///     Adding a large number of entries to a zip file can take a long
952        ///     time.  For example, when calling <see cref="AddDirectory(string)"/> on a
953        ///     directory that contains 50,000 files, it could take 3 minutes or so.
954        ///     This event handler allws an application to track the progress of the Add
955        ///     operation, and to optionally cancel a lengthy Add operation.
956        /// </remarks>
957        ///
958        /// <example>
959        /// <code lang="C#">
960        ///
961        /// int _numEntriesToAdd= 0;
962        /// int _numEntriesAdded= 0;
963        /// void AddProgressHandler(object sender, AddProgressEventArgs e)
964        /// {
965        ///     switch (e.EventType)
966        ///     {
967        ///         case ZipProgressEventType.Adding_Started:
968        ///             Console.WriteLine("Adding files to the zip...");
969        ///             break;
970        ///         case ZipProgressEventType.Adding_AfterAddEntry:
971        ///             _numEntriesAdded++;
972        ///             Console.WriteLine(String.Format("Adding file {0}/{1} :: {2}",
973        ///                                      _numEntriesAdded, _numEntriesToAdd, e.CurrentEntry.FileName));
974        ///             break;
975        ///         case ZipProgressEventType.Adding_Completed:
976        ///             Console.WriteLine("Added all files");
977        ///             break;
978        ///     }
979        /// }
980        ///
981        /// void CreateTheZip()
982        /// {
983        ///     using (ZipFile zip = new ZipFile())
984        ///     {
985        ///         zip.AddProgress += AddProgressHandler;
986        ///         zip.AddDirectory(System.IO.Path.GetFileName(DirToZip));
987        ///         zip.Save(ZipFileToCreate);
988        ///     }
989        /// }
990        ///
991        /// </code>
992        ///
993        /// <code lang="VB">
994        ///
995        /// Private Sub AddProgressHandler(ByVal sender As Object, ByVal e As AddProgressEventArgs)
996        ///     Select Case e.EventType
997        ///         Case ZipProgressEventType.Adding_Started
998        ///             Console.WriteLine("Adding files to the zip...")
999        ///             Exit Select
1000        ///         Case ZipProgressEventType.Adding_AfterAddEntry
1001        ///             Console.WriteLine(String.Format("Adding file {0}", e.CurrentEntry.FileName))
1002        ///             Exit Select
1003        ///         Case ZipProgressEventType.Adding_Completed
1004        ///             Console.WriteLine("Added all files")
1005        ///             Exit Select
1006        ///     End Select
1007        /// End Sub
1008        ///
1009        /// Sub CreateTheZip()
1010        ///     Using zip as ZipFile = New ZipFile
1011        ///         AddHandler zip.AddProgress, AddressOf AddProgressHandler
1012        ///         zip.AddDirectory(System.IO.Path.GetFileName(DirToZip))
1013        ///         zip.Save(ZipFileToCreate);
1014        ///     End Using
1015        /// End Sub
1016        ///
1017        /// </code>
1018        ///
1019        /// </example>
1020        ///
1021        /// <seealso cref="Ionic.Zip.ZipFile.SaveProgress"/>
1022        /// <seealso cref="Ionic.Zip.ZipFile.ReadProgress"/>
1023        /// <seealso cref="Ionic.Zip.ZipFile.ExtractProgress"/>
1024        internal event EventHandler<AddProgressEventArgs> AddProgress;
1025
1026        private void OnAddStarted()
1027        {
1028            EventHandler<AddProgressEventArgs> ap = AddProgress;
1029            if (ap != null)
1030            {
1031                var e = AddProgressEventArgs.Started(ArchiveNameForEvent);
1032                ap(this, e);
1033                if (e.Cancel) // workitem 13371
1034                    _addOperationCanceled = true;
1035            }
1036        }
1037
1038        private void OnAddCompleted()
1039        {
1040            EventHandler<AddProgressEventArgs> ap = AddProgress;
1041            if (ap != null)
1042            {
1043                var e = AddProgressEventArgs.Completed(ArchiveNameForEvent);
1044                ap(this, e);
1045            }
1046        }
1047
1048        internal void AfterAddEntry(ZipEntry entry)
1049        {
1050            EventHandler<AddProgressEventArgs> ap = AddProgress;
1051            if (ap != null)
1052            {
1053                var e = AddProgressEventArgs.AfterEntry(ArchiveNameForEvent, entry, _entries.Count);
1054                ap(this, e);
1055                if (e.Cancel) // workitem 13371
1056                    _addOperationCanceled = true;
1057            }
1058        }
1059
1060        #endregion
1061
1062
1063
1064        #region Error
1065        /// <summary>
1066        /// An event that is raised when an error occurs during open or read of files
1067        /// while saving a zip archive.
1068        /// </summary>
1069        ///
1070        /// <remarks>
1071        ///  <para>
1072        ///     Errors can occur as a file is being saved to the zip archive.  For
1073        ///     example, the File.Open may fail, or a File.Read may fail, because of
1074        ///     lock conflicts or other reasons.  If you add a handler to this event,
1075        ///     you can handle such errors in your own code.  If you don't add a
1076        ///     handler, the library will throw an exception if it encounters an I/O
1077        ///     error during a call to <c>Save()</c>.
1078        ///  </para>
1079        ///
1080        ///  <para>
1081        ///    Setting a handler implicitly sets <see cref="ZipFile.ZipErrorAction"/> to
1082        ///    <c>ZipErrorAction.InvokeErrorEvent</c>.
1083        ///  </para>
1084        ///
1085        ///  <para>
1086        ///    The handler you add applies to all <see cref="ZipEntry"/> items that are
1087        ///    subsequently added to the <c>ZipFile</c> instance. If you set this
1088        ///    property after you have added items to the <c>ZipFile</c>, but before you
1089        ///    have called <c>Save()</c>, errors that occur while saving those items
1090        ///    will not cause the error handler to be invoked.
1091        ///  </para>
1092        ///
1093        ///  <para>
1094        ///    If you want to handle any errors that occur with any entry in the zip
1095        ///    file using the same error handler, then add your error handler once,
1096        ///    before adding any entries to the zip archive.
1097        ///  </para>
1098        ///
1099        ///  <para>
1100        ///    In the error handler method, you need to set the <see
1101        ///    cref="ZipEntry.ZipErrorAction"/> property on the
1102        ///    <c>ZipErrorEventArgs.CurrentEntry</c>.  This communicates back to
1103        ///    DotNetZip what you would like to do with this particular error.  Within
1104        ///    an error handler, if you set the <c>ZipEntry.ZipErrorAction</c> property
1105        ///    on the <c>ZipEntry</c> to <c>ZipErrorAction.InvokeErrorEvent</c> or if
1106        ///    you don't set it at all, the library will throw the exception. (It is the
1107        ///    same as if you had set the <c>ZipEntry.ZipErrorAction</c> property on the
1108        ///    <c>ZipEntry</c> to <c>ZipErrorAction.Throw</c>.) If you set the
1109        ///    <c>ZipErrorEventArgs.Cancel</c> to true, the entire <c>Save()</c> will be
1110        ///    canceled.
1111        ///  </para>
1112        ///
1113        ///  <para>
1114        ///    In the case that you use <c>ZipErrorAction.Skip</c>, implying that
1115        ///    you want to skip the entry for which there's been an error, DotNetZip
1116        ///    tries to seek backwards in the output stream, and truncate all bytes
1117        ///    written on behalf of that particular entry. This works only if the
1118        ///    output stream is seekable.  It will not work, for example, when using
1119        ///    ASPNET's Response.OutputStream.
1120        ///  </para>
1121        ///
1122        /// </remarks>
1123        ///
1124        /// <example>
1125        ///
1126        /// This example shows how to use an event handler to handle
1127        /// errors during save of the zip file.
1128        /// <code lang="C#">
1129        ///
1130        /// public static void MyZipError(object sender, ZipErrorEventArgs e)
1131        /// {
1132        ///     Console.WriteLine("Error saving {0}...", e.FileName);
1133        ///     Console.WriteLine("   Exception: {0}", e.exception);
1134        ///     ZipEntry entry = e.CurrentEntry;
1135        ///     string response = null;
1136        ///     // Ask the user whether he wants to skip this error or not
1137        ///     do
1138        ///     {
1139        ///         Console.Write("Retry, Skip, Throw, or Cancel ? (R/S/T/C) ");
1140        ///         response = Console.ReadLine();
1141        ///         Console.WriteLine();
1142        ///
1143        ///     } while (response != null &amp;&amp;
1144        ///              response[0]!='S' &amp;&amp; response[0]!='s' &amp;&amp;
1145        ///              response[0]!='R' &amp;&amp; response[0]!='r' &amp;&amp;
1146        ///              response[0]!='T' &amp;&amp; response[0]!='t' &amp;&amp;
1147        ///              response[0]!='C' &amp;&amp; response[0]!='c');
1148        ///
1149        ///     e.Cancel = (response[0]=='C' || response[0]=='c');
1150        ///
1151        ///     if (response[0]=='S' || response[0]=='s')
1152        ///         entry.ZipErrorAction = ZipErrorAction.Skip;
1153        ///     else if (response[0]=='R' || response[0]=='r')
1154        ///         entry.ZipErrorAction = ZipErrorAction.Retry;
1155        ///     else if (response[0]=='T' || response[0]=='t')
1156        ///         entry.ZipErrorAction = ZipErrorAction.Throw;
1157        /// }
1158        ///
1159        /// public void SaveTheFile()
1160        /// {
1161        ///   string directoryToZip = "fodder";
1162        ///   string directoryInArchive = "files";
1163        ///   string zipFileToCreate = "Archive.zip";
1164        ///   using (var zip = new ZipFile())
1165        ///   {
1166        ///     // set the event handler before adding any entries
1167        ///     zip.ZipError += MyZipError;
1168        ///     zip.AddDirectory(directoryToZip, directoryInArchive);
1169        ///     zip.Save(zipFileToCreate);
1170        ///   }
1171        /// }
1172        /// </code>
1173        ///
1174        /// <code lang="VB">
1175        /// Private Sub MyZipError(ByVal sender As Object, ByVal e As Ionic.Zip.ZipErrorEventArgs)
1176        ///     ' At this point, the application could prompt the user for an action to take.
1177        ///     ' But in this case, this application will simply automatically skip the file, in case of error.
1178        ///     Console.WriteLine("Zip Error,  entry {0}", e.CurrentEntry.FileName)
1179        ///     Console.WriteLine("   Exception: {0}", e.exception)
1180        ///     ' set the desired ZipErrorAction on the CurrentEntry to communicate that to DotNetZip
1181        ///     e.CurrentEntry.ZipErrorAction = Zip.ZipErrorAction.Skip
1182        /// End Sub
1183        ///
1184        /// Public Sub SaveTheFile()
1185        ///     Dim directoryToZip As String = "fodder"
1186        ///     Dim directoryInArchive As String = "files"
1187        ///     Dim zipFileToCreate as String = "Archive.zip"
1188        ///     Using zipArchive As ZipFile = New ZipFile
1189        ///         ' set the event handler before adding any entries
1190        ///         AddHandler zipArchive.ZipError, AddressOf MyZipError
1191        ///         zipArchive.AddDirectory(directoryToZip, directoryInArchive)
1192        ///         zipArchive.Save(zipFileToCreate)
1193        ///     End Using
1194        /// End Sub
1195        ///
1196        /// </code>
1197        /// </example>
1198        ///
1199        /// <seealso cref="Ionic.Zip.ZipFile.ZipErrorAction"/>
1200        internal event EventHandler<ZipErrorEventArgs> ZipError;
1201
1202        internal bool OnZipErrorSaving(ZipEntry entry, Exception exc)
1203        {
1204            if (ZipError != null)
1205            {
1206                lock (LOCK)
1207                {
1208                    var e = ZipErrorEventArgs.Saving(this.Name, entry, exc);
1209                    ZipError(this, e);
1210                    if (e.Cancel)
1211                        _saveOperationCanceled = true;
1212                }
1213            }
1214            return _saveOperationCanceled;
1215        }
1216        #endregion
1217
1218    }
1219}
Note: See TracBrowser for help on using the repository browser.