diff options
Diffstat (limited to 'libjava/classpath/java/util/zip/ZipEntry.java')
-rw-r--r-- | libjava/classpath/java/util/zip/ZipEntry.java | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/libjava/classpath/java/util/zip/ZipEntry.java b/libjava/classpath/java/util/zip/ZipEntry.java new file mode 100644 index 0000000..ae21997 --- /dev/null +++ b/libjava/classpath/java/util/zip/ZipEntry.java @@ -0,0 +1,432 @@ +/* ZipEntry.java -- + Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package java.util.zip; + +import java.util.Calendar; +import java.util.Date; + +/** + * This class represents a member of a zip archive. ZipFile and + * ZipInputStream will give you instances of this class as information + * about the members in an archive. On the other hand ZipOutputStream + * needs an instance of this class to create a new member. + * + * @author Jochen Hoenicke + */ +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 int size; + private long compressedSize = -1; + private int crc; + private int dostime; + private short known = 0; + private short method = -1; + private byte[] extra = null; + private String comment = null; + + int flags; /* used by ZipOutputStream */ + int offset; /* used by ZipFile and ZipOutputStream */ + + /** + * Compression method. This method doesn't compress at all. + */ + public static final int STORED = 0; + /** + * Compression method. This method uses the Deflater. + */ + public static final int DEFLATED = 8; + + /** + * Creates a zip entry with the given name. + * @param name the name. May include directory components separated + * by '/'. + * + * @exception NullPointerException when name is null. + * @exception IllegalArgumentException when name is bigger then 65535 chars. + */ + public ZipEntry(String name) + { + int length = name.length(); + if (length > 65535) + throw new IllegalArgumentException("name length is " + length); + this.name = name; + } + + /** + * Creates a copy of the given zip entry. + * @param e the entry to copy. + */ + public ZipEntry(ZipEntry e) + { + this(e, e.name); + } + + ZipEntry(ZipEntry e, String name) + { + this.name = name; + known = e.known; + size = e.size; + compressedSize = e.compressedSize; + crc = e.crc; + dostime = e.dostime; + method = e.method; + extra = e.extra; + comment = e.comment; + } + + final void setDOSTime(int dostime) + { + this.dostime = dostime; + known |= KNOWN_TIME; + } + + final int getDOSTime() + { + if ((known & KNOWN_TIME) == 0) + return 0; + else + return dostime; + } + + /** + * Creates a copy of this zip entry. + */ + /** + * Clones the entry. + */ + public Object clone() + { + try + { + // 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; + } + catch (CloneNotSupportedException ex) + { + throw new InternalError(); + } + } + + /** + * Returns the entry name. The path components in the entry are + * always separated by slashes ('/'). + */ + public String getName() + { + return name; + } + + /** + * Sets the time of last modification of the entry. + * @time the time of last modification of the entry. + */ + public void setTime(long time) + { + Calendar cal = getCalendar(); + synchronized (cal) + { + cal.setTime(new Date(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.known |= KNOWN_TIME; + } + + /** + * Gets the time of last modification of the entry. + * @return the time of last modification of the entry, or -1 if unknown. + */ + public long getTime() + { + if ((known & KNOWN_TIME) == 0) + return -1; + + // The extra bytes might contain the time (posix/unix extension) + parseExtra (); + + 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.getTime().getTime(); + } + } + 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; + } + + /** + * Sets the size of the uncompressed data. + * @exception IllegalArgumentException if size is not in 0..0xffffffffL + */ + public void setSize(long size) + { + if ((size & 0xffffffff00000000L) != 0) + throw new IllegalArgumentException(); + this.size = (int) size; + this.known |= KNOWN_SIZE; + } + + /** + * Gets the size of the uncompressed data. + * @return the size or -1 if unknown. + */ + public long getSize() + { + return (known & KNOWN_SIZE) != 0 ? size & 0xffffffffL : -1L; + } + + /** + * Sets the size of the compressed data. + */ + public void setCompressedSize(long csize) + { + this.compressedSize = csize; + } + + /** + * Gets the size of the compressed data. + * @return the size or -1 if unknown. + */ + public long getCompressedSize() + { + return compressedSize; + } + + /** + * Sets the crc of the uncompressed data. + * @exception IllegalArgumentException if crc is not in 0..0xffffffffL + */ + public void setCrc(long crc) + { + if ((crc & 0xffffffff00000000L) != 0) + throw new IllegalArgumentException(); + this.crc = (int) crc; + this.known |= KNOWN_CRC; + } + + /** + * Gets the crc of the uncompressed data. + * @return the crc or -1 if unknown. + */ + public long getCrc() + { + return (known & KNOWN_CRC) != 0 ? crc & 0xffffffffL : -1L; + } + + /** + * Sets the compression method. Only DEFLATED and STORED are + * supported. + * @exception IllegalArgumentException if method is not supported. + * @see ZipOutputStream#DEFLATED + * @see ZipOutputStream#STORED + */ + public void setMethod(int method) + { + if (method != ZipOutputStream.STORED + && method != ZipOutputStream.DEFLATED) + throw new IllegalArgumentException(); + this.method = (short) method; + } + + /** + * Gets the compression method. + * @return the compression method or -1 if unknown. + */ + public int getMethod() + { + return method; + } + + /** + * Sets the extra data. + * @exception IllegalArgumentException if extra is longer than 0xffff bytes. + */ + public void setExtra(byte[] extra) + { + if (extra == null) + { + this.extra = null; + return; + } + if (extra.length > 0xffff) + throw new IllegalArgumentException(); + this.extra = extra; + } + + private void parseExtra() + { + // Already parsed? + if ((known & KNOWN_EXTRA) != 0) + return; + + if (extra == null) + { + known |= KNOWN_EXTRA; + return; + } + + try + { + int pos = 0; + while (pos < extra.length) + { + int sig = (extra[pos++] & 0xff) + | (extra[pos++] & 0xff) << 8; + int len = (extra[pos++] & 0xff) + | (extra[pos++] & 0xff) << 8; + if (sig == 0x5455) + { + /* extended time stamp */ + int flags = extra[pos]; + if ((flags & 1) != 0) + { + long time = ((extra[pos+1] & 0xff) + | (extra[pos+2] & 0xff) << 8 + | (extra[pos+3] & 0xff) << 16 + | (extra[pos+4] & 0xff) << 24); + setTime(time); + } + } + pos += len; + } + } + catch (ArrayIndexOutOfBoundsException ex) + { + /* be lenient */ + return; + } + + known |= KNOWN_EXTRA; + } + + /** + * Gets the extra data. + * @return the extra data or null if not set. + */ + public byte[] getExtra() + { + return extra; + } + + /** + * Sets the entry comment. + * @exception IllegalArgumentException if comment is longer than 0xffff. + */ + public void setComment(String comment) + { + if (comment != null && comment.length() > 0xffff) + throw new IllegalArgumentException(); + this.comment = comment; + } + + /** + * Gets the comment. + * @return the comment or null if not set. + */ + public String getComment() + { + return comment; + } + + /** + * Gets true, if the entry is a directory. This is solely + * determined by the name, a trailing slash '/' marks a directory. + */ + public boolean isDirectory() + { + int nlen = name.length(); + return nlen > 0 && name.charAt(nlen - 1) == '/'; + } + + /** + * Gets the string representation of this ZipEntry. This is just + * the name as returned by getName(). + */ + public String toString() + { + return name; + } + + /** + * Gets the hashCode of this ZipEntry. This is just the hashCode + * of the name. Note that the equals method isn't changed, though. + */ + public int hashCode() + { + return name.hashCode(); + } +} |