**** Merged from MCS ****
[mono-project.git] / mcs / class / ICSharpCode.SharpZipLib / ICSharpCode.SharpZipLib / Zip / ZipEntry.cs
blob1cb65df10a5ec8bf189a4a7a5a04d861e2d4454c
1 // ZipEntry.cs
2 // Copyright (C) 2001 Mike Krueger
3 //
4 // This file was translated from java, it was part of the GNU Classpath
5 // Copyright (C) 2001 Free Software Foundation, Inc.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 // Linking this library statically or dynamically with other modules is
22 // making a combined work based on this library. Thus, the terms and
23 // conditions of the GNU General Public License cover the whole
24 // combination.
25 //
26 // As a special exception, the copyright holders of this library give you
27 // permission to link this library with independent modules to produce an
28 // executable, regardless of the license terms of these independent
29 // modules, and to copy and distribute the resulting executable under
30 // terms of your choice, provided that you also meet, for each linked
31 // independent module, the terms and conditions of the license of that
32 // module. An independent module is a module which is not derived from
33 // or based on this library. If you modify this library, you may extend
34 // this exception to your version of the library, but you are not
35 // obligated to do so. If you do not wish to do so, delete this
36 // exception statement from your version.
38 using System;
40 namespace ICSharpCode.SharpZipLib.Zip
43 public enum CompressionMethod
45 Stored = 0,
46 Deflated = 8,
49 /// <summary>
50 /// This class represents a member of a zip archive. ZipFile and
51 /// ZipInputStream will give you instances of this class as information
52 /// about the members in an archive. On the other hand ZipOutputStream
53 /// needs an instance of this class to create a new member.
54 ///
55 /// author of the original java version : Jochen Hoenicke
56 /// </summary>
57 public class ZipEntry : ICloneable
59 static int KNOWN_SIZE = 1;
60 static int KNOWN_CSIZE = 2;
61 static int KNOWN_CRC = 4;
62 static int KNOWN_TIME = 8;
64 string name;
65 uint size;
66 ushort version;
67 uint compressedSize;
68 uint crc;
69 uint dosTime;
71 ushort known = 0;
72 CompressionMethod method = CompressionMethod.Deflated;
73 byte[] extra = null;
74 string comment = null;
75 bool isCrypted;
77 int zipFileIndex = -1; /* used by ZipFile */
78 int flags; /* used by ZipOutputStream */
79 int offset; /* used by ZipFile and ZipOutputStream */
81 public bool IsEncrypted {
82 get {
83 return (flags & 1) != 0;
85 set {
86 if (value) {
87 flags |= 1;
88 } else {
89 flags &= ~1;
94 public int ZipFileIndex {
95 get {
96 return zipFileIndex;
98 set {
99 zipFileIndex = value;
103 public int Offset {
104 get {
105 return offset;
107 set {
108 offset = value;
112 public int Flags { // Stops having two things represent same concept in class (flag isCrypted removed)
113 get {
114 return flags;
116 set {
117 flags = value;
122 /// <summary>
123 /// Creates a zip entry with the given name.
124 /// </summary>
125 /// <param name="name">
126 /// the name. May include directory components separated by '/'.
127 /// </param>
128 public ZipEntry(string name)
130 if (name == null) {
131 throw new System.ArgumentNullException("name");
133 this.DateTime = System.DateTime.Now;
134 this.name = name;
137 /// <summary>
138 /// Creates a copy of the given zip entry.
139 /// </summary>
140 /// <param name="e">
141 /// the entry to copy.
142 /// </param>
143 public ZipEntry(ZipEntry e)
145 name = e.name;
146 known = e.known;
147 size = e.size;
148 compressedSize = e.compressedSize;
149 crc = e.crc;
150 dosTime = e.dosTime;
151 method = e.method;
152 extra = e.extra;
153 comment = e.comment;
156 public int Version {
157 get {
158 return version;
160 set {
161 version = (ushort)value;
165 public long DosTime {
166 get {
167 if ((known & KNOWN_TIME) == 0) {
168 return 0;
169 } else {
170 return dosTime;
173 set {
174 this.dosTime = (uint)value;
175 known |= (ushort)KNOWN_TIME;
180 /// <summary>
181 /// Gets/Sets the time of last modification of the entry.
182 /// </summary>
183 public DateTime DateTime {
184 get {
185 uint sec = 2 * (dosTime & 0x1f);
186 uint min = (dosTime >> 5) & 0x3f;
187 uint hrs = (dosTime >> 11) & 0x1f;
188 uint day = (dosTime >> 16) & 0x1f;
189 uint mon = ((dosTime >> 21) & 0xf);
190 uint year = ((dosTime >> 25) & 0x7f) + 1980; /* since 1900 */
191 return new System.DateTime((int)year, (int)mon, (int)day, (int)hrs, (int)min, (int)sec);
193 set {
194 DosTime = ((uint)value.Year - 1980 & 0x7f) << 25 |
195 ((uint)value.Month) << 21 |
196 ((uint)value.Day) << 16 |
197 ((uint)value.Hour) << 11 |
198 ((uint)value.Minute) << 5 |
199 ((uint)value.Second) >> 1;
203 /// <summary>
204 /// Returns the entry name. The path components in the entry are
205 /// always separated by slashes ('/').
206 /// </summary>
207 public string Name {
208 get {
209 return name;
213 // /// <summary>
214 // /// Gets/Sets the time of last modification of the entry.
215 // /// </summary>
216 // /// <returns>
217 // /// the time of last modification of the entry, or -1 if unknown.
218 // /// </returns>
219 // public long Time {
220 // get {
221 // return (known & KNOWN_TIME) != 0 ? time * 1000L : -1;
222 // }
223 // set {
224 // this.time = (int) (value / 1000L);
225 // this.known |= (ushort)KNOWN_TIME;
226 // }
227 // }
229 /// <summary>
230 /// Gets/Sets the size of the uncompressed data.
231 /// </summary>
232 /// <exception cref="System.ArgumentOutOfRangeException">
233 /// if size is not in 0..0xffffffffL
234 /// </exception>
235 /// <returns>
236 /// the size or -1 if unknown.
237 /// </returns>
238 public long Size {
239 get {
240 return (known & KNOWN_SIZE) != 0 ? (long)size : -1L;
242 set {
243 if (((ulong)value & 0xFFFFFFFF00000000L) != 0) {
244 throw new ArgumentOutOfRangeException("size");
246 this.size = (uint)value;
247 this.known |= (ushort)KNOWN_SIZE;
251 /// <summary>
252 /// Gets/Sets the size of the compressed data.
253 /// </summary>
254 /// <exception cref="System.ArgumentOutOfRangeException">
255 /// if csize is not in 0..0xffffffffL
256 /// </exception>
257 /// <returns>
258 /// the size or -1 if unknown.
259 /// </returns>
260 public long CompressedSize {
261 get {
262 return (known & KNOWN_CSIZE) != 0 ? (long)compressedSize : -1L;
264 set {
265 if (((ulong)value & 0xffffffff00000000L) != 0) {
266 throw new ArgumentOutOfRangeException();
268 this.compressedSize = (uint)value;
269 this.known |= (ushort)KNOWN_CSIZE;
273 /// <summary>
274 /// Gets/Sets the crc of the uncompressed data.
275 /// </summary>
276 /// <exception cref="System.ArgumentOutOfRangeException">
277 /// if crc is not in 0..0xffffffffL
278 /// </exception>
279 /// <returns>
280 /// the crc or -1 if unknown.
281 /// </returns>
282 public long Crc {
283 get {
284 return (known & KNOWN_CRC) != 0 ? crc & 0xffffffffL : -1L;
286 set {
287 if (((ulong)crc & 0xffffffff00000000L) != 0)
289 throw new Exception();
291 this.crc = (uint)value;
292 this.known |= (ushort)KNOWN_CRC;
296 /// <summary>
297 /// Gets/Sets the compression method. Only DEFLATED and STORED are supported.
298 /// </summary>
299 /// <exception cref="System.ArgumentOutOfRangeException">
300 /// if method is not supported.
301 /// </exception>
302 /// <returns>
303 /// the compression method or -1 if unknown.
304 /// </returns>
305 /// <see cref="ZipOutputStream.DEFLATED"/>
306 /// <see cref="ZipOutputStream.STORED"/>
307 public CompressionMethod CompressionMethod {
308 get {
309 return method;
311 set {
312 this.method = value;
316 /// <summary>
317 /// Gets/Sets the extra data.
318 /// </summary>
319 /// <exception cref="System.ArgumentOutOfRangeException">
320 /// if extra is longer than 0xffff bytes.
321 /// </exception>
322 /// <returns>
323 /// the extra data or null if not set.
324 /// </returns>
325 public byte[] ExtraData {
326 get {
327 return extra;
329 set {
330 if (value == null) {
331 this.extra = null;
332 return;
335 if (value.Length > 0xffff) {
336 throw new System.ArgumentOutOfRangeException();
338 this.extra = value;
339 try {
340 int pos = 0;
341 while (pos < extra.Length) {
342 int sig = (extra[pos++] & 0xff) | (extra[pos++] & 0xff) << 8;
343 int len = (extra[pos++] & 0xff) | (extra[pos++] & 0xff) << 8;
344 if (sig == 0x5455) {
345 /* extended time stamp, unix format by Rainer Prem <Rainer@Prem.de> */
346 int flags = extra[pos];
347 if ((flags & 1) != 0) {
348 int iTime = ((extra[pos+1] & 0xff) |
349 (extra[pos+2] & 0xff) << 8 |
350 (extra[pos+3] & 0xff) << 16 |
351 (extra[pos+4] & 0xff) << 24);
353 DateTime = (new DateTime ( 1970, 1, 1, 0, 0, 0 ) + new TimeSpan ( 0, 0, 0, iTime, 0 )).ToLocalTime ();
354 known |= (ushort)KNOWN_TIME;
357 pos += len;
359 } catch (Exception) {
360 /* be lenient */
361 return;
366 /// <summary>
367 /// Gets/Sets the entry comment.
368 /// </summary>
369 /// <exception cref="System.ArgumentOutOfRangeException">
370 /// if comment is longer than 0xffff.
371 /// </exception>
372 /// <returns>
373 /// the comment or null if not set.
374 /// </returns>
375 public string Comment {
376 get {
377 return comment;
379 set {
380 if (value.Length > 0xffff)
382 throw new ArgumentOutOfRangeException();
384 this.comment = value;
388 /// <summary>
389 /// Gets true, if the entry is a directory. This is solely
390 /// determined by the name, a trailing slash '/' marks a directory.
391 /// </summary>
392 public bool IsDirectory {
393 get {
394 int nlen = name.Length;
395 return nlen > 0 && name[nlen - 1] == '/';
399 /// <value>
400 /// True, if the entry is encrypted.
401 /// </value>
402 public bool IsCrypted {
403 get {
404 return isCrypted;
406 set {
407 isCrypted = value;
411 /// <summary>
412 /// Creates a copy of this zip entry.
413 /// </summary>
414 public object Clone()
416 return this.MemberwiseClone();
419 /// <summary>
420 /// Gets the string representation of this ZipEntry. This is just
421 /// the name as returned by getName().
422 /// </summary>
423 public override string ToString()
425 return name;