blob: bcc27e63a0fceaf6c71b69ea06d063d8fda6d35d [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1995-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package java.util.zip;
27
28import java.util.Date;
29
30/**
31 * This class is used to represent a ZIP file entry.
32 *
33 * @author David Connelly
34 */
35public
36class ZipEntry implements ZipConstants, Cloneable {
37 String name; // entry name
38 long time = -1; // modification time (in DOS time)
39 long crc = -1; // crc-32 of entry data
40 long size = -1; // uncompressed size of entry data
41 long csize = -1; // compressed size of entry data
42 int method = -1; // compression method
43 byte[] extra; // optional extra field data for entry
44 String comment; // optional comment string for entry
45
46 /**
47 * Compression method for uncompressed entries.
48 */
49 public static final int STORED = 0;
50
51 /**
52 * Compression method for compressed (deflated) entries.
53 */
54 public static final int DEFLATED = 8;
55
56 static {
57 /* Zip library is loaded from System.initializeSystemClass */
58 initIDs();
59 }
60
61 private static native void initIDs();
62
63 /**
64 * Creates a new zip entry with the specified name.
65 *
66 * @param name the entry name
67 * @exception NullPointerException if the entry name is null
68 * @exception IllegalArgumentException if the entry name is longer than
69 * 0xFFFF bytes
70 */
71 public ZipEntry(String name) {
72 if (name == null) {
73 throw new NullPointerException();
74 }
75 if (name.length() > 0xFFFF) {
76 throw new IllegalArgumentException("entry name too long");
77 }
78 this.name = name;
79 }
80
81 /**
82 * Creates a new zip entry with fields taken from the specified
83 * zip entry.
84 * @param e a zip Entry object
85 */
86 public ZipEntry(ZipEntry e) {
87 name = e.name;
88 time = e.time;
89 crc = e.crc;
90 size = e.size;
91 csize = e.csize;
92 method = e.method;
93 extra = e.extra;
94 comment = e.comment;
95 }
96
97 /*
98 * Creates a new zip entry for the given name with fields initialized
99 * from the specified jzentry data.
100 */
101 ZipEntry(String name, long jzentry) {
102 this.name = name;
103 initFields(jzentry);
104 }
105
106 private native void initFields(long jzentry);
107
108 /*
109 * Creates a new zip entry with fields initialized from the specified
110 * jzentry data.
111 */
112 ZipEntry(long jzentry) {
113 initFields(jzentry);
114 }
115
116 /**
117 * Returns the name of the entry.
118 * @return the name of the entry
119 */
120 public String getName() {
121 return name;
122 }
123
124 /**
125 * Sets the modification time of the entry.
126 * @param time the entry modification time in number of milliseconds
127 * since the epoch
128 * @see #getTime()
129 */
130 public void setTime(long time) {
131 this.time = javaToDosTime(time);
132 }
133
134 /**
135 * Returns the modification time of the entry, or -1 if not specified.
136 * @return the modification time of the entry, or -1 if not specified
137 * @see #setTime(long)
138 */
139 public long getTime() {
140 return time != -1 ? dosToJavaTime(time) : -1;
141 }
142
143 /**
144 * Sets the uncompressed size of the entry data.
145 * @param size the uncompressed size in bytes
146 * @exception IllegalArgumentException if the specified size is less
147 * than 0 or greater than 0xFFFFFFFF bytes
148 * @see #getSize()
149 */
150 public void setSize(long size) {
151 if (size < 0 || size > 0xFFFFFFFFL) {
152 throw new IllegalArgumentException("invalid entry size");
153 }
154 this.size = size;
155 }
156
157 /**
158 * Returns the uncompressed size of the entry data, or -1 if not known.
159 * @return the uncompressed size of the entry data, or -1 if not known
160 * @see #setSize(long)
161 */
162 public long getSize() {
163 return size;
164 }
165
166 /**
167 * Returns the size of the compressed entry data, or -1 if not known.
168 * In the case of a stored entry, the compressed size will be the same
169 * as the uncompressed size of the entry.
170 * @return the size of the compressed entry data, or -1 if not known
171 * @see #setCompressedSize(long)
172 */
173 public long getCompressedSize() {
174 return csize;
175 }
176
177 /**
178 * Sets the size of the compressed entry data.
179 * @param csize the compressed size to set to
180 * @see #getCompressedSize()
181 */
182 public void setCompressedSize(long csize) {
183 this.csize = csize;
184 }
185
186 /**
187 * Sets the CRC-32 checksum of the uncompressed entry data.
188 * @param crc the CRC-32 value
189 * @exception IllegalArgumentException if the specified CRC-32 value is
190 * less than 0 or greater than 0xFFFFFFFF
191 * @see #getCrc()
192 */
193 public void setCrc(long crc) {
194 if (crc < 0 || crc > 0xFFFFFFFFL) {
195 throw new IllegalArgumentException("invalid entry crc-32");
196 }
197 this.crc = crc;
198 }
199
200 /**
201 * Returns the CRC-32 checksum of the uncompressed entry data, or -1 if
202 * not known.
203 * @return the CRC-32 checksum of the uncompressed entry data, or -1 if
204 * not known
205 * @see #setCrc(long)
206 */
207 public long getCrc() {
208 return crc;
209 }
210
211 /**
212 * Sets the compression method for the entry.
213 * @param method the compression method, either STORED or DEFLATED
214 * @exception IllegalArgumentException if the specified compression
215 * method is invalid
216 * @see #getMethod()
217 */
218 public void setMethod(int method) {
219 if (method != STORED && method != DEFLATED) {
220 throw new IllegalArgumentException("invalid compression method");
221 }
222 this.method = method;
223 }
224
225 /**
226 * Returns the compression method of the entry, or -1 if not specified.
227 * @return the compression method of the entry, or -1 if not specified
228 * @see #setMethod(int)
229 */
230 public int getMethod() {
231 return method;
232 }
233
234 /**
235 * Sets the optional extra field data for the entry.
236 * @param extra the extra field data bytes
237 * @exception IllegalArgumentException if the length of the specified
238 * extra field data is greater than 0xFFFF bytes
239 * @see #getExtra()
240 */
241 public void setExtra(byte[] extra) {
242 if (extra != null && extra.length > 0xFFFF) {
243 throw new IllegalArgumentException("invalid extra field length");
244 }
245 this.extra = extra;
246 }
247
248 /**
249 * Returns the extra field data for the entry, or null if none.
250 * @return the extra field data for the entry, or null if none
251 * @see #setExtra(byte[])
252 */
253 public byte[] getExtra() {
254 return extra;
255 }
256
257 /**
258 * Sets the optional comment string for the entry.
259 * @param comment the comment string
260 * @exception IllegalArgumentException if the length of the specified
261 * comment string is greater than 0xFFFF bytes
262 * @see #getComment()
263 */
264 public void setComment(String comment) {
265 if (comment != null && comment.length() > 0xffff/3
266 && ZipOutputStream.getUTF8Length(comment) > 0xffff) {
267 throw new IllegalArgumentException("invalid entry comment length");
268 }
269 this.comment = comment;
270 }
271
272 /**
273 * Returns the comment string for the entry, or null if none.
274 * @return the comment string for the entry, or null if none
275 * @see #setComment(String)
276 */
277 public String getComment() {
278 return comment;
279 }
280
281 /**
282 * Returns true if this is a directory entry. A directory entry is
283 * defined to be one whose name ends with a '/'.
284 * @return true if this is a directory entry
285 */
286 public boolean isDirectory() {
287 return name.endsWith("/");
288 }
289
290 /**
291 * Returns a string representation of the ZIP entry.
292 */
293 public String toString() {
294 return getName();
295 }
296
297 /*
298 * Converts DOS time to Java time (number of milliseconds since epoch).
299 */
300 private static long dosToJavaTime(long dtime) {
301 Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
302 (int)(((dtime >> 21) & 0x0f) - 1),
303 (int)((dtime >> 16) & 0x1f),
304 (int)((dtime >> 11) & 0x1f),
305 (int)((dtime >> 5) & 0x3f),
306 (int)((dtime << 1) & 0x3e));
307 return d.getTime();
308 }
309
310 /*
311 * Converts Java time to DOS time.
312 */
313 private static long javaToDosTime(long time) {
314 Date d = new Date(time);
315 int year = d.getYear() + 1900;
316 if (year < 1980) {
317 return (1 << 21) | (1 << 16);
318 }
319 return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
320 d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
321 d.getSeconds() >> 1;
322 }
323
324 /**
325 * Returns the hash code value for this entry.
326 */
327 public int hashCode() {
328 return name.hashCode();
329 }
330
331 /**
332 * Returns a copy of this entry.
333 */
334 public Object clone() {
335 try {
336 ZipEntry e = (ZipEntry)super.clone();
337 e.extra = (extra == null) ? null : extra.clone();
338 return e;
339 } catch (CloneNotSupportedException e) {
340 // This should never happen, since we are Cloneable
341 throw new InternalError();
342 }
343 }
344}