You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by eb...@apache.org on 2013/12/19 13:30:01 UTC
svn commit: r1552293 - in /commons/proper/compress/trunk/src:
changes/changes.xml
main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java
Author: ebourg
Date: Thu Dec 19 12:30:01 2013
New Revision: 1552293
URL: http://svn.apache.org/r1552293
Log:
Support shrunk entries in ZipArchiveInputStream
Modified:
commons/proper/compress/trunk/src/changes/changes.xml
commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java
commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java
Modified: commons/proper/compress/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/changes/changes.xml?rev=1552293&r1=1552292&r2=1552293&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/changes/changes.xml (original)
+++ commons/proper/compress/trunk/src/changes/changes.xml Thu Dec 19 12:30:01 2013
@@ -61,7 +61,7 @@ The <action> type attribute can be add,u
Read-Only support for .Z compressed files.
</action>
<action type="add" date="2013-12-06" due-to="Damjan Jovanovic">
- ZipFile now supports reading entries compressed using the
+ ZipFile and ZipArchiveInputStream now support reading entries compressed using the
SHRINKING method.
</action>
<action issue="COMPRESS-245" type="fix" date="2013-12-06">
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=1552293&r1=1552292&r2=1552293&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 Dec 19 12:30:01 2013
@@ -271,6 +271,12 @@ public class ZipArchiveInputStream exten
}
processZip64Extra(size, cSize);
+
+ if (current.entry.getCompressedSize() != -1
+ && current.entry.getMethod() == ZipMethod.UNSHRINKING.getCode()) {
+ current.in = new UnshrinkingInputStream(new BoundedInputStream(in, current.entry.getCompressedSize()));
+ }
+
entriesRead++;
return current.entry;
}
@@ -369,6 +375,8 @@ public class ZipArchiveInputStream exten
read = readStored(buffer, offset, length);
} else if (current.entry.getMethod() == ZipArchiveOutputStream.DEFLATED) {
read = readDeflated(buffer, offset, length);
+ } else if (current.entry.getMethod() == ZipMethod.UNSHRINKING.getCode()) {
+ read = current.in.read(buffer, offset, length);
} else {
throw new UnsupportedZipFeatureException(ZipMethod.getMethodByCode(current.entry.getMethod()),
current.entry);
@@ -970,5 +978,88 @@ public class ZipArchiveInputStream exten
* The checksum calculated as the current entry is read.
*/
private final CRC32 crc = new CRC32();
+
+ /**
+ * The input stream decompressing the data for shrunk and imploded entries.
+ */
+ private InputStream in;
+ }
+
+ /**
+ * Bounded input stream adapted from commons-io
+ */
+ private class BoundedInputStream extends InputStream {
+
+ /** the wrapped input stream */
+ private final InputStream in;
+
+ /** the max length to provide */
+ private final long max;
+
+ /** the number of bytes already returned */
+ private long pos = 0;
+
+ /**
+ * Creates a new <code>BoundedInputStream</code> that wraps the given input
+ * stream and limits it to a certain size.
+ *
+ * @param in The wrapped input stream
+ * @param size The maximum number of bytes to return
+ */
+ public BoundedInputStream(final InputStream in, final long size) {
+ this.max = size;
+ this.in = in;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (max >= 0 && pos >= max) {
+ return -1;
+ }
+ final int result = in.read();
+ pos++;
+ count(1);
+ current.bytesReadFromStream++;
+ return result;
+ }
+
+ @Override
+ public int read(final byte[] b) throws IOException {
+ return this.read(b, 0, b.length);
+ }
+
+ @Override
+ public int read(final byte[] b, final int off, final int len) throws IOException {
+ if (max >= 0 && pos >= max) {
+ return -1;
+ }
+ final long maxRead = max >= 0 ? Math.min(len, max - pos) : len;
+ final int bytesRead = in.read(b, off, (int) maxRead);
+
+ if (bytesRead == -1) {
+ return -1;
+ }
+
+ pos += bytesRead;
+ count(bytesRead);
+ current.bytesReadFromStream += bytesRead;
+ return bytesRead;
+ }
+
+ @Override
+ public long skip(final long n) throws IOException {
+ final long toSkip = max >= 0 ? Math.min(n, max - pos) : n;
+ final long skippedBytes = in.skip(toSkip);
+ pos += skippedBytes;
+ return skippedBytes;
+ }
+
+ @Override
+ public int available() throws IOException {
+ if (max >= 0 && pos >= max) {
+ return 0;
+ }
+ return in.available();
+ }
}
}
Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java?rev=1552293&r1=1552292&r2=1552293&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java (original)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStreamTest.java Thu Dec 19 12:30:01 2013
@@ -27,6 +27,8 @@ import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
+
+import org.apache.commons.compress.utils.IOUtils;
import org.junit.Test;
public class ZipArchiveInputStreamTest {
@@ -120,4 +122,29 @@ public class ZipArchiveInputStreamTest {
zae = in.getNextZipEntry();
}
}
+
+ @Test
+ public void testUnshrinkEntry() throws Exception {
+ ZipArchiveInputStream in = new ZipArchiveInputStream(new FileInputStream(getFile("SHRUNK.ZIP")));
+
+ ZipArchiveEntry entry = in.getNextZipEntry();
+ assertEquals("method", ZipMethod.UNSHRINKING.getCode(), entry.getMethod());
+
+ FileInputStream original = new FileInputStream(getFile("test1.xml"));
+ try {
+ assertArrayEquals(IOUtils.toByteArray(original), IOUtils.toByteArray(in));
+ } finally {
+ original.close();
+ }
+
+ entry = in.getNextZipEntry();
+ assertEquals("method", ZipMethod.UNSHRINKING.getCode(), entry.getMethod());
+
+ original = new FileInputStream(getFile("test2.xml"));
+ try {
+ assertArrayEquals(IOUtils.toByteArray(original), IOUtils.toByteArray(in));
+ } finally {
+ original.close();
+ }
+ }
}