Rebasing the Inflater support on jzlib which, unlike GNU ClassPath, has correct implementation of Huffman code. Making the implementation more easily testable by turning Inflater and ZipInputStream into pure delegates. Current implementation is going to need proper long support.
2 * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
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).
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.
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
26 package java.util.zip;
29 * This class is used to represent a ZIP file entry.
31 * @author David Connelly
34 class ZipEntry implements ZipConstants, Cloneable {
35 String name; // entry name
36 long time = -1; // modification time (in DOS time)
37 long crc = -1; // crc-32 of entry data
38 long size = -1; // uncompressed size of entry data
39 long csize = -1; // compressed size of entry data
40 int method = -1; // compression method
41 int flag = 0; // general purpose flag
42 byte[] extra; // optional extra field data for entry
43 String comment; // optional comment string for entry
46 * Compression method for uncompressed entries.
48 public static final int STORED = 0;
51 * Compression method for compressed (deflated) entries.
53 public static final int DEFLATED = 8;
56 * Creates a new zip entry with the specified name.
58 * @param name the entry name
59 * @exception NullPointerException if the entry name is null
60 * @exception IllegalArgumentException if the entry name is longer than
63 public ZipEntry(String name) {
65 throw new NullPointerException();
67 if (name.length() > 0xFFFF) {
68 throw new IllegalArgumentException("entry name too long");
74 * Creates a new zip entry with fields taken from the specified
76 * @param e a zip Entry object
78 public ZipEntry(ZipEntry e) {
91 * Creates a new un-initialized zip entry
96 * Returns the name of the entry.
97 * @return the name of the entry
99 public String getName() {
104 * Sets the modification time of the entry.
105 * @param time the entry modification time in number of milliseconds
109 public void setTime(long time) {
110 this.time = javaToDosTime(time);
114 * Returns the modification time of the entry, or -1 if not specified.
115 * @return the modification time of the entry, or -1 if not specified
116 * @see #setTime(long)
118 public long getTime() {
119 return time != -1 ? dosToJavaTime(time) : -1;
123 * Sets the uncompressed size of the entry data.
124 * @param size the uncompressed size in bytes
125 * @exception IllegalArgumentException if the specified size is less
126 * than 0, is greater than 0xFFFFFFFF when
127 * <a href="package-summary.html#zip64">ZIP64 format</a> is not supported,
128 * or is less than 0 when ZIP64 is supported
131 public void setSize(long size) {
133 throw new IllegalArgumentException("invalid entry size");
139 * Returns the uncompressed size of the entry data, or -1 if not known.
140 * @return the uncompressed size of the entry data, or -1 if not known
141 * @see #setSize(long)
143 public long getSize() {
148 * Returns the size of the compressed entry data, or -1 if not known.
149 * In the case of a stored entry, the compressed size will be the same
150 * as the uncompressed size of the entry.
151 * @return the size of the compressed entry data, or -1 if not known
152 * @see #setCompressedSize(long)
154 public long getCompressedSize() {
159 * Sets the size of the compressed entry data.
160 * @param csize the compressed size to set to
161 * @see #getCompressedSize()
163 public void setCompressedSize(long csize) {
168 * Sets the CRC-32 checksum of the uncompressed entry data.
169 * @param crc the CRC-32 value
170 * @exception IllegalArgumentException if the specified CRC-32 value is
171 * less than 0 or greater than 0xFFFFFFFF
174 public void setCrc(long crc) {
175 if (crc < 0 || crc > 0xFFFFFFFFL) {
176 throw new IllegalArgumentException("invalid entry crc-32");
182 * Returns the CRC-32 checksum of the uncompressed entry data, or -1 if
184 * @return the CRC-32 checksum of the uncompressed entry data, or -1 if
188 public long getCrc() {
193 * Sets the compression method for the entry.
194 * @param method the compression method, either STORED or DEFLATED
195 * @exception IllegalArgumentException if the specified compression
199 public void setMethod(int method) {
200 if (method != STORED && method != DEFLATED) {
201 throw new IllegalArgumentException("invalid compression method");
203 this.method = method;
207 * Returns the compression method of the entry, or -1 if not specified.
208 * @return the compression method of the entry, or -1 if not specified
209 * @see #setMethod(int)
211 public int getMethod() {
216 * Sets the optional extra field data for the entry.
217 * @param extra the extra field data bytes
218 * @exception IllegalArgumentException if the length of the specified
219 * extra field data is greater than 0xFFFF bytes
222 public void setExtra(byte[] extra) {
223 if (extra != null && extra.length > 0xFFFF) {
224 throw new IllegalArgumentException("invalid extra field length");
230 * Returns the extra field data for the entry, or null if none.
231 * @return the extra field data for the entry, or null if none
232 * @see #setExtra(byte[])
234 public byte[] getExtra() {
239 * Sets the optional comment string for the entry.
241 * <p>ZIP entry comments have maximum length of 0xffff. If the length of the
242 * specified comment string is greater than 0xFFFF bytes after encoding, only
243 * the first 0xFFFF bytes are output to the ZIP file entry.
245 * @param comment the comment string
249 public void setComment(String comment) {
250 this.comment = comment;
254 * Returns the comment string for the entry, or null if none.
255 * @return the comment string for the entry, or null if none
256 * @see #setComment(String)
258 public String getComment() {
263 * Returns true if this is a directory entry. A directory entry is
264 * defined to be one whose name ends with a '/'.
265 * @return true if this is a directory entry
267 public boolean isDirectory() {
268 return name.endsWith("/");
272 * Returns a string representation of the ZIP entry.
274 public String toString() {
279 * Converts DOS time to Java time (number of milliseconds since epoch).
281 private static long dosToJavaTime(long dtime) {
284 Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
285 (int)(((dtime >> 21) & 0x0f) - 1),
286 (int)((dtime >> 16) & 0x1f),
287 (int)((dtime >> 11) & 0x1f),
288 (int)((dtime >> 5) & 0x3f),
289 (int)((dtime << 1) & 0x3e));
295 * Converts Java time to DOS time.
297 private static long javaToDosTime(long time) {
300 Date d = new Date(time);
301 int year = d.getYear() + 1900;
303 return (1 << 21) | (1 << 16);
305 return (year - 1980) << 25 | (d.getMonth() + 1) << 21 |
306 d.getDate() << 16 | d.getHours() << 11 | d.getMinutes() << 5 |
312 * Returns the hash code value for this entry.
314 public int hashCode() {
315 return name.hashCode();
319 * Returns a copy of this entry.
321 public Object clone() {
323 ZipEntry e = (ZipEntry)super.clone();
324 e.extra = (extra == null) ? null : extra.clone();
326 } catch (CloneNotSupportedException e) {
327 // This should never happen, since we are Cloneable
328 throw new IllegalStateException();