1:
37:
38:
39: package ;
40:
41: import ;
42:
43:
51: public class ZipEntry implements ZipConstants, Cloneable
52: {
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;
58:
59: private static Calendar cal;
60:
61: private String name;
62: private int size;
63: private long compressedSize = -1;
64: private int crc;
65: private int dostime;
66: private short known = 0;
67: private short method = -1;
68: private byte[] extra = null;
69: private String comment = null;
70:
71: int flags;
72: int offset;
73:
74:
77: public static final int STORED = 0;
78:
81: public static final int DEFLATED = 8;
82:
83:
91: public ZipEntry(String name)
92: {
93: int length = name.length();
94: if (length > 65535)
95: throw new IllegalArgumentException("name length is " + length);
96: this.name = name;
97: }
98:
99:
103: public ZipEntry(ZipEntry e)
104: {
105: this(e, e.name);
106: }
107:
108: ZipEntry(ZipEntry e, String name)
109: {
110: this.name = name;
111: known = e.known;
112: size = e.size;
113: compressedSize = e.compressedSize;
114: crc = e.crc;
115: dostime = e.dostime;
116: method = e.method;
117: extra = e.extra;
118: comment = e.comment;
119: }
120:
121: final void setDOSTime(int dostime)
122: {
123: this.dostime = dostime;
124: known |= KNOWN_TIME;
125: }
126:
127: final int getDOSTime()
128: {
129: if ((known & KNOWN_TIME) == 0)
130: return 0;
131: else
132: return dostime;
133: }
134:
135:
138:
141: public Object clone()
142: {
143: try
144: {
145:
146: ZipEntry clone = (ZipEntry) super.clone();
147: if (extra != null)
148: clone.extra = (byte[]) extra.clone();
149: return clone;
150: }
151: catch (CloneNotSupportedException ex)
152: {
153: throw new InternalError();
154: }
155: }
156:
157:
161: public String getName()
162: {
163: return name;
164: }
165:
166:
170: public void setTime(long time)
171: {
172: Calendar cal = getCalendar();
173: synchronized (cal)
174: {
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;
182: }
183: this.known |= KNOWN_TIME;
184: }
185:
186:
190: public long getTime()
191: {
192:
193: parseExtra();
194:
195: if ((known & KNOWN_TIME) == 0)
196: return -1;
197:
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;
204:
205: try
206: {
207: cal = getCalendar();
208: synchronized (cal)
209: {
210: cal.set(year, mon, day, hrs, min, sec);
211: return cal.getTimeInMillis();
212: }
213: }
214: catch (RuntimeException ex)
215: {
216:
217: known &= ~KNOWN_TIME;
218: return -1;
219: }
220: }
221:
222: private static synchronized Calendar getCalendar()
223: {
224: if (cal == null)
225: cal = Calendar.getInstance();
226:
227: return cal;
228: }
229:
230:
234: public void setSize(long size)
235: {
236: if ((size & 0xffffffff00000000L) != 0)
237: throw new IllegalArgumentException();
238: this.size = (int) size;
239: this.known |= KNOWN_SIZE;
240: }
241:
242:
246: public long getSize()
247: {
248: return (known & KNOWN_SIZE) != 0 ? size & 0xffffffffL : -1L;
249: }
250:
251:
254: public void setCompressedSize(long csize)
255: {
256: this.compressedSize = csize;
257: }
258:
259:
263: public long getCompressedSize()
264: {
265: return compressedSize;
266: }
267:
268:
272: public void setCrc(long crc)
273: {
274: if ((crc & 0xffffffff00000000L) != 0)
275: throw new IllegalArgumentException();
276: this.crc = (int) crc;
277: this.known |= KNOWN_CRC;
278: }
279:
280:
284: public long getCrc()
285: {
286: return (known & KNOWN_CRC) != 0 ? crc & 0xffffffffL : -1L;
287: }
288:
289:
296: public void setMethod(int method)
297: {
298: if (method != ZipOutputStream.STORED
299: && method != ZipOutputStream.DEFLATED)
300: throw new IllegalArgumentException();
301: this.method = (short) method;
302: }
303:
304:
308: public int getMethod()
309: {
310: return method;
311: }
312:
313:
317: public void setExtra(byte[] extra)
318: {
319: if (extra == null)
320: {
321: this.extra = null;
322: return;
323: }
324: if (extra.length > 0xffff)
325: throw new IllegalArgumentException();
326: this.extra = extra;
327: }
328:
329: private void parseExtra()
330: {
331:
332: if ((known & KNOWN_EXTRA) != 0)
333: return;
334:
335: if (extra == null)
336: {
337: known |= KNOWN_EXTRA;
338: return;
339: }
340:
341: try
342: {
343: int pos = 0;
344: while (pos < extra.length)
345: {
346: int sig = (extra[pos++] & 0xff)
347: | (extra[pos++] & 0xff) << 8;
348: int len = (extra[pos++] & 0xff)
349: | (extra[pos++] & 0xff) << 8;
350: if (sig == 0x5455)
351: {
352:
353: int flags = extra[pos];
354: if ((flags & 1) != 0)
355: {
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);
360: setTime(time);
361: }
362: }
363: pos += len;
364: }
365: }
366: catch (ArrayIndexOutOfBoundsException ex)
367: {
368:
369: }
370:
371: known |= KNOWN_EXTRA;
372: return;
373: }
374:
375:
379: public byte[] getExtra()
380: {
381: return extra;
382: }
383:
384:
388: public void setComment(String comment)
389: {
390: if (comment != null && comment.length() > 0xffff)
391: throw new IllegalArgumentException();
392: this.comment = comment;
393: }
394:
395:
399: public String getComment()
400: {
401: return comment;
402: }
403:
404:
408: public boolean isDirectory()
409: {
410: int nlen = name.length();
411: return nlen > 0 && name.charAt(nlen - 1) == '/';
412: }
413:
414:
418: public String toString()
419: {
420: return name;
421: }
422:
423:
427: public int hashCode()
428: {
429: return name.hashCode();
430: }
431: }