diff --git a/src/main/org/apache/tools/zip/AsiExtraField.java b/src/main/org/apache/tools/zip/AsiExtraField.java index 87f7d2c56..e5f9b2f97 100644 --- a/src/main/org/apache/tools/zip/AsiExtraField.java +++ b/src/main/org/apache/tools/zip/AsiExtraField.java @@ -135,15 +135,15 @@ public class AsiExtraField implements ZipExtraField, UnixStat, Cloneable { public byte[] getLocalFileDataData() { // CRC will be added later byte[] data = new byte[getLocalFileDataLength().getValue() - 4]; - System.arraycopy((new ZipShort(getMode())).getBytes(), 0, data, 0, 2); + System.arraycopy(ZipShort.getBytes(getMode()), 0, data, 0, 2); byte[] linkArray = getLinkedFile().getBytes(); - System.arraycopy((new ZipLong(linkArray.length)).getBytes(), + System.arraycopy(ZipLong.getBytes(linkArray.length), 0, data, 2, 4); - System.arraycopy((new ZipShort(getUserId())).getBytes(), + System.arraycopy(ZipShort.getBytes(getUserId()), 0, data, 6, 2); - System.arraycopy((new ZipShort(getGroupId())).getBytes(), + System.arraycopy(ZipShort.getBytes(getGroupId()), 0, data, 8, 2); System.arraycopy(linkArray, 0, data, 10, linkArray.length); @@ -153,7 +153,7 @@ public class AsiExtraField implements ZipExtraField, UnixStat, Cloneable { long checksum = crc.getValue(); byte[] result = new byte[data.length + 4]; - System.arraycopy((new ZipLong(checksum)).getBytes(), 0, result, 0, 4); + System.arraycopy(ZipLong.getBytes(checksum), 0, result, 0, 4); System.arraycopy(data, 0, result, 4, data.length); return result; } @@ -282,7 +282,7 @@ public class AsiExtraField implements ZipExtraField, UnixStat, Cloneable { public void parseFromLocalFileData(byte[] data, int offset, int length) throws ZipException { - long givenChecksum = (new ZipLong(data, offset)).getValue(); + long givenChecksum = ZipLong.getValue(data, offset); byte[] tmp = new byte[length - 4]; System.arraycopy(data, offset + 4, tmp, 0, length - 4); crc.reset(); @@ -295,10 +295,10 @@ public class AsiExtraField implements ZipExtraField, UnixStat, Cloneable { + Long.toHexString(realChecksum)); } - int newMode = (new ZipShort(tmp, 0)).getValue(); - byte[] linkArray = new byte[(int) (new ZipLong(tmp, 2)).getValue()]; - uid = (new ZipShort(tmp, 6)).getValue(); - gid = (new ZipShort(tmp, 8)).getValue(); + int newMode = ZipShort.getValue(tmp, 0); + byte[] linkArray = new byte[(int) ZipLong.getValue(tmp, 2)]; + uid = ZipShort.getValue(tmp, 6); + gid = ZipShort.getValue(tmp, 8); if (linkArray.length == 0) { link = ""; diff --git a/src/main/org/apache/tools/zip/ZipEntry.java b/src/main/org/apache/tools/zip/ZipEntry.java index c05eab276..7e03cee16 100644 --- a/src/main/org/apache/tools/zip/ZipEntry.java +++ b/src/main/org/apache/tools/zip/ZipEntry.java @@ -20,6 +20,8 @@ package org.apache.tools.zip; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Vector; +import java.util.Date; +import java.util.Calendar; import java.util.zip.ZipException; /** @@ -386,6 +388,24 @@ public class ZipEntry extends java.util.zip.ZipEntry implements Cloneable { this.name = name; } + /** + * @since Ant 1.7 + */ + public int hashCode(){ + return getName().hashCode(); + } + + /** + * @since Ant 1.7 + */ + public boolean equals(Object o){ + if (o instanceof ZipEntry){ + ZipEntry other = (ZipEntry)o; + return other.getName().equals(getName()); + } + return false; + } + /** * Helper for JDK 1.1 * diff --git a/src/main/org/apache/tools/zip/ZipFile.java b/src/main/org/apache/tools/zip/ZipFile.java index 6710c7412..9b4d15167 100644 --- a/src/main/org/apache/tools/zip/ZipFile.java +++ b/src/main/org/apache/tools/zip/ZipFile.java @@ -64,17 +64,17 @@ public class ZipFile { * Maps ZipEntrys to Longs, recording the offsets of the local * file headers. */ - private Hashtable entries = new Hashtable(); + private Hashtable entries = new Hashtable(509); /** * Maps String to ZipEntrys, name -> actual entry. */ - private Hashtable nameMap = new Hashtable(); + private Hashtable nameMap = new Hashtable(509); - /** - * Maps ZipEntrys to Longs, recording the offsets of the actual file data. - */ - private Hashtable dataOffsets = new Hashtable(); + private static final class OffsetEntry { + long headerOffset = -1; + long dataOffset = - 1; + } /** * The encoding to use for filenames and the file comment. @@ -201,12 +201,13 @@ public class ZipFile { */ public InputStream getInputStream(ZipEntry ze) throws IOException, ZipException { - Long start = (Long) dataOffsets.get(ze); - if (start == null) { + OffsetEntry offsetEntry = (OffsetEntry)entries.get(ze); + if (offsetEntry == null){ return null; } + long start = offsetEntry.dataOffset; BoundedInputStream bis = - new BoundedInputStream(start.longValue(), ze.getCompressedSize()); + new BoundedInputStream(start, ze.getCompressedSize()); switch (ze.getMethod()) { case ZipEntry.STORED: return bis; @@ -253,57 +254,66 @@ public class ZipFile { byte[] signatureBytes = new byte[4]; archive.readFully(signatureBytes); - ZipLong sig = new ZipLong(signatureBytes); - while (sig.equals(ZipOutputStream.CFH_SIG)) { + long sig = ZipLong.getValue(signatureBytes); + final long cfh_sig = ZipLong.getValue(ZipOutputStream.CFH_SIG); + while (sig == cfh_sig) { archive.readFully(cfh); int off = 0; ZipEntry ze = new ZipEntry(); - ZipShort versionMadeBy = new ZipShort(cfh, off); + int versionMadeBy = ZipShort.getValue(cfh, off); off += 2; - ze.setPlatform((versionMadeBy.getValue() >> 8) & 0x0F); + ze.setPlatform((versionMadeBy >> 8) & 0x0F); off += 4; // skip version info and general purpose byte - ze.setMethod((new ZipShort(cfh, off)).getValue()); + ze.setMethod(ZipShort.getValue(cfh, off)); off += 2; - ze.setTime(fromDosTime(new ZipLong(cfh, off)).getTime()); + // FIXME this is actually not very cpu cycles friendly as we are converting from + // dos to java while the underlying Sun implementation will convert + // from java to dos time for internal storage... + long time = dosToJavaTime(ZipLong.getValue(cfh, off)); + ze.setTime(time); off += 4; - ze.setCrc((new ZipLong(cfh, off)).getValue()); + ze.setCrc(ZipLong.getValue(cfh, off)); off += 4; - ze.setCompressedSize((new ZipLong(cfh, off)).getValue()); + ze.setCompressedSize(ZipLong.getValue(cfh, off)); off += 4; - ze.setSize((new ZipLong(cfh, off)).getValue()); + ze.setSize(ZipLong.getValue(cfh, off)); off += 4; - int fileNameLen = (new ZipShort(cfh, off)).getValue(); + int fileNameLen = ZipShort.getValue(cfh, off); off += 2; - int extraLen = (new ZipShort(cfh, off)).getValue(); + int extraLen = ZipShort.getValue(cfh, off); off += 2; - int commentLen = (new ZipShort(cfh, off)).getValue(); + int commentLen = ZipShort.getValue(cfh, off); off += 2; off += 2; // disk number - ze.setInternalAttributes((new ZipShort(cfh, off)).getValue()); + ze.setInternalAttributes(ZipShort.getValue(cfh, off)); off += 2; - ze.setExternalAttributes((new ZipLong(cfh, off)).getValue()); + ze.setExternalAttributes(ZipLong.getValue(cfh, off)); off += 4; - // LFH offset - entries.put(ze, new Long((new ZipLong(cfh, off)).getValue())); - byte[] fileName = new byte[fileNameLen]; archive.readFully(fileName); ze.setName(getString(fileName)); + + // LFH offset, + OffsetEntry offset = new OffsetEntry(); + offset.headerOffset = ZipLong.getValue(cfh, off); + // data offset will be filled later + entries.put(ze, offset); + nameMap.put(ze.getName(), ze); archive.skipBytes(extraLen); @@ -313,7 +323,7 @@ public class ZipFile { ze.setComment(getString(comment)); archive.readFully(signatureBytes); - sig = new ZipLong(signatureBytes); + sig = ZipLong.getValue(signatureBytes); } } @@ -352,7 +362,7 @@ public class ZipFile { throws IOException { long off = archive.length() - MIN_EOCD_SIZE; archive.seek(off); - byte[] sig = ZipOutputStream.EOCD_SIG.getBytes(); + byte[] sig = ZipOutputStream.EOCD_SIG; int curr = archive.read(); boolean found = false; while (curr != -1) { @@ -378,7 +388,7 @@ public class ZipFile { archive.seek(off + CFD_LOCATOR_OFFSET); byte[] cfdOffset = new byte[4]; archive.readFully(cfdOffset); - archive.seek((new ZipLong(cfdOffset)).getValue()); + archive.seek(ZipLong.getValue(cfdOffset)); } /** @@ -408,31 +418,42 @@ public class ZipFile { Enumeration e = getEntries(); while (e.hasMoreElements()) { ZipEntry ze = (ZipEntry) e.nextElement(); - long offset = ((Long) entries.get(ze)).longValue(); + OffsetEntry offsetEntry = (OffsetEntry)entries.get(ze); + long offset = offsetEntry.headerOffset; archive.seek(offset + LFH_OFFSET_FOR_FILENAME_LENGTH); byte[] b = new byte[2]; archive.readFully(b); - int fileNameLen = (new ZipShort(b)).getValue(); + int fileNameLen = ZipShort.getValue(b); archive.readFully(b); - int extraFieldLen = (new ZipShort(b)).getValue(); + int extraFieldLen = ZipShort.getValue(b); archive.skipBytes(fileNameLen); byte[] localExtraData = new byte[extraFieldLen]; archive.readFully(localExtraData); ze.setExtra(localExtraData); - dataOffsets.put(ze, + /*dataOffsets.put(ze, new Long(offset + LFH_OFFSET_FOR_FILENAME_LENGTH + 2 + 2 + fileNameLen + extraFieldLen)); + */ + offsetEntry.dataOffset = offset + LFH_OFFSET_FOR_FILENAME_LENGTH + + 2 + 2 + fileNameLen + extraFieldLen; } } /** * Convert a DOS date/time field to a Date object. * - * @param l contains the stored DOS time. + * @param zipDosTime contains the stored DOS time. * @return a Date instance corresponding to the given time. */ - protected static Date fromDosTime(ZipLong l) { - long dosTime = l.getValue(); + protected static Date fromDosTime(ZipLong zipDosTime) { + long dosTime = zipDosTime.getValue(); + return new Date(dosToJavaTime(dosTime)); + } + + /* + * Converts DOS time to Java time (number of milliseconds since epoch). + */ + private static long dosToJavaTime(long dosTime) { Calendar cal = Calendar.getInstance(); cal.set(Calendar.YEAR, (int) ((dosTime >> 25) & 0x7f) + 1980); cal.set(Calendar.MONTH, (int) ((dosTime >> 21) & 0x0f) - 1); @@ -440,9 +461,10 @@ public class ZipFile { cal.set(Calendar.HOUR_OF_DAY, (int) (dosTime >> 11) & 0x1f); cal.set(Calendar.MINUTE, (int) (dosTime >> 5) & 0x3f); cal.set(Calendar.SECOND, (int) (dosTime << 1) & 0x3e); - return cal.getTime(); + return cal.getTimeInMillis(); } + /** * Retrieve a String from the given bytes using the encoding set * for this ZipFile. diff --git a/src/main/org/apache/tools/zip/ZipLong.java b/src/main/org/apache/tools/zip/ZipLong.java index f3e33907c..d592db39b 100644 --- a/src/main/org/apache/tools/zip/ZipLong.java +++ b/src/main/org/apache/tools/zip/ZipLong.java @@ -29,7 +29,6 @@ public final class ZipLong implements Cloneable { /** * Create instance from a number. - * * @since 1.1 */ public ZipLong(long value) { @@ -38,7 +37,6 @@ public final class ZipLong implements Cloneable { /** * Create instance from bytes. - * * @since 1.1 */ public ZipLong (byte[] bytes) { @@ -47,22 +45,34 @@ public final class ZipLong implements Cloneable { /** * Create instance from the four bytes starting at offset. - * * @since 1.1 */ public ZipLong (byte[] bytes, int offset) { - value = (bytes[offset + 3] << 24) & 0xFF000000L; - value += (bytes[offset + 2] << 16) & 0xFF0000; - value += (bytes[offset + 1] << 8) & 0xFF00; - value += (bytes[offset] & 0xFF); + value = ZipLong.getValue(bytes, offset); } /** - * Get value as two bytes in big endian byte order. - * + * Get value as four bytes in big endian byte order. * @since 1.1 */ public byte[] getBytes() { + return ZipLong.getBytes(value); + } + + /** + * Get value as Java int. + * @since 1.1 + */ + public long getValue() { + return value; + } + + /** + * Get value as four bytes in big endian byte order. + * @param value the value to convert + * @return value as four bytes in big endian byte order + */ + public static byte[] getBytes(long value){ byte[] result = new byte[4]; result[0] = (byte) ((value & 0xFF)); result[1] = (byte) ((value & 0xFF00) >> 8); @@ -72,14 +82,28 @@ public final class ZipLong implements Cloneable { } /** - * Get value as Java int. - * - * @since 1.1 + * Helper method to get the value as a java long from four bytes starting at given array offset + * @param bytes the array of bytes + * @param offset the offset to start + * @return the correspondanding java int value */ - public long getValue() { + public static long getValue(byte[] bytes, int offset){ + long value = (bytes[offset + 3] << 24) & 0xFF000000L; + value += (bytes[offset + 2] << 16) & 0xFF0000; + value += (bytes[offset + 1] << 8) & 0xFF00; + value += (bytes[offset] & 0xFF); return value; } + /** + * Helper method to get the value as a java long from a four-byte array + * @param bytes the array of bytes + * @return the correspondanding java long value + */ + public static long getValue(byte[] bytes){ + return getValue(bytes, 0); + } + /** * Override to make two instances with same value equal. * diff --git a/src/main/org/apache/tools/zip/ZipOutputStream.java b/src/main/org/apache/tools/zip/ZipOutputStream.java index a0b3a8996..cd262503d 100644 --- a/src/main/org/apache/tools/zip/ZipOutputStream.java +++ b/src/main/org/apache/tools/zip/ZipOutputStream.java @@ -27,6 +27,7 @@ import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.Hashtable; import java.util.Vector; +import java.util.Calendar; import java.util.zip.CRC32; import java.util.zip.Deflater; import java.util.zip.ZipException; @@ -131,14 +132,14 @@ public class ZipOutputStream extends FilterOutputStream { * * @since 1.1 */ - private ZipLong cdOffset = new ZipLong(0); + private long cdOffset = 0; /** * Length of central directory. * * @since 1.1 */ - private ZipLong cdLength = new ZipLong(0); + private long cdLength = 0; /** * Helper, a 0 as ZipShort. @@ -297,11 +298,11 @@ public class ZipOutputStream extends FilterOutputStream { */ public void finish() throws IOException { closeEntry(); - cdOffset = new ZipLong(written); + cdOffset = written; for (int i = 0; i < entries.size(); i++) { writeCentralFileHeader((ZipEntry) entries.elementAt(i)); } - cdLength = new ZipLong(written - cdOffset.getValue()); + cdLength = written - cdOffset; writeCentralDirectoryEnd(); offsets.clear(); entries.removeAllElements(); @@ -363,9 +364,9 @@ public class ZipOutputStream extends FilterOutputStream { long save = raf.getFilePointer(); raf.seek(localDataStart); - writeOut((new ZipLong(entry.getCrc())).getBytes()); - writeOut((new ZipLong(entry.getCompressedSize())).getBytes()); - writeOut((new ZipLong(entry.getSize())).getBytes()); + writeOut(ZipLong.getBytes(entry.getCrc())); + writeOut(ZipLong.getBytes(entry.getCompressedSize())); + writeOut(ZipLong.getBytes(entry.getSize())); raf.seek(save); } @@ -517,25 +518,25 @@ public class ZipOutputStream extends FilterOutputStream { * * @since 1.1 */ - protected static final ZipLong LFH_SIG = new ZipLong(0X04034B50L); + protected static final byte[] LFH_SIG = ZipLong.getBytes(0X04034B50L); /** * data descriptor signature * * @since 1.1 */ - protected static final ZipLong DD_SIG = new ZipLong(0X08074B50L); + protected static final byte[] DD_SIG = ZipLong.getBytes(0X08074B50L); /** * central file header signature * * @since 1.1 */ - protected static final ZipLong CFH_SIG = new ZipLong(0X02014B50L); + protected static final byte[] CFH_SIG = ZipLong.getBytes(0X02014B50L); /** * end of central dir signature * * @since 1.1 */ - protected static final ZipLong EOCD_SIG = new ZipLong(0X06054B50L); + protected static final byte[] EOCD_SIG = ZipLong.getBytes(0X06054B50L); /** * Writes next block of compressed data to the output stream. @@ -555,9 +556,9 @@ public class ZipOutputStream extends FilterOutputStream { * @since 1.1 */ protected void writeLocalFileHeader(ZipEntry ze) throws IOException { - offsets.put(ze, new ZipLong(written)); + offsets.put(ze, ZipLong.getBytes(written)); - writeOut(LFH_SIG.getBytes()); + writeOut(LFH_SIG); written += 4; // version needed to extract @@ -565,18 +566,18 @@ public class ZipOutputStream extends FilterOutputStream { if (ze.getMethod() == DEFLATED && raf == null) { // requires version 2 as we are going to store length info // in the data descriptor - writeOut((new ZipShort(20)).getBytes()); + writeOut(ZipShort.getBytes(20)); // bit3 set to signal, we use a data descriptor - writeOut((new ZipShort(8)).getBytes()); + writeOut(ZipShort.getBytes(8)); } else { - writeOut((new ZipShort(10)).getBytes()); + writeOut(ZipShort.getBytes(10)); writeOut(ZERO); } written += 4; // compression method - writeOut((new ZipShort(ze.getMethod())).getBytes()); + writeOut(ZipShort.getBytes(ze.getMethod())); written += 2; // last mod. time and date @@ -592,20 +593,20 @@ public class ZipOutputStream extends FilterOutputStream { writeOut(LZERO); writeOut(LZERO); } else { - writeOut((new ZipLong(ze.getCrc())).getBytes()); - writeOut((new ZipLong(ze.getSize())).getBytes()); - writeOut((new ZipLong(ze.getSize())).getBytes()); + writeOut(ZipLong.getBytes(ze.getCrc())); + writeOut(ZipLong.getBytes(ze.getSize())); + writeOut(ZipLong.getBytes(ze.getSize())); } written += 12; // file name length byte[] name = getBytes(ze.getName()); - writeOut((new ZipShort(name.length)).getBytes()); + writeOut(ZipShort.getBytes(name.length)); written += 2; // extra field length byte[] extra = ze.getLocalFileDataExtra(); - writeOut((new ZipShort(extra.length)).getBytes()); + writeOut(ZipShort.getBytes(extra.length)); written += 2; // file name @@ -628,10 +629,10 @@ public class ZipOutputStream extends FilterOutputStream { if (ze.getMethod() != DEFLATED || raf != null) { return; } - writeOut(DD_SIG.getBytes()); - writeOut((new ZipLong(entry.getCrc())).getBytes()); - writeOut((new ZipLong(entry.getCompressedSize())).getBytes()); - writeOut((new ZipLong(entry.getSize())).getBytes()); + writeOut(DD_SIG); + writeOut(ZipLong.getBytes(entry.getCrc())); + writeOut(ZipLong.getBytes(entry.getCompressedSize())); + writeOut(ZipLong.getBytes(entry.getSize())); written += 16; } @@ -641,11 +642,11 @@ public class ZipOutputStream extends FilterOutputStream { * @since 1.1 */ protected void writeCentralFileHeader(ZipEntry ze) throws IOException { - writeOut(CFH_SIG.getBytes()); + writeOut(CFH_SIG); written += 4; // version made by - writeOut((new ZipShort((ze.getPlatform() << 8) | 20)).getBytes()); + writeOut(ZipShort.getBytes((ze.getPlatform() << 8) | 20)); written += 2; // version needed to extract @@ -653,18 +654,18 @@ public class ZipOutputStream extends FilterOutputStream { if (ze.getMethod() == DEFLATED && raf == null) { // requires version 2 as we are going to store length info // in the data descriptor - writeOut((new ZipShort(20)).getBytes()); + writeOut(ZipShort.getBytes(20)); // bit3 set to signal, we use a data descriptor - writeOut((new ZipShort(8)).getBytes()); + writeOut(ZipShort.getBytes(8)); } else { - writeOut((new ZipShort(10)).getBytes()); + writeOut(ZipShort.getBytes(10)); writeOut(ZERO); } written += 4; // compression method - writeOut((new ZipShort(ze.getMethod())).getBytes()); + writeOut(ZipShort.getBytes(ze.getMethod())); written += 2; // last mod. time and date @@ -674,19 +675,19 @@ public class ZipOutputStream extends FilterOutputStream { // CRC // compressed length // uncompressed length - writeOut((new ZipLong(ze.getCrc())).getBytes()); - writeOut((new ZipLong(ze.getCompressedSize())).getBytes()); - writeOut((new ZipLong(ze.getSize())).getBytes()); + writeOut(ZipLong.getBytes(ze.getCrc())); + writeOut(ZipLong.getBytes(ze.getCompressedSize())); + writeOut(ZipLong.getBytes(ze.getSize())); written += 12; // file name length byte[] name = getBytes(ze.getName()); - writeOut((new ZipShort(name.length)).getBytes()); + writeOut(ZipShort.getBytes(name.length)); written += 2; // extra field length byte[] extra = ze.getCentralDirectoryExtra(); - writeOut((new ZipShort(extra.length)).getBytes()); + writeOut(ZipShort.getBytes(extra.length)); written += 2; // file comment length @@ -695,7 +696,7 @@ public class ZipOutputStream extends FilterOutputStream { comm = ""; } byte[] commentB = getBytes(comm); - writeOut((new ZipShort(commentB.length)).getBytes()); + writeOut(ZipShort.getBytes(commentB.length)); written += 2; // disk number start @@ -703,15 +704,15 @@ public class ZipOutputStream extends FilterOutputStream { written += 2; // internal file attributes - writeOut((new ZipShort(ze.getInternalAttributes())).getBytes()); + writeOut(ZipShort.getBytes(ze.getInternalAttributes())); written += 2; // external file attributes - writeOut((new ZipLong(ze.getExternalAttributes())).getBytes()); + writeOut(ZipLong.getBytes(ze.getExternalAttributes())); written += 4; // relative offset of LFH - writeOut(((ZipLong) offsets.get(ze)).getBytes()); + writeOut((byte[]) offsets.get(ze)); written += 4; // file name @@ -733,24 +734,24 @@ public class ZipOutputStream extends FilterOutputStream { * @since 1.1 */ protected void writeCentralDirectoryEnd() throws IOException { - writeOut(EOCD_SIG.getBytes()); + writeOut(EOCD_SIG); // disk numbers writeOut(ZERO); writeOut(ZERO); // number of entries - byte[] num = (new ZipShort(entries.size())).getBytes(); + byte[] num = ZipShort.getBytes(entries.size()); writeOut(num); writeOut(num); // length and location of CD - writeOut(cdLength.getBytes()); - writeOut(cdOffset.getBytes()); + writeOut(ZipLong.getBytes(cdLength)); + writeOut(ZipLong.getBytes(cdOffset)); // ZIP file comment byte[] data = getBytes(comment); - writeOut((new ZipShort(data.length)).getBytes()); + writeOut(ZipShort.getBytes(data.length)); writeOut(data); } @@ -759,7 +760,7 @@ public class ZipOutputStream extends FilterOutputStream { * * @since 1.1 */ - private static final ZipLong DOS_TIME_MIN = new ZipLong(0x00002100L); + private static final byte[] DOS_TIME_MIN = ZipLong.getBytes(0x00002100L); /** * Convert a Date object to a DOS date/time field. @@ -781,7 +782,7 @@ public class ZipOutputStream extends FilterOutputStream { Date time = new Date(t); int year = time.getYear() + 1900; if (year < 1980) { - return DOS_TIME_MIN.getBytes(); + return DOS_TIME_MIN; } int month = time.getMonth() + 1; long value = ((year - 1980) << 25) @@ -790,12 +791,7 @@ public class ZipOutputStream extends FilterOutputStream { | (time.getHours() << 11) | (time.getMinutes() << 5) | (time.getSeconds() >> 1); - byte[] result = new byte[4]; - result[0] = (byte) ((value & 0xFF)); - result[1] = (byte) ((value & 0xFF00) >> 8); - result[2] = (byte) ((value & 0xFF0000) >> 16); - result[3] = (byte) ((value & 0xFF000000L) >> 24); - return result; + return ZipLong.getBytes(value); } /** diff --git a/src/main/org/apache/tools/zip/ZipShort.java b/src/main/org/apache/tools/zip/ZipShort.java index 1c4ed51bc..f272c0c7c 100644 --- a/src/main/org/apache/tools/zip/ZipShort.java +++ b/src/main/org/apache/tools/zip/ZipShort.java @@ -38,7 +38,6 @@ public final class ZipShort implements Cloneable { /** * Create instance from bytes. - * * @since 1.1 */ public ZipShort (byte[] bytes) { @@ -47,17 +46,14 @@ public final class ZipShort implements Cloneable { /** * Create instance from the two bytes starting at offset. - * * @since 1.1 */ public ZipShort (byte[] bytes, int offset) { - value = (bytes[offset + 1] << 8) & 0xFF00; - value += (bytes[offset] & 0xFF); + value = ZipShort.getValue(bytes, offset); } /** * Get value as two bytes in big endian byte order. - * * @since 1.1 */ public byte[] getBytes() { @@ -69,13 +65,43 @@ public final class ZipShort implements Cloneable { /** * Get value as Java int. - * * @since 1.1 */ public int getValue() { return value; } + /** + * Get value as two bytes in big endian byte order. + */ + public static byte[] getBytes(int value){ + byte[] result = new byte[2]; + result[0] = (byte) (value & 0xFF); + result[1] = (byte) ((value & 0xFF00) >> 8); + return result; + } + + /** + * Helper method to get the value as a java int from two bytes starting at given array offset + * @param bytes the array of bytes + * @param offset the offset to start + * @return the correspondanding java int value + */ + public static int getValue(byte[] bytes, int offset){ + int value = (bytes[offset + 1] << 8) & 0xFF00; + value += (bytes[offset] & 0xFF); + return value; + } + + /** + * Helper method to get the value as a java int from a two-byte array + * @param bytes the array of bytes + * @return the correspondanding java int value + */ + public static int getValue(byte[] bytes){ + return getValue(bytes, 0); + } + /** * Override to make two instances with same value equal. *