< prev index next >
src/java.base/share/classes/java/util/zip/ZipEntry.java
Print this page
rev 11478 : 8073497: Lazy conversion of ZipEntry time
Reviewed-by: sherman, plevart
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -39,11 +39,13 @@
*/
public
class ZipEntry implements ZipConstants, Cloneable {
String name; // entry name
- long time = -1; // last modification time
+ long xdostime = -1; // last modification time (in extended DOS time,
+ // where milliseconds lost in conversion might
+ // be encoded into the upper half)
FileTime mtime; // last modification time, from extra field data
FileTime atime; // last access time, from extra field data
FileTime ctime; // creation time, from extra field data
long crc = -1; // crc-32 of entry data
long size = -1; // uncompressed size of entry data
@@ -62,10 +64,32 @@
* Compression method for compressed (deflated) entries.
*/
public static final int DEFLATED = 8;
/**
+ * DOS time constant for representing timestamps before 1980.
+ */
+ static final long DOSTIME_BEFORE_1980 = (1 << 21) | (1 << 16);
+
+ /**
+ * Approximately 128 years, in milliseconds (ignoring leap years etc).
+ *
+ * This establish an approximate high-bound value for DOS times in
+ * milliseconds since epoch, used to enable an efficient but
+ * sufficient bounds check to avoid generating extended last modified
+ * time entries.
+ *
+ * Calculating the exact number is locale dependent, would require loading
+ * TimeZone data eagerly, and would make little practical sense. Since DOS
+ * times theoretically go to 2107 - with compatibility not guaranteed
+ * after 2099 - setting this to a time that is before but near 2099
+ * should be sufficient.
+ */
+ private static final long UPPER_DOSTIME_BOUND =
+ 128L * 365 * 24 * 60 * 60 * 1000;
+
+ /**
* Creates a new zip entry with the specified name.
*
* @param name
* The entry name
*
@@ -91,11 +115,11 @@
* @throws NullPointerException if the entry object is null
*/
public ZipEntry(ZipEntry e) {
Objects.requireNonNull(e, "entry");
name = e.name;
- time = e.time;
+ xdostime = e.xdostime;
mtime = e.mtime;
atime = e.atime;
ctime = e.ctime;
crc = e.crc;
size = e.size;
@@ -135,12 +159,18 @@
*
* @see #getTime()
* @see #getLastModifiedTime()
*/
public void setTime(long time) {
- this.time = time;
+ this.xdostime = javaToExtendedDosTime(time);
+ // Avoid setting the mtime field if time is in the valid
+ // range for a DOS time
+ if (xdostime != DOSTIME_BEFORE_1980 && time <= UPPER_DOSTIME_BOUND) {
this.mtime = null;
+ } else {
+ this.mtime = FileTime.from(time, TimeUnit.MILLISECONDS);
+ }
}
/**
* Returns the last modification time of the entry.
*
@@ -156,11 +186,14 @@
*
* @see #setTime(long)
* @see #setLastModifiedTime(FileTime)
*/
public long getTime() {
- return time;
+ if (mtime != null) {
+ return mtime.toMillis();
+ }
+ return (xdostime != -1) ? extendedDosToJavaTime(xdostime) : -1;
}
/**
* Sets the last modification time of the entry.
*
@@ -179,11 +212,11 @@
* @see #getLastModifiedTime()
* @since 1.8
*/
public ZipEntry setLastModifiedTime(FileTime time) {
this.mtime = Objects.requireNonNull(time, "lastModifiedTime");
- this.time = time.to(TimeUnit.MILLISECONDS);
+ this.xdostime = javaToExtendedDosTime(time.to(TimeUnit.MILLISECONDS));
return this;
}
/**
* Returns the last modification time of the entry.
@@ -202,13 +235,13 @@
* @since 1.8
*/
public FileTime getLastModifiedTime() {
if (mtime != null)
return mtime;
- if (time == -1)
+ if (xdostime == -1)
return null;
- return FileTime.from(time, TimeUnit.MILLISECONDS);
+ return FileTime.from(getTime(), TimeUnit.MILLISECONDS);
}
/**
* Sets the last access time of the entry.
*
< prev index next >