From 3a608112e7ec34d8e628354462a90eb52326ec99 Mon Sep 17 00:00:00 2001 From: Gerry Shaw Date: Thu, 8 Aug 2013 23:10:32 -0700 Subject: [PATCH] Initial git checkin Original subversion repository no longer available. --- LICENSE.md | 49 +++ README.md | 22 + Zip.build | 183 ++++++++ bin/Zip.Tests.dll | Bin 0 -> 4608 bytes bin/Zip.chm | Bin 0 -> 49950 bytes bin/Zip.dll | Bin 0 -> 16384 bytes bin/Zip.xml | 684 ++++++++++++++++++++++++++++++ bin/zlib.dll | Bin 0 -> 53760 bytes examples/MiniZip/MiniZip.cs | 196 +++++++++ src/Zip.Tests/AllTests.cs | 53 +++ src/Zip.Tests/ExceptionTest.cs | 48 +++ src/Zip.Tests/ZLibTest.cs | 45 ++ src/Zip.Tests/ZipExceptionTest.cs | 48 +++ src/Zip.Tests/ZipFileTest.cs | 49 +++ src/Zip.Tests/data/test.zip | Bin 0 -> 43970 bytes src/Zip/AssemblyInfo.cs | 39 ++ src/Zip/ZipEntry.cs | 245 +++++++++++ src/Zip/ZipEntryCollection.cs | 195 +++++++++ src/Zip/ZipException.cs | 51 +++ src/Zip/ZipLib.cs | 378 +++++++++++++++++ src/Zip/ZipReader.cs | 298 +++++++++++++ src/Zip/ZipWriter.cs | 181 ++++++++ 22 files changed, 2764 insertions(+) create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 Zip.build create mode 100644 bin/Zip.Tests.dll create mode 100644 bin/Zip.chm create mode 100644 bin/Zip.dll create mode 100644 bin/Zip.xml create mode 100644 bin/zlib.dll create mode 100644 examples/MiniZip/MiniZip.cs create mode 100644 src/Zip.Tests/AllTests.cs create mode 100644 src/Zip.Tests/ExceptionTest.cs create mode 100644 src/Zip.Tests/ZLibTest.cs create mode 100644 src/Zip.Tests/ZipExceptionTest.cs create mode 100644 src/Zip.Tests/ZipFileTest.cs create mode 100644 src/Zip.Tests/data/test.zip create mode 100644 src/Zip/AssemblyInfo.cs create mode 100644 src/Zip/ZipEntry.cs create mode 100644 src/Zip/ZipEntryCollection.cs create mode 100644 src/Zip/ZipException.cs create mode 100644 src/Zip/ZipLib.cs create mode 100644 src/Zip/ZipReader.cs create mode 100644 src/Zip/ZipWriter.cs diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..4dba023 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,49 @@ +Zip License +----------- + +Copyright (C) 2001 Gerry Shaw + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Gerry Shaw (gerry_shaw@yahoo.com) + + +zlib License +------------ + +Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + +http://www.gzip.org/zlib/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..fbd73ca --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# Zip + +Zip is a free .NET Zip library based on the java.util.zip package. It uses the +freely available zlib library for the compression engine and a contribution +to the zlib library for zip file manipulation. + +Note: This is a very old library and I no longer support it. I'm putting it +up on GitHub for historical and keep safe reasons more than anything. That said +it has been used in may products and continues to be of some value. + +## Authors + +* Gerry Shaw + +### Special Thanks + +* The [zlib](http://www.gzip.org/zlib) developers +* Philip Craig for [NUnit](http://nunit.sourceforge.net) + +## License + +BSD diff --git a/Zip.build b/Zip.build new file mode 100644 index 0000000..0a1770e --- /dev/null +++ b/Zip.build @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bin/Zip.Tests.dll b/bin/Zip.Tests.dll new file mode 100644 index 0000000000000000000000000000000000000000..20ec8a238addea34edb5f9e7f681b1397848dba7 GIT binary patch literal 4608 zcmeHKTWlOx8UAK=y|&l!CSHS-NKP{*rkGHT)*(eTM2&B8;>d|j)(&j~IJ3K_>uGjp zwzFdr2dT0^szimjNL2-bs)(n)AP_1vqT=!p9xEk}pel-Z=>xY1UJw+*_y04tcMU4# zk*a4s|2hBleE&alE#n0hVMu1w58Gq?)w5 z3he8aygSYT`Z_H8$e-=t-PqiS$*+hJb((96o18WWxavmjs7g+;O>rPEY7Zcar`*Ui zLK>>-Ds3bdQ}1k3z)UAEANG*s?$D`=r?itF_!xSRJ!Fr|S8=Rs5@4WYVTf}u#L&G$ zJ{R`VXq<)3-@`GPJFSClqre%7Vz=!HrLoda4)-z-Yk&^_%wGRYDWkPxRzu_coHGA` zf!sJh-2A@w0O??VpB?h0=EGv#wLRti_% z>lY^6l6!n|;)KHQL4*CPO#0}vfI|S^l5shX{Gi?zlUuCeLH0*i%ecd_l;P-^)rC3s z_sMSwKhp>+?4_|V)|n4}-(niT->i>IL8VxPtjkdRnZL#nIj2;;jJF@Uu$@<4yf$F? zY5x$faNKXn_>}buX<%L93jd}`zN3=wDgCX|zgmB?@))#*7L}ImF*}bc#}Z#MkU8ad z0MFui^z3jyCD%_*BnR-zRM)HAos{F7q3$=S<$f$X67RW#Z(*2rPbzmCe`NJ+TuHgV zDEB$#p2OS9T~+SIzWvq+Eq{>c7)AVkvcnCN`-O5z%nW{&auPFx+leKPSi)fxYzdYO z`jt!kvKUA?@yp^sVu|DQ%VJ8o7qMVHOzwq5r&#!^nblXVz4Q;(NAVUOVYMXh38jlByVg7w@H^`qK8=4^D|ixz?I+-?*2mNK=kW|;`yk~vRsLn$aQt=q z99#_G22OE@y~fN40EetmR-=bpc8hFR`;sEe<01RCmqcOVit5GhntqgA9e7z~N-mkG z?T3LAJ|#y?>^F_$)jdCG$IkV2zq;&B`0ffsE$JeVpQej|21>1;0}cj6N`c|NRd zG|c0;?6=$%(~jG2tAU3mJ+la%w-!Q^sDXM#cU!Cz| zcP9>-?P?e`{0hpO?btN2RC(G|V@x+1I*$Z6eWPkxF;mbemlyqt4!Xr|H4Y<`O}yIT z>|Qh%UJn$;+G6O{xY)6vUUd_%l{fs@AfX~$E1Sso8vadBW=Xu#s$pjq6?YpZkli`o zs|R5__N#5onaW1J?o}FQI_4fz+2BOG$p)-X5=RlNY_<$8ChtVXXT6}-FgRmk;pU^T znM$T>HNlx84wKyrvtiH-q&ot4t6?=uqHu;ABn;%`@JIzV{XIy^ly_3@WnY{Z7{0oMm9dZBw literal 0 HcmV?d00001 diff --git a/bin/Zip.chm b/bin/Zip.chm new file mode 100644 index 0000000000000000000000000000000000000000..153b5075234f3d456ab51ccfc33027aaabcd5593 GIT binary patch literal 49950 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 WAOe911RxNBKm-C12tXhMfgt`AI(4N0 literal 0 HcmV?d00001 diff --git a/bin/Zip.dll b/bin/Zip.dll new file mode 100644 index 0000000000000000000000000000000000000000..00b7aa6843ad7d3e65d7eb01cca0e40cea48faee GIT binary patch literal 16384 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 literal 0 HcmV?d00001 diff --git a/bin/Zip.xml b/bin/Zip.xml new file mode 100644 index 0000000..3990879 --- /dev/null +++ b/bin/Zip.xml @@ -0,0 +1,684 @@ + + + + Zip + + + + Thrown whenever an error occurs during the build. + + + Constructs an exception with no descriptive information. + + + Constructs an exception with a descriptive message. + The error message that explains the reason for the exception. + + + Constructs an exception with a descriptive message and a reference to the instance of the Exception that is the root cause of the this exception. + The error message that explains the reason for the exception. + An instance of Exception that is the cause of the current Exception. If is non-null, then the current Exception is raised in a catch block handling innerException. + + + Initializes a new instance of the BuildException class with serialized data. + The object that holds the serialized object data. + The contextual information about the source or destination. + + + Specifies how the the zip entry should be compressed. + + + No compression. + + + Default and only supported compression method. + + + Specifies the amount of compression to apply to compressed zip entires. + + + Default compression level. A good choice for speed and size. + + + Do not perfrom compression. + + + Compress the entry as fast as possible size trading size for time. + + + Compress the entry using a balance of size and time. + + + Compress the entry to smallest possible size trading time for size. + + + Represents a entry in a zip file. + + + Initializes a instance of the class with the given name. + The name of entry that will be stored in the directory of the zip file. + + + Creates a new Zip file entry reading values from a zip file. + + + Returns a string representation of the Zip entry. + + + Check if only contains Ascii 8 bit characters. + + + Gets and sets the local file comment for the entry. + + Currently only Ascii 8 bit characters are supported in comments. + A comment cannot exceed 65535 bytes. + + + + Gets the compressed size of the entry data in bytes, or -1 if not known. + + + Gets the CRC-32 checksum of the uncompressed entry data. + + + Gets and sets the optional extra field data for the entry. + ExtraField data cannot exceed 65535 bytes. + + + Gets and sets the default compresion method for zip file entries. See for a list of possible values. + + + Gets and sets the default compresion level for zip file entries. See for a partial list of values. + + + Gets the size of the uncompressed entry data in in bytes. + + + Gets and sets the modification time of the entry. + + + Gets and sets the name of the entry. + + Currently only Ascii 8 bit characters are supported in comments. + A comment cannot exceed 65535 bytes. + + + + Flag that indicates if this entry is a directory or a file. + + + Gets the compression ratio as a percentage. + Returns -1.0 if unknown. + + + Support methods for uncompressing zip files. + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g WinZip, InfoZip tools and compatible. + Encryption and multi volume ZipFile (span) are not supported. Old compressions used by old PKZip 1.x are not supported. + Copyright (C) 1998 Gilles Vollant. http://www.winimage.com/zLibDll/unzip.htm + C# wrapper by Gerry Shaw (gerry_shaw@yahoo.com). http://www.organicbit.com/zip/ + + + + Create a zip file. + + + Open a new zip entry for writing. + + + Write data to the zip file. + + + Close the current entry in the zip file. + + + Close the zip file. + + + Opens a zip file for reading. + The name of the zip to open. At this time only file names with ANSI (8 bit) characters are supported. + + A handle usable with other functions of the ZipLib class. + Otherwise IntPtr.Zero if the zip file could not e opened (file doen not exist or is not valid). + + + + Closes a zip file opened with unzipOpen. + The zip file handle opened by . + If there are files inside the zip file opened with these files must be closed with before call unzClose. + + Zero if there was no error. + Otherwise a value less than zero. See for the specific reason. + + + + Get global information about the zip file. + The zip file handle opened by . + An address of a struct to hold the information. No preparation of the structure is needed. + + Zero if there was no error. + Otherwise a value less than zero. See for the specific reason. + + + + Get the comment associated with the entire zip file. + The zip file handle opened by + The buffer to hold the comment. + The length of the buffer in bytes (8 bit characters). + + The number of characters in the comment if there was no error. + Otherwise a value less than zero. See for the specific reason. + + + + Set the current file of the zip file to the first file. + The zip file handle opened by . + + Zero if there was no error. + Otherwise a value less than zero. See for the specific reason. + + + + Set the current file of the zip file to the next file. + The zip file handle opened by . + + Zero if there was no error. + Otherwise if there are no more entries. + + + + Try locate the entry in the zip file. + The zip file handle opened by . + The name of the entry to look for. + If 0 use the OS default. If 1 use case sensitivity like strcmp, Unix style. If 2 do not use case sensitivity like strcmpi, Windows style. + + Zero if there was no error. + Otherwise if there are no more entries. + + + + Get information about the current entry in the zip file. + The zip file handle opened by . + A ZipEntryInfo struct to hold information about the entry or null. + An array of sbyte characters to hold the entry name or null. + The length of the entryNameBuffer in bytes. + An array to hold the extra field data for the entry or null. + The length of the extraField array in bytes. + An array of sbyte characters to hold the entry name or null. + The length of theh commentBuffer in bytes. + + If entryInfoPtr is not null the structure will contain information about the current file. + If entryNameBuffer is not null the name of the entry will be copied into it. + If extraField is not null the extra field data of the entry will be copied into it. + If commentBuffer is not null the comment of the entry will be copied into it. + + + Zero if there was no error. + Otherwise a value less than zero. See for the specific reason. + + + + Open the zip file entry for reading. + The zip file handle opened by . + + Zero if there was no error. + Otherwise a value from . + + + + Close the file entry opened by . + The zip file handle opened by . + + Zero if there was no error. + CrcError if the file was read but the Crc does not match. + Otherwise a value from . + + + + Read bytes from the current zip file entry. + The zip file handle opened by . + Buffer to store the uncompressed data into. + Number of bytes to write from . + + The number of byte copied if somes bytes are copied. + Zero if the end of file was reached. + Less than zero with error code if there is an error. See for a list of possible error codes. + + + + Give the current position in uncompressed data of the zip file entry currently opened. + The zip file handle opened by . + The number of bytes into the uncompressed data read so far. + + + Determine if the end of the zip file entry has been reached. + The zip file handle opened by . + + One if the end of file was reached. + Zero if elsewhere. + + + + Converts a CLR string to a 8 bit ANSI array of characters. + The string to convert. + A 8 bit ANSI array of characters. + + + Converst an 8 bit ANSI C style string to a CLR string. + The array of a characters that holds the string. + The CLR string representing the characters passed in. + + + List of possible error codes. + + + No error. + + + Unknown error. + + + Last entry in directory reached. + + + Parameter error. + + + Zip file is invalid. + + + Internal program error. + + + Crc values do not match. + + + Global information about the zip file. + + + The number of entries in the directory. + + + Length of zip file comment in bytes (8 bit characters). + + + Custom ZipLib date time structure. + + + Seconds after the minute - [0,59] + + + Minutes after the hour - [0,59] + + + Hours since midnight - [0,23] + + + Day of the month - [1,31] + + + Months since January - [0,11] + + + Years - [1980..2044] + + + Information stored in zip file directory about an entry. + + + Version needed to extract (2 bytes). + + + General purpose bit flag (2 bytes). + + + Compression method (2 bytes). + + + Last mod file date in Dos fmt (4 bytes). + + + Crc-32 (4 bytes). + + + Compressed size (4 bytes). + + + Uncompressed size (4 bytes). + + + Filename length (2 bytes). + + + Extra field length (2 bytes). + + + File comment length (2 bytes). + + + Disk number start (2 bytes). + + + Internal file attributes (2 bytes). + + + External file attributes (4 bytes). + + + File modification date of entry. + + + A collection that stores objects. + + + + Initializes a new instance of . + + + Initializes a new instance of based on another . + A from which the contents are copied. + + + Initializes a new instance of containing any array of objects. + A array of objects with which to intialize the collection. + + + Adds a with the specified value to the . + The to add. + The index at which the new element was inserted. + + + + Copies the elements of an array to the end of the . + An array of type containing the objects to add to the collection. + None. + + + + Adds the contents of another to the end of the collection. + A containing the objects to add to the collection. + None. + + + + Gets a value indicating whether the contains the specified . + The to locate. + + if the is contained in the collection; + otherwise, . + + + + + Copies the values to a one-dimensional instance at the specified index. + The one-dimensional that is the destination of the values copied from . + The index in where copying begins. + None. + is multidimensional. -or- The number of elements in the is greater than the available space between and the end of . + is . + is less than 's lowbound. + + + + Returns the index of a in the . + The to locate. + + The index of the of in the + , if found; otherwise, -1. + + + + + Inserts a into the at the specified index. + The zero-based index where should be inserted. + The to insert. + None. + + + + Returns an enumerator that can iterate through the . + None. + + + + Removes a specific from the . + The to remove from the . + None. + is not found in the Collection. + + + Represents the entry at the specified index of the . + The zero-based index of the entry to locate in the collection. + + The entry at the specified index of the collection. + + is outside the valid range of indexes for the collection. + + + Enumerator for . + + + Initializes a new instance of the class. + + + Advance the enumerator to the next entry in the collection. + true if there are more entries; false if there are no more entires in the collection. + + + Set the enumerator to just before the start of the collection. Call to advance to the first entry in the collection. + + + Gets the current entry. + + + Provides support for reading files in the ZIP file format. Includes support for both compressed and uncompressed entries. + This example shows how to view the entries in a ZIP file. + + public static void View(string zipFileName) { + ZipReader reader = new ZipReader(zipFileName); + + Console.WriteLine("Archive: {0} ({1} files)", zipFileName, reader.Entries.Count); + Console.WriteLine(reader.Comment); + + string format = "{0,8} {1,8} {2,5} {3,10} {4,5} {5}"; + Console.WriteLine(format, " Length ", " Size ", "Ratio", " Date ", "Time ", "Name"); + Console.WriteLine(format, "--------", "--------", "-----", "----------", "-----", "----"); + + foreach (ZipEntry entry in reader.Entries) { + if (!entry.IsDirectory) { + Console.WriteLine(format, + entry.Length, + entry.CompressedLength, + entry.Ratio.ToString("P0"), + entry.ModifiedTime.ToString("yyyy-MM-dd"), + entry.ModifiedTime.ToString("hh:mm"), + entry.Name); + } + } + reader.Close(); + } + + + This example shows how to extract files from a ZIP file. + + public static void Extract(string zipFileName) { + ZipReader reader = new ZipReader(zipFileName); + Console.WriteLine("Archive: {0}", zipFileName); + Console.WriteLine(reader.Comment); + + // buffer to hold temp bytes + byte[] buffer = new byte[4096]; + int byteCount; + + // Get the zipped entries + while (reader.MoveNext()) { + ZipEntry entry = reader.Current; + + if (entry.IsDirectory) { + Directory.CreateDirectory(entry.Name); + } else { + Console.Write(" {0}", entry.Name); + + // create output stream + FileStream writer = File.Open(entry.Name, FileMode.Create); + + // write uncompressed data + while ((byteCount = reader.Read(buffer, 0, buffer.Length)) > 0) { + Console.Write("."); + writer.Write(buffer, 0, byteCount); + } + writer.Close(); + Console.WriteLine(); + } + } + reader.Close(); + } + + + + + ZipFile handle to read data from. + + + Name of zip file. + + + Contents of zip file directory. + + + Global zip file comment. + + + True if an entry is open for reading. + + + Current zip entry open for reading. + + + Initializes a instance of the class for reading the zip file with the given name. + The name of zip file that will be read. + + + Cleans up the resources used by this zip file. + + + Dispose is synonym for Close. + + + Closes the zip file and releases any resources. + + + Advances the enumerator to the next element of the collection. + Sets to the next zip entry. + true if the next entry is not null; otherwise false. + + + Move to just before the first entry in the zip directory. + + + Seek to the specified entry. + The name of the entry to seek to. + + + Uncompress a block of bytes from the current zip entry and writes the data in a given buffer. + The array to write data into. + The byte offset in at which to begin writing. + The maximum number of bytes to read. + + + Gets the name of the zip file that was passed to the constructor. + + + Gets the global comment for the zip file. + + + Gets a object that contains all the entries in the zip file directory. + + + Gets the current entry in the zip file.. + + + Provides support for writing files in the ZIP file format. Includes support for both compressed and uncompressed entries. + This example shows how to create a ZIP file. + + public static void Add(string zipFileName, string[] entryPatterns) { + string currentDirectory = Directory.GetCurrentDirectory(); + Console.WriteLine("Creating {0}", zipFileName); + + ZipWriter writer = new ZipWriter(zipFileName); + + // buffer to hold temp bytes + byte[] buffer = new byte[4096]; + int byteCount; + + // add files to archive + foreach (string pattern in entryPatterns) { + foreach (string path in Directory.GetFiles(currentDirectory, pattern)) { + string fileName = Path.GetFileName(path); + Console.Write("Adding {0}", fileName); + + ZipEntry entry = new ZipEntry(fileName); + entry.ModifiedTime = File.GetLastWriteTime(fileName); + entry.Comment = "local file comment"; + + writer.AddEntry(entry); + + FileStream reader = File.OpenRead(entry.Name); + while ((byteCount = reader.Read(buffer, 0, buffer.Length)) > 0) { + Console.Write("."); + writer.Write(buffer, 0, byteCount); + } + reader.Close(); + Console.WriteLine(); + } + } + + writer.Close(); + } + + + + + Name of the zip file. + + + Zip file global comment. + + + True if currently writing a new zip file entry. + + + Zip file handle. + + + Initializes a new instance fo the class with a specified file name. Any Existing file will be overwritten. + The name of the zip file to create. + + + Cleans up the resources used by this zip file. + + + Dispose is synonym for Close. + + + Closes the zip file and releases any resources. + + + Creates a new zip entry in the directory and positions the stream to the start of the entry data. + The zip entry to be written. + Closes the current entry if still active. + + + Compress a block of bytes from the given buffer and writes them into the current zip entry. + The array to read data from. + The byte offset in at which to begin reading. + The maximum number of bytes to write. + + + Gets the name of the zip file. + + + Gets and sets the zip file comment. + + + diff --git a/bin/zlib.dll b/bin/zlib.dll new file mode 100644 index 0000000000000000000000000000000000000000..d106ac6d44f71072ffed2c2d93adf2f87a48df99 GIT binary patch literal 53760 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 literal 0 HcmV?d00001 diff --git a/examples/MiniZip/MiniZip.cs b/examples/MiniZip/MiniZip.cs new file mode 100644 index 0000000..218b5c5 --- /dev/null +++ b/examples/MiniZip/MiniZip.cs @@ -0,0 +1,196 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using System.IO; +using OrganicBit.Zip; + +namespace OrganicBit.Zip.Examples { + + public class MiniZip { + + public static void ShowHelp() { + Console.WriteLine( +@"MiniZip - A simple zip file manipulator +http://www.organicbit.com/zip/ + +Usage: minizip [-v|-e|-a] [files to add] + +Examples: + minizip # displays this message + minizip -v # view contents + minizip -e # extract files + minizip -a [*.txt] # add files +"); + } + + public static void View(string zipFileName) { + ZipReader reader = new ZipReader(zipFileName); + + Console.WriteLine("Archive: {0} ({1} files)", zipFileName, reader.Entries.Count); + Console.WriteLine(reader.Comment); + + string format = "{0,8} {1,8} {2,5} {3,10} {4,5} {5}"; + Console.WriteLine(format, " Length ", " Size ", "Ratio", " Date ", "Time ", "Name"); + Console.WriteLine(format, "--------", "--------", "-----", "----------", "-----", "----"); + + foreach (ZipEntry entry in reader.Entries) { + if (!entry.IsDirectory) { + Console.WriteLine(format, + entry.Length, + entry.CompressedLength, + entry.Ratio.ToString("P0"), + entry.ModifiedTime.ToString("yyyy-MM-dd"), + entry.ModifiedTime.ToString("hh:mm"), + entry.Name); + } + } + reader.Close(); + } + + public static void Extract(string zipFileName) { + ZipReader reader = new ZipReader(zipFileName); + Console.WriteLine("Archive: {0}", zipFileName); + Console.WriteLine(reader.Comment); + + // buffer to hold temp bytes + byte[] buffer = new byte[4096]; + int byteCount; + + // Get the zipped entries + while (reader.MoveNext()) { + ZipEntry entry = reader.Current; + + if (entry.IsDirectory) { + Directory.CreateDirectory(entry.Name); + } else { + Console.Write(" {0}", entry.Name); + + // create output stream + FileStream writer = File.Open(entry.Name, FileMode.Create); + + // write uncompressed data + while ((byteCount = reader.Read(buffer, 0, buffer.Length)) > 0) { + Console.Write("."); + writer.Write(buffer, 0, byteCount); + } + writer.Close(); + Console.WriteLine(); + } + } + reader.Close(); + } + + public static void Add(string zipFileName, string[] entryPatterns) { + string currentDirectory = Directory.GetCurrentDirectory(); + Console.WriteLine("Creating {0}", zipFileName); + + ZipWriter writer = new ZipWriter(zipFileName); + + // buffer to hold temp bytes + byte[] buffer = new byte[4096]; + int byteCount; + + // add files to archive + foreach (string pattern in entryPatterns) { + foreach (string path in Directory.GetFiles(currentDirectory, pattern)) { + string fileName = Path.GetFileName(path); + Console.Write("Adding {0}", fileName); + + ZipEntry entry = new ZipEntry(fileName); + entry.ModifiedTime = File.GetLastWriteTime(fileName); + entry.Comment = "local file comment"; + + writer.AddEntry(entry); + + FileStream reader = File.OpenRead(entry.Name); + while ((byteCount = reader.Read(buffer, 0, buffer.Length)) > 0) { + Console.Write("."); + writer.Write(buffer, 0, byteCount); + } + reader.Close(); + Console.WriteLine(); + } + } + + writer.Close(); + } + + enum Action { + Nothing, + ShowHelp, + View, + Extract, + Add + } + + static Action ParseCommandLine(string[] args) { + Action action = Action.ShowHelp; + if (args.Length >= 2) { + if (args[0][0] == '-') { + switch (args[0][1]) { + case 'v': + action = Action.View; + break; + + case 'e': + action = Action.Extract; + break; + + case 'a': + action = Action.Add; + break; + } + } + } + return action; + } + + public static int Main(string[] args) { + try { + Action action = ParseCommandLine(args); + switch (action) { + case Action.ShowHelp: + ShowHelp(); + break; + + case Action.View: + View(args[1]); + break; + + case Action.Extract: + Extract(args[1]); + break; + + case Action.Add: + string[] patterns = new string[args.Length - 2]; + Array.Copy(args, 2, patterns, 0, args.Length - 2); + Add(args[1], patterns); + break; + } + } catch (Exception e) { + Console.WriteLine(e.Message); + Environment.Exit(1); + } + + return 0; + } + } +} diff --git a/src/Zip.Tests/AllTests.cs b/src/Zip.Tests/AllTests.cs new file mode 100644 index 0000000..06a4a1f --- /dev/null +++ b/src/Zip.Tests/AllTests.cs @@ -0,0 +1,53 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using System.Reflection; +using NUnit.Framework; + +namespace OrganicBit.Zip.Tests { + + // This class bundles all our tests into a single suite. If you wanted + // you could create other suites with a sub set of the tests. All that is + // required is a property called Suite that returns a ITest object. The + // ITest object most commonly returned is a TestSuite. For single class + // tests this member can be included within the TestCase. + public class AllTests { + public static ITest Suite { + get { + // Use reflection to automagically scan all the classes that + // inherit from TestCase and add them to the suite. + TestSuite suite = new TestSuite("Zip Tests"); + /* + Assembly assembly = Assembly.GetExecutingAssembly(); + foreach(Type type in assembly.GetTypes()) { + if (type.IsSubclassOf(typeof(TestCase)) && !type.IsAbstract) { + suite.AddTestSuite(type); + } + } + */ + suite.AddTestSuite(typeof(ZipExceptionTest)); + suite.AddTestSuite(typeof(ZipFileTest)); + suite.AddTestSuite(typeof(ZLibTest)); + return suite; + } + } + } +} diff --git a/src/Zip.Tests/ExceptionTest.cs b/src/Zip.Tests/ExceptionTest.cs new file mode 100644 index 0000000..d9dc805 --- /dev/null +++ b/src/Zip.Tests/ExceptionTest.cs @@ -0,0 +1,48 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; +using NUnit.Framework; + +namespace OrganicBit.Zip.Tests { + + // By Eric Gunnerson (Microsoft Corporation) + // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp08162001.asp + internal class ExceptionTest { + public static void TestSerialization(Exception e) { + string tempFileName = Path.GetTempFileName(); + + Stream streamRead = null; + Stream streamWrite = File.Create(tempFileName); + BinaryFormatter binaryWrite = new BinaryFormatter(); + binaryWrite.Serialize(streamWrite, e); + streamWrite.Close(); + + streamRead = File.OpenRead(tempFileName); + BinaryFormatter binaryRead = new BinaryFormatter(); + object oout = binaryRead.Deserialize(streamRead); + streamRead.Close(); + + File.Delete(tempFileName); + } + } +} diff --git a/src/Zip.Tests/ZLibTest.cs b/src/Zip.Tests/ZLibTest.cs new file mode 100644 index 0000000..a76e47e --- /dev/null +++ b/src/Zip.Tests/ZLibTest.cs @@ -0,0 +1,45 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using OrganicBit.Zip; +using NUnit.Framework; + +namespace OrganicBit.Zip.Tests { + + public class ZLibTest : TestCase { + + public ZLibTest(String name) : base(name) { + } + + protected override void SetUp() { + } + + protected override void TearDown() { + } + + public void Test_Version() { + try { + //Assert(ZLib.Version == "1.1.3"); + } catch (Exception) { + } + } + } +} \ No newline at end of file diff --git a/src/Zip.Tests/ZipExceptionTest.cs b/src/Zip.Tests/ZipExceptionTest.cs new file mode 100644 index 0000000..a12be72 --- /dev/null +++ b/src/Zip.Tests/ZipExceptionTest.cs @@ -0,0 +1,48 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using OrganicBit.Zip; +using NUnit.Framework; + +namespace OrganicBit.Zip.Tests { + + public class ZipExceptionTest : TestCase { + + public ZipExceptionTest(String name) : base(name) { + } + + protected override void SetUp() { + } + + protected override void TearDown() { + } + + public void Test_Serialization() { + try { + // getting a BadFormatException when accessing anything in Zip.dll + // new ZipException(); + } catch (Exception e) { + Console.WriteLine(e.ToString()); + } + //ExceptionTest.TestSerialization(new ZipException()); + } + } +} diff --git a/src/Zip.Tests/ZipFileTest.cs b/src/Zip.Tests/ZipFileTest.cs new file mode 100644 index 0000000..01c0c92 --- /dev/null +++ b/src/Zip.Tests/ZipFileTest.cs @@ -0,0 +1,49 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using OrganicBit.Zip; +using NUnit.Framework; + +namespace OrganicBit.Zip.Tests { + + public class ZipFileTest : TestCase { + + public ZipFileTest(String name) : base(name) { + } + + protected override void SetUp() { + } + + protected override void TearDown() { + } + + public void Test_Loading() { + /* + ZipFile zip = new ZipFile("test.zip"); + Console.WriteLine(zip.ToString()); + + foreach (ZipEntry entry in zip.Entries) { + Console.WriteLine(entry.ToString()); + } + */ + } + } +} \ No newline at end of file diff --git a/src/Zip.Tests/data/test.zip b/src/Zip.Tests/data/test.zip new file mode 100644 index 0000000000000000000000000000000000000000..95d53c668cca094876fed45336d97d0ef0ee6327 GIT binary patch literal 43970 zcmV(|K+(TYO9KQH000080HF!{C?b!Op4Mpq007be00;m80D5d`VlHHCZ0)@ZU{uw$ zKYZqqWC#N@$N*8Jj56BPK@AQh$L;7)L*vr_kRjt_}CYROV1D4d&723!QLB6YnC-y zS2nD;uVL|W>ypLw^((yAd#kJszIyAjdTZ|766^96ORH`hHZ0jD${0HTi>K#K`QhGJ zDC6!w?VSzx)|=$LbKw5*=EwFH!ZoLC-CF^-HS0<4-*(N@+$~9TKYsH$6mgumf!7c|{>QMwt@|Nj0VKUQkfmz8@;{2xzb$5@${EnJ!TR0|?j z>q5u0GuSJwc$Q0T=`63#8E(|FK6!yHjrr2qoTakYW|Nz2X5D9aGFG$E)og(yvT>&d z-B^u0sq#b{^Vv3jl86BNzSUaCF1f%qo|R=F(#pzes#%>amF3zB;MW5a8#}9OLg`+c zbuJ1v^cHUQ=i1WErj~B7QFUf&hBx)5$a*|7z028U^1q1SNP#Wg_d(Bdl)^dQ?0cu@ z1Mm_<_PC^vBHmwTOCPc7St`iX@+?xtrC2WNFtuzL997&ORXR9oa(`6X;HcF8sIN4G zqBQ+c2L?xdq>V=XY;e?`{wUwzsBQgGuE9~?>yH{UIBIQw6v^_qs7ev#T^ARe9}Qj` z7d#;v+!z;pO*FVJE?5^0u8Ir(Sfh54+4RUg7b1}!34f?dO@Rj^kqB`@LeD7TE$ZeC zY>*ukHDdsQ-K9*Yvz0{HDNgQD$OKs6Xu83u;(W&%gGEZ4+UJ zo*(pwZ4_ZcdIJ4n#Ud=Z*Q*BHECPo1E>Q!{o>v2my~S$4J`pgice)zz6A>`HH(d=_ zB?3&nW7U9JBEZ}`94u}_V1_ARLLfVfVPn+wF^|qsuJhiSe9)WpDhc1-qUxdaOoFvH zZ{z!Dwghhic_+P^NY3s4aH4-_;tSK@Ir$53s{a!`EC0$dI{Bc_>_To|vP;e9)41%Y z#p$)BtsX(cl+k#`!0p-mRU`r_kS6Ea^oTY$-iRn8Md|kGJ}*R+p_<(jiRS59fb?tu zMtz+v9|39d!Wxn=U8}V$mIZ&fgxdC-LTB-t*W<9$jqE{Yi5S^-UqESm(|r(HCjC@>gpEPdxs^LJUNeb-AQ`I z{nV5593k)ZMNd8Xn#?(;pUOMDSo_YcrU| z)_cvk-KIYn=Q{VAHXTJ(8;_CBG`0STkpDyOgov}#_g4s1z3C5njWgF~_U)G~Hbw}b zX5D9qvb@*_z6`#cVL-*f=hMky`a2x@DLxC!y+iNFouc<8`8y20p56!i9r}MEtI(I| z@6d)6^LUN_pcK?kq0;Q(yR^u=u7DF~fi2b9xqc+7G7zeSvBlO?7~#E~LhX`g)i^uX z-Ac$rn~1g{u`CkbK#5US7>TK5WQZ2cW`LyYwXD;>!zNf`apUqy8I!E5mw9Wf%i$TX za>V60rMh9oa_fwSWsB>r#fz7Ds~X0~GEc^^)9Kp{~UT>uj_Ce zY#Z(0Y1Zw=gXc5d8TH}w=)=kA!xzzqFQX5qq7SE|4}H;xGtq~$(T8)h2imYbi z0Wt42Y-h!M|Bj3f3mG=4l*cWPRFaS+8Xk}CRv>8>lFCpUal>mYDt0S(qO=Y(693o$ zG(n;S7w6|@o*(RA^7>gwK-7gZO9D0A~*=&E`@P-dTP0GbO zUNs>6ml|(kx8ex*YP*#}-)FMMAJWg*cxJ02nVbGn8BU<;sNEH!7S500zeGnn5qkg~ zzdBmXz}VnFYbZH=!1VAZ$XL$KhCbD?F2|9!>%qVXaqMA-L%jy34-y{!V+Kd3D?T32 z6&hyb@gc?F=yI{pO+2bojnW5rRFA$F?+aYEn^E<2(n`xEHQ=A>X@ox`K^h3M$H+YC=;s3F$$*o`JXvt2Vh~JW-R0fK zcDk-ZT6a*Nuj`T@e{wXR(~Ot5Y#q%hnJPcNfr=??QqoZ=8cuEgu^tRkF3(I+dJ}kH zKQ-w2taw)YUtdz@A&rn4XlI|AT8x0nJiQfPL1 zxyP;i<_xU0hz@92S+}D-)T2H5 zbGF<6p6=w&SYtYy?UwIfD&Jq)mMG_BA3EyT)mEqp`p!E-Y<9so$ZCYLoOJe3wqqB& zzo4za3=0aG4*kus%MoS|WsQ3sDXN)qCVOZ+>llZijA|La*~pevEnD(uINx0LN-?7UX@_3i9m8s6pybCh(t={s?e4Dpe&bP?<201?^oIReV@62P63oWw8%seU1 z?sYo3Fa=MZ(|^A9p#S}u{*GH@k3O7Dy@2kpDxVcdl1Dj`NF8n<@urt}&GaxZ{xCBv zakQ5O4r1^K{iJ>);H zUB8OWZSn*s&JP;z4t=DBh}aH^?c73ty(Tux5ZL84V2~*DkuS5d$(sqvRyI|$$A60y zn7Ed&sb*WY(epw1Q8ED$^}HJO{Z{VX@_TsYxnB7>VmMeSoSbpg+`5$%qM^(aID+Q< zoaU*Gsl+`$)T-F}&+AQ(21(@|H*F43V2&}+Zfbb|kAA1*8_II@@CO!CluLgXzat0C!hb$T=wsxn7*#VUSp%)!%oEe7#J(Sa0>MVTEbT)f9TqxUolC zBT4z)ef~b(s)X${X9yil9NNWPOEJiF{#{lw30@=R7Ix_$AbE7!zFW7y$fH~!k>^^9 z{zJ;KtRy{j%v|hI{zkz$={J%2GnWO4ttHB5JeAqM11<7R4!f)o zlISWQ0$*yV&+4qRS=L{J26{)aVWL^HW1HpDv)O_USECQFW}`%^l9*H=$~CO84$epr zwuL5lJd3I2Cmf@uGEY#S9kB$69nczxPj3Rq0U7Pm|BzcCrj|E}wIEkp_VNdfZ<$l^ z4fQB5%%nc40V_I5d2 zV^k&J9#sOaF|zzr-B}s#17_Xl@&jfz&%)N2DfG|wv+_KP49^3WO8e*YkYeJ+9IFBe!^m`6CZ_4I3kzp;obMV(g)A=7M_i z*uWXAFqKWuqCnx7LM@~8ZIO(#KN030(%(GDW;Zn@V+pdnsFYa%ZuuKccje94wKG5 z607qKTx-4X8>l{ZPF|RbEVFI0ot3Fdy38s=q2$=u9Qe^3lu?o^=VYKmp%k4;f4`fCzhY#RDbJth1Ers!mm4Bne|a3I zFx6+Xa=VYpGbXYbS>@HTH~#_x*xD>dd$3^01@^Wo4mj8Uip^+p?1DrJ9o1H|R?e|w4GG3Jj*LLER`Ed<%T+W#!7j{Jh@?!+>ou*C6l=` zzkgJy{AGTL#07I1{q5(RosC*{nD~sj>LBJ;TRqAo&TVxSCBdTu3ixUe)XqvIgy&c`~6QHQ;o3Yi^;(VRGpd}fSTq{mRL zSm-~ho!`k`ukb7Sg{Kc++dkiR!QZayq!?zfe*oTaQ}BAZ=jKVa|nnNZvq zQb_EL9+E%)voK^{Bo^vjk0B7;{7r5jh8iAFEyGZ7;_WJTcL~$5hRt5ea!T!A+V{%v zH0H|i&(5;L-YX3nAMp2}ebr3ke7!+$f1MgzSS@RO3d2DDGH9&1T)gfLrepbfkZcif zWsOUVq1Sc$bi0e(N(CRe-~*$si+v{J>4L7o#!8lw1v=Xu%t9$`Nl`m>u0|NC2-tXm zIZI?~_PG&P!)|Jj^Gt5Si;KanwS}JcDkJuCr2}BguJ&3f9T%E>ig)vv~0L zT^z@6coY|qQ~6yDqScEO5@9EWEwG;Ku|8eHbmq!tg>K@|=5*fZf-zdwT!4lbW{nFw zBC-p%cNUV3XN4K#I;v$nd$O4;s~UU?JKPn0S6f##__f;Zs@c$^YlVGRE$5aY1)l-^hSDX_@NPBU zB61uLw(MP!Cb*eDHjdy{92(a8rx!3+4fS5d142p? za&7(7i?p(Ve49vYGCrA8E6K;K;Q%mZo;9Y&LaYbom%Yo`As5!IuJE7HHQbX=Euw~} zv*zp>Frz(7+X}Qac`3x?1?0o*rMV!MhK1vqD`Q+YXy|5z*<@Bxvt|7(R70itw)H%z ziX)OUU5<8LHy20luxlPkr#4JmRnDA6oLNYm>B{b{7g%f|wA=Jr#wU@jxi({USU(Hp zsZ&Ybs#g67S|U=Z$`>v290!9fn@DxYJg_<=@b}fhdIZ+&xw^n;Zw0v$ooK#`~1bCjHVA4i?gPc28$zg`*vD7@tMLAi;onh0pn7MveI#A2qae(LZtw zG*9l)siWp<-NmD(;LuT4nC>{zwqS&oI=%BhHENg#qoD@YhG(VhS|HcYg9YhY!*)Bn z8s`okO;a;}L!*fgrggfw!IZH226d=uyran6AIW*A#=d*w8Cr&0r9;WgwUUpz07}br z%`-jHM8l8jsB0@+$(|-=3D#-PS7RL5T?AL;x7od`5*Ge>bI-`N&d}H-g(J}u;S%xYw4p;h~ zg`acB^ss9Yjl94S5E50GTK-6!>nRN!R5_RPy?uABR0Li7Oq8p+kH&+|!AG+qt4PCS9;X`*ubl^T7KX5mx12^Qm*rj& zxR^67woP+Cj}sRoAS}*t>!)(u>rmYg7M-!8V!n_Sq^j=`dVP?3SLa{gpu1?}_s8Y~ zlG$e=!-}LT>RVV2>JR$^wZ0VP7I<%xOqjw;P>t6foFR{*azqI* z(j}f)teie&gyBeEsbp=(>eGfGPQKOore%+UNzkQ*2WH!9Wo{; zy#`v9B^p+<5y2nyA8n{+rQeLulZ8FbHw2G0B!ud0X<7_7Xt`3Gb(LPG<@qMtc(6}3 z?Y!yUs?N;4CE{x)Uut!x*5{o*qnb_E`a@cOhql_O^-YNP-Wcy48Sm9Q_cXM(X{Km> z8jRo|i=Y+uLmN8?N#`5QV~E}5<{GHsW9x1Q!pQ<*57(n_IU*R%v<9By>|14`mE(M( zi78M(hH|dW>Qq*1+3RGafdvFTX~`VjqOXm(i}-puY{A$mkN@L&NU}&QnbtW@1tH^{ z7eGV{tu4r~wb)^~z_!xVl22&vG__>ItzD`tY6R;kP#n%rOfBOP=J9xBpH=qRWM7)> z%awhS?8}#ZM%ibUeR|oKE&DQLUzYOrM`ZgI_;*Dd?Xu4;`{sTAo73IEjtV?L1->bl zm6}@i(+B`gJRv2qpMkM)nw^a`6nEw=kp8V9W2jHpI%h$fE^D<{pS9ShNAPO+(wod# znd^w_vsJE;cHK#@{dt zRWejv1rz@a#YHu#)Fx#a&zK(0Ta--I2)3HnS*E;A{<7?1B^ycD96gG+hvd9PmF#tq zCPsc>Jkw}S4V+px#L->>#sv3yXrr%YBCluc16;3;_W*kfW(N1ufr%X{B4u>_$LrqE z4Afycl3=@?%t=>%5vN_P#x1*y%3oLVMZCKx$eR>)Wf1#@U7TKG-_1x8bAAsk)fl5o z*Ms*%OVkZz$C1~FIvyp9j0Y1jWylmDt>6#qb2dhZMh)+Il=@A#uuAL>mBi$ zmLpZsj})weN>U59^Rg?WVt!}f2-x4FXTwP~>gC~74y-LbOProB7wY9i*ywz9xKQtC z$4u+7cI2al3Q+z$UzAj5ib8+T3S5G}D^k(PT!e*7xpqZA3zH3#>lU3^q+Gp%_oU1d zrodteyQmi=WIr{-X!WKNhA1ajPDEjjT`*yQR+}Lk{?H}Y4`KWUPWcRCoeo*uKxYU> zN;sBOagAH?*GDNkOu2`iGp_UM{QF@H zWMC9(DP^u&c4f5eeAPcU>MvFO(^S7lnIs~@m4tgy|AgA?DGwZHpP5>W=qn7|22(&w zTLyU<{=W03mR{nxzKE&ieg2^FB@0DPyH&90A+yae5JfUwJ-9hFDw}K;XK|K)Dfn@R9-3w#2N-e_q=2-0S=nm=jpc~2z@*ImVNl>qnuVzqBq4gxEV#)R5 zyW|JS3o2P>#X@_CCq(Ch|D%uU(k1U|=ypg`J+LTJUL)BFRv^Wt=O%N9o`y}#2AxC6u$<9OxYAmwez$HD$ z1k=oT5gL`(&0Jou;f!3a)+660H|xDZgxfA5!mqi1K!p3Qm0f1qoO$R&I`V=c51Mj` z@LF$Fx-(Bfd0DX{ze8raUUn5=41r#8(tSJ43zc_j(LbAQ1~Zw~HY1#JH}s7G`sNix z1)FSUZe_qYB17Zu%D}GmNgH=i-p-y1(b*OZm|__I7UlGX zfqpQk{b1nzU?5dwC}(GdO+)dhj!v+2()!vZ_iGHCrchn!Tv{8rR4mLcQYKNW3NuJ} zgz`yvk3-uBm7wY~#}U3EL7Ia4#T0lHPjUsMk@+>Ew!P15<6=19T~5P(>oVRG&ae-& z^L(L2We;sjUc)6IWa0>o z+CE=3@p537PiL>71&z&p91lol-?gf}_0t+v==QxpJqbIsIrrqR14o)|+bP<47^1ur z)8kw;^p^9)fTk8YG;co~II{jP%w>Rjqrul?v-r28gXde&_1JQgS8ahLWHk<5y7^6o~rdoJq1qqJmD2vOg!V;=hbyS=amGMU)W-+p8vg^Bwv)vvQ5A_6qM|m+7jrJ@8`_QVs@(UhotWYIS z+}Qy7F)piWCAV@TdV6rJ8c&<08`c25M3$X}B#!ohbgDl0C_g(LiIDa5BwSce9$laE zZT@Jc$4#fnh%|#cXqS{Ln9$J_ovLEveu5spA^m%JoPoyILNm92#pkhT_;m~_0dv$)8j#Ni}OxwDA+n3Jjfq!HT@TDVYd~eHxW|qG~UayYbpAtCkP28{!64b;> zGPZw#tfBX{_70ZDa)jBlqe^A|^HC}EP$`5E>xP$0zhG{%&aG@fD#Tz$rbr z9RW!24QC!Bo0&$3nP|_}KQ+-e4CYVdZI_ zVih6U%11&vYdkZpg!X(z!ZajIWra4RrIS}SM0?amm_;6%b4t3-a*ym9FBfL0tx$SM z+w3s1os`D^aXLtpL2Q&!#th7@XE|1Oe=5uw1DidO7ED-9y2sg7PSat8<~AnSL;1Z4 zEN47saj?&r&fho0^vG>SNs8D4M+-4i^wL2WT_c?kwNUFx93~~v;%0uE3Df5S!h?0Q zy@%fSziyzD(nCL=i5xOA(hDaI`+Dg>vzhJmA5CIi-HQJ`jlWMP&rVtWZPa0y3)VTV z3+uSL*z12UDfEf%&?ojD%HLBL;Rh%4p?__~P_yGnb5AUSHw#1XtDCt}SitDyF@nf` z&Mk(ozzyZzY@{AflldW>mhXaID49y-)e-r6=zwf&ARVXap(EGavV?%A*}nh0wQ;=T zp!2M$+)>9 zTt}w>Zb5_9?O$C_fT~0(bXe-kMBb=W%&P)FCYsEqL;JbTZr@F`ao3pU-08iRz3Dsv zG;$l0>>c^6t5<8^9iaDhQhg5qLea#eeq&4vzyx!pzNM33b1my%{<#&RF6Bj==$ zu>ckVxjg4Nxxkmh8z<2Q2Xzx!3DbE06t)>I=1ZiaL%!#S^FBJr!Z$@|`Lqk{;eT(e z|IBr!M>bG{4s3k?DA-`**=O+A^hh0rd2RW%`jC>~KRPzpVxZ&h;^+t;yXv8@B;v16 zhx?BY59b)T8rAWaI1Gd+mB30c8V#Xi$^H(#v!k(|231CMHHqk1NL6(^cC{I1@s&TI z4#W?=A8iXqU&qn^BbyET0mJ~;GD|S+-!M*R8$+M!Wc{~UiD8CZVqhJpFj`x~caUNG zNa~@k#v3Sef2Oeh+ni9y#daf~v#a4zT$2z$%8u;XA`X-E^)hiCzqW$XQYX5crmF@^26 z9|QJ>J_Rzez74d`?&*=pSiI^5YK>PH%>Uf4Tt)0mtfkv+>%+6v-#*mY)0h)QZ^VBd zJ?4^o+lC~bA_&#&AjwX88jq)R-tnv})RRD?**qA|o1>1sz*VN2q{Vu7AgPVwDO#7it+yebpe2A$J|0g zD4-{P(yOvLhM#DRkiL4zD&L>Vree%`^f1Hh`(b663T&ggv^6vg?4t5>@ii1^W{d4 z*?wkbH3mD0xm;Zj8dv~wWvj+?jX}=f*sZa0?9>(2blSnq=Z#Z~Kr$$8Gut06rS>cL zK;EoN1YA#1`@Q5A&?LhEvAO>X52h>FjZ2BDl$4bS1smt zw%Q=i)q`=8?0a>e$?!oVqO9Wb66J5#Uy7(^!EGuAYW>s-o-3wTIR-zwsE7e(^%!V{ z5{T4(#kxGiv%2mQm0{h~r!|+XUi2wwnVqtLXgPol^(Yd!1y%)wRS9(}5V`iE!p!}M z6haQz-{M0i7Xqk|XD;%H*&gqZzg!oey~G$Zl&$=z?fD*hH~s&#VE>g0rrt_b+Z%SJ zWDm4QTNZy+F6S_Phrb@G@`bWm=+TLPDmT_azE06l(P{1@)tuQsm)feUN$) z-7YP0YQNHTd(_@5kQ4c!{6&1;u#S{VFC9Y4<^7?DEqSW_4OVZ!ps6>AjM;;$FDc+?r3^+FwRpd>LE4GbD3u zj%5BTz?dhQ{~hqOOEQ0wFPWd6Bbi5HK2i=ijC7{}Wk_e5C7Gl1vw`;kYb8&)viCEH z=b35IW4;WtswmeLrj@HFe{D3oicav*2)=sCcB?aYe!@8|?u2uGTBUAxg`7W8&QBkF z9FESz=`khF)R-P??^NfjmfBQI7W31JB5o^R{_)<}MyrOHk+r&s$&9V}BZx%m61?oT z$oVPJa{V8h)%|cQH7bpHtaO4Ng6wuyL6bT(jW#xI%){q)&TgnIZqpZz=VrQv8T@B3 zojaFE)4AZva>=|A#x+?0riW=+9D^n;+4S(Y)gfaeoh-Yoaz!c|%U&mmIoDwClyBE{ z@c}>AAbTdV{1oQ4lzWPb9lKzA<&S7{n=#qC0bEa*0Y!mawu)R9kn`_Iadrd4@v-;? z+6hB1jec{!YTIl5?MYA*p`KiIQ`-z?1w2kS>}OVzELcn%X6R-miR34aadBPLT2w+3iiKeA|z=@-K`Jv z>qamLdK!3|Y~OWiRwEy)`TC%-OO(~)zM!`GRLE*-c~VE4G9*cQGAKOTFu2XK?rXML z!-r;yXzM^bInhUi`9(9F=qZ;by5Z|0a9N_;-{yf_H?$cpM_Ij!Ur)+;PFYjnx1e>; zQB#2>e~P_>zf559EukR^o4vT) zqg=-ikdY|JKt|Fp2Qba=8YB`5$73v_DYV=~MUT3uXet;_+$R5LO}{oxoe?Eg+mO~- z5ek{kn}SmB=0(#ILg9E{5(?%K`TD!T`=-G4v>VUmTTd+=JN)lxZ2GAG{>Hu_Ooz67 zL$s-_$%O3;-agTUU!0}ZaC2p5${%5_^cE0XKx#sELU7JBu)X#@;hEh0(S_vO<(Y;U z#8+Ell%Ba$M)BJ+@)8X-sLX!37HZ;JSa4AZmuVp=(^XFTNzG>&l<)HOU5KmiFIUCo z+nVE+%n3!3`3zufv1I;6iDdpEAY3Y$=Xu})BAx;JgV8P_{uot-PYb?rCW8NC8Y5|> z)9;zc9!O_JT(M_4-;o!93xU+_q{rFx)W#w9lXMS9O79SM_jvmr;$cp0btyp%yYT~F ztH00EIF^JBu`0>%ITHJfbshT1-)^Be=5m-_gwcLrO3mI~(3-S!!XJCxGnZ&g#w(&O~#2r~Nay8Ppx@fi#i_>}~ry&UYKevd`?N$ugVX zcD<|ho``V#pK4J50ecUp~u zpGx9kl-u_yaR!NE2i?5!44HNfS4^iA64)7(LBq={(hG^%f7V@xNN8`nDt$dxB zh_+ijWPiIc>p@2wi%-9E?J2kaqa=BP`l4cy^3Z?q-Ikd5pW`nM;*q0o3sW%xkr)4(NO$ILYCWFGX+LT(2SjBdRK{v|& zRWv)z0@qlWC)K%MUTa*38GGvKx5L>+ej4kHq3Is~8Pobw#EXjt zAKdu9d5lCa81MX$j%cK!5_vk6=gC}a@tKtUbmpPII%Oq!i3VoLqx_D?MO#wI-|?>) zblHQT52L-UQaYVcYbsWD)4p>5nH2H996$cBTPH=|AbpLFVNR7yEx*_Cb=DNe5&v2J zYxMrH>3f~CUm=6e|G_zaBM^EDbEsjaN7{6J4wbQ(%LuaDsvsQib{te!7N)avw4^Y+ zZ3Io3k!v)pA6Tq2Hk>iYqrIcT(lF{JPiokelGTmQsMYuWgk}dZ{tmU?odX|E3WPPIH@9WU2lFN|I&e3ekWnhVpgRjt*w0aaSM^C2;L#MwC9Q580 z*70J26k5bvhw{x-evQ88nh2TCR#Sl9N>vvx`jhpXCu=&NW_!vrAKC8r-ON^ zVXY`tEQa+QxIl+Od|GzSAJLcsE{$5}IZPLW`Fc9tl=VKHoF`6T`9_S4p<&4=i3yZ2 z4b(O!QyWo-Xe70kc6!gX8A9)+$g}WFjYQSla1xo`;Iu;@hy2C&0G7T(Y3VN;8nh#b?)eFxND zevH2=5z|4EHd={q2%Qw++u;K^g6&*-R7La+y`KV^1@aW8qPj5MR(EmE(fM(-bfvZ> zQ_p~&W?i?M-NUnM^_R*%yg&Ovk^R!dk<%`R^FY(E5qzfa$IW7~)+TfP4VD(JF%N3K*O9LtdoJ_5-YA`W)ZetXm##e~UF6bZ6yyz1(a-J~>Ap+gOy^Y+w}@kMiq2&c;Y3 zS6C`5)D;Z=8n!;BRsAZHspoyJfqI2AQq_}2xAOeQ{6x(~I<}~Uy24tkuN{f`8NYfd zdJaRpH$OzxDD<{VDW7Dgl<{r~LYtM)o|Cn>%+1etjI145#P1KGBOGb|3+H{;u=2E$ zVptcLk(<@y8f<69!b%k8zi`f*=%;fvM#L{d{HxS-o*_PETz_r+m;^W5Y}3P`&U@Zw z!4ti|`X+3=QouaG0>C1`Qa}x$4zLp71*`!y$uHYB5G%cGYf+t6)!D2%Td5UvHx;XE zDGlbfl;+Kn(|pG>y|z-{Sk#_INIYhv*EHlzd5UVVZQMb)b+RXUIDgqJm}{HI>~fvW zoSESpGTq;CW={1PX8AwSJKyqs;XEc|%D5_# zze#iKRnGkOLmxSJH(nK7u({OkSaZ{Kf2Y11Aq}4gjWqk0Xy(Ee7)yf%#!~x9+Vy|X z+|O77Mcq4SBkelKS37pi@{V*I(G{f5LrJsb&8ZX)Q~5DYSjQ2@_q+Gg(E;x`_Sojf zh&0dJG7uTu%zbj|<8x(R;3~FzR)Efs*i0=h zr0eCEsRoU9XUMeWDpWwPptyStba<8)Cdfe1{dIh3$t>R=)F%Ra*82hJ%}R z+4l$=%o$!~M?RZ>f5d(s4{5qE$e%JDe@3!(djISCZc3A64_iW%8vn+?ICkF;%;;qX}D+0fx;6Ngg@P)Me0Zo4>5?0bOm`guMnwU$+tn`}&A<;>s>Z z-=Y6tn>k&AE!-h~nltWGXOGuPT|UeHSCQ1O=#kdI<9r{=>IRFAv&DgYu|8@E95e-9 zKF`J`T(^7pfp-? zNiV8N`5nr61|@oe#$Of}Da`|A`RM+VH2)OIXV`e2s#-mt+Tf0qL=WXHw^D=$XEKfZr)HEI#h z_7_1(b8C9c(-9NFM zE~{`Eo#$!M32d0MO2_UW&s=8vr%naZMF|}Dn!qL2b3R%RwNf`TkH!AF?hV;xmOU1h zL#Mlkv)Nf?XygGoCyS0$?q#R>ZlpN%MH?M-u2c8=$)EA?+2eKR!I^mUHM5+FbfPUp zYb!pT+&B>_Qh}QN6E@R)c_hkJBxaiB@>nE10*RUFToCPL-K>uzp?jU}<|}JJMxY{# zjb|cMWrbX1q-%5#7DL{x%Ka(_>fOOse&5VidS6>^rHf{Qt#s>*+)5YCICh0Mq`-ZG z*5bC(1vKFeHvHWNe|SSWp1SZ+So(U zoS!&)nDRE?OQb3Bu+I;D1pBKDvXwS8Y@^`T?_ohM};UNOH~-by9(j;0z8yTMDbh*o}_yT4Anz6Q8{h=FTFutXu<4bx(p`-B)1Tftwt?# zS+WT)*=1pysE}%V*NapnA=!RXR>S1SIf_>uIx31K^mv_W&5ncBY}7m3CG&Q&L+u^T zt{?vezUB)4qCe}STQPvqtDI)dmbRx=nq}gdRT!e^%#@o!GbdsCs!Fp$L9_kA(lIBh z4=M8FDmom8-Vy!iVA{p;@F}qyzXinAohIo|QNAb+TO*H!59_2MMKeo_d zFY+kA)lm6Ov(tAM zy`yMWQ(ji$;qSkJ*?aQHhS{ys&lKPWK9Zm#gEO_w-(m+~l@QH1<x7@l@LliupTE#uM!leOR;L1*p}(JWub#er)3VBR#)}!KYjgeE!Vp z4TnCc9>USUOt5VW$H!>LGoo@Z8)URV|1`%Z^_zsx)A9K1A)e|yDL)<0Q}2sL#_*H{ zB+quUO;&QJyFvY>pnLFfeisT8jH?XPW{T~}h zQS?vqGg!94zc<2CSU%?DwD#`oqUn&lDIfX5n+ovvF7SWzRQ6UitO>7;ZJ`)aEz_AI ztDcrErNC@wOS+p*O7DZou@Xnl#fOVgeDM_|sQ2z++Q>!`H)ANSX`+4PT^CrS5-y?6K5S1Lt1&$Wc zg#CtsQP?cjA@dOVNuGmkADyQ=N6G&OOeni!KlIx7!rru#kl`K_Gt93SWI=10iL zfq|pe3bv=Du`eJ0=4Ya*6HymSBhMRahg zI?^(OFu}BEU(--_#!g#tHkS2jHJiwE;f)`W4l+HrQ}Zwv+x#Ga_eLT;-M5w-)Uq}j zSh_IHrjbt9CG!9#P~sM4NS_Z9q!X&9KuLtZoM5JRIsQaOV_u}%|1w8H3U21EFWKLt z&9C-nO5Rh|5jCvZ-!fwoTrC1>DZu}!HV|1K3LIzW)k`mf&+>43dxUVyllZBKbnm^v zXF1t8N^`y{^dHxAf_ZJJ&V5An^%+6XoAM+&!)V;6c7;58W_nIxyxp*mkxu5%)$&xD zPtgoBJ<#s^7hWvtoa;Xhgs67k26Z%~Ucz2A`aibPC5bkzC+M{$+TSdHm6nUDSr$~G zwp!QM{Wlgatd^%=@bxlYLleEhF+R9PLlUh}8`$L?Tg^%f3`MMi8wfMp)pBWpS-E{U z4Man=oao=FpX=+ctnlx!#$%w~H?WBmL~si!0#Xj;TuhO&2=eQeNIB#XIk%AMjs&OZ z-sc_G?Q~~6-OkhnU56ffd=>2w_!9H|eY$mjQ{`{4AbW(aTNS}DoQr4!s>HF&Q_b?V z<&FsECq|kQ26nwj)&>8HhcEfXHhSi(@(XOKfg{!7+$Rzv5!2=$AtyoQAFZ;=^@1^TW$Iy2oyasSJ537#&pQor%{z&rrA@FS{ zUlJZ(P9~lw#T3}(GY+88dyO*$e`3Esc>qDAgD zk-%}&mY+%kgc#Ob=Q!wSZ~H!HU)I9e_sS?;Y$#s+pEVT6p{7UFnjYIkHC111sm*kr zH*H=R;ino?)bW^41M+6Vy404Y4#!zE9%;(z-;pv{2Sx2O#}S%C%+u0M+|e=iLd*zz zVPJ&8Dy5gP(-Tl&d*V!)-tC}W0D7qmkv7)rI5MM}jdga@xFe;t&fx4dwS0(@oNtIpZ|9_4(?2WDq>Gj3_0NiD z%4;xh8B4R`?J8lTv*P`*c*RUOSUUNHyp=N)FzUUgn!U^`sXp{KQGsrsIyauhSMvh* zfC4>V=}f%^P#sOQE{eN*aCdiicXubaTW~f6hakZnf(Lgt5Ineh(2cvh@5}$*t$R*& zO;6X%vaaf`?w(oeTThF-EEL(yz3W^pZ%<&5hA$#r|j2}ROz*6&ik?dMD#bm!?BoNv4`yMc&IaX$;-kCUPX69Fv1fqBgABf(GiqZNs7*$j-J~`>{o+&oh_58MM9i<{foKVc;zv$0ax1i$oLyYjJH=4yO-E%uo} zO43OY@f0*2Smen3!hGzbN|O~OBI+fF2j;rkml;4sv@ZIyHF2Fvpu_1U^+(w)?TON^ z7Qo+tv*$0zrLN~cko$#w{`3dRj~>x(=&(KtIH}8M$ZVvN1D78&q#9O@yYg#^N3HXl z7EXW)I>b$~t2ot|-M>dcvlCzXUsKcNT>;p)^M-^yrE2b2;OEn#i5P+?UJb*-;2J}8 zHBKPr#7!#c5{mn`IK`DWJ?f^hI$IcPF?i7CfU22&$TSgmZ(Yv<1bTXcs7BC{7H*Y8 zmJ;?%i&_2Ig&AyH#qL!5+TE3I2SJq?+=o!!-1gr+?mroJPa^(QJ7m<*3Ln=uY-PDt zde%J1SfaSd`?`kuBuSKSqSzm^HDM{+l7ThTep|^>9F2hn{#2+;vm7Sj-odreEj1cUtg+ z%vCG>9jZP;Xj4uBVYq~Ls31#8#_mNoaxu3VA>I+QcaDsT!IskIGF1!Q^xU(~eWbX{ ze{cVc0*XLY<1PC|j!jR_%*{8Fu6acIn$EHq({C>ml)-zH89g8_OuKmv)ZpQtbN6s2 zse9vPM7<98gJau#PplkZX%aD1|RJf=;SDOi_HDHVagv!$Sr+95WyA=ubG4ZO+@m;8er85xlTV3qP%Q+wd zT<;&uthaCC^Hb8yZz!|ls6){kkktBjHF*uo7RZ}xu>SR*o6WiZM&!(F^`J_Of#b5{ zy`0AHhSCio4@Et#n-`0&C{+?!mb^Dn*?X>-cbMQZ5=qzH;pPqTg1(W)^nj>&9@ksG zi$Zq6qeaUAI5i%?b4cwa^B=TaWj#GOO0O{|a)b89pXqkKbM?TQn8g=PJA5 zhzrqi&*QF?6vxxp&7ydvp_QD6c0Bfnp2R!6tBt?lk?ET^Q3e!n(|3MZ5sOCtdh)8I zYa4B5qO3|&W^p2bqGu&YT(Osz4CdYnk zR8L*iVa6j$(xp1;DE}+uOKU}5S)qZK4dc3HaT|vKfVK>&zso#=@2I7;(UXP_Q0o*X zAm;;xhC@5Vsq_y#iHlIK$ zw%a#;yWpT+lI6m?J^`BM!4@+5E8tiReEnmhTGq)OkITz+oiZjFC{Flu4S`SuUjuZv z)6z5@sOSD;EbS6Kyve11-&0cctDz8v0-cuFsjEV}=9d`L5#0G?oQ<3erav4bam!!BQK>`XB3s?m`DN)Z9tb^C7}I&ArAWWtJa*#`8L(@1`Dn-P(&D-aIj2(t z82S(`FSNQ##*p%B!a-O2!nUi@WX^|edYR9^@WqzLF9ipxj+IyrS56;1>(m(@u1xmG zwIQJm97{dgJj`&&K*E;)iVRh<J9}s#| z*zB~c=*hhb^!3oq3x{qkS7DlZxQB)Xe&Zi2y6JZX|Pb7P)K+f8Fjm{yHL@f zgVn;bfYOYbq_OC#SQ+eW@#tleni?ayamWotNqN_O2+|zS^fm&c>SMyBSp^zCkyc#g z6itB~aJxTSwk=WSG)D40@h#XfBZL7LMUtHABU*>7jMT^xP8~pu4r15A!HB&gjQt(S zAM_Af#mfT zLbabavqwiyTh=RLp<~w)8b3>9o?DECtK@9+EWQ;nXs*)J7*Pjac#q;-#=8<#Qx!S|) z@p-P3-Ag9>i?2ec3*YVDts%1PI-HT#vI$e4*C1Jk1Md-q_R%+l#GC0u)~Md0#AE37 z6A2f=AVPkfi_TayA&>SZclg2N;|FRnof8nQ#o@yE>E)(xBrQ8?hT?=#FI7GOn6wWcaoMTx%sQ!;?*1uk)Ju*n}R|DsvT zH*is=^YCF<6xA2Omq23oZqjwbKIs0}ZwlUsozVi7T*1bAY*0dF^RLHX@(6kg(P+PC zm0o8CQ-KGfD%20oPiJi{=R8i!67`Cyls_YMaF&awYHG%?OH>CcX~?4w<*sakLe^^C z#u{5hyBea~t`{eMvfd=f2K%v2x}rZPCq0^l&_^RmJtByLSDI3@j>c~KWvbWZBNj$* z8M<=@2VW&Jx*xdOj4e`_=JsN*$Ff;fUrOrZM1#m1+E+Zbg?00p0`Tgy9Qk#aQ2I0n z?%8964Q@`#K2BaiYFsHK{TWll)O56M9-Z<`_3PiqN)E>%+dI_K`hU~EnFn4GxCrAju?2n6JMktk(re1X zZf{uMCz1p{y`qGj5_q2!307C^N(Ndi7u9oUW94M+pWP6u?a%on$!N?9ce3Tsy*B!h z_BiFQD;;oXzV=}FRVXb44jfBePh~yNE=~SI-$ysG1u`4cCZTXHlQGHdq{c-UZf!p zmy$Bh5AV3cfrk6NLZQBh!3}r1Ga5B&m4QujDZ9vF7^jd=)4&2Rh}WsvrALGr-)6Md z@2)Sz2D*59_C+@t#gVs=lI7I1St=``@UcqdfVa48v10ODB#~%DV*C33QL!Fb*`qXm zy+3jlI~UHb2ehLQn;#^T@-O^paiQ1p4j*sVA!W<4W|G9=8H%+0K7N?1-V{ffFp zJO+GIIloDUiQU!$Dh9>n2teFPg}%5U9k=P+eOD00+&>(2h=!BRpi0Exh>?KSWfHX z`d}++TEng*(RAt)ADfAU-4i7!;`WGz`o(Zp<7h`nLl-F9`hHE@k(?`}0$y6UCz2to zI<;xzl@k^qPONH_$Yv-a8Z{3e^~b~|U@^*;_h$y+FLnMp$K^aKC0-ZQ4kthE!?F&y zy=Q6T_Q%6)AY;RTFN5NY5{I1bMm?8;WpSJ%56yn;nlD3klFpFsm)wHtxyuDL66KZUiXV&U&T45;*ejgX`74+zt%D>>$CF7CW$ugo6^c!p+xI@+Y)=jy(64!N!6^=m< zCb80a)@Ifv%i?;{)0pzbjY zTW@syxt`0$hfm)&Bl?x0M~I(9lD2~E%fuvb61BZzJ+{Iy2z8Qm~XF z>W;u_4Cy9d1oTtikwKSn(N|ku0mZya;0^ad^M_)1Go92|!9`&w`ovLuG;p7lw^o+4-=q%vzB(;ps;9AjO zw+sbN2n2Mdi85Eu=zWFx;M2^So~3>gSjRd=l{C=dG7wqz*rrwr8fJ(_st7=+s7|?I%G2Qd`P|o_LRSRSPRXnyg z8vm7@m&-}Z{YOtIsJ!35{pX%kb~hL5w`A7+kOcB4LE?Ccwh{1r!1sh!c^J&=ka#Q$6~oQ#+BiaYiQ)U9L?gp z`^=F z2$=jqnX#%jS^fL;cHsND-G@eM!8EH;{Bh9_w&%*C{K-ZqVJR+NmL~JIO~nUpw}wO{ooR?&>}Qe>RD>I?B6zKRdgvcib1!D7JP= zS)TbZDJStz|6*^0`b}d~>O%#W)|j{~$v7jwoj!T#15=BQYc-~h>UEbd2{A4j^?nS7 zCbeEPe_1rcP2OI1?3TI9Z&*WvY>F=*f9Rw4la;BtM+PX3I59N~N}(DG{zM3Khha+5 z_jJgiXro9)K_JdWJ9L&vB5O z{jLEc--oKeSWbMldi>qKqp^RDD-oA~l?Q0xOtLdGq+?(d@3 zl><-ub#>c1@=vuhH}aUyF!!b3tASW&}9@I&=0H|76D`%PZ||bJU>rf4Xoeb`y8Jh z!~Pgw&d9*-zyaM_{rdu1Kf)QN4r02^j`?A+AET!UTAVI^u|bHy%nzv-&3H$g!I;5e z=qfAL2~5Q*SlDJx)%+Rf%fEX=xMV0u5s|K|FWJ3@d`NHEPUv@!^kr}%j3}}>%JuLzLY%#=n@p5{qqv1qc z5C2#8@9I+1Up7y3fe%oJrQJ8c=(Z-r8o7{nYE&crLpRU)f?5^WE^ z22NpGCuaU_!?NPhI6)2(%0VsjuMLt>mr74&0B}yzH4(;1;JDDxz}#ZYARDy=b?f}H z(QJDj&SK#sm03w*B}_cz4nzRo{E#ZcUw`x!hw0yorgz=ZeKiwFMVA4xE{Y)9EGoX^ zXESK9;~rr0tu6wrvJKFBHe&)i?gHkYK-W)3e?JhAuUU7N;BJRVJ>I2Cj7HDT8+^92 z&do15pvRZw5H zf1TFu<`l<@N;b-X=jm`_L>bZ&iuidJnMIk@bf^q8UMippaa1zH!@ZbKhWF|W!ZWjB zpNbOhpCJ-Uf|Tp*k~&9=>voGIvc~`b*z9fNDVy3EfJ=h% zM75$wvexLVrco8>-0zI$I2D_Q&dc0cH{_U?l;w9=^ORzdr_%!bSn9y-PFu=~ z`vjmAv5RNAv>C0=xJwRg?e9^TMkIiRyUvaN<%B!!AD&Zscb&Wfk-f!23z~vt7$kvrCQ-#lMdQ`}~kuTl! zv7P+a)tKvg{b#hd!8^zioI8m6XjINtQ{_-!X?-k15>w<7Rv~7vAf%kC<~w(aZUwOn zb%fUD4k6SF=>}!jUIrsx$HNPC^n}>;DlwLw&@oe!2wo|$!LWl5b-_4-m*^)i1Svw! z-dL`Yl?t_Ftork8!S%xQdi7fN%8Ezd6o)w?wKl!c6~Bu(J#xe6h!ko?AcB$YAOg|k;hG_BAiqJoK)xZVBlE)n;jW~5 z+aLgN%8-8$^pW|IVZg zBie%OwGE+w_~OQAj=z-?0)S+OzJsWRdxLO8-*OhG-Gc263*icZ5r;^E_a$+|-Z~6n z>;*u`LUzN`L;ryUVqaZCkZmdTvWsJ|!`I`xF>RSajzbPZE<@%+F~hv!y5Vo(_6qj; z^~yJ!m)Jz#nE*i%Mo?`q7Zkv#Ey2(7fp&4Z#oO;39)NYB0F>HBix}VH1U79?MRvkp zkOIGbmY&F0N8sZ?7nuv&x+!qEzYFg|tnZx;c)L9n6##RA2~_$sjVCW0Jtq-URwyjP0M^PXk?3E8_wUrS18UzGI8KJci zUl_T8z6*W1_zDDsyut&kwre8;2ruk`w4WuhKM3c-80fiu5!Fd{aqi|C^-8>cxK$g{ z33XBKCKe%tccBjy`~FG=Omkz}?nZtz0nTr!hP@K5FK^XGb&|TkxJYw_D@8hm;MOCU z!vP_WL((9i$;p!7Dj-WB4j?%p93lM0S$pC1k?J87A+aG%L(piRAO%8Hd-;3SAeA7< z;Eov>H zz}$Bb{hMqYh~Qf3%U!4c%w=}ZZRf+~n`Y0!Wk=of?t4K}rnHD^7twhWz4PP_pX6ID zR?p8J+b?%SJV$)~Gp-YbAoG_G5q~h>d_loLSLz0VBVUS%WGlkT{@1m60i?`OEbCUN zIS6)m8o})XR5xfmg-VqU$SagW5;twaC)C=Mlj4pF(#o*0HbsZ_m1M(BI1M!G%_}qd z-jgb`PN!0y_f|xoAvH?QYAz1@N{42D-GxP#+DFO)o@|e6kP2g3H{(5cox5Nyl6N>f z2;KsAtwibL4~m+a+A_L{haH9cAbm7b9QyumRmQqK zpRm9V`m8MuHcK@?ANRbtj2?}rvRh@-$qB}~^2%TCE3y6x*?D@#nR;75DVDI{pk?O~ zY9FnrF{{#$P6(4i1teMl+3+0u#;BMXu8_3ME0HinPz=%RVJ1X=Z{Taz>9w*O$%`kU zoharXsRG|56Vi=DJO59BR$^g&YYKQfsN3fal zI7xy~2@O+vol}K_6R~e{IybXKxIS-e2la5#v>(CGoog4AP9a9Cpm);8oyfs)qT=qI z${|MA1uf0}Nt4#UaT-A2w#0EaqbtqHC!ln9TdiV;YYijig;CX5_Un>vO+{G`Dk>A< zRwd<5cgskNv^U{)bctl@R^PDIwmLJu=$@N}2gs1sc;vcP`{y55mJIL58Xeelea_g9 z1=DN#RifR~#|jpl{3kqFXtHWEtk*MBNGBSzAhG>lmL9&l#pnXvk&%`Db&duk=wWxU zi0z%-{t*Z|5yn%o`{PxZOqiX3*whfnN_|>7IkgAsM zUKtYG7*BGPwDB&;7h)xLBqV4|?}mc*n2i4rqcju$J-}S}<;Fj{d~h8c(XVYp8l+D2 zRAbG=5WdW`-e0-s?!LcZ<+D5-9y<7H{RYk@GYd}D?vgap`WigrPtj!qm`{!aYcy7$ zlxn#c3hHEAMyywuwE$gKG*7$6|15P>zP$e7S&FPo(~0YnKQw9R?+A2%51Wm~MO`W# zC+vzl&CoU=A~O!YjO`fuc#Ge}Mb)8)d$|h!nV(JrKX!<@39qM%8h(%8`gL%wGPBv6 zJZNC2V@;+-xV5`7mh4K?9F6Je+~DTm5)F@z(uLk>T;y_ycO_vF$84j0MXkQG zvvF&>@4?3lZq;ecZ0Pr*n(?YXJWT18r)FP0SrxJV@>K9rw|^Z=BV6!a-l0z0#Oc-q ze%;i7Ja=1HsH{=kjth6hy`Dzsp5$pH0$*fO6OT3~j} zZfzhhCRk}ZF&#v?Zj4zM{ZjnIg5gpbO~+NptzZIQenq=&6Z15XyeeiT?VIN|9QSnI z?}~F_vyB)1B&yM)8jg>g@qkhB&d%lgIvjHax4lVmBjtSifR4NUi1a9n3Fg{fMtZc^ zp2D~$i+xFvergL3h>r#+YpxYg^)Dmˠ~xj2C3F-@7)jildh`^omFdAFyquFaxf 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 literal 0 HcmV?d00001 diff --git a/src/Zip/AssemblyInfo.cs b/src/Zip/AssemblyInfo.cs new file mode 100644 index 0000000..f6d7ea7 --- /dev/null +++ b/src/Zip/AssemblyInfo.cs @@ -0,0 +1,39 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyTitle("Zip")] +[assembly: AssemblyDescription("A .NET Zip library")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("http://www.organicbit.com/zip/")] +[assembly: AssemblyProduct("NAnt")] +[assembly: AssemblyCopyright("Copyright (C) 2001 Gerry Shaw")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyVersion("0.9.0.*")] + +// This will not compile with Visual Studio. If you want to build a signed +// executable use the NAnt build file. To build under Visual Studio just +// exclude this file from the build. +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile(@"..\Zip.key")] +//[assembly: AssemblyKeyName("")] diff --git a/src/Zip/ZipEntry.cs b/src/Zip/ZipEntry.cs new file mode 100644 index 0000000..0a73544 --- /dev/null +++ b/src/Zip/ZipEntry.cs @@ -0,0 +1,245 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using System.IO; + +namespace OrganicBit.Zip { + + /// Specifies how the the zip entry should be compressed. + public enum CompressionMethod { + /// No compression. + Stored = 0, + + /// Default and only supported compression method. + Deflated = 8 + } + + /// Specifies the amount of compression to apply to compressed zip entires. + public enum CompressionLevel : int { + /// Default compression level. A good choice for speed and size. + Default = -1, + + /// Do not perfrom compression. + None = 0, + + /// Compress the entry as fast as possible size trading size for time. + Fastest = 1, + + /// Compress the entry using a balance of size and time. + Average = 5, + + /// Compress the entry to smallest possible size trading time for size. + Smallest = 9 + } + + /// Represents a entry in a zip file. + public class ZipEntry { + + string _name = String.Empty; + uint _crc = 0; + long _compressedLength = -1; + long _uncompressedLength = -1; + byte[] _extraField = null; + string _comment = String.Empty; + DateTime _modifiedTime = DateTime.Now; + + CompressionMethod _method = CompressionMethod.Deflated; + int _level = (int) CompressionLevel.Default; + + /// Initializes a instance of the class with the given name. + /// The name of entry that will be stored in the directory of the zip file. + public ZipEntry(string name) { + Name = name; + } + + /// Creates a new Zip file entry reading values from a zip file. + internal ZipEntry(IntPtr handle) { + ZipEntryInfo entryInfo; + int result = 0; + unsafe { + result = ZipLib.unzGetCurrentFileInfo(handle, &entryInfo, null, 0, null, 0, null, 0); + } + if (result != 0) { + throw new ZipException("Could not read entries from zip file " + Name); + } + + ExtraField = new byte[entryInfo.ExtraFieldLength]; + sbyte[] entryNameBuffer = new sbyte[entryInfo.FileNameLength]; + sbyte[] commentBuffer = new sbyte[entryInfo.CommentLength]; + + unsafe { + result = ZipLib.unzGetCurrentFileInfo(handle, &entryInfo, + entryNameBuffer, (uint) entryNameBuffer.Length, + ExtraField, (uint) ExtraField.Length, + commentBuffer, (uint) commentBuffer.Length); + } + if (result != 0) { + throw new ZipException("Could not read entries from zip file " + Name); + } + + _name = ZipLib.AnsiToString(entryNameBuffer); + _comment = ZipLib.AnsiToString(commentBuffer); + + _crc = entryInfo.Crc; + _compressedLength = entryInfo.CompressedSize; + _uncompressedLength = entryInfo.UncompressedSize; + _method = (CompressionMethod) entryInfo.CompressionMethod; + _modifiedTime = new DateTime( + (int) entryInfo.DateTime.Year, + (int) entryInfo.DateTime.Month + 1, + (int) entryInfo.DateTime.Day, + (int) entryInfo.DateTime.Hours, + (int) entryInfo.DateTime.Minutes, + (int) entryInfo.DateTime.Seconds); + } + + /// Gets and sets the local file comment for the entry. + /// + /// Currently only Ascii 8 bit characters are supported in comments. + /// A comment cannot exceed 65535 bytes. + /// + public string Comment { + get { return _comment; } + set { + // null comments are valid + if (value != null) { + if (value.Length > 0xffff) { + throw new ArgumentOutOfRangeException("Comment cannot not exceed 65535 characters."); + } + if (!IsAscii(value)) { + throw new ArgumentException("Name can only contain Ascii 8 bit characters."); + } + } + + // TODO: check for ASCII only characters + _comment = value; + } + } + + /// Gets the compressed size of the entry data in bytes, or -1 if not known. + public long CompressedLength { + get { return _compressedLength; } + } + + /// Gets the CRC-32 checksum of the uncompressed entry data. + public uint Crc { + get { return _crc; } + } + + /// Gets and sets the optional extra field data for the entry. + /// ExtraField data cannot exceed 65535 bytes. + public byte[] ExtraField { + get { + return _extraField; + } + set { + if (value.Length > 0xffff) { + throw new ArgumentOutOfRangeException("ExtraField cannot not exceed 65535 bytes."); + } + _extraField = value; + } + } + + /// Gets and sets the default compresion method for zip file entries. See for a list of possible values. + public CompressionMethod Method { + get { return _method; } + set { _method = value; } + } + + /// Gets and sets the default compresion level for zip file entries. See for a partial list of values. + public int Level { + get { return _level; } + set { + if (value < -1 || value > 9) { + throw new ArgumentOutOfRangeException("Level", value, "Level value must be between -1 and 9."); + } + _level = value; + } + } + + /// Gets the size of the uncompressed entry data in in bytes. + public long Length { + get { return _uncompressedLength; } + } + + /// Gets and sets the modification time of the entry. + public DateTime ModifiedTime { + get { return _modifiedTime; } + set { _modifiedTime = value; } + } + + /// Gets and sets the name of the entry. + /// + /// Currently only Ascii 8 bit characters are supported in comments. + /// A comment cannot exceed 65535 bytes. + /// + public string Name { + get { return _name; } + set { + if (value == null) { + throw new ArgumentNullException("Name cannot be null."); + } + if (value.Length > 0xffff) { + throw new ArgumentOutOfRangeException("Name cannot not exceed 65535 characters."); + } + if (!IsAscii(value)) { + throw new ArgumentException("Name can only contain Ascii 8 bit characters."); + } + // TODO: check for ASCII only characters + _name = value; + } + } + + /// Flag that indicates if this entry is a directory or a file. + public bool IsDirectory { + get { + return (Length == 0 && CompressedLength == 0); + } + } + + /// Gets the compression ratio as a percentage. + /// Returns -1.0 if unknown. + public float Ratio { + get { + float ratio = -1.0f; + if (Length > 0) { + ratio = Convert.ToSingle(Length - CompressedLength) / Length; + } + return ratio; + } + } + + /// Returns a string representation of the Zip entry. + public override string ToString() { + return String.Format("{0} {1}", Name, base.ToString()); + } + + /// Check if only contains Ascii 8 bit characters. + static bool IsAscii(string str) { + foreach (char ch in str) { + if (ch > 0xff) { + return false; + } + } + return true; + } + } +} diff --git a/src/Zip/ZipEntryCollection.cs b/src/Zip/ZipEntryCollection.cs new file mode 100644 index 0000000..78102de --- /dev/null +++ b/src/Zip/ZipEntryCollection.cs @@ -0,0 +1,195 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using System.Collections; + +namespace OrganicBit.Zip { + + /// A collection that stores objects. + /// + [Serializable()] + public class ZipEntryCollection : CollectionBase { + + /// Initializes a new instance of . + public ZipEntryCollection() { + } + + /// Initializes a new instance of based on another . + /// A from which the contents are copied. + public ZipEntryCollection(ZipEntryCollection value) { + this.AddRange(value); + } + + /// Initializes a new instance of containing any array of objects. + /// A array of objects with which to intialize the collection. + public ZipEntryCollection(ZipEntry[] value) { + this.AddRange(value); + } + + /// Represents the entry at the specified index of the . + /// The zero-based index of the entry to locate in the collection. + /// + /// The entry at the specified index of the collection. + /// + /// is outside the valid range of indexes for the collection. + public ZipEntry this[int index] { + get { + return ((ZipEntry)(List[index])); + } + set { + List[index] = value; + } + } + + /// Adds a with the specified value to the . + /// The to add. + /// The index at which the new element was inserted. + /// + public int Add(ZipEntry value) { + return List.Add(value); + } + + /// Copies the elements of an array to the end of the . + /// An array of type containing the objects to add to the collection. + /// None. + /// + public void AddRange(ZipEntry[] value) { + for (int i = 0; (i < value.Length); i = (i + 1)) { + this.Add(value[i]); + } + } + + /// Adds the contents of another to the end of the collection. + /// A containing the objects to add to the collection. + /// None. + /// + public void AddRange(ZipEntryCollection value) { + for (int i = 0; (i < value.Count); i = (i + 1)) { + this.Add(value[i]); + } + } + + /// Gets a value indicating whether the contains the specified . + /// The to locate. + /// + /// if the is contained in the collection; + /// otherwise, . + /// + /// + public bool Contains(ZipEntry value) { + return List.Contains(value); + } + + /// Copies the values to a one-dimensional instance at the specified index. + /// The one-dimensional that is the destination of the values copied from . + /// The index in where copying begins. + /// None. + /// is multidimensional. -or- The number of elements in the is greater than the available space between and the end of . + /// is . + /// is less than 's lowbound. + /// + public void CopyTo(ZipEntry[] array, int index) { + List.CopyTo(array, index); + } + + /// Returns the index of a in the . + /// The to locate. + /// + /// The index of the of in the + /// , if found; otherwise, -1. + /// + /// + public int IndexOf(ZipEntry value) { + return List.IndexOf(value); + } + + /// Inserts a into the at the specified index. + /// The zero-based index where should be inserted. + /// The to insert. + /// None. + /// + public void Insert(int index, ZipEntry value) { + List.Insert(index, value); + } + + /// Returns an enumerator that can iterate through the . + /// None. + /// + public new ZipEntryEnumerator GetEnumerator() { + return new ZipEntryEnumerator(this); + } + + /// Removes a specific from the . + /// The to remove from the . + /// None. + /// is not found in the Collection. + public void Remove(ZipEntry value) { + List.Remove(value); + } + + /// Enumerator for . + public class ZipEntryEnumerator : object, IEnumerator { + + private IEnumerator baseEnumerator; + + private IEnumerable temp; + + /// Initializes a new instance of the class. + public ZipEntryEnumerator(ZipEntryCollection mappings) { + this.temp = ((IEnumerable)(mappings)); + this.baseEnumerator = temp.GetEnumerator(); + } + + /// Gets the current entry. + public ZipEntry Current { + get { + return ((ZipEntry)(baseEnumerator.Current)); + } + } + + object IEnumerator.Current { + get { + return baseEnumerator.Current; + } + } + + + /// Advance the enumerator to the next entry in the collection. + /// true if there are more entries; false if there are no more entires in the collection. + public bool MoveNext() { + return baseEnumerator.MoveNext(); + } + + bool IEnumerator.MoveNext() { + return baseEnumerator.MoveNext(); + } + + /// Set the enumerator to just before the start of the collection. Call to advance to the first entry in the collection. + public void Reset() { + baseEnumerator.Reset(); + } + + void IEnumerator.Reset() { + baseEnumerator.Reset(); + } + } + } +} diff --git a/src/Zip/ZipException.cs b/src/Zip/ZipException.cs new file mode 100644 index 0000000..eac22f1 --- /dev/null +++ b/src/Zip/ZipException.cs @@ -0,0 +1,51 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using System.Runtime.Serialization; + +namespace OrganicBit.Zip { + + /// Thrown whenever an error occurs during the build. + [Serializable] + public class ZipException : ApplicationException { + + /// Constructs an exception with no descriptive information. + public ZipException() : base() { + } + + /// Constructs an exception with a descriptive message. + /// The error message that explains the reason for the exception. + public ZipException(String message) : base(message) { + } + + /// Constructs an exception with a descriptive message and a reference to the instance of the Exception that is the root cause of the this exception. + /// The error message that explains the reason for the exception. + /// An instance of Exception that is the cause of the current Exception. If is non-null, then the current Exception is raised in a catch block handling innerException. + public ZipException(String message, Exception innerException) : base(message, innerException) { + } + + /// Initializes a new instance of the BuildException class with serialized data. + /// The object that holds the serialized object data. + /// The contextual information about the source or destination. + public ZipException(SerializationInfo info, StreamingContext context) : base(info, context) { + } + } +} diff --git a/src/Zip/ZipLib.cs b/src/Zip/ZipLib.cs new file mode 100644 index 0000000..310c956 --- /dev/null +++ b/src/Zip/ZipLib.cs @@ -0,0 +1,378 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using System.IO; +using System.Text; +using System.Runtime.InteropServices; + +namespace OrganicBit.Zip { + + /// Support methods for uncompressing zip files. + /// + /// This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g WinZip, InfoZip tools and compatible. + /// Encryption and multi volume ZipFile (span) are not supported. Old compressions used by old PKZip 1.x are not supported. + /// Copyright (C) 1998 Gilles Vollant. http://www.winimage.com/zLibDll/unzip.htm + /// C# wrapper by Gerry Shaw (gerry_shaw@yahoo.com). http://www.organicbit.com/zip/ + /// + internal sealed class ZipLib { + + // prevent instances of this class from being constructed + private ZipLib() {} + + /* + Create a zipfile. + pathname contain on Windows NT a filename like "c:\\zlib\\zlib111.zip" or on an Unix computer "zlib/zlib111.zip". + if the file pathname exist and append=1, the zip will be created at the end of the file. (useful if the file contain a self extractor code) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function of this zip package. + */ + /// Create a zip file. + [DllImport("zlib.dll", ExactSpelling=true, CharSet=CharSet.Ansi)] + public static extern IntPtr zipOpen(string fileName, int append); + + /* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + */ + /// Open a new zip entry for writing. + [DllImport("zlib.dll", ExactSpelling=true, CharSet=CharSet.Ansi)] + unsafe public static extern int zipOpenNewFileInZip(IntPtr handle, + string entryName, + ZipFileEntryInfo* entryInfoPtr, + byte[] extraField, + uint extraFieldLength, + byte[] extraFieldGlobal, + uint extraFieldGlobalLength, + string comment, + int method, + int level); + + + /// Write data to the zip file. + [DllImport("zlib.dll")] + public static extern int zipWriteInFileInZip(IntPtr handle, byte[] buffer, uint count); + + /// Close the current entry in the zip file. + [DllImport("zlib.dll")] + public static extern int zipCloseFileInZip(IntPtr handle); + + /// Close the zip file. + [DllImport("zlib.dll", ExactSpelling=true, CharSet=CharSet.Ansi)] + public static extern int zipClose(IntPtr handle, string comment); + + + /// Opens a zip file for reading. + /// The name of the zip to open. At this time only file names with ANSI (8 bit) characters are supported. + /// + /// A handle usable with other functions of the ZipLib class. + /// Otherwise IntPtr.Zero if the zip file could not e opened (file doen not exist or is not valid). + /// + [DllImport("zlib.dll", ExactSpelling=true, CharSet=CharSet.Ansi)] + public static extern IntPtr unzOpen(string fileName); + + /// Closes a zip file opened with unzipOpen. + /// The zip file handle opened by . + /// If there are files inside the zip file opened with these files must be closed with before call unzClose. + /// + /// Zero if there was no error. + /// Otherwise a value less than zero. See for the specific reason. + /// + [DllImport("zlib.dll")] + public static extern int unzClose(IntPtr handle); + + /// Get global information about the zip file. + /// The zip file handle opened by . + /// An address of a struct to hold the information. No preparation of the structure is needed. + /// + /// Zero if there was no error. + /// Otherwise a value less than zero. See for the specific reason. + /// + [DllImport("zlib.dll")] + public unsafe static extern int unzGetGlobalInfo(IntPtr handle, ZipFileInfo* globalInfoPtr); + + /// Get the comment associated with the entire zip file. + /// The zip file handle opened by + /// The buffer to hold the comment. + /// The length of the buffer in bytes (8 bit characters). + /// + /// The number of characters in the comment if there was no error. + /// Otherwise a value less than zero. See for the specific reason. + /// + [DllImport("zlib.dll")] + public static extern int unzGetGlobalComment(IntPtr handle, sbyte[] commentBuffer, uint commentBufferLength); + + /// Set the current file of the zip file to the first file. + /// The zip file handle opened by . + /// + /// Zero if there was no error. + /// Otherwise a value less than zero. See for the specific reason. + /// + [DllImport("zlib.dll")] + public static extern int unzGoToFirstFile(IntPtr handle); + + /// Set the current file of the zip file to the next file. + /// The zip file handle opened by . + /// + /// Zero if there was no error. + /// Otherwise if there are no more entries. + /// + [DllImport("zlib.dll")] + public static extern int unzGoToNextFile(IntPtr handle); + + /// Try locate the entry in the zip file. + /// The zip file handle opened by . + /// The name of the entry to look for. + /// If 0 use the OS default. If 1 use case sensitivity like strcmp, Unix style. If 2 do not use case sensitivity like strcmpi, Windows style. + /// + /// Zero if there was no error. + /// Otherwise if there are no more entries. + /// + [DllImport("zlib.dll", ExactSpelling=true, CharSet=CharSet.Ansi)] + public static extern int unzLocateFile(IntPtr handle, string entryName, int caseSensitivity); + + /// Get information about the current entry in the zip file. + /// The zip file handle opened by . + /// A ZipEntryInfo struct to hold information about the entry or null. + /// An array of sbyte characters to hold the entry name or null. + /// The length of the entryNameBuffer in bytes. + /// An array to hold the extra field data for the entry or null. + /// The length of the extraField array in bytes. + /// An array of sbyte characters to hold the entry name or null. + /// The length of theh commentBuffer in bytes. + /// + /// If entryInfoPtr is not null the structure will contain information about the current file. + /// If entryNameBuffer is not null the name of the entry will be copied into it. + /// If extraField is not null the extra field data of the entry will be copied into it. + /// If commentBuffer is not null the comment of the entry will be copied into it. + /// + /// + /// Zero if there was no error. + /// Otherwise a value less than zero. See for the specific reason. + /// + [DllImport("zlib.dll", ExactSpelling=true, CharSet=CharSet.Ansi)] + public unsafe static extern int unzGetCurrentFileInfo(IntPtr handle, ZipEntryInfo* entryInfoPtr, + sbyte[] entryNameBuffer, uint entryNameBufferLength, + byte[] extraField, uint extraFieldLength, + sbyte[] commentBuffer, uint commentBufferLength); + + /// Open the zip file entry for reading. + /// The zip file handle opened by . + /// + /// Zero if there was no error. + /// Otherwise a value from . + /// + [DllImport("zlib.dll")] + public static extern int unzOpenCurrentFile(IntPtr handle); + + /// Close the file entry opened by . + /// The zip file handle opened by . + /// + /// Zero if there was no error. + /// CrcError if the file was read but the Crc does not match. + /// Otherwise a value from . + /// + [DllImport("zlib.dll")] + public static extern int unzCloseCurrentFile(IntPtr handle); + + /// Read bytes from the current zip file entry. + /// The zip file handle opened by . + /// Buffer to store the uncompressed data into. + /// Number of bytes to write from . + /// + /// The number of byte copied if somes bytes are copied. + /// Zero if the end of file was reached. + /// Less than zero with error code if there is an error. See for a list of possible error codes. + /// + [DllImport("zlib.dll")] + public static extern int unzReadCurrentFile(IntPtr handle, byte[] buffer, uint count); + + /// Give the current position in uncompressed data of the zip file entry currently opened. + /// The zip file handle opened by . + /// The number of bytes into the uncompressed data read so far. + [DllImport("zlib.dll")] + public static extern long unztell(IntPtr handle); + + /// Determine if the end of the zip file entry has been reached. + /// The zip file handle opened by . + /// + /// One if the end of file was reached. + /// Zero if elsewhere. + /// + [DllImport("zlib.dll")] + public static extern int unzeof(IntPtr handle); + + /// Converts a CLR string to a 8 bit ANSI array of characters. + /// The string to convert. + /// A 8 bit ANSI array of characters. + public static sbyte[] StringToAnsi(string str) { + int length = str.Length; + sbyte[] chars = new sbyte[length + 1]; + for (int i = 0; i < length; i++) { + chars[i] = (sbyte) str[i]; + } + + return chars; + } + + /// Converst an 8 bit ANSI C style string to a CLR string. + /// The array of a characters that holds the string. + /// The CLR string representing the characters passed in. + public static string AnsiToString(sbyte[] chars) { + int length = chars.Length; + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < length; i++) { + builder.Append((char) chars[i]); + } + return builder.ToString(); + } + } + + /// List of possible error codes. + internal enum ErrorCode : int { + /// No error. + Ok = 0, + + /// Unknown error. + Error = -1, + + /// Last entry in directory reached. + EndOfListOfFile = -100, + + /// Parameter error. + ParameterError = -102, + + /// Zip file is invalid. + BadZipFile = -103, + + /// Internal program error. + InternalError = -104, + + /// Crc values do not match. + CrcError = -105 + } + + /// Global information about the zip file. + [StructLayout(LayoutKind.Sequential)] + internal struct ZipFileInfo { + /// The number of entries in the directory. + public UInt32 EntryCount; + + /// Length of zip file comment in bytes (8 bit characters). + public UInt32 CommentLength; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct ZipFileEntryInfo { + public ZipDateTimeInfo DateTime; + public UInt32 DosDate; + public UInt32 InternalFileAttributes; // 2 bytes + public UInt32 ExternalFileAttributes; // 4 bytes + } + + /// Custom ZipLib date time structure. + [StructLayout(LayoutKind.Sequential)] + internal struct ZipDateTimeInfo { + /// Seconds after the minute - [0,59] + public UInt32 Seconds; + + /// Minutes after the hour - [0,59] + public UInt32 Minutes; + + /// Hours since midnight - [0,23] + public UInt32 Hours; + + /// Day of the month - [1,31] + public UInt32 Day; + + /// Months since January - [0,11] + public UInt32 Month; + + /// Years - [1980..2044] + public UInt32 Year; + + // implicit conversion from DateTime to ZipDateTimeInfo + public static implicit operator ZipDateTimeInfo(DateTime date) { + ZipDateTimeInfo d; + d.Seconds = (uint) date.Second; + d.Minutes = (uint) date.Minute; + d.Hours = (uint) date.Hour; + d.Day = (uint) date.Day; + d.Month = (uint) date.Month - 1; + d.Year = (uint) date.Year; + return d; + } + } + + /// Information stored in zip file directory about an entry. + [StructLayout(LayoutKind.Sequential)] + internal struct ZipEntryInfo { + // Version made by (2 bytes). + public UInt32 Version; + + /// Version needed to extract (2 bytes). + public UInt32 VersionNeeded; + + /// General purpose bit flag (2 bytes). + public UInt32 Flag; + + /// Compression method (2 bytes). + public UInt32 CompressionMethod; + + /// Last mod file date in Dos fmt (4 bytes). + public UInt32 DosDate; + + /// Crc-32 (4 bytes). + public UInt32 Crc; + + /// Compressed size (4 bytes). + public UInt32 CompressedSize; + + /// Uncompressed size (4 bytes). + public UInt32 UncompressedSize; + + /// Filename length (2 bytes). + public UInt32 FileNameLength; + + /// Extra field length (2 bytes). + public UInt32 ExtraFieldLength; + + /// File comment length (2 bytes). + public UInt32 CommentLength; + + /// Disk number start (2 bytes). + public UInt32 DiskStartNumber; + + /// Internal file attributes (2 bytes). + public UInt32 InternalFileAttributes; + + /// External file attributes (4 bytes). + public UInt32 ExternalFileAttributes; + + /// File modification date of entry. + public ZipDateTimeInfo DateTime; + } +} diff --git a/src/Zip/ZipReader.cs b/src/Zip/ZipReader.cs new file mode 100644 index 0000000..54bba75 --- /dev/null +++ b/src/Zip/ZipReader.cs @@ -0,0 +1,298 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using System.Collections; +using System.Runtime.Serialization; + +namespace OrganicBit.Zip { + + /// Provides support for reading files in the ZIP file format. Includes support for both compressed and uncompressed entries. + /// This example shows how to view the entries in a ZIP file. + /// + /// public static void View(string zipFileName) { + /// ZipReader reader = new ZipReader(zipFileName); + /// + /// Console.WriteLine("Archive: {0} ({1} files)", zipFileName, reader.Entries.Count); + /// Console.WriteLine(reader.Comment); + /// + /// string format = "{0,8} {1,8} {2,5} {3,10} {4,5} {5}"; + /// Console.WriteLine(format, " Length ", " Size ", "Ratio", " Date ", "Time ", "Name"); + /// Console.WriteLine(format, "--------", "--------", "-----", "----------", "-----", "----"); + /// + /// foreach (ZipEntry entry in reader.Entries) { + /// if (!entry.IsDirectory) { + /// Console.WriteLine(format, + /// entry.Length, + /// entry.CompressedLength, + /// entry.Ratio.ToString("P0"), + /// entry.ModifiedTime.ToString("yyyy-MM-dd"), + /// entry.ModifiedTime.ToString("hh:mm"), + /// entry.Name); + /// } + /// } + /// reader.Close(); + /// } + /// + /// + /// This example shows how to extract files from a ZIP file. + /// + /// public static void Extract(string zipFileName) { + /// ZipReader reader = new ZipReader(zipFileName); + /// Console.WriteLine("Archive: {0}", zipFileName); + /// Console.WriteLine(reader.Comment); + /// + /// // buffer to hold temp bytes + /// byte[] buffer = new byte[4096]; + /// int byteCount; + /// + /// // Get the zipped entries + /// while (reader.MoveNext()) { + /// ZipEntry entry = reader.Current; + /// + /// if (entry.IsDirectory) { + /// Directory.CreateDirectory(entry.Name); + /// } else { + /// Console.Write(" {0}", entry.Name); + /// + /// // create output stream + /// FileStream writer = File.Open(entry.Name, FileMode.Create); + /// + /// // write uncompressed data + /// while ((byteCount = reader.Read(buffer, 0, buffer.Length)) > 0) { + /// Console.Write("."); + /// writer.Write(buffer, 0, byteCount); + /// } + /// writer.Close(); + /// Console.WriteLine(); + /// } + /// } + /// reader.Close(); + /// } + /// + /// + public class ZipReader : IEnumerator, IDisposable { + + /// ZipFile handle to read data from. + IntPtr _handle = IntPtr.Zero; + + /// Name of zip file. + string _fileName = null; + + /// Contents of zip file directory. + ZipEntryCollection _entries = null; + + /// Global zip file comment. + string _comment = null; + + /// True if an entry is open for reading. + bool _entryOpen = false; + + /// Current zip entry open for reading. + ZipEntry _current = null; + + /// Initializes a instance of the class for reading the zip file with the given name. + /// The name of zip file that will be read. + public ZipReader(string fileName) { + _fileName = fileName; + _handle = ZipLib.unzOpen(fileName); + if (_handle == IntPtr.Zero) { + string msg = String.Format("Could not open zip file '{0}'.", fileName); + throw new ZipException(msg); + } + } + + /// Cleans up the resources used by this zip file. + ~ZipReader() { + CloseFile(); + } + + /// Dispose is synonym for Close. + void IDisposable.Dispose() { + Close(); + } + + /// Closes the zip file and releases any resources. + public void Close() { + // Free unmanaged resources. + CloseFile(); + + // If base type implements IDisposable we would call it here. + + // Request the system not call the finalizer method for this object. + GC.SuppressFinalize(this); + } + + /// Gets the name of the zip file that was passed to the constructor. + public string Name { + get { return _fileName; } + } + + /// Gets the global comment for the zip file. + public string Comment { + get { + if (_comment == null) { + ZipFileInfo info; + int result = 0; + unsafe { + result = ZipLib.unzGetGlobalInfo(_handle, &info); + } + if (result < 0) { + string msg = String.Format("Could not read comment from zip file '{0}'.", Name); + throw new ZipException(msg); + } + + sbyte[] buffer = new sbyte[info.CommentLength]; + result = ZipLib.unzGetGlobalComment(_handle, buffer, (uint) buffer.Length); + if (result < 0) { + string msg = String.Format("Could not read comment from zip file '{0}'.", Name); + throw new ZipException(msg); + } + _comment = ZipLib.AnsiToString(buffer); + } + return _comment; + } + } + + /// Gets a object that contains all the entries in the zip file directory. + public ZipEntryCollection Entries { + get { + if (_entries == null) { + _entries = new ZipEntryCollection(); + + int result = ZipLib.unzGoToFirstFile(_handle); + while (result == 0) { + ZipEntry entry = new ZipEntry(_handle); + _entries.Add(entry); + result = ZipLib.unzGoToNextFile(_handle); + } + } + return _entries; + } + } + + object IEnumerator.Current { + get { + return _current; + } + } + + /// Gets the current entry in the zip file.. + public ZipEntry Current { + get { + return _current; + } + } + + /// Advances the enumerator to the next element of the collection. + /// Sets to the next zip entry. + /// true if the next entry is not null; otherwise false. + public bool MoveNext() { + // close any open entry + CloseEntry(); + + int result; + if (_current == null) { + result = ZipLib.unzGoToFirstFile(_handle); + } else { + result = ZipLib.unzGoToNextFile(_handle); + } + if (result < 0) { + // last entry found - not an exceptional case + _current = null; + } else { + // entry found + OpenEntry(); + } + + return (_current != null); + } + + /// Move to just before the first entry in the zip directory. + public void Reset() { + CloseEntry(); + _current = null; + } + + /// Seek to the specified entry. + /// The name of the entry to seek to. + public void Seek(string entryName) { + CloseEntry(); + int result = ZipLib.unzLocateFile(_handle, entryName, 0); + if (result < 0) { + string msg = String.Format("Could not locate entry named '{0}'.", entryName); + throw new ZipException(msg); + } + OpenEntry(); + } + + private void OpenEntry() { + _current = new ZipEntry(_handle); + int result = ZipLib.unzOpenCurrentFile(_handle); + if (result < 0) { + _current = null; + throw new ZipException("Could not open entry for reading."); + } + _entryOpen = true; + } + + /// Uncompress a block of bytes from the current zip entry and writes the data in a given buffer. + /// The array to write data into. + /// The byte offset in at which to begin writing. + /// The maximum number of bytes to read. + public int Read(byte[] buffer, int index, int count) { + if (index != 0) { + throw new ArgumentException("index", "Only index values of zero currently supported."); + } + int bytesRead = ZipLib.unzReadCurrentFile(_handle, buffer, (uint) count); + if (bytesRead < 0) { + throw new ZipException("Error reading zip entry."); + } + return bytesRead; + } + + private void CloseEntry() { + if (_entryOpen) { + int result = ZipLib.unzCloseCurrentFile(_handle); + if (result < 0) { + switch ((ErrorCode) result) { + case ErrorCode.CrcError: + throw new ZipException("All the file was read but the CRC did not match."); + + default: + throw new ZipException("Could not close zip entry."); + } + } + _entryOpen = false; + } + } + + private void CloseFile() { + if (_handle != IntPtr.Zero) { + CloseEntry(); + int result = ZipLib.unzClose(_handle); + if (result < 0) { + throw new ZipException("Could not close zip file."); + } + _handle = IntPtr.Zero; + } + } + } +} diff --git a/src/Zip/ZipWriter.cs b/src/Zip/ZipWriter.cs new file mode 100644 index 0000000..0c3e4d5 --- /dev/null +++ b/src/Zip/ZipWriter.cs @@ -0,0 +1,181 @@ +// Copyright (C) 2001 Gerry Shaw +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// +// Gerry Shaw (gerry_shaw@yahoo.com) + +using System; +using System.Runtime.Serialization; + +namespace OrganicBit.Zip { + + /// Provides support for writing files in the ZIP file format. Includes support for both compressed and uncompressed entries. + /// This example shows how to create a ZIP file. + /// + /// public static void Add(string zipFileName, string[] entryPatterns) { + /// string currentDirectory = Directory.GetCurrentDirectory(); + /// Console.WriteLine("Creating {0}", zipFileName); + /// + /// ZipWriter writer = new ZipWriter(zipFileName); + /// + /// // buffer to hold temp bytes + /// byte[] buffer = new byte[4096]; + /// int byteCount; + /// + /// // add files to archive + /// foreach (string pattern in entryPatterns) { + /// foreach (string path in Directory.GetFiles(currentDirectory, pattern)) { + /// string fileName = Path.GetFileName(path); + /// Console.Write("Adding {0}", fileName); + /// + /// ZipEntry entry = new ZipEntry(fileName); + /// entry.ModifiedTime = File.GetLastWriteTime(fileName); + /// entry.Comment = "local file comment"; + /// + /// writer.AddEntry(entry); + /// + /// FileStream reader = File.OpenRead(entry.Name); + /// while ((byteCount = reader.Read(buffer, 0, buffer.Length)) > 0) { + /// Console.Write("."); + /// writer.Write(buffer, 0, byteCount); + /// } + /// reader.Close(); + /// Console.WriteLine(); + /// } + /// } + /// + /// writer.Close(); + /// } + /// + /// + public class ZipWriter : IDisposable { + + /// Name of the zip file. + string _fileName; + + /// Zip file global comment. + string _comment = ""; + + /// True if currently writing a new zip file entry. + bool _entryOpen = false; + + /// Zip file handle. + IntPtr _handle = IntPtr.Zero; + + /// Initializes a new instance fo the class with a specified file name. Any Existing file will be overwritten. + /// The name of the zip file to create. + public ZipWriter(string fileName) { + _fileName = fileName; + + _handle = ZipLib.zipOpen(fileName, 0); + if (_handle == IntPtr.Zero) { + string msg = String.Format("Could not open zip file '{0}' for writing.", fileName); + throw new ZipException(msg); + } + } + + /// Cleans up the resources used by this zip file. + ~ZipWriter() { + CloseFile(); + } + + /// Dispose is synonym for Close. + void IDisposable.Dispose() { + Close(); + } + + /// Closes the zip file and releases any resources. + public void Close() { + // Free unmanaged resources. + CloseFile(); + + // If base type implements IDisposable we would call it here. + + // Request the system not call the finalizer method for this object. + GC.SuppressFinalize(this); + } + + /// Gets the name of the zip file. + public string Name { + get { + return _fileName; + } + } + + /// Gets and sets the zip file comment. + public string Comment { + get { return _comment; } + set { _comment = value; } + } + + /// Creates a new zip entry in the directory and positions the stream to the start of the entry data. + /// The zip entry to be written. + /// Closes the current entry if still active. + public void AddEntry(ZipEntry entry) { + ZipFileEntryInfo info; + info.DateTime = entry.ModifiedTime; + + int result; + unsafe { + byte[] extra = null; + uint extraLength = 0; + if (entry.ExtraField != null) { + extra = entry.ExtraField; + extraLength = (uint) entry.ExtraField.Length; + } + + result = ZipLib.zipOpenNewFileInZip( + _handle, + entry.Name, + &info, + extra, + extraLength, + null, 0, + entry.Comment, + (int) entry.Method, + entry.Level); + } + _entryOpen = true; + } + + /// Compress a block of bytes from the given buffer and writes them into the current zip entry. + /// The array to read data from. + /// The byte offset in at which to begin reading. + /// The maximum number of bytes to write. + public void Write(byte[] buffer, int index, int count) { + int result = ZipLib.zipWriteInFileInZip(_handle, buffer, (uint) count); + } + + private void CloseEntry() { + if (_entryOpen) { + int result = ZipLib.zipCloseFileInZip(_handle); + _entryOpen = false; + } + } + + void CloseFile() { + if (_handle != IntPtr.Zero) { + CloseEntry(); + int result = ZipLib.zipClose(_handle, _comment); + if (result < 0) { + throw new ZipException("Could not close zip file."); + } + _handle = IntPtr.Zero; + } + } + } +}