[jboss-svn-commits] JBoss Common SVN: r3246 - in jzipfile/trunk: src and 11 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jun 12 20:55:58 EDT 2009


Author: david.lloyd at jboss.com
Date: 2009-06-12 20:55:58 -0400 (Fri, 12 Jun 2009)
New Revision: 3246

Added:
   jzipfile/trunk/pom.xml
   jzipfile/trunk/src/
   jzipfile/trunk/src/main/
   jzipfile/trunk/src/main/java/
   jzipfile/trunk/src/main/java/org/
   jzipfile/trunk/src/main/java/org/jboss/
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/EmptyInputStream.java
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/LimitedInputStream.java
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/RandomAccessInputStream.java
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalog.java
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalogBuilder.java
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCompressionMethod.java
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipDataInputStream.java
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntry.java
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntryImpl.java
   jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntryType.java
   jzipfile/trunk/src/test/
   jzipfile/trunk/src/test/java/
   jzipfile/trunk/src/test/java/org/
   jzipfile/trunk/src/test/java/org/jboss/
   jzipfile/trunk/src/test/java/org/jboss/jzipfile/
   jzipfile/trunk/src/test/java/org/jboss/jzipfile/SimpleZipFilesTests.java
   jzipfile/trunk/src/test/resources/
   jzipfile/trunk/src/test/resources/empty.zip
   jzipfile/trunk/src/test/resources/single-deflated.zip
   jzipfile/trunk/src/test/resources/single-stored.zip
Modified:
   jzipfile/trunk/
Log:
Initial import: jzipfile simplified zip file reader


Property changes on: jzipfile/trunk
___________________________________________________________________
Name: svn:ignore
   + target


Added: jzipfile/trunk/pom.xml
===================================================================
--- jzipfile/trunk/pom.xml	                        (rev 0)
+++ jzipfile/trunk/pom.xml	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,74 @@
+<!--
+  ~ JBoss, Home of Professional Open Source.
+  ~ Copyright 2009, Red Hat Middleware LLC, and individual contributors
+  ~ as indicated by the @author tags. See the copyright.txt file in the
+  ~ distribution for a full listing of individual contributors.
+  ~
+  ~ This is free software; you can redistribute it and/or modify it
+  ~ under the terms of the GNU Lesser General Public License as
+  ~ published by the Free Software Foundation; either version 2.1 of
+  ~ the License, or (at your option) any later version.
+  ~
+  ~ This software 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
+  ~ Lesser General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public
+  ~ License along with this software; if not, write to the Free
+  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.jboss.jzipfil</groupId>
+    <artifactId>jzipfile</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+    <dependencies>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <classifier>jdk15</classifier>
+            <version>5.8</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.0.2</version>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-source-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+    <distributionManagement>
+        <repository>
+            <id>repository.jboss.org</id>
+            <name>JBoss Maven2 Repository</name>
+            <url>http://repository.jboss.org/maven2</url>
+        </repository>
+    </distributionManagement>
+</project>

Added: jzipfile/trunk/src/main/java/org/jboss/jzipfile/EmptyInputStream.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/EmptyInputStream.java	                        (rev 0)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/EmptyInputStream.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+final class EmptyInputStream extends InputStream {
+    public static final InputStream INSTANCE = new EmptyInputStream();
+
+    private EmptyInputStream() {
+    }
+
+    public int read(final byte[] b) throws IOException {
+        return -1;
+    }
+
+    public int read(final byte[] b, final int off, final int len) throws IOException {
+        return -1;
+    }
+
+    public int read() throws IOException {
+        return -1;
+    }
+
+    public int available() throws IOException {
+        return 0;
+    }
+}

