FSF GCC merge 02/23/03
[official-gcc.git] / libjava / java / util / zip / ZipEntry.java
blob5284d793f6c01635a0e50a5a639212eb30d0bb1e
1 /* java.util.zip.ZipEntry
2 Copyright (C) 2001, 2002 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)
9 any later version.
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., 59 Temple Place, Suite 330, Boston, MA
19 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.
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 package java.util.zip;
39 import java.util.Calendar;
40 import java.util.TimeZone;
41 import java.util.Date;
43 /**
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 int KNOWN_SIZE = 1;
54 private static int KNOWN_CSIZE = 2;
55 private static int KNOWN_CRC = 4;
56 private static int KNOWN_TIME = 8;
58 private static Calendar cal;
60 private String name;
61 private int size;
62 private int compressedSize;
63 private int crc;
64 private int dostime;
65 private short known = 0;
66 private short method = -1;
67 private byte[] extra = null;
68 private String comment = null;
70 int flags; /* used by ZipOutputStream */
71 int offset; /* used by ZipFile and ZipOutputStream */
74 /**
75 * Compression method. This method doesn't compress at all.
77 public final static int STORED = 0;
78 /**
79 * Compression method. This method uses the Deflater.
81 public final static int DEFLATED = 8;
83 /**
84 * Creates a zip entry with the given name.
85 * @param name the name. May include directory components separated
86 * by '/'.
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();
94 if (length > 65535)
95 throw new IllegalArgumentException("name length is " + length);
96 this.name = name;
99 /**
100 * Creates a copy of the given zip entry.
101 * @param e the entry to copy.
103 public ZipEntry(ZipEntry e)
105 name = e.name;
106 known = e.known;
107 size = e.size;
108 compressedSize = e.compressedSize;
109 crc = e.crc;
110 dostime = e.dostime;
111 method = e.method;
112 extra = e.extra;
113 comment = e.comment;
116 final void setDOSTime(int dostime)
118 this.dostime = dostime;
119 known |= KNOWN_TIME;
122 final int getDOSTime()
124 if ((known & KNOWN_TIME) == 0)
125 return 0;
126 else
127 return dostime;
131 * Creates a copy of this zip entry.
134 * Clones the entry.
136 public Object clone()
140 // The JCL says that the `extra' field is also copied.
141 ZipEntry clone = (ZipEntry) super.clone();
142 if (extra != null)
143 clone.extra = (byte[]) extra.clone();
144 return clone;
146 catch (CloneNotSupportedException ex)
148 throw new InternalError();
153 * Returns the entry name. The path components in the entry are
154 * always separated by slashes ('/').
156 public String getName()
158 return name;
162 * Sets the time of last modification of the entry.
163 * @time the time of last modification of the entry.
165 public void setTime(long time)
167 Calendar cal = getCalendar();
168 synchronized (cal)
170 cal.setTime(new Date(time*1000L));
171 dostime = (cal.get(cal.YEAR) - 1980 & 0x7f) << 25
172 | (cal.get(cal.MONTH) + 1) << 21
173 | (cal.get(cal.DAY_OF_MONTH)) << 16
174 | (cal.get(cal.HOUR_OF_DAY)) << 11
175 | (cal.get(cal.MINUTE)) << 5
176 | (cal.get(cal.SECOND)) >> 1;
178 dostime = (int) (dostime / 1000L);
179 this.known |= KNOWN_TIME;
183 * Gets the time of last modification of the entry.
184 * @return the time of last modification of the entry, or -1 if unknown.
186 public long getTime()
188 if ((known & KNOWN_TIME) == 0)
189 return -1;
191 int sec = 2 * (dostime & 0x1f);
192 int min = (dostime >> 5) & 0x3f;
193 int hrs = (dostime >> 11) & 0x1f;
194 int day = (dostime >> 16) & 0x1f;
195 int mon = ((dostime >> 21) & 0xf) - 1;
196 int year = ((dostime >> 25) & 0x7f) + 1980; /* since 1900 */
200 cal = getCalendar();
201 synchronized (cal)
203 cal.set(year, mon, day, hrs, min, sec);
204 return cal.getTime().getTime();
207 catch (RuntimeException ex)
209 /* Ignore illegal time stamp */
210 known &= ~KNOWN_TIME;
211 return -1;
215 private static synchronized Calendar getCalendar()
217 if (cal == null)
218 cal = Calendar.getInstance();
220 return cal;
224 * Sets the size of the uncompressed data.
225 * @exception IllegalArgumentException if size is not in 0..0xffffffffL
227 public void setSize(long size)
229 if ((size & 0xffffffff00000000L) != 0)
230 throw new IllegalArgumentException();
231 this.size = (int) size;
232 this.known |= KNOWN_SIZE;
236 * Gets the size of the uncompressed data.
237 * @return the size or -1 if unknown.
239 public long getSize()
241 return (known & KNOWN_SIZE) != 0 ? size & 0xffffffffL : -1L;
245 * Sets the size of the compressed data.
246 * @exception IllegalArgumentException if size is not in 0..0xffffffffL
248 public void setCompressedSize(long csize)
250 if ((csize & 0xffffffff00000000L) != 0)
251 throw new IllegalArgumentException();
252 this.compressedSize = (int) csize;
253 this.known |= KNOWN_CSIZE;
257 * Gets the size of the compressed data.
258 * @return the size or -1 if unknown.
260 public long getCompressedSize()
262 return (known & KNOWN_CSIZE) != 0 ? compressedSize & 0xffffffffL : -1L;
266 * Sets the crc of the uncompressed data.
267 * @exception IllegalArgumentException if crc is not in 0..0xffffffffL
269 public void setCrc(long crc)
271 if ((crc & 0xffffffff00000000L) != 0)
272 throw new IllegalArgumentException();
273 this.crc = (int) crc;
274 this.known |= KNOWN_CRC;
278 * Gets the crc of the uncompressed data.
279 * @return the crc or -1 if unknown.
281 public long getCrc()
283 return (known & KNOWN_CRC) != 0 ? crc & 0xffffffffL : -1L;
287 * Sets the compression method. Only DEFLATED and STORED are
288 * supported.
289 * @exception IllegalArgumentException if method is not supported.
290 * @see ZipOutputStream#DEFLATED
291 * @see ZipOutputStream#STORED
293 public void setMethod(int method)
295 if (method != ZipOutputStream.STORED
296 && method != ZipOutputStream.DEFLATED)
297 throw new IllegalArgumentException();
298 this.method = (short) method;
302 * Gets the compression method.
303 * @return the compression method or -1 if unknown.
305 public int getMethod()
307 return method;
311 * Sets the extra data.
312 * @exception IllegalArgumentException if extra is longer than 0xffff bytes.
314 public void setExtra(byte[] extra)
316 if (extra == null)
318 this.extra = null;
319 return;
322 if (extra.length > 0xffff)
323 throw new IllegalArgumentException();
324 this.extra = extra;
327 int pos = 0;
328 while (pos < extra.length)
330 int sig = (extra[pos++] & 0xff)
331 | (extra[pos++] & 0xff) << 8;
332 int len = (extra[pos++] & 0xff)
333 | (extra[pos++] & 0xff) << 8;
334 if (sig == 0x5455)
336 /* extended time stamp */
337 int flags = extra[pos];
338 if ((flags & 1) != 0)
340 long time = ((extra[pos+1] & 0xff)
341 | (extra[pos+2] & 0xff) << 8
342 | (extra[pos+3] & 0xff) << 16
343 | (extra[pos+4] & 0xff) << 24);
344 setTime(time);
347 pos += len;
350 catch (ArrayIndexOutOfBoundsException ex)
352 /* be lenient */
353 return;
358 * Gets the extra data.
359 * @return the extra data or null if not set.
361 public byte[] getExtra()
363 return extra;
367 * Sets the entry comment.
368 * @exception IllegalArgumentException if comment is longer than 0xffff.
370 public void setComment(String comment)
372 if (comment != null && comment.length() > 0xffff)
373 throw new IllegalArgumentException();
374 this.comment = comment;
378 * Gets the comment.
379 * @return the comment or null if not set.
381 public String getComment()
383 return comment;
387 * Gets true, if the entry is a directory. This is solely
388 * determined by the name, a trailing slash '/' marks a directory.
390 public boolean isDirectory()
392 int nlen = name.length();
393 return nlen > 0 && name.charAt(nlen - 1) == '/';
397 * Gets the string representation of this ZipEntry. This is just
398 * the name as returned by getName().
400 public String toString()
402 return name;
406 * Gets the hashCode of this ZipEntry. This is just the hashCode
407 * of the name. Note that the equals method isn't changed, though.
409 public int hashCode()
411 return name.hashCode();