2 Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
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
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. */
39 package java.util.zip;
41 import java.util.Calendar;
44 * This class represents a member of a zip archive. ZipFile and
45 * ZipInputStream will give you instances of this class as information
46 * about the members in an archive. On the other hand ZipOutputStream
47 * needs an instance of this class to create a new member.
49 * @author Jochen Hoenicke
51 public class ZipEntry implements ZipConstants, Cloneable
53 private static final int KNOWN_SIZE = 1;
54 private static final int KNOWN_CSIZE = 2;
55 private static final int KNOWN_CRC = 4;
56 private static final int KNOWN_TIME = 8;
57 private static final int KNOWN_EXTRA = 16;
59 private static Calendar cal;
63 private long compressedSize = -1;
66 private short known = 0;
67 private short method = -1;
68 private byte[] extra = null;
69 private String comment = null;
71 int flags; /* used by ZipOutputStream */
72 int offset; /* used by ZipFile and ZipOutputStream */
75 * Compression method. This method doesn't compress at all.
77 public static final int STORED = 0;
79 * Compression method. This method uses the Deflater.
81 public static final int DEFLATED = 8;
84 * Creates a zip entry with the given name.
85 * @param name the name. May include directory components separated
88 * @exception NullPointerException when name is null.
89 * @exception IllegalArgumentException when name is bigger then 65535 chars.
91 public ZipEntry(String name)
93 int length = name.length();
95 throw new IllegalArgumentException("name length is " + length);
100 * Creates a copy of the given zip entry.
101 * @param e the entry to copy.
103 public ZipEntry(ZipEntry e)
108 ZipEntry(ZipEntry e, String name)
113 compressedSize = e.compressedSize;
121 final void setDOSTime(int dostime)
123 this.dostime = dostime;
127 final int getDOSTime()
129 if ((known & KNOWN_TIME) == 0)
136 * Creates a copy of this zip entry.
141 public Object clone()
145 // The JCL says that the `extra' field is also copied.
146 ZipEntry clone = (ZipEntry) super.clone();
148 clone.extra = (byte[]) extra.clone();
151 catch (CloneNotSupportedException ex)
153 throw new InternalError();
158 * Returns the entry name. The path components in the entry are
159 * always separated by slashes ('/').
161 public String getName()
167 * Sets the time of last modification of the entry.
168 * @time the time of last modification of the entry.
170 public void setTime(long time)
172 Calendar cal = getCalendar();
175 cal.setTimeInMillis(time);
176 dostime = (cal.get(Calendar.YEAR) - 1980 & 0x7f) << 25
177 | (cal.get(Calendar.MONTH) + 1) << 21
178 | (cal.get(Calendar.DAY_OF_MONTH)) << 16
179 | (cal.get(Calendar.HOUR_OF_DAY)) << 11
180 | (cal.get(Calendar.MINUTE)) << 5
181 | (cal.get(Calendar.SECOND)) >> 1;
183 this.known |= KNOWN_TIME;
187 * Gets the time of last modification of the entry.
188 * @return the time of last modification of the entry, or -1 if unknown.
190 public long getTime()
192 // The extra bytes might contain the time (posix/unix extension)
195 if ((known & KNOWN_TIME) == 0)
198 int sec = 2 * (dostime & 0x1f);
199 int min = (dostime >> 5) & 0x3f;
200 int hrs = (dostime >> 11) & 0x1f;
201 int day = (dostime >> 16) & 0x1f;
202 int mon = ((dostime >> 21) & 0xf) - 1;
203 int year = ((dostime >> 25) & 0x7f) + 1980; /* since 1900 */
210 cal.set(year, mon, day, hrs, min, sec);
211 return cal.getTimeInMillis();
214 catch (RuntimeException ex)
216 /* Ignore illegal time stamp */
217 known &= ~KNOWN_TIME;
222 private static synchronized Calendar getCalendar()
225 cal = Calendar.getInstance();
231 * Sets the size of the uncompressed data.
232 * @exception IllegalArgumentException if size is not in 0..0xffffffffL
234 public void setSize(long size)
236 if ((size & 0xffffffff00000000L) != 0)
237 throw new IllegalArgumentException();
238 this.size = (int) size;
239 this.known |= KNOWN_SIZE;
243 * Gets the size of the uncompressed data.
244 * @return the size or -1 if unknown.
246 public long getSize()
248 return (known & KNOWN_SIZE) != 0 ? size & 0xffffffffL : -1L;
252 * Sets the size of the compressed data.
254 public void setCompressedSize(long csize)
256 this.compressedSize = csize;
260 * Gets the size of the compressed data.
261 * @return the size or -1 if unknown.
263 public long getCompressedSize()
265 return compressedSize;
269 * Sets the crc of the uncompressed data.
270 * @exception IllegalArgumentException if crc is not in 0..0xffffffffL
272 public void setCrc(long crc)
274 if ((crc & 0xffffffff00000000L) != 0)
275 throw new IllegalArgumentException();
276 this.crc = (int) crc;
277 this.known |= KNOWN_CRC;
281 * Gets the crc of the uncompressed data.
282 * @return the crc or -1 if unknown.
286 return (known & KNOWN_CRC) != 0 ? crc & 0xffffffffL : -1L;
290 * Sets the compression method. Only DEFLATED and STORED are
292 * @exception IllegalArgumentException if method is not supported.
293 * @see ZipOutputStream#DEFLATED
294 * @see ZipOutputStream#STORED
296 public void setMethod(int method)
298 if (method != ZipOutputStream.STORED
299 && method != ZipOutputStream.DEFLATED)
300 throw new IllegalArgumentException();
301 this.method = (short) method;
305 * Gets the compression method.
306 * @return the compression method or -1 if unknown.
308 public int getMethod()
314 * Sets the extra data.
315 * @exception IllegalArgumentException if extra is longer than 0xffff bytes.
317 public void setExtra(byte[] extra)
324 if (extra.length > 0xffff)
325 throw new IllegalArgumentException();
329 private void parseExtra()
332 if ((known & KNOWN_EXTRA) != 0)
337 known |= KNOWN_EXTRA;
344 while (pos < extra.length)
346 int sig = (extra[pos++] & 0xff)
347 | (extra[pos++] & 0xff) << 8;
348 int len = (extra[pos++] & 0xff)
349 | (extra[pos++] & 0xff) << 8;
352 /* extended time stamp */
353 int flags = extra[pos];
354 if ((flags & 1) != 0)
356 long time = ((extra[pos+1] & 0xff)
357 | (extra[pos+2] & 0xff) << 8
358 | (extra[pos+3] & 0xff) << 16
359 | (extra[pos+4] & 0xff) << 24);
366 catch (ArrayIndexOutOfBoundsException ex)
371 known |= KNOWN_EXTRA;
376 * Gets the extra data.
377 * @return the extra data or null if not set.
379 public byte[] getExtra()
385 * Sets the entry comment.
386 * @exception IllegalArgumentException if comment is longer than 0xffff.
388 public void setComment(String comment)
390 if (comment != null && comment.length() > 0xffff)
391 throw new IllegalArgumentException();
392 this.comment = comment;
397 * @return the comment or null if not set.
399 public String getComment()
405 * Gets true, if the entry is a directory. This is solely
406 * determined by the name, a trailing slash '/' marks a directory.
408 public boolean isDirectory()
410 int nlen = name.length();
411 return nlen > 0 && name.charAt(nlen - 1) == '/';
415 * Gets the string representation of this ZipEntry. This is just
416 * the name as returned by getName().
418 public String toString()
424 * Gets the hashCode of this ZipEntry. This is just the hashCode
425 * of the name. Note that the equals method isn't changed, though.
427 public int hashCode()
429 return name.hashCode();