Added: jzipfile/trunk/src/main/java/org/jboss/jzipfile/LimitedInputStream.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/LimitedInputStream.java	                        (rev 0)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/LimitedInputStream.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+import java.io.InputStream;
+import java.io.IOException;
+import static java.lang.StrictMath.min;
+
+class LimitedInputStream extends InputStream {
+
+    private final InputStream delegate;
+    private long limit;
+
+    LimitedInputStream(final InputStream delegate, final long limit) {
+        this.delegate = delegate;
+        this.limit = limit;
+    }
+
+    public int read() throws IOException {
+        if (limit > 0) {
+            final int b = delegate.read();
+            if (b == -1) {
+                limit = 0;
+            }
+            return b;
+        }
+        return -1;
+    }
+
+    public int read(final byte[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    public int read(final byte[] b, final int off, final int len) throws IOException {
+        if (limit == 0) {
+            return -1;
+        }
+        final int cnt = delegate.read(b, off, (int)min(limit, len));
+        if (cnt > 0) {
+            limit -= (long)cnt;
+        } else {
+            limit = 0;
+        }
+        return cnt;
+    }
+
+    public long skip(final long n) throws IOException {
+        final long cnt = delegate.skip(min(n, limit));
+        limit -= cnt;
+        return cnt;
+    }
+
+    public int available() throws IOException {
+        return delegate.available();
+    }
+
+    public void close() throws IOException {
+        limit = 0;
+        delegate.close();
+    }
+}

Added: jzipfile/trunk/src/main/java/org/jboss/jzipfile/RandomAccessInputStream.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/RandomAccessInputStream.java	                        (rev 0)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/RandomAccessInputStream.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,65 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.io.IOException;
+
+class RandomAccessInputStream extends InputStream {
+
+    private long ptr;
+    private final RandomAccessFile delegate;
+
+    public RandomAccessInputStream(final RandomAccessFile delegate) {
+        this.delegate = delegate;
+    }
+
+    public int read() throws IOException {
+        return delegate.read();
+    }
+
+    public int read(final byte[] b, final int off, final int len) throws IOException {
+        return delegate.read(b, off, len);
+    }
+
+    public void mark(final int readlimit) {
+        try {
+            ptr = delegate.getFilePointer();
+        } catch (IOException e) {
+            throw new IllegalStateException();
+        }
+    }
+
+    public void reset() throws IOException {
+        delegate.seek(ptr);
+    }
+
+    public boolean markSupported() {
+        return true;
+    }
+
+    public void close() throws IOException {
+        delegate.close();
+    }
+}

Added: jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java	                        (rev 0)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/Zip.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,276 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.RandomAccessFile;
+import java.io.DataInput;
+import java.io.FileOutputStream;
+import java.io.Closeable;
+import java.util.zip.ZipException;
+import java.util.zip.InflaterInputStream;
+import java.util.zip.Inflater;
+
+/**
+ * Zip file manipulation methods.
+ */
+public final class Zip {
+
+    private Zip() {
+    }
+
+    /**
+     * Read the zip catalog of the given file.
+     *
+     * @param file the file to read
+     * @return the built catalog
+     * @throws IOException if an I/O error occurs
+     */
+    public static ZipCatalog readCatalog(File file) throws IOException {
+        return readCatalog(findCatalog(file));
+    }
+
+    /**
+     * Fid 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
+     * @return an input stream positioned at the start of the catalog
+     * @throws IOException if an I/O error occurs
+     */
+    public static InputStream findCatalog(File file) throws IOException {
+        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);
+                }
+                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
+        return new RandomAccessInputStream(raf);
+    }
+
+    private static boolean catScan(DataInput input, int limit) throws IOException {
+        // RAF uses big-endian... :-P
+        int sig = Integer.reverseBytes(input.readInt());
+        do {
+            if (sig == 0x06054b50) {
+                return true;
+            }
+            if (limit-- > 0) {
+                sig = (sig >>> 8) | (input.readUnsignedByte() << 24);
+            }
+        } while (limit > 0);
+        return false;
+    }
+
+    /**
+     * 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
+     * {@code InputStream} will be used and closed by this method.
+     *
+     * @param inputStream the input stream from which to build a catalog
+     * @return the built catalog
+     * @throws IOException if an I/O error occurs
+     */
+    public static ZipCatalog readCatalog(InputStream inputStream) throws IOException {
+        final ZipCatalogBuilder builder = new ZipCatalogBuilder();
+        builder.read(inputStream);
+        return builder.getZipCatalog();
+    }
+
+    /**
+     * Read the zip catalog of the given file.
+     *
+     * @param fileName the name of the file to read
+     * @return the built catalog
+     * @throws IOException if an I/O error occurs
+     */
+    public static ZipCatalog readCatalog(String fileName) throws IOException {
+        return readCatalog(new File(fileName));
+    }
+
+    /**
+     * Open a zip entry.
+     *
+     * @param zipFile the zip file to access
+     * @param zipEntry the zip entry from that file
+     * @return an {@code InputStream} which may be used to read the zip file entry data
+     * @throws IOException if an I/O error occurs
+     */
+    public static InputStream openEntry(File zipFile, ZipEntry zipEntry) throws IOException {
+        final FileInputStream fis = new FileInputStream(zipFile);
+        new ZipDataInputStream(fis).skipFully(zipEntry.getOffset());
+        return openEntry(fis, zipEntry);
+    }
+
+    /**
+     * Open a zip entry.  The given input stream must be located at the start of the zip entry's data.  When the
+     * returned input stream is closed, the provided input stream will be closed as well.
+     *
+     * @param inputStream the input stream
+     * @param zipEntry the zip entry
+     * @return an uncompressing input stream
+     * @throws IOException if an I/O error occurs
+     */
+    public static InputStream openEntry(InputStream inputStream, ZipEntry zipEntry) throws IOException {
+        // read the local file header...
+        final ZipDataInputStream zdis = inputStream instanceof ZipDataInputStream ? (ZipDataInputStream) inputStream : new ZipDataInputStream(inputStream);
+        readLocalFile(zdis, zipEntry);
+        switch (zipEntry.getEntryType()) {
+            case FILE: break;
+            default: {
+                throw new ZipException("Attempt to open a zip entry with an unsupported type");
+            }
+        }
+        switch (zipEntry.getCompressionMethod()) {
+            case STORE: {
+                return new LimitedInputStream(inputStream, zipEntry.getCompressedSize());
+            }
+            case DEFLATE: {
+                final Inflater inflater = new Inflater(true);
+                return new LimitedInputStream(new InflaterInputStream(new LimitedInputStream(inputStream, zipEntry.getCompressedSize()), inflater), zipEntry.getSize());
+            }
+        }
+        throw new ZipException("Unsupported compression algorithm " + zipEntry.getCompressionMethod());
+    }
+
+    private static void readLocalFile(final ZipDataInputStream is, final ZipEntry entry) throws IOException {
+        // main header
+        final int sig = is.readInt();
+        if (sig != 0x04034b50) {
+            throw new ZipException("Corrupted zip entry (local file header signature is incorrect)");
+        }
+        final int extVers = is.readUnsignedShort();
+        if (extVers > 20) {
+            throw new ZipException("Entry requires a later version to extract");
+        }
+        is.readUnsignedShort(); // GP bits - may be needed for some methods?
+        final ZipCompressionMethod method = ZipCompressionMethod.getMethod(is.readUnsignedShort());
+        is.readInt(); // local mod time
+        is.readInt(); // local crc32 (usually 0)
+        is.readInt(); // compressed size (header) (usually 0)
+        is.readInt(); // uncomp size (header) (usually 0)
+        final int fnameLen = is.readUnsignedShort();
+        final int extraLen = is.readUnsignedShort();
+        final byte[] fileNameBytes = new byte[fnameLen];
+        is.readFully(fileNameBytes);
+        final ZipCompressionMethod expectedMethod = entry.getCompressionMethod();
+        if (! expectedMethod.equals(method)) {
+            throw new ZipException(String.format("Compression methods do not match (expected \"%s\", got \"%s\")", expectedMethod, method));
+        }
+        final String actualFileName = new String(fileNameBytes, "US-ASCII");
+        final String expectFileName = entry.getName();
+        if (! expectFileName.equals(actualFileName)) {
+            throw new ZipException(String.format("File names do not match (expected \"%s\", got \"%s\")", expectFileName, actualFileName));
+        }
+        is.skipFully(extraLen);
+    }
+
+    /**
+     * Extract a zip file (in entirety) to a destination directory.
+     *
+     * @param zipFile the zip file
+     * @param destDir the destination directory
+     * @throws IOException if an I/O error occurs
+     */
+    public static void extract(File zipFile, File destDir) throws IOException {
+        final byte[] buf = new byte[16384];
+        final ZipCatalog catalog = readCatalog(zipFile);
+        for (ZipEntry zipEntry : catalog.allEntries()) {
+            final String name = zipEntry.getName();
+            final ZipEntryType entryType = zipEntry.getEntryType();
+            if (entryType == ZipEntryType.DIRECTORY) {
+                new File(destDir, name).mkdirs();
+            } else if (entryType == ZipEntryType.FILE) {
+                final File file = new File(destDir, name).getCanonicalFile();
+                final File parentFile = file.getParentFile();
+                if (parentFile != null) {
+                    parentFile.mkdirs();
+                }
+                file.delete();
+                final FileOutputStream fos = new FileOutputStream(file);
+                try {
+                    final InputStream inputStream = Zip.openEntry(zipFile, zipEntry);
+                    try {
+                        for (;;) {
+                            final int cnt = inputStream.read(buf);
+                            if (cnt == -1) {
+                                inputStream.close();
+                                fos.close();
+                                break;
+                            }
+                            fos.write(buf, 0, cnt);
+                        }
+                    } finally {
+                        safeClose(inputStream);
+                    }
+                } finally {
+                    safeClose(fos);
+                }
+            } else {
+                // skip unknown entry
+            }
+        }
+    }
+
+    private static void safeClose(final Closeable closeable) {
+        try {
+            if (closeable != null) closeable.close();
+        } catch (IOException e) {
+            // eat
+        }
+    }
+}

