3 // Copyright (C) 2001 Mike Krueger
4 // Copyright (C) 2004 John Reilly
6 // This file was translated from java, it was part of the GNU Classpath
7 // Copyright (C) 2001 Free Software Foundation, Inc.
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 // Linking this library statically or dynamically with other modules is
24 // making a combined work based on this library. Thus, the terms and
25 // conditions of the GNU General Public License cover the whole
28 // As a special exception, the copyright holders of this library give you
29 // permission to link this library with independent modules to produce an
30 // executable, regardless of the license terms of these independent
31 // modules, and to copy and distribute the resulting executable under
32 // terms of your choice, provided that you also meet, for each linked
33 // independent module, the terms and conditions of the license of that
34 // module. An independent module is a module which is not derived from
35 // or based on this library. If you modify this library, you may extend
36 // this exception to your version of the library, but you are not
37 // obligated to do so. If you do not wish to do so, delete this
38 // exception statement from your version.
42 using ICSharpCode.SharpZipLib.Silverlight.Zip;
43 using ICSharpCode.SharpZipLib.Zip;
45 namespace ICSharpCode.SharpZipLib.Silverlight.Zip
48 /// Defines known values for the <see cref="HostSystemID"/> property.
50 public enum HostSystemID
53 /// Host system = MSDOS
57 /// Host system = Amiga
61 /// Host system = Open VMS
65 /// Host system = Unix
69 /// Host system = VMCms
73 /// Host system = Atari ST
81 /// Host system = Macintosh
85 /// Host system = ZSystem
93 /// Host system = Windows NT
101 /// Host system = VSE
105 /// Host system = Acorn RISC
109 /// Host system = VFAT
113 /// Host system = Alternate MVS
117 /// Host system = BEOS
121 /// Host system = Tandem
125 /// Host system = OS400
129 /// Host system = OSX
133 /// Host system = WinZIP AES
139 /// This class represents an entry in a zip archive. This can be a file
141 /// ZipFile and ZipInputStream will give you instances of this class as
142 /// information about the members in an archive. ZipOutputStream
143 /// uses an instance of this class when creating an entry in a Zip file.
145 /// <br/>Author of the original java version : Jochen Hoenicke
147 public class ZipEntry
154 CompressedSize = 0x02,
157 ExternalAttributes = 0x10,
162 /// Creates a zip entry with the given name.
164 /// <param name="name">
165 /// The name for this entry. Can include directory components.
166 /// The convention for names is 'unix' style paths with relative names only.
167 /// There are with no device names and path elements are separated by '/' characters.
169 /// <exception cref="ArgumentNullException">
170 /// The name passed is null
172 public ZipEntry(string name)
173 : this(name, 0, ZipConstants.VersionMadeBy, CompressionMethod.Deflated)
178 /// Creates a zip entry with the given name and version required to extract
180 /// <param name="name">
181 /// The name for this entry. Can include directory components.
182 /// The convention for names is 'unix' style paths with no device names and
183 /// path elements separated by '/' characters. This is not enforced see <see cref="CleanName(string)">CleanName</see>
184 /// on how to ensure names are valid if this is desired.
186 /// <param name="versionRequiredToExtract">
187 /// The minimum 'feature version' required this entry
189 /// <exception cref="ArgumentNullException">
190 /// The name passed is null
192 internal ZipEntry(string name, int versionRequiredToExtract)
193 : this(name, versionRequiredToExtract, ZipConstants.VersionMadeBy,
194 CompressionMethod.Deflated)
199 /// Initializes an entry with the given name and made by information
201 /// <param name="name">Name for this entry</param>
202 /// <param name="madeByInfo">Version and HostSystem Information</param>
203 /// <param name="versionRequiredToExtract">Minimum required zip feature version required to extract this entry</param>
204 /// <param name="method">Compression method for this entry.</param>
205 /// <exception cref="ArgumentNullException">
206 /// The name passed is null
208 /// <exception cref="ArgumentOutOfRangeException">
209 /// versionRequiredToExtract should be 0 (auto-calculate) or > 10
212 /// This constructor is used by the ZipFile class when reading from the central header
213 /// It is not generally useful, use the constructor specifying the name only.
215 internal ZipEntry(string name, int versionRequiredToExtract, int madeByInfo,
216 CompressionMethod method)
219 throw new System.ArgumentNullException("ZipEntry name");
222 if ( name.Length > 0xffff ) {
223 throw new ArgumentException("Name is too long", "name");
226 if ( (versionRequiredToExtract != 0) && (versionRequiredToExtract < 10) ) {
227 throw new ArgumentOutOfRangeException("versionRequiredToExtract");
230 this.DateTime = System.DateTime.Now;
232 this.versionMadeBy = (ushort)madeByInfo;
233 this.versionToExtract = (ushort)versionRequiredToExtract;
234 this.method = method;
238 /// Creates a deep copy of the given zip entry.
240 /// <param name="entry">
241 /// The entry to copy.
243 [Obsolete("Use Clone instead")]
244 public ZipEntry(ZipEntry entry)
246 if ( entry == null ) {
247 throw new ArgumentNullException("entry");
253 compressedSize = entry.compressedSize;
255 dosTime = entry.dosTime;
256 method = entry.method;
257 comment = entry.comment;
258 versionToExtract = entry.versionToExtract;
259 versionMadeBy = entry.versionMadeBy;
260 externalFileAttributes = entry.externalFileAttributes;
263 zipFileIndex = entry.zipFileIndex;
264 offset = entry.offset;
266 forceZip64_ = entry.forceZip64_;
268 if ( entry.extra != null ) {
269 extra = new byte[entry.extra.Length];
270 Array.Copy(entry.extra, 0, extra, 0, entry.extra.Length);
277 /// Get a value indicating wether the entry has a CRC value available.
282 return (known & Known.Crc) != 0;
287 /// Get/Set flag indicating if entry is encrypted.
288 /// A simple helper routine to aid interpretation of <see cref="Flags">flags</see>
290 /// <remarks>This is an assistant that interprets the <see cref="Flags">flags</see> property.</remarks>
291 public bool IsCrypted
294 return (flags & 1) != 0;
307 /// Get / set a flag indicating wether entry name and comment text are
308 /// encoded in <a href="http://www.unicode.org">unicode UTF8</a>.
310 /// <remarks>This is an assistant that interprets the <see cref="Flags">flags</see> property.</remarks>
311 public bool IsUnicodeText
314 return ( flags & (int)GeneralBitFlags.UnicodeText ) != 0;
318 flags |= (int)GeneralBitFlags.UnicodeText;
321 flags &= ~(int)GeneralBitFlags.UnicodeText;
327 /// Value used during password checking for PKZIP 2.0 / 'classic' encryption.
329 internal byte CryptoCheckValue
332 return cryptoCheckValue_;
336 cryptoCheckValue_ = value;
341 /// Get/Set general purpose bit flag for entry
344 /// General purpose bit flag<br/>
346 /// Bit 0: If set, indicates the file is encrypted<br/>
347 /// Bit 1-2 Only used for compression type 6 Imploding, and 8, 9 deflating<br/>
349 /// Bit 1 if set indicates an 8K sliding dictionary was used. If clear a 4k dictionary was used<br/>
350 /// Bit 2 if set indicates 3 Shannon-Fanno trees were used to encode the sliding dictionary, 2 otherwise<br/>
354 /// 0 0 Normal compression was used<br/>
355 /// 0 1 Maximum compression was used<br/>
356 /// 1 0 Fast compression was used<br/>
357 /// 1 1 Super fast compression was used<br/>
359 /// Bit 3: If set, the fields crc-32, compressed size
360 /// and uncompressed size are were not able to be written during zip file creation
361 /// The correct values are held in a data descriptor immediately following the compressed data. <br/>
362 /// Bit 4: Reserved for use by PKZIP for enhanced deflating<br/>
363 /// Bit 5: If set indicates the file contains compressed patch data<br/>
364 /// Bit 6: If set indicates strong encryption was used.<br/>
365 /// Bit 7-10: Unused or reserved<br/>
366 /// Bit 11: If set the name and comments for this entry are in <a href="http://www.unicode.org">unicode</a>.<br/>
367 /// Bit 12-15: Unused or reserved<br/>
369 /// <seealso cref="IsUnicodeText"></seealso>
370 /// <seealso cref="IsCrypted"></seealso>
382 /// Get/Set index of this entry in Zip file
384 /// <remarks>This is only valid when the entry is part of a <see cref="ZipFile"></see></remarks>
385 public long ZipFileIndex
391 zipFileIndex = value;
396 /// Get/set offset for use in central header
409 /// Get/Set external file attributes as an integer.
410 /// The values of this are operating system dependant see
411 /// <see cref="HostSystem">HostSystem</see> for details
413 public int ExternalFileAttributes
416 if ((known & Known.ExternalAttributes) == 0) {
420 return externalFileAttributes;
425 externalFileAttributes = value;
426 known |= Known.ExternalAttributes;
431 /// Get the version made by for this entry or zero if unknown.
432 /// The value / 10 indicates the major version number, and
433 /// the value mod 10 is the minor version number
435 public int VersionMadeBy
438 return (versionMadeBy & 0xff);
443 /// Get a value indicating this entry is for a DOS/Windows system.
445 public bool IsDOSEntry
448 return ((HostSystem == ( int )HostSystemID.Msdos) ||
449 (HostSystem == ( int )HostSystemID.WindowsNT));
454 /// Test the external attributes for this <see cref="ZipEntry"/> to
455 /// see if the external attributes are Dos based (including WINNT and variants)
456 /// and match the values
458 /// <param name="attributes">The attributes to test.</param>
459 /// <returns>Returns true if the external attributes are known to be DOS/Windows
460 /// based and have the same attributes set as the value passed.</returns>
461 bool HasDosAttributes(int attributes)
464 if ( (known & Known.ExternalAttributes) != 0 ) {
465 if ( ((HostSystem == (int)HostSystemID.Msdos) ||
466 (HostSystem == (int)HostSystemID.WindowsNT)) &&
467 (ExternalFileAttributes & attributes) == attributes) {
475 /// Gets the compatability information for the <see cref="ExternalFileAttributes">external file attribute</see>
476 /// If the external file attributes are compatible with MS-DOS and can be read
477 /// by PKZIP for DOS version 2.04g then this value will be zero. Otherwise the value
478 /// will be non-zero and identify the host system on which the attributes are compatible.
482 /// The values for this as defined in the Zip File format and by others are shown below. The values are somewhat
483 /// misleading in some cases as they are not all used as shown. You should consult the relevant documentation
484 /// to obtain up to date and correct information. The modified appnote by the infozip group is
485 /// particularly helpful as it documents a lot of peculiarities. The document is however a little dated.
486 /// <list type="table">
487 /// <item>0 - MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)</item>
488 /// <item>1 - Amiga</item>
489 /// <item>2 - OpenVMS</item>
490 /// <item>3 - Unix</item>
491 /// <item>4 - VM/CMS</item>
492 /// <item>5 - Atari ST</item>
493 /// <item>6 - OS/2 HPFS</item>
494 /// <item>7 - Macintosh</item>
495 /// <item>8 - Z-System</item>
496 /// <item>9 - CP/M</item>
497 /// <item>10 - Windows NTFS</item>
498 /// <item>11 - MVS (OS/390 - Z/OS)</item>
499 /// <item>12 - VSE</item>
500 /// <item>13 - Acorn Risc</item>
501 /// <item>14 - VFAT</item>
502 /// <item>15 - Alternate MVS</item>
503 /// <item>16 - BeOS</item>
504 /// <item>17 - Tandem</item>
505 /// <item>18 - OS/400</item>
506 /// <item>19 - OS/X (Darwin)</item>
507 /// <item>99 - WinZip AES</item>
508 /// <item>remainder - unused</item>
511 public int HostSystem
514 return (versionMadeBy >> 8) & 0xff;
518 versionMadeBy &= 0xff;
519 versionMadeBy |= (ushort)((value & 0xff) << 8);
524 /// Get minimum Zip feature version required to extract this entry
527 /// Minimum features are defined as:<br/>
528 /// 1.0 - Default value<br/>
529 /// 1.1 - File is a volume label<br/>
530 /// 2.0 - File is a folder/directory<br/>
531 /// 2.0 - File is compressed using Deflate compression<br/>
532 /// 2.0 - File is encrypted using traditional encryption<br/>
533 /// 2.1 - File is compressed using Deflate64<br/>
534 /// 2.5 - File is compressed using PKWARE DCL Implode<br/>
535 /// 2.7 - File is a patch data set<br/>
536 /// 4.5 - File uses Zip64 format extensions<br/>
537 /// 4.6 - File is compressed using BZIP2 compression<br/>
538 /// 5.0 - File is encrypted using DES<br/>
539 /// 5.0 - File is encrypted using 3DES<br/>
540 /// 5.0 - File is encrypted using original RC2 encryption<br/>
541 /// 5.0 - File is encrypted using RC4 encryption<br/>
542 /// 5.1 - File is encrypted using AES encryption<br/>
543 /// 5.1 - File is encrypted using corrected RC2 encryption<br/>
544 /// 5.1 - File is encrypted using corrected RC2-64 encryption<br/>
545 /// 6.1 - File is encrypted using non-OAEP key wrapping<br/>
546 /// 6.2 - Central directory encryption (not confirmed yet)<br/>
547 /// 6.3 - File is compressed using LZMA<br/>
548 /// 6.3 - File is compressed using PPMD+<br/>
549 /// 6.3 - File is encrypted using Blowfish<br/>
550 /// 6.3 - File is encrypted using Twofish<br/>
552 /// <seealso cref="CanDecompress"></seealso>
556 // Return recorded version if known.
557 if (versionToExtract != 0) {
558 return versionToExtract;
562 if ( CentralHeaderRequiresZip64 ) {
563 result = ZipConstants.VersionZip64;
565 else if (CompressionMethod.Deflated == method) {
568 else if (IsDirectory == true) {
571 else if (IsCrypted == true) {
574 else if (HasDosAttributes(0x08) ) {
583 /// Get a value indicating wether this entry can be decompressed by the library.
585 /// <remarks>This is based on the <see cref="Version"></see> and
586 /// wether the <see cref="IsCompressionMethodSupported()">compression method</see> is supported.</remarks>
587 public bool CanDecompress
590 return (Version <= ZipConstants.VersionMadeBy) &&
595 IsCompressionMethodSupported();
600 /// Force this entry to be recorded using Zip64 extensions.
602 public void ForceZip64()
608 /// Get a value indicating wether Zip64 extensions were forced.
610 /// <returns>A <see cref="bool"/> value of true if Zip64 extensions have been forced on; false if not.</returns>
611 public bool IsZip64Forced()
617 /// Gets a value indicating if the entry requires Zip64 extensions
618 /// to store the full entry values.
620 /// <value>A <see cref="bool"/> value of true if a local header requires Zip64 extensions; false if not.</value>
621 public bool LocalHeaderRequiresZip64
624 bool result = forceZip64_;
627 ulong trueCompressedSize = compressedSize;
629 if ( (versionToExtract == 0) && IsCrypted ) {
630 trueCompressedSize += ZipConstants.CryptoHeaderSize;
633 // TODO: A better estimation of the true limit based on compression overhead should be used
634 // to determine when an entry should use Zip64.
636 ((this.size >= uint.MaxValue) || (trueCompressedSize >= uint.MaxValue)) &&
637 ((versionToExtract == 0) || (versionToExtract >= ZipConstants.VersionZip64));
645 /// Get a value indicating wether the central directory entry requires Zip64 extensions to be stored.
647 public bool CentralHeaderRequiresZip64
650 return LocalHeaderRequiresZip64 || (offset >= uint.MaxValue);
655 /// Get/Set DosTime value.
658 /// The MS-DOS date format can only represent dates between 1/1/1980 and 12/31/2107.
663 if ((known & Known.Time) == 0) {
673 dosTime = (uint)value;
681 /// Gets/Sets the time of last modification of the entry.
684 /// The <see cref="DosTime"></see> property is updated to match this as far as possible.
686 public DateTime DateTime
689 var sec = Math.Min(59, (int) (2 * (dosTime & 0x1f)));
690 var min = Math.Min(59, (int) ((dosTime >> 5) & 0x3f));
691 var hrs = Math.Min(23, (int) ((dosTime >> 11) & 0x1f));
692 var mon = Math.Max(1, Math.Min(12, (int) ((dosTime >> 21) & 0xf)));
693 var year = ((dosTime >> 25) & 0x7f) + 1980;
694 var day = Math.Max(1, Math.Min(DateTime.DaysInMonth((int)year, (int)mon), (int)((dosTime >> 16) & 0x1f)));
695 return new DateTime((int)year, (int)mon, day, (int)hrs, (int)min, (int)sec);
698 var year = (uint) value.Year;
699 var month = (uint) value.Month;
700 var day = (uint) value.Day;
701 var hour = (uint) value.Hour;
702 var minute = (uint) value.Minute;
703 var second = (uint) value.Second;
713 else if ( year > 2107 ) {
722 DosTime = ((year - 1980) & 0x7f) << 25 |
732 /// Returns the entry name.
735 /// The unix naming convention is followed.
736 /// Path components in the entry should always separated by forward slashes ('/').
737 /// Dos device names like C: should also be removed.
738 /// See the <see cref="ZipNameTransform"/> class, or <see cref="CleanName(string)"/>
748 /// Gets/Sets the size of the uncompressed data.
751 /// The size or -1 if unknown.
753 /// <remarks>Setting the size before adding an entry to an archive can help
754 /// avoid compatability problems with some archivers which dont understand Zip64 extensions.</remarks>
758 return (known & Known.Size) != 0 ? (long)size : -1L;
761 this.size = (ulong)value;
762 this.known |= Known.Size;
767 /// Gets/Sets the size of the compressed data.
770 /// The compressed entry size or -1 if unknown.
772 public long CompressedSize
775 return (known & Known.CompressedSize) != 0 ? (long)compressedSize : -1L;
778 this.compressedSize = (ulong)value;
779 this.known |= Known.CompressedSize;
784 /// Gets/Sets the crc of the uncompressed data.
786 /// <exception cref="System.ArgumentOutOfRangeException">
787 /// Crc is not in the range 0..0xffffffffL
790 /// The crc value or -1 if unknown.
795 return (known & Known.Crc) != 0 ? crc & 0xffffffffL : -1L;
798 if (((ulong)crc & 0xffffffff00000000L) != 0) {
799 throw new ArgumentOutOfRangeException("value");
801 this.crc = (uint)value;
802 this.known |= Known.Crc;
807 /// Gets/Sets the compression method. Only Deflated and Stored are supported.
810 /// The compression method for this entry
812 /// <see cref="Zip.CompressionMethod.Deflated"/>
813 /// <see cref="Zip.CompressionMethod.Stored"/>
814 public CompressionMethod CompressionMethod {
820 if ( !IsCompressionMethodSupported(value) ) {
821 throw new NotSupportedException("Compression method not supported");
828 /// Gets/Sets the extra data.
830 /// <exception cref="System.ArgumentOutOfRangeException">
831 /// Extra data is longer than 64KB (0xffff) bytes.
834 /// Extra data or null if not set.
836 public byte[] ExtraData {
839 // TODO: This is slightly safer but less efficient. Think about wether it should change.
840 // return (byte[]) extra.Clone();
849 if (value.Length > 0xffff) {
850 throw new System.ArgumentOutOfRangeException("value");
853 extra = new byte[value.Length];
854 Array.Copy(value, 0, extra, 0, value.Length);
860 /// Process extra data fields updating the entry based on the contents.
862 /// <param name="localHeader">True if the extra data fields should be handled
863 /// for a local header, rather than for a central header.
865 internal void ProcessExtraData(bool localHeader)
867 ZipExtraData extraData = new ZipExtraData(this.extra);
869 if ( extraData.Find(0x0001) ) {
870 if ( (versionToExtract & 0xff) < ZipConstants.VersionZip64 ) {
871 throw new ZipException("Zip64 Extended information found but version is not valid");
874 // The recorded size will change but remember that this is zip64.
877 if ( extraData.ValueLength < 4 ) {
878 throw new ZipException("Extra data extended Zip64 information length is invalid");
881 if ( localHeader || (size == uint.MaxValue) ) {
882 size = (ulong)extraData.ReadLong();
885 if ( localHeader || (compressedSize == uint.MaxValue) ) {
886 compressedSize = (ulong)extraData.ReadLong();
889 if ( !localHeader && (offset == uint.MaxValue) ) {
890 offset = extraData.ReadLong();
895 ((versionToExtract & 0xff) >= ZipConstants.VersionZip64) &&
896 ((size == uint.MaxValue) || (compressedSize == uint.MaxValue))
898 throw new ZipException("Zip64 Extended information required but is missing.");
902 if ( extraData.Find(10) ) {
903 // No room for any tags.
904 if ( extraData.ValueLength < 8 ) {
905 throw new ZipException("NTFS Extra data invalid");
908 extraData.ReadInt(); // Reserved
910 while ( extraData.UnreadCount >= 4 ) {
911 int ntfsTag = extraData.ReadShort();
912 int ntfsLength = extraData.ReadShort();
913 if ( ntfsTag == 1 ) {
914 if ( ntfsLength >= 24 ) {
915 long lastModification = extraData.ReadLong();
916 long lastAccess = extraData.ReadLong();
917 long createTime = extraData.ReadLong();
919 DateTime = System.DateTime.FromFileTime(lastModification);
924 // An unknown NTFS tag so simply skip it.
925 extraData.Skip(ntfsLength);
929 else if ( extraData.Find(0x5455) ) {
930 int length = extraData.ValueLength;
931 int flags = extraData.ReadByte();
933 // Can include other times but these are ignored. Length of data should
934 // actually be 1 + 4 * no of bits in flags.
935 if ( ((flags & 1) != 0) && (length >= 5) ) {
936 int iTime = extraData.ReadInt();
938 DateTime = (new System.DateTime ( 1970, 1, 1, 0, 0, 0 ).ToUniversalTime() +
939 new TimeSpan ( 0, 0, 0, iTime, 0 )).ToLocalTime();
945 /// Gets/Sets the entry comment.
947 /// <exception cref="System.ArgumentOutOfRangeException">
948 /// If comment is longer than 0xffff.
951 /// The comment or null if not set.
954 /// A comment is only available for entries when read via the <see cref="ZipFile"/> class.
955 /// The <see cref="ZipInputStream"/> class doesnt have the comment data available.
957 public string Comment {
962 // This test is strictly incorrect as the length is in characters
963 // while the storage limit is in bytes.
964 // While the test is partially correct in that a comment of this length or greater
965 // is definitely invalid, shorter comments may also have an invalid length
966 // where there are multi-byte characters
967 // The full test is not possible here however as the code page to apply conversions with
969 if ( (value != null) && (value.Length > 0xffff) ) {
970 throw new ArgumentOutOfRangeException("value", "cannot exceed 65535");
978 /// Gets a value indicating if the entry is a directory.
982 /// A directory is determined by an entry name with a trailing slash '/'.
983 /// The external file attributes can also indicate an entry is for a directory.
984 /// Currently only dos/windows attributes are tested in this manner.
985 /// The trailing slash convention should always be followed.
987 public bool IsDirectory
990 int nameLength = name.Length;
993 ((name[nameLength - 1] == '/') || (name[nameLength - 1] == '\\'))) ||
1001 /// Get a value of true if the entry appears to be a file; false otherwise
1004 /// This only takes account of DOS/Windows attributes. Other operating systems are ignored.
1005 /// For linux and others the result may be incorrect.
1010 return !IsDirectory && !HasDosAttributes(8);
1015 /// Test entry to see if data can be extracted.
1017 /// <returns>Returns true if data can be extracted for this entry; false otherwise.</returns>
1018 public bool IsCompressionMethodSupported()
1020 return IsCompressionMethodSupported(CompressionMethod);
1023 #region ICloneable Members
1025 /// Creates a copy of this zip entry.
1027 /// <returns>An <see cref="Object"/> that is a copy of the current instance.</returns>
1028 public object Clone()
1030 ZipEntry result = (ZipEntry)this.MemberwiseClone();
1032 // Ensure extra data is unique if it exists.
1033 if ( extra != null ) {
1034 result.extra = new byte[extra.Length];
1035 Array.Copy(extra, 0, result.extra, 0, extra.Length);
1044 /// Gets a string representation of this ZipEntry.
1046 /// <returns>A readable textual representation of this <see cref="ZipEntry"/></returns>
1047 public override string ToString()
1053 /// Test a <see cref="CompressionMethod">compression method</see> to see if this library
1054 /// supports extracting data compressed with that method
1056 /// <param name="method">The compression method to test.</param>
1057 /// <returns>Returns true if the compression method is supported; false otherwise</returns>
1058 public static bool IsCompressionMethodSupported(CompressionMethod method)
1061 ( method == CompressionMethod.Deflated ) ||
1062 ( method == CompressionMethod.Stored );
1066 /// Cleans a name making it conform to Zip file conventions.
1067 /// Devices names ('c:\') and UNC share names ('\\server\share') are removed
1068 /// and forward slashes ('\') are converted to back slashes ('/').
1069 /// Names are made relative by trimming leading slashes which is compatible
1070 /// with the ZIP naming convention.
1072 /// <param name="name">The name to clean</param>
1073 /// <returns>The 'cleaned' name.</returns>
1075 /// The <seealso cref="ZipNameTransform">Zip name transform</seealso> class is more flexible.
1077 public static string CleanName(string name)
1080 return string.Empty;
1083 if (Path.IsPathRooted(name) == true) {
1085 // for UNC names... \\machine\share\zoom\beet.txt gives \zoom\beet.txt
1086 name = name.Substring(Path.GetPathRoot(name).Length);
1089 name = name.Replace(@"\", "/");
1091 while ( (name.Length > 0) && (name[0] == '/')) {
1092 name = name.Remove(0, 1);
1097 #region Instance Fields
1099 int externalFileAttributes = -1; // contains external attributes (O/S dependant)
1101 ushort versionMadeBy; // Contains host system and version information
1102 // only relevant for central header entries
1106 ulong compressedSize;
1107 ushort versionToExtract; // Version required to extract (library handles <= 2.0)
1111 CompressionMethod method = CompressionMethod.Deflated;
1115 int flags; // general purpose bit flags
1117 long zipFileIndex = -1; // used by ZipFile
1118 long offset; // used by ZipFile and ZipOutputStream
1121 byte cryptoCheckValue_;