commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bode...@apache.org
Subject svn commit: r758896 - in /commons/proper/compress/trunk/src: main/java/org/apache/commons/compress/archivers/zip/ test/java/org/apache/commons/compress/archivers/zip/
Date Thu, 26 Mar 2009 22:30:00 GMT
Author: bodewig
Date: Thu Mar 26 22:29:59 2009
New Revision: 758896

URL: http://svn.apache.org/viewvc?rev=758896&view=rev
Log:
support as much as possible of ZipFile as a stream can do in ZipArchiveInputStream, COMPRESS-47

Modified:
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipLong.java
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java
    commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/UTF8ZipFilesTest.java

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java?rev=758896&r1=758895&r2=758896&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java
(original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveEntry.java
Thu Mar 26 22:29:59 2009
@@ -55,6 +55,7 @@
      */
     public ZipArchiveEntry(java.util.zip.ZipEntry entry) throws ZipException {
         super(entry);
+        setName(entry.getName());
         byte[] extra = entry.getExtra();
         if (extra != null) {
             setExtraFields(ExtraFieldUtils.parse(extra));

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java?rev=758896&r1=758895&r2=758896&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
(original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
Thu Mar 26 22:29:59 2009
@@ -18,41 +18,250 @@
  */
 package org.apache.commons.compress.archivers.zip;
 
+import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.zip.ZipInputStream;
+import java.io.PushbackInputStream;
+import java.util.zip.CRC32;
+import java.util.zip.DataFormatException;
+import java.util.zip.Inflater;
+import java.util.zip.ZipException;
 
 import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.ArchiveInputStream;
 
 public class ZipArchiveInputStream extends ArchiveInputStream {
 
-    private final ZipInputStream input;
+    private static final int SHORT = 2;
+    private static final int WORD = 4;
+
+    /**
+     * The zip encoding to use for filenames and the file comment.
+     */
+    private final ZipEncoding zipEncoding;
+
+    /**
+     * Whether to look for and use Unicode extra fields.
+     */
+    private final boolean useUnicodeExtraFields;
+
+    private final InputStream in;
+
+    private final Inflater inf = new Inflater(true);
+    private final CRC32 crc = new CRC32();
+
+    private final byte[] SINGLE = new byte[1];
+    private final byte[] buf = new byte[ZipArchiveOutputStream.BUFFER_SIZE];
+
+    private ZipArchiveEntry current = null;
+    private boolean closed = false;
+    private boolean hitCentralDirectory = false;
+    private int readBytesOfEntry = 0, offsetInBuffer = 0;
+    private int bytesReadFromStream = 0;
+    private int lengthOfLastRead = 0;
+    private boolean hasDataDescriptor = false;
+
+    private static final int LFH_LEN = 30;
+    /*
+      local file header signature     4 bytes  (0x04034b50)
+      version needed to extract       2 bytes
+      general purpose bit flag        2 bytes
+      compression method              2 bytes
+      last mod file time              2 bytes
+      last mod file date              2 bytes
+      crc-32                          4 bytes
+      compressed size                 4 bytes
+      uncompressed size               4 bytes
+      file name length                2 bytes
+      extra field length              2 bytes
+    */
 
     public ZipArchiveInputStream(InputStream inputStream) {
-        input = new ZipInputStream(inputStream);
+        this(inputStream, ZipEncodingHelper.UTF8, true);
+    }
+
+    /**
+     * @param encoding the encoding to use for file names, use null
+     * for the platform's default encoding
+     * @param useUnicodeExtraFields whether to use InfoZIP Unicode
+     * Extra Fields (if present) to set the file names.
+     */
+    public ZipArchiveInputStream(InputStream inputStream,
+                                 String encoding,
+                                 boolean useUnicodeExtraFields) {
+        zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
+        this.useUnicodeExtraFields = useUnicodeExtraFields;
+        in = new PushbackInputStream(inputStream, buf.length);
     }
 
     public ZipArchiveEntry getNextZipEntry() throws IOException {
-        java.util.zip.ZipEntry entry = input.getNextEntry();
-        if(entry == null) {
+        if (closed || hitCentralDirectory) {
             return null;
         }
-        return new ZipArchiveEntry(entry);
+        if (current != null) {
+            closeEntry();
+        }
+        int x = 0, count = 0;
+        byte[] lfh = new byte[LFH_LEN];
+        try {
+            readFully(lfh);
+        } catch (EOFException e) {
+            return null;
+        }
+        ZipLong sig = new ZipLong(lfh);
+        if (sig.equals(ZipLong.CFH_SIG)) {
+            hitCentralDirectory = true;
+            return null;
+        }
+        if (!sig.equals(ZipLong.LFH_SIG)) {
+            return null;
+        }
+
+        int off = WORD;
+        current = new ZipArchiveEntry();
+
+        int versionMadeBy = ZipShort.getValue(lfh, off);
+        off += SHORT;
+        current.setPlatform((versionMadeBy >> ZipFile.BYTE_SHIFT)
+                            & ZipFile.NIBLET_MASK);
+
+        final int generalPurposeFlag = ZipShort.getValue(lfh, off);
+        final boolean hasEFS = 
+            (generalPurposeFlag & ZipArchiveOutputStream.EFS_FLAG) != 0;
+        final ZipEncoding entryEncoding =
+            hasEFS ? ZipEncodingHelper.UTF8_ZIP_ENCODING : zipEncoding;
+        hasDataDescriptor = (generalPurposeFlag & 8) != 0;
+
+        off += SHORT;
+
+        current.setMethod(ZipShort.getValue(lfh, off));
+        off += SHORT;
+
+        long time = ZipUtil.dosToJavaTime(ZipLong.getValue(lfh, off));
+        current.setTime(time);
+        off += WORD;
+
+        if (!hasDataDescriptor) {
+            current.setCrc(ZipLong.getValue(lfh, off));
+            off += WORD;
+
+            current.setCompressedSize(ZipLong.getValue(lfh, off));
+            off += WORD;
+
+            current.setSize(ZipLong.getValue(lfh, off));
+            off += WORD;
+        } else {
+            off += 3 * WORD;
+        }
+
+        int fileNameLen = ZipShort.getValue(lfh, off);
+
+        off += SHORT;
+
+        int extraLen = ZipShort.getValue(lfh, off);
+        off += SHORT;
+
+        byte[] fileName = new byte[fileNameLen];
+        readFully(fileName);
+        current.setName(entryEncoding.decode(fileName));
+
+        byte[] extraData = new byte[extraLen];
+        readFully(extraData);
+        current.setExtra(extraData);
+
+        ZipUtil.setNameAndCommentFromExtraFields(current, fileName, null);
+
+        return current;
     }
 
     public ArchiveEntry getNextEntry() throws IOException {
         return getNextZipEntry();
     }
 
-    public int read(byte[] b, int off, int len) throws IOException {
-        return input.read(b, off, len);
+    public int read(byte[] buffer, int start, int length) throws IOException {
+        if (closed) {
+            throw new IOException("The stream is closed");
+        }
+        if (inf.finished() || current == null) {
+            return -1;
+        }
+
+        // avoid int overflow, check null buffer
+        if (start <= buffer.length && length >= 0 && start >= 0
+            && buffer.length - start >= length) {
+            if (current.getMethod() == ZipArchiveOutputStream.STORED) {
+                int csize = (int) current.getSize();
+                if (readBytesOfEntry >= csize) {
+                    return -1;
+                }
+                if (offsetInBuffer >= lengthOfLastRead) {
+                    offsetInBuffer = 0;
+                    if ((lengthOfLastRead = in.read(buf)) == -1) {
+                        return -1;
+                    }
+                    bytesReadFromStream += lengthOfLastRead;
+                }
+                int toRead = length > lengthOfLastRead
+                    ? lengthOfLastRead - offsetInBuffer
+                    : length;
+                if ((csize - readBytesOfEntry) < toRead) {
+                    toRead = csize - readBytesOfEntry;
+                }
+                System.arraycopy(buf, offsetInBuffer, buffer, start, toRead);
+                offsetInBuffer += toRead;
+                readBytesOfEntry += toRead;
+                crc.update(buffer, start, toRead);
+                return toRead;
+            }
+            if (inf.needsInput()) {
+                fill();
+                if (lengthOfLastRead > 0) {
+                    bytesReadFromStream += lengthOfLastRead;
+                }
+            }
+            int read = 0;
+            try {
+                read = inf.inflate(buffer, start, length);
+            } catch (DataFormatException e) {
+                throw new ZipException(e.getMessage());
+            }
+            if (read == 0 && inf.finished()) {
+                return -1;
+            }
+            crc.update(buffer, start, read);
+            return read;
+        }
+        throw new ArrayIndexOutOfBoundsException();
+    }
+
+    public void close() throws IOException {
+        if (!closed) {
+            closed = true;
+            in.close();
+        }
     }
 
     public int read() throws IOException {
-        return input.read();
+        int num = read(SINGLE, 0, 1);
+        return num == -1 ? -1 : SINGLE[0] & ZipArchiveOutputStream.BYTE_MASK;
     }
 
+    public long skip(long value) throws IOException {
+        if (value >= 0) {
+            long skipped = 0;
+            byte[] b = new byte[1024];
+            while (skipped != value) {
+                long rem = value - skipped;
+                int x = read(b, 0, (int) (b.length > rem ? rem : b.length));
+                if (x == -1) {
+                    return skipped;
+                }
+                skipped += x;
+            }
+            return skipped;
+        }
+        throw new IllegalArgumentException();
+    }
 
     public static boolean matches(byte[] signature, int length) {
         if (length < ZipArchiveOutputStream.LFH_SIG.length) {
@@ -67,4 +276,59 @@
 
         return true;
     }
+
+    private void closeEntry() throws IOException {
+        if (closed) {
+            throw new IOException("The stream is closed");
+        }
+        if (current == null) {
+            return;
+        }
+        // Ensure all entry bytes are read
+        skip(Long.MAX_VALUE);
+        int inB, out;
+        if (current.getMethod() == ZipArchiveOutputStream.DEFLATED) {
+            inB = inf.getTotalIn();
+            out = inf.getTotalOut();
+        } else {
+            inB = readBytesOfEntry;
+            out = readBytesOfEntry;
+        }
+        int diff = 0;
+
+        // Pushback any required bytes
+        if ((diff = bytesReadFromStream - inB) != 0) {
+            ((PushbackInputStream) in).unread(buf,
+                                              lengthOfLastRead - diff, diff);
+        }
+
+        if (hasDataDescriptor) {
+            readFully(new byte[4 * WORD]);
+        }
+
+        inf.reset();
+        readBytesOfEntry = offsetInBuffer = bytesReadFromStream =
+            lengthOfLastRead = 0;
+        crc.reset();
+        current = null;
+    }
+
+    private void fill() throws IOException {
+        if (closed) {
+            throw new IOException("The stream is closed");
+        }
+        if ((lengthOfLastRead = in.read(buf)) > 0) {
+            inf.setInput(buf, 0, lengthOfLastRead);
+        }
+    }
+
+    private void readFully(byte[] b) throws IOException {
+        int count = 0, x = 0;
+        while (count != b.length) {
+            count += x = in.read(b, count, b.length - count);
+            if (x == -1) {
+                throw new EOFException();
+            }
+        }
+    }
 }

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java?rev=758896&r1=758895&r2=758896&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
(original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveOutputStream.java
Thu Mar 26 22:29:59 2009
@@ -57,10 +57,10 @@
  */
 public class ZipArchiveOutputStream extends ArchiveOutputStream {
 
-    private static final int BYTE_MASK = 0xFF;
+    static final int BYTE_MASK = 0xFF;
     private static final int SHORT = 2;
     private static final int WORD = 4;
-    private static final int BUFFER_SIZE = 512;
+    static final int BUFFER_SIZE = 512;
     /* 
      * Apparently Deflater.setInput gets slowed down a lot on Sun JVMs
      * when it gets handed a really big buffer.  See
@@ -586,7 +586,7 @@
     /**
      * local file header signature
      */
-    static final byte[] LFH_SIG = ZipLong.getBytes(0X04034B50L);
+    static final byte[] LFH_SIG = ZipLong.LFH_SIG.getBytes();
     /**
      * data descriptor signature
      */
@@ -594,7 +594,7 @@
     /**
      * central file header signature
      */
-    static final byte[] CFH_SIG = ZipLong.getBytes(0X02014B50L);
+    static final byte[] CFH_SIG = ZipLong.CFH_SIG.getBytes();
     /**
      * end of central dir signature
      */

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java?rev=758896&r1=758895&r2=758896&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
(original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java
Thu Mar 26 22:29:59 2009
@@ -25,7 +25,6 @@
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.zip.CRC32;
 import java.util.zip.Inflater;
 import java.util.zip.InflaterInputStream;
 import java.util.zip.ZipException;
@@ -62,8 +61,8 @@
     private static final int HASH_SIZE = 509;
     private static final int SHORT     =   2;
     private static final int WORD      =   4;
-    private static final int NIBLET_MASK = 0x0f;
-    private static final int BYTE_SHIFT = 8;
+    static final int NIBLET_MASK = 0x0f;
+    static final int BYTE_SHIFT = 8;
     private static final int POS_0 = 0;
     private static final int POS_1 = 1;
     private static final int POS_2 = 2;
@@ -529,9 +528,14 @@
                 + SHORT + SHORT + fileNameLen + extraFieldLen;
 
             if (entriesWithoutEFS.containsKey(ze)) {
-                setNameAndCommentFromExtraFields(ze,
-                                                 (NameAndComment)
-                                                 entriesWithoutEFS.get(ze));
+                String orig = ze.getName();
+                NameAndComment nc = (NameAndComment) entriesWithoutEFS.get(ze);
+                ZipUtil.setNameAndCommentFromExtraFields(ze, nc.name,
+                                                         nc.comment);
+                if (!orig.equals(ze.getName())) {
+                    nameMap.remove(orig);
+                    nameMap.put(ze.getName(), ze);
+                }
             }
         }
     }
@@ -553,64 +557,6 @@
     }
 
     /**
-     * If the entry has Unicode*ExtraFields and the CRCs of the
-     * names/comments match those of the extra fields, transfer the
-     * known Unicode values from the extra field.
-     */
-    private void setNameAndCommentFromExtraFields(ZipArchiveEntry ze,
-                                                  NameAndComment nc) {
-        UnicodePathExtraField name = (UnicodePathExtraField)
-            ze.getExtraField(UnicodePathExtraField.UPATH_ID);
-        String originalName = ze.getName();
-        String newName = getUnicodeStringIfOriginalMatches(name, nc.name);
-        if (newName != null && !originalName.equals(newName)) {
-            ze.setName(newName);
-            nameMap.remove(originalName);
-            nameMap.put(newName, ze);
-        }
-
-        if (nc.comment != null && nc.comment.length > 0) {
-            UnicodeCommentExtraField cmt = (UnicodeCommentExtraField)
-                ze.getExtraField(UnicodeCommentExtraField.UCOM_ID);
-            String newComment =
-                getUnicodeStringIfOriginalMatches(cmt, nc.comment);
-            if (newComment != null) {
-                ze.setComment(newComment);
-            }
-        }
-    }
-
-    /**
-     * If the stored CRC matches the one of the given name, return the
-     * Unicode name of the given field.
-     *
-     * <p>If the field is null or the CRCs don't match, return null
-     * instead.</p>
-     */
-    private String getUnicodeStringIfOriginalMatches(AbstractUnicodeExtraField f,
-                                                     byte[] orig) {
-        if (f != null) {
-            CRC32 crc32 = new CRC32();
-            crc32.update(orig);
-            long origCRC32 = crc32.getValue();
-
-            if (origCRC32 == f.getNameCRC32()) {
-                try {
-                    return ZipEncodingHelper
-                        .UTF8_ZIP_ENCODING.decode(f.getUnicodeName());
-                } catch (IOException ex) {
-                    // UTF-8 unsupported?  should be impossible the
-                    // Unicode*ExtraField must contain some bad bytes
-
-                    // TODO log this anywhere?
-                    return null;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
      * InputStream that delegates requests to the underlying
      * RandomAccessFile, making sure that only bytes from a certain
      * range can be read.

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipLong.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipLong.java?rev=758896&r1=758895&r2=758896&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipLong.java
(original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipLong.java
Thu Mar 26 22:29:59 2009
@@ -41,6 +41,9 @@
 
     private final long value;
 
+    public static final ZipLong CFH_SIG = new ZipLong(0X02014B50L);
+    public static final ZipLong LFH_SIG = new ZipLong(0X04034B50L);
+
     /**
      * Create instance from a number.
      * @param value the long to store as a ZipLong

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java?rev=758896&r1=758895&r2=758896&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java
(original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipUtil.java
Thu Mar 26 22:29:59 2009
@@ -17,8 +17,10 @@
  */
 package org.apache.commons.compress.archivers.zip;
 
+import java.io.IOException;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.zip.CRC32;
 
 public abstract class ZipUtil {
     /**
@@ -103,5 +105,64 @@
         return cal.getTime().getTime();
     }
 
+    /**
+     * If the entry has Unicode*ExtraFields and the CRCs of the
+     * names/comments match those of the extra fields, transfer the
+     * known Unicode values from the extra field.
+     */
+    static void setNameAndCommentFromExtraFields(ZipArchiveEntry ze,
+                                                 byte[] originalNameBytes,
+                                                 byte[] commentBytes) {
+        UnicodePathExtraField name = (UnicodePathExtraField)
+            ze.getExtraField(UnicodePathExtraField.UPATH_ID);
+        String originalName = ze.getName();
+        String newName = getUnicodeStringIfOriginalMatches(name,
+                                                           originalNameBytes);
+        if (newName != null && !originalName.equals(newName)) {
+            ze.setName(newName);
+        }
+
+        if (commentBytes != null && commentBytes.length > 0) {
+            UnicodeCommentExtraField cmt = (UnicodeCommentExtraField)
+                ze.getExtraField(UnicodeCommentExtraField.UCOM_ID);
+            String newComment =
+                getUnicodeStringIfOriginalMatches(cmt, commentBytes);
+            if (newComment != null) {
+                ze.setComment(newComment);
+            }
+        }
+    }
+
+    /**
+     * If the stored CRC matches the one of the given name, return the
+     * Unicode name of the given field.
+     *
+     * <p>If the field is null or the CRCs don't match, return null
+     * instead.</p>
+     */
+    private static 
+        String getUnicodeStringIfOriginalMatches(AbstractUnicodeExtraField f,
+                                                 byte[] orig) {
+        if (f != null) {
+            CRC32 crc32 = new CRC32();
+            crc32.update(orig);
+            long origCRC32 = crc32.getValue();
+
+            if (origCRC32 == f.getNameCRC32()) {
+                try {
+                    return ZipEncodingHelper
+                        .UTF8_ZIP_ENCODING.decode(f.getUnicodeName());
+                } catch (IOException ex) {
+                    // UTF-8 unsupported?  should be impossible the
+                    // Unicode*ExtraField must contain some bad bytes
+
+                    // TODO log this anywhere?
+                    return null;
+                }
+            }
+        }
+        return null;
+    }
+
 
 }
\ No newline at end of file

Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/UTF8ZipFilesTest.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/UTF8ZipFilesTest.java?rev=758896&r1=758895&r2=758896&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/UTF8ZipFilesTest.java
(original)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/UTF8ZipFilesTest.java
Thu Mar 26 22:29:59 2009
@@ -19,6 +19,7 @@
 package org.apache.commons.compress.archivers.zip;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
@@ -99,6 +100,24 @@
         }
     }
 
+    public void testRead7ZipArchiveForStream() throws IOException,
+                                                      URISyntaxException {
+        URL zip = getClass().getResource("/utf8-7zip-test.zip");
+        FileInputStream archive =
+            new FileInputStream(new File(new URI(zip.toString())));
+        ZipArchiveInputStream zi = null;
+        try {
+            zi = new ZipArchiveInputStream(archive, CP437, false);
+            assertEquals(ASCII_TXT, zi.getNextEntry().getName());
+            assertEquals(OIL_BARREL_TXT, zi.getNextEntry().getName());
+            assertEquals(EURO_FOR_DOLLAR_TXT, zi.getNextEntry().getName());
+        } finally {
+            if (zi != null) {
+                zi.close();
+            }
+        }
+    }
+
     /*
      * WinZIP created archive, uses Unicode Extra Fields but only in
      * the central directory.
@@ -117,8 +136,47 @@
         }
     }
 
+    public void testReadWinZipArchiveForStream() throws IOException,
+                                                      URISyntaxException {
+        URL zip = getClass().getResource("/utf8-winzip-test.zip");
+        FileInputStream archive =
+            new FileInputStream(new File(new URI(zip.toString())));
+        ZipArchiveInputStream zi = null;
+        try {
+            zi = new ZipArchiveInputStream(archive, null, true);
+            assertEquals(EURO_FOR_DOLLAR_TXT, zi.getNextEntry().getName());
+            assertEquals(OIL_BARREL_TXT, zi.getNextEntry().getName());
+            assertEquals(ASCII_TXT, zi.getNextEntry().getName());
+        } finally {
+            if (zi != null) {
+                zi.close();
+            }
+        }
+    }
+
     public void testZipFileReadsUnicodeFields() throws IOException {
         File file = File.createTempFile("unicode-test", ".zip");
+        ZipArchiveInputStream zi = null;
+        try {
+            createTestFile(file, US_ASCII, false, true);
+            FileInputStream archive = new FileInputStream(file);
+            zi = new ZipArchiveInputStream(archive, US_ASCII, true);
+            assertEquals(OIL_BARREL_TXT, zi.getNextEntry().getName());
+            assertEquals(EURO_FOR_DOLLAR_TXT, zi.getNextEntry().getName());
+            assertEquals(ASCII_TXT, zi.getNextEntry().getName());
+        } finally {
+            if (zi != null) {
+                zi.close();
+            }
+            if (file.exists()) {
+                file.delete();
+            }
+        }
+    }
+
+    public void testZipArchiveInputStreamReadsUnicodeFields()
+        throws IOException {
+        File file = File.createTempFile("unicode-test", ".zip");
         ZipFile zf = null;
         try {
             createTestFile(file, US_ASCII, false, true);



Mime
View raw message