Added: jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalog.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalog.java	                        (rev 0)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalog.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,34 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+import java.util.Map;
+
+/**
+ * A zip file catalog.
+ */
+public interface ZipCatalog {
+    Map<String, ZipEntry> indexedByName();
+
+    Iterable<ZipEntry> allEntries();
+}

Added: jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalogBuilder.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalogBuilder.java	                        (rev 0)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCatalogBuilder.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,154 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+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;
+
+final class ZipCatalogBuilder {
+    private final Map<String, ZipEntry> entryMap = new LinkedHashMap<String, ZipEntry>();
+    private final List<ZipEntry> allEntries = new ArrayList<ZipEntry>();
+
+    ZipCatalogBuilder() {
+    }
+
+    void read(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");
+            }
+            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");
+            }
+            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 (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();
+        }
+        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() {
+        final Map<String, ZipEntry> byNameMap = Collections.unmodifiableMap(entryMap);
+        final Collection<ZipEntry> allEntries = Collections.unmodifiableCollection(ZipCatalogBuilder.this.allEntries);
+        return new ZipCatalog() {
+            public Map<String, ZipEntry> indexedByName() {
+                return byNameMap;
+            }
+
+            public Iterable<ZipEntry> allEntries() {
+                return allEntries;
+            }
+        };
+    }
+}

