diff options
author | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2008-09-10 01:42:41 +0000 |
---|---|---|
committer | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2008-09-10 01:42:41 +0000 |
commit | f3a76994e35f1ff91731dd3b85ef5c253025bb31 (patch) | |
tree | 43e43c5b2e41728f0b3850b8e2ceaff488295021 /java | |
parent | 9f3e716b63aae6e7c5b0bb335d73a327192b4967 (diff) | |
download | classpath-f3a76994e35f1ff91731dd3b85ef5c253025bb31.tar.gz |
ZipEntry tweaks to improve performance.
2008-02-07 Ian Rogers <ian.rogers@manchester.ac.uk>
* java/util/zip/ZipEntry.java:
Use byte fields instead of integer fields,
store the time as well as the DOS time and
don't retain a global Calendar instance.
(setDOSTime(int)): Set KNOWN_DOSTIME instead
of KNOWN_TIME, and unset KNOWN_TIME.
(getDOSTime()): Compute DOS time from UNIX time
only when needed.
(clone()): Provide cloning via the ZipEntry constructor
where possible.
(setTime(long)): Don't compute DOS time at this point.
(getCalendar()): Removed.
Diffstat (limited to 'java')
-rw-r--r-- | java/util/zip/ZipEntry.java | 166 |
1 files changed, 96 insertions, 70 deletions
diff --git a/java/util/zip/ZipEntry.java b/java/util/zip/ZipEntry.java index 893f04374..a6d01af5f 100644 --- a/java/util/zip/ZipEntry.java +++ b/java/util/zip/ZipEntry.java @@ -50,23 +50,39 @@ import java.util.Calendar; */ public class ZipEntry implements ZipConstants, Cloneable { - private static final int KNOWN_SIZE = 1; - private static final int KNOWN_CSIZE = 2; - private static final int KNOWN_CRC = 4; - private static final int KNOWN_TIME = 8; - private static final int KNOWN_EXTRA = 16; - - private static Calendar cal; - - private String name; + private static final byte KNOWN_SIZE = 1; + private static final byte KNOWN_CSIZE = 2; + private static final byte KNOWN_CRC = 4; + private static final byte KNOWN_TIME = 8; + private static final byte KNOWN_DOSTIME = 16; + private static final byte KNOWN_EXTRA = 32; + + /** Immutable name of the entry */ + private final String name; + /** Uncompressed size */ private int size; + /** Compressed size */ private long compressedSize = -1; + /** CRC of uncompressed data */ private int crc; + /** Comment or null if none */ + private String comment = null; + /** The compression method. Either DEFLATED or STORED, by default -1. */ + private byte method = -1; + /** Flags specifying what we know about this entry */ + private byte known = 0; + /** + * The 32bit DOS encoded format for the time of this entry. Only valid if + * KNOWN_DOSTIME is set in known. + */ private int dostime; - private short known = 0; - private short method = -1; + /** + * The 64bit Java encoded millisecond time since the beginning of the epoch. + * Only valid if KNOWN_TIME is set in known. + */ + private long time; + /** Extra data */ private byte[] extra = null; - private String comment = null; int flags; /* used by ZipOutputStream */ int offset; /* used by ZipFile and ZipOutputStream */ @@ -113,6 +129,7 @@ public class ZipEntry implements ZipConstants, Cloneable compressedSize = e.compressedSize; crc = e.crc; dostime = e.dostime; + time = e.time; method = e.method; extra = e.extra; comment = e.comment; @@ -121,37 +138,60 @@ public class ZipEntry implements ZipConstants, Cloneable final void setDOSTime(int dostime) { this.dostime = dostime; - known |= KNOWN_TIME; + known |= KNOWN_DOSTIME; + known &= ~KNOWN_TIME; } final int getDOSTime() { - if ((known & KNOWN_TIME) == 0) - return 0; - else + if ((known & KNOWN_DOSTIME) != 0) return dostime; + else if ((known & KNOWN_TIME) != 0) + { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(time); + dostime = (cal.get(Calendar.YEAR) - 1980 & 0x7f) << 25 + | (cal.get(Calendar.MONTH) + 1) << 21 + | (cal.get(Calendar.DAY_OF_MONTH)) << 16 + | (cal.get(Calendar.HOUR_OF_DAY)) << 11 + | (cal.get(Calendar.MINUTE)) << 5 + | (cal.get(Calendar.SECOND)) >> 1; + known |= KNOWN_DOSTIME; + return dostime; + } + else + return 0; } /** * Creates a copy of this zip entry. */ - /** - * Clones the entry. - */ public Object clone() { - try + // JCL defines this as being the same as the copy constructor above, + // except that value of the "extra" field is also copied. Take care + // that in the case of a subclass we use clone() rather than the copy + // constructor. + ZipEntry clone; + if (this.getClass() == ZipEntry.class) + clone = new ZipEntry(this); + else { - // The JCL says that the `extra' field is also copied. - ZipEntry clone = (ZipEntry) super.clone(); - if (extra != null) - clone.extra = (byte[]) extra.clone(); - return clone; + try + { + clone = (ZipEntry) super.clone(); + } + catch (CloneNotSupportedException e) + { + throw new InternalError(); + } } - catch (CloneNotSupportedException ex) + if (extra != null) { - throw new InternalError(); + clone.extra = new byte[extra.length]; + System.arraycopy(extra, 0, clone.extra, 0, extra.length); } + return clone; } /** @@ -169,18 +209,9 @@ public class ZipEntry implements ZipConstants, Cloneable */ public void setTime(long time) { - Calendar cal = getCalendar(); - synchronized (cal) - { - cal.setTimeInMillis(time); - dostime = (cal.get(Calendar.YEAR) - 1980 & 0x7f) << 25 - | (cal.get(Calendar.MONTH) + 1) << 21 - | (cal.get(Calendar.DAY_OF_MONTH)) << 16 - | (cal.get(Calendar.HOUR_OF_DAY)) << 11 - | (cal.get(Calendar.MINUTE)) << 5 - | (cal.get(Calendar.SECOND)) >> 1; - } + this.time = time; this.known |= KNOWN_TIME; + this.known &= ~KNOWN_DOSTIME; } /** @@ -192,39 +223,34 @@ public class ZipEntry implements ZipConstants, Cloneable // The extra bytes might contain the time (posix/unix extension) parseExtra(); - if ((known & KNOWN_TIME) == 0) - return -1; - - int sec = 2 * (dostime & 0x1f); - int min = (dostime >> 5) & 0x3f; - int hrs = (dostime >> 11) & 0x1f; - int day = (dostime >> 16) & 0x1f; - int mon = ((dostime >> 21) & 0xf) - 1; - int year = ((dostime >> 25) & 0x7f) + 1980; /* since 1900 */ - - try - { - cal = getCalendar(); - synchronized (cal) - { - cal.set(year, mon, day, hrs, min, sec); - return cal.getTimeInMillis(); - } - } - catch (RuntimeException ex) + if ((known & KNOWN_TIME) != 0) + return time; + else if ((known & KNOWN_DOSTIME) != 0) { - /* Ignore illegal time stamp */ - known &= ~KNOWN_TIME; - return -1; + int sec = 2 * (dostime & 0x1f); + int min = (dostime >> 5) & 0x3f; + int hrs = (dostime >> 11) & 0x1f; + int day = (dostime >> 16) & 0x1f; + int mon = ((dostime >> 21) & 0xf) - 1; + int year = ((dostime >> 25) & 0x7f) + 1980; /* since 1900 */ + + try + { + Calendar cal = Calendar.getInstance(); + cal.set(year, mon, day, hrs, min, sec); + time = cal.getTimeInMillis(); + known |= KNOWN_TIME; + return time; + } + catch (RuntimeException ex) + { + /* Ignore illegal time stamp */ + known &= ~KNOWN_TIME; + return -1; + } } - } - - private static synchronized Calendar getCalendar() - { - if (cal == null) - cal = Calendar.getInstance(); - - return cal; + else + return -1; } /** @@ -298,7 +324,7 @@ public class ZipEntry implements ZipConstants, Cloneable if (method != ZipOutputStream.STORED && method != ZipOutputStream.DEFLATED) throw new IllegalArgumentException(); - this.method = (short) method; + this.method = (byte) method; } /** |