[jboss-svn-commits] JBoss Common SVN: r3248 - jzipfile/trunk/src/main/java/org/jboss/jzipfile.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Jun 12 21:19:08 EDT 2009
Author: david.lloyd at jboss.com
Date: 2009-06-12 21:19:08 -0400 (Fri, 12 Jun 2009)
New Revision: 3248
Modified:
jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java
jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalogBuilder.java
Log:
Minor fixes and javadoc updates
Modified: jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java 2009-06-13 00:59:21 UTC (rev 3247)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java 2009-06-13 01:19:08 UTC (rev 3248)
@@ -54,7 +54,7 @@
}
/**
- * Fid the zip catalog for the given file. The returned input stream is positioned at the start of the zip
+ * Find the zip catalog for the given file. The returned input stream is positioned at the start of the zip
* directory structure.
*
* @param file the file to examine
@@ -62,44 +62,49 @@
* @throws IOException if an I/O error occurs
*/
public static InputStream findCatalog(File file) throws IOException {
+ boolean ok = false;
final RandomAccessFile raf = new RandomAccessFile(file, "r");
- final long len = raf.length();
- if (len < 22L) {
- throw new ZipException("The provided file is too short to hold even one end-of-central-directory record");
- }
- // First, check at len-22 in the (common) case that there is no zip file comment.
- raf.seek(len - 22);
- if (! catScan(raf, 0)) {
- // OK, let's back off incrementally, starting from 64 bytes out and going up by a factor of 4 each time
- int spos = 64;
- int lim = 64 - 22;
- raf.seek(len - 64);
- while (! catScan(raf, lim)) {
- int newSpos = spos << 2;
- lim = newSpos - spos;
- spos = newSpos;
- if (spos >= 65536) try {
- throw new ZipException("No directory found");
- } finally {
- safeClose(raf);
+ try {
+ final long len = raf.length();
+ if (len < 22L) {
+ throw new ZipException("The provided file is too short to hold even one end-of-central-directory record");
+ }
+ // First, check at len-22 in the (common) case that there is no zip file comment.
+ raf.seek(len - 22);
+ if (! catScan(raf, 0)) {
+ // OK, let's back off incrementally, starting from 64 bytes out and going up by a factor of 4 each time
+ int spos = 64;
+ int lim = 64 - 22;
+ raf.seek(len - 64);
+ while (! catScan(raf, lim)) {
+ int newSpos = spos << 2;
+ lim = newSpos - spos;
+ spos = newSpos;
+ if (spos >= 65536) {
+ throw new ZipException("No directory found");
+ }
+ raf.seek(len - spos);
}
- raf.seek(len - spos);
}
+ // OK, the EOD was located. Now read it to find the start of the directory
+ final int diskNo = Short.reverseBytes(raf.readShort()) & 0xffff; // disk #
+ final int cddNo = Short.reverseBytes(raf.readShort()) & 0xffff; // central dir disk #
+ final int diskEC = Short.reverseBytes(raf.readShort()) & 0xffff; // entry count in central dir # on this disk
+ final int totalEC = Short.reverseBytes(raf.readShort()) & 0xffff; // entry count in central dir #
+ if (diskNo != cddNo || cddNo != 0) {
+ throw new ZipException("Multi-disk zips not supported");
+ }
+ if (diskEC != totalEC) {
+ throw new ZipException("Entry count inconsistency in end-of-directory record");
+ }
+ raf.readInt(); // size of central dir
+ raf.seek(Integer.reverseBytes(raf.readInt())); // offset of central dir
+ final RandomAccessInputStream is = new RandomAccessInputStream(raf);
+ ok = true;
+ return is;
+ } finally {
+ if (! ok) safeClose(raf);
}
- // OK, the EOD was located. Now read it to find the start of the directory
- final int diskNo = Short.reverseBytes(raf.readShort()) & 0xffff; // disk #
- final int cddNo = Short.reverseBytes(raf.readShort()) & 0xffff; // central dir disk #
- final int diskEC = Short.reverseBytes(raf.readShort()) & 0xffff; // entry count in central dir # on this disk
- final int totalEC = Short.reverseBytes(raf.readShort()) & 0xffff; // entry count in central dir #
- if (diskNo != cddNo || cddNo != 0) {
- throw new ZipException("Multi-disk zips not supported");
- }
- if (diskEC != totalEC) {
- throw new ZipException("Entry count inconsistency in end-of-directory record");
- }
- raf.readInt(); // size of central dir
- raf.seek(Integer.reverseBytes(raf.readInt())); // offset of central dir
- return new RandomAccessInputStream(raf);
}
private static boolean catScan(DataInput input, int limit) throws IOException {
@@ -117,8 +122,8 @@
}
/**
- * Read the zip catalog referred to by the given input stream. The input stream should be pointed to the
- * start of the catalog. <b>Note:</b> the passed in
+ * Read the zip catalog referred to by the given input stream, which is pointed at the
+ * start of the catalog (also known as the "central directory"). <b>Note:</b> the passed in
* {@code InputStream} will be used and closed by this method.
*
* @param inputStream the input stream from which to build a catalog
@@ -127,7 +132,7 @@
*/
public static ZipCatalog readCatalog(InputStream inputStream) throws IOException {
final ZipCatalogBuilder builder = new ZipCatalogBuilder();
- builder.read(inputStream);
+ builder.readDirectory(inputStream);
return builder.getZipCatalog();
}
@@ -143,7 +148,9 @@
}
/**
- * Open a zip entry.
+ * Open a zip entry, returning an input stream which may be used to read the contents of the
+ * entry. Depending on how the entry is stored, the returned stream may or may not support
+ * {@code mark/reset}.
*
* @param zipFile the zip file to access
* @param zipEntry the zip entry from that file
@@ -227,6 +234,9 @@
* @throws IOException if an I/O error occurs
*/
public static void extract(File zipFile, File destDir) throws IOException {
+ if (! destDir.isDirectory()) {
+ throw new IOException("Destination is not a directory");
+ }
final byte[] buf = new byte[16384];
final ZipCatalog catalog = readCatalog(zipFile);
for (ZipEntry zipEntry : catalog.allEntries()) {
@@ -266,7 +276,7 @@
}
}
- private static void safeClose(final Closeable closeable) {
+ static void safeClose(final Closeable closeable) {
try {
if (closeable != null) closeable.close();
} catch (IOException e) {
Modified: jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalogBuilder.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalogBuilder.java 2009-06-13 00:59:21 UTC (rev 3247)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalogBuilder.java 2009-06-13 01:19:08 UTC (rev 3248)
@@ -29,8 +29,6 @@
import java.util.Collections;
import java.util.Collection;
import java.util.zip.ZipException;
-import java.util.zip.Inflater;
-import java.util.zip.InflaterInputStream;
import java.io.InputStream;
import java.io.IOException;
@@ -41,101 +39,105 @@
ZipCatalogBuilder() {
}
- void read(InputStream is) throws IOException {
+ void readDirectory(InputStream is) throws IOException {
readDirectory(is instanceof ZipDataInputStream ? (ZipDataInputStream) is : new ZipDataInputStream(is));
}
void readDirectory(ZipDataInputStream is) throws IOException {
- // Format:
- // central directory
- // [zip64 end of central directory rec]
- // [zip64 end of central directory locator]
- // end of central directory record
- int sig = is.readInt();
- while (sig == 0x02014b50) {
- // central directory file header (0..n)
- int madeBy = is.readUnsignedShort();
- int needed = is.readUnsignedShort();
- if (needed > 20) {
- throw new ZipException("Need a later version to extract");
+ try {
+ // Format:
+ // central directory
+ // [zip64 end of central directory rec]
+ // [zip64 end of central directory locator]
+ // end of central directory record
+ int sig = is.readInt();
+ while (sig == 0x02014b50) {
+ // central directory file header (0..n)
+ is.readUnsignedShort(); // madeBy
+ int needed = is.readUnsignedShort();
+ if (needed > 20) {
+ throw new ZipException("Need a later version to extract");
+ }
+ is.readUnsignedShort(); // gpbits
+ final ZipCompressionMethod method = ZipCompressionMethod.getMethod(is.readUnsignedShort());
+ int modTimeBytes = is.readUnsignedShort();
+ int modDateBytes = is.readUnsignedShort();
+ int crc32 = is.readInt();
+ int compSize = is.readInt();
+ int uncompSize = is.readInt();
+ int fnameLen = is.readUnsignedShort();
+ int extraLen = is.readUnsignedShort();
+ int commentLen = is.readUnsignedShort();
+ int diskNumStart = is.readUnsignedShort();
+ if (diskNumStart != 0) {
+ throw new ZipException("Multi-disk archives not supported");
+ }
+ is.readUnsignedShort(); // internal attr
+ is.readInt(); // external attr
+ int localHeaderOffs = is.readInt();
+ final byte[] fileNameBytes = new byte[fnameLen];
+ is.readFully(fileNameBytes);
+ final byte[] extraBytes = new byte[extraLen];
+ is.readFully(extraBytes);
+ final byte[] commentBytes = new byte[commentLen];
+ is.readFully(commentBytes);
+ final String name = new String(fileNameBytes, "US-ASCII");
+ // interpret type
+ final ZipEntryType type;
+ if (name.indexOf('/') == 0) {
+ throw new ZipException("Leading slash not allowed in file name \"" + name + "\"");
+ }
+ if (uncompSize == 0 && name.lastIndexOf('/') == name.length() - 1) {
+ type = ZipEntryType.DIRECTORY;
+ } else {
+ type = ZipEntryType.FILE;
+ }
+ final String comment = new String(commentBytes, "US-ASCII");
+ final ZipEntryImpl entry = new ZipEntryImpl(name, comment, localHeaderOffs, uncompSize & 0xffffffffL, compSize & 0xffffffffL, crc32, type, 0L, method, extraBytes);
+ allEntries.add(entry);
+ entryMap.put(name, entry);
+ // next sig
+ sig = is.readInt();
}
- int gpbits = is.readUnsignedShort();
- final ZipCompressionMethod method = ZipCompressionMethod.getMethod(is.readUnsignedShort());
- int modTimeBytes = is.readUnsignedShort();
- int modDateBytes = is.readUnsignedShort();
- int crc32 = is.readInt();
- int compSize = is.readInt();
- int uncompSize = is.readInt();
- int fnameLen = is.readUnsignedShort();
- int extraLen = is.readUnsignedShort();
- int commentLen = is.readUnsignedShort();
- int diskNumStart = is.readUnsignedShort();
- if (diskNumStart != 0) {
- throw new ZipException("Multi-disk archives not supported");
+ if (sig == 0x05054b50) {
+ // central directory signature (0..1)
+ final int size = is.readUnsignedShort();
+ is.skipFully(size & 0xffffffffL);
+
+ // next sig
+ sig = is.readInt();
}
- int internalAttr = is.readUnsignedShort();
- int externalAttr = is.readInt();
- int localHeaderOffs = is.readInt();
- final byte[] fileNameBytes = new byte[fnameLen];
- is.readFully(fileNameBytes);
- final byte[] extraBytes = new byte[extraLen];
- is.readFully(extraBytes);
- final byte[] commentBytes = new byte[commentLen];
- is.readFully(commentBytes);
- final String name = new String(fileNameBytes, "US-ASCII");
- // interpret type
- final ZipEntryType type;
- if (name.indexOf('/') == 0) {
- throw new ZipException("Leading slash not allowed in file name \"" + name + "\"");
+ if (sig == 0x06064b50) {
+ if (true) throw new ZipException("64-bit zip records unsupported");
+ // zip64 EOD record (0..1)
+ is.readLong();
+ is.readUnsignedShort();
+ is.readUnsignedShort();
+ is.readInt();
+ is.readInt();
+ is.readLong();
+ is.readLong();
+ is.readLong();
+ is.readLong();
+ // next sig
+ sig = is.readInt();
}
- if (uncompSize == 0 && name.lastIndexOf('/') == name.length() - 1) {
- type = ZipEntryType.DIRECTORY;
- } else {
- type = ZipEntryType.FILE;
+ if (sig == 0x07064b50) {
+ if (true) throw new ZipException("64-bit zip records unsupported");
+ // zip64 EOD locator (0..1)
+
+ // next sig
+ sig = is.readInt();
}
- final String comment = new String(commentBytes, "US-ASCII");
- final ZipEntryImpl entry = new ZipEntryImpl(name, comment, localHeaderOffs, uncompSize & 0xffffffffL, compSize & 0xffffffffL, crc32, type, 0L, method, extraBytes);
- allEntries.add(entry);
- entryMap.put(name, entry);
- // next sig
- sig = is.readInt();
+ if (sig == 0x06054b50) {
+ // EOD (exactly 1)
+ is.close();
+ return;
+ }
+ throw new ZipException(String.format("Unexpected signature byte 0x%08x", Integer.valueOf(sig)));
+ } finally {
+ Zip.safeClose(is);
}
- if (sig == 0x05054b50) {
- // central directory signature (0..1)
- final int size = is.readUnsignedShort();
- is.skipFully(size & 0xffffffffL);
-
- // next sig
- sig = is.readInt();
- }
- if (sig == 0x06064b50) {
- if (true) throw new ZipException("64-bit zip records unsupported");
- // zip64 EOD record (0..1)
- is.readLong();
- is.readUnsignedShort();
- is.readUnsignedShort();
- is.readInt();
- is.readInt();
- is.readLong();
- is.readLong();
- is.readLong();
- is.readLong();
- // next sig
- sig = is.readInt();
- }
- if (sig == 0x07064b50) {
- if (true) throw new ZipException("64-bit zip records unsupported");
- // zip64 EOD locator (0..1)
-
- // next sig
- sig = is.readInt();
- }
- if (sig == 0x06054b50) {
- // EOD (exactly 1)
- is.close();
- return;
- }
- throw new ZipException(String.format("Unexpected signature byte 0x%08x", Integer.valueOf(sig)));
}
public ZipCatalog getZipCatalog() {
More information about the jboss-svn-commits
mailing list