Added: jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCompressionMethod.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCompressionMethod.java	                        (rev 0)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipCompressionMethod.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,73 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+/**
+ * Possible compression methods.
+ */
+public enum ZipCompressionMethod {
+    STORE,
+    SHRINK,
+    REDUCE_1,
+    REDUCE_2,
+    REDUCE_3,
+    REDUCE_4,
+    IMPLODE,
+    DEFLATE,
+    DEFLATE64,
+    BZIP2,
+    LZMA,
+    TERSE,
+    LZ77,
+    WAVPAK,
+    PPMD,
+
+    UNKNOWN;
+
+    /**
+     * Get the compression method for the given code.
+     *
+     * @param code the compression method code
+     * @return the compression method, or {@link #UNKNOWN} if it is not recognized
+     */
+    public static ZipCompressionMethod getMethod(int code) {
+        switch (code) {
+            case 0: return STORE;
+            case 1: return SHRINK;
+            case 2: return REDUCE_1;
+            case 3: return REDUCE_2;
+            case 4: return REDUCE_3;
+            case 5: return REDUCE_4;
+            case 6: return IMPLODE;
+            case 8: return DEFLATE;
+            case 9: return DEFLATE64;
+            case 12: return BZIP2;
+            case 14: return LZMA;
+            case 18: return TERSE;
+            case 19: return LZ77;
+            case 97: return WAVPAK;
+            case 98: return PPMD;
+            default: return UNKNOWN;
+        }
+    }
+}

Added: jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipDataInputStream.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipDataInputStream.java	                        (rev 0)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipDataInputStream.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,184 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.RandomAccessFile;
+import java.io.DataInput;
+
+/**
+ * Similar to {@code DataInputStream}, but reads in little-endian order and keeps track
+ * of the current offset.
+ */
+final class ZipDataInputStream extends InputStream implements DataInput {
+
+    private final InputStream delegate;
+    private long offset;
+
+    ZipDataInputStream(final InputStream delegate) {
+        this.delegate = delegate;
+    }
+
+    ZipDataInputStream(final RandomAccessFile delegate) {
+        this.delegate = new RandomAccessInputStream(delegate);
+    }
+
+    public int read() throws IOException {
+        final int b = delegate.read();
+        if (b >= 0) {
+            offset++;
+            return b & 0xff;
+        }
+        return b;
+    }
+
+    public int read(final byte[] b, final int off, final int len) throws IOException {
+        int cnt = delegate.read(b, off, len);
+        if (cnt >= 0) {
+            offset += (long)cnt;
+        }
+        return cnt;
+    }
+
+    public long skip(final long n) throws IOException {
+        final long cnt = delegate.skip(n);
+        offset += cnt;
+        return cnt;
+    }
+
+    public void skipFully(long n) throws IOException {
+        while (n > 0L) {
+            final long cnt = skip(n);
+            if (cnt <= 0L) {
+                readByte();
+                n--;
+            } else {
+                n -= cnt;
+            }
+        }
+    }
+
+    public void close() throws IOException {
+        delegate.close();
+    }
+
+    public long getOffset() {
+        return offset;
+    }
+
+    public void readFully(final byte[] b) throws IOException {
+        readFully(b, 0, b.length);
+    }
+
+    public void readFully(final byte[] b, int offs, int len) throws IOException {
+        while (len > 0) {
+            int cnt = read(b, offs, len);
+            if (cnt == -1) {
+                throw new EOFException();
+            }
+            offs += cnt;
+            len -= cnt;
+        }
+    }
+
+    public long readLong() throws IOException {
+        int a = readInt();
+        int b = readInt();
+        return ((long)a) | ((long)b) << 0x20L;
+    }
+
+    public int readInt() throws IOException {
+        int a = read();
+        int b = read();
+        int c = read();
+        int d = read();
+        if (a == -1 || b == -1 || c == -1 || d == -1) {
+            throw new EOFException();
+        }
+        return a | (b << 0x8) | (c << 0x10) | (d << 0x18);
+    }
+
+    public int readUnsignedShort() throws IOException {
+        int a = read();
+        int b = read();
+        if (a == -1 || b == -1) {
+            throw new EOFException();
+        }
+        return a | b << 0x8;
+    }
+
+    public short readShort() throws IOException {
+        int a = read();
+        int b = read();
+        if (a == -1 || b == -1) {
+            throw new EOFException();
+        }
+        return (short) (a & 0xff | (b & 0xff) << 0x8);
+    }
+
+    public int readUnsignedByte() throws IOException {
+        int a = read();
+        if (a == -1) {
+            throw new EOFException();
+        }
+        return a;
+    }
+
+    public byte readByte() throws IOException {
+        int a = read();
+        if (a == -1) {
+            throw new EOFException();
+        }
+        return (byte) a;
+    }
+
+    public int skipBytes(final int n) throws IOException {
+        return (int) skip(n);
+    }
+
+    public boolean readBoolean() throws IOException {
+        return readByte() != 0;
+    }
+
+    public char readChar() throws IOException {
+        return (char) readUnsignedShort();
+    }
+
+    public float readFloat() throws IOException {
+        return Float.intBitsToFloat(readInt());
+    }
+
+    public double readDouble() throws IOException {
+        return Double.longBitsToDouble(readLong());
+    }
+
+    public String readLine() throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    public String readUTF() throws IOException {
+        return null;
+    }
+}

Added: jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntry.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntry.java	                        (rev 0)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntry.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,99 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+/**
+ * A zip entry.
+ */
+public interface ZipEntry {
+
+    /**
+     * Get the name of this entry.
+     *
+     * @return the name
+     */
+    String getName();
+
+    /**
+     * Get the comment associated with this zip entry.
+     *
+     * @return the comment
+     */
+    String getComment();
+
+    /**
+     * Get the offset of the data for this zip entry within the file.
+     *
+     * @return the byte offset from the start of the zip file
+     */
+    long getOffset();
+
+    /**
+     * Get the size (uncompressed) of this entry.
+     *
+     * @return the size in bytes
+     */
+    long getSize();
+
+    /**
+     * Get the compressed size of this entry.
+     *
+     * @return the size in bytes
+     */
+    long getCompressedSize();
+
+    /**
+     * Get the CRC-32 checksum of this entry, if there is one.
+     *
+     * @return the checksum
+     */
+    int getCrc32();
+
+    /**
+     * Get the entry type.
+     *
+     * @return the entry type (will not be {@code null})
+     */
+    ZipEntryType getEntryType();
+
+    /**
+     * Get the entry modification time.
+     *
+     * @return the modification time
+     */
+    long getModificationTime();
+
+    /**
+     * Get the compression method.
+     *
+     * @return the compression method (will not be {@code null})
+     */
+    ZipCompressionMethod getCompressionMethod();
+
+    /**
+     * Get the raw extra data bytes.
+     *
+     * @return the extra data bytes
+     */
+    byte[] getRawExtraData();
+}

Added: jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntryImpl.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntryImpl.java	                        (rev 0)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntryImpl.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,93 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+final class ZipEntryImpl implements ZipEntry {
+    private final String name;
+    private final String comment;
+    private final long offset;
+    private final long size;
+    private final long compressedSize;
+    private final int crc32;
+    private final ZipEntryType entryType;
+    private final long modificationTime;
+    private final ZipCompressionMethod compressionMethod;
+    private final byte[] rawExtraData;
+
+    ZipEntryImpl(final String name, final String comment, final long offset, final long size, final long compressedSize, final int crc32, final ZipEntryType entryType, final long modificationTime, final ZipCompressionMethod compressionMethod, final byte[] rawExtraData) {
+        this.name = name;
+        this.comment = comment;
+        this.offset = offset;
+        this.size = size;
+        this.compressedSize = compressedSize;
+        this.crc32 = crc32;
+        this.entryType = entryType;
+        this.modificationTime = modificationTime;
+        this.compressionMethod = compressionMethod;
+        this.rawExtraData = rawExtraData;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getComment() {
+        return comment;
+    }
+
+    public long getOffset() {
+        return offset;
+    }
+
+    public long getSize() {
+        return size;
+    }
+
+    public long getCompressedSize() {
+        return compressedSize;
+    }
+
+    public int getCrc32() {
+        return crc32;
+    }
+
+    public ZipEntryType getEntryType() {
+        return entryType;
+    }
+
+    public long getModificationTime() {
+        return modificationTime;
+    }
+
+    public ZipCompressionMethod getCompressionMethod() {
+        return compressionMethod;
+    }
+
+    public byte[] getRawExtraData() {
+        return rawExtraData;
+    }
+
+    public String toString() {
+        return String.format("Zip Entry: name=\"%s\", compressed size=%d, uncompressed size=%d, offset=%d, type=%s, method=%s, crc32=0x%08x, comment=\"%s\"", name, Long.valueOf(compressedSize), Long.valueOf(size), Long.valueOf(offset), entryType, compressionMethod, Integer.valueOf(crc32), comment);
+    }
+}

Added: jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntryType.java
===================================================================
--- jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntryType.java	                        (rev 0)
+++ jzipfile/trunk/src/main/java/org/jboss/jzipfile/ZipEntryType.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+/**
+ * Possible entry types.
+ */
+public enum ZipEntryType {
+    FILE,
+    DIRECTORY,
+
+    UNKNOWN
+}

Added: jzipfile/trunk/src/test/java/org/jboss/jzipfile/SimpleZipFilesTests.java
===================================================================
--- jzipfile/trunk/src/test/java/org/jboss/jzipfile/SimpleZipFilesTests.java	                        (rev 0)
+++ jzipfile/trunk/src/test/java/org/jboss/jzipfile/SimpleZipFilesTests.java	2009-06-13 00:55:58 UTC (rev 3246)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.jzipfile;
+
+import org.testng.annotations.Test;
+import static org.testng.AssertJUnit.*;
+import java.io.IOException;
+import java.io.File;
+import java.io.InputStream;
+import java.util.Iterator;
+
+ at Test
+public final class SimpleZipFilesTests {
+
+    private static File testFile(String name) {
+        return new File("src/test/resources/" + name);
+    }
+
+    public void testEmpty() throws IOException {
+        final ZipCatalog catalog = Zip.readCatalog(testFile("empty.zip"));
+        assertFalse("Unexpected content in empty zip", catalog.allEntries().iterator().hasNext());
+        assertFalse("Unexpected content in empty zip map", catalog.indexedByName().entrySet().iterator().hasNext());
+    }
+
+    public void testStored() throws IOException {
+        final File file = testFile("single-stored.zip");
+        final ZipCatalog catalog = Zip.readCatalog(file);
+        final Iterator<ZipEntry> i = catalog.allEntries().iterator();
+        assertTrue("Missing entry", i.hasNext());
+        final ZipEntry entry = i.next();
+        assertFalse("Extra entry", i.hasNext());
+        // now open it
+        final InputStream inputStream = Zip.openEntry(file, entry);
+        // read a few bytes
+        inputStream.read(new byte[64]);
+        inputStream.close();
+    }
+
+    public void testDeflated() throws IOException {
+        final File file = testFile("single-deflated.zip");
+        final ZipCatalog catalog = Zip.readCatalog(file);
+        final Iterator<ZipEntry> i = catalog.allEntries().iterator();
+        assertTrue("Missing entry", i.hasNext());
+        final ZipEntry entry = i.next();
+        assertFalse("Extra entry", i.hasNext());
+        // now open it
+        final InputStream inputStream = Zip.openEntry(file, entry);
+        // read a few bytes
+        inputStream.read(new byte[64]);
+        inputStream.close();
+    }
+}

Added: jzipfile/trunk/src/test/resources/empty.zip
===================================================================
(Binary files differ)


Property changes on: jzipfile/trunk/src/test/resources/empty.zip
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: jzipfile/trunk/src/test/resources/single-deflated.zip
===================================================================
(Binary files differ)


Property changes on: jzipfile/trunk/src/test/resources/single-deflated.zip
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: jzipfile/trunk/src/test/resources/single-stored.zip
===================================================================
(Binary files differ)


Property changes on: jzipfile/trunk/src/test/resources/single-stored.zip
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream




More information about the jboss-svn-commits mailing list