Repository: commons-compress Updated Branches: refs/heads/master 6a5014ed5 -> e926d99b1
COMPRESS-327 read-only in memory SeekableByteChannel Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/e926d99b Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/e926d99b Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/e926d99b Branch: refs/heads/master Commit: e926d99b192110cb53332ab932bcb43e0d947d19 Parents: 6a5014e Author: Stefan Bodewig <bode...@apache.org> Authored: Thu Oct 13 13:17:08 2016 +0200 Committer: Stefan Bodewig <bode...@apache.org> Committed: Thu Oct 13 13:17:08 2016 +0200 ---------------------------------------------------------------------- .../utils/SeekableInMemoryByteChannel.java | 95 ++++++++++++++++++++ .../archivers/sevenz/SevenZFileTest.java | 21 +++++ .../compress/archivers/zip/ZipFileTest.java | 36 ++++++++ 3 files changed, 152 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/e926d99b/src/main/java/org/apache/commons/compress/utils/SeekableInMemoryByteChannel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/utils/SeekableInMemoryByteChannel.java b/src/main/java/org/apache/commons/compress/utils/SeekableInMemoryByteChannel.java new file mode 100644 index 0000000..ab3a606 --- /dev/null +++ b/src/main/java/org/apache/commons/compress/utils/SeekableInMemoryByteChannel.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.commons.compress.utils; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.NonWritableChannelException; +import java.nio.channels.SeekableByteChannel; + +/** + * A {@link SeekableByteChannel} implementation that wraps a byte[]. + */ +public class SeekableInMemoryByteChannel implements SeekableByteChannel { + + private final byte[] data; + private volatile boolean closed; + private volatile long position, size; + + public SeekableInMemoryByteChannel(byte[] data) { + this.data = data; + size = data.length; + } + + @Override + public long position() { + return position; + } + + @Override + public SeekableByteChannel position(long newPosition) { + position = newPosition; + return this; + } + + @Override + public long size() { + return size; + } + + @Override + public SeekableByteChannel truncate(long newSize) { + size = newSize; + return this; + } + + @Override + public int read(ByteBuffer buf) throws IOException { + if (!isOpen()) { + throw new ClosedChannelException(); + } + long pos = position; + long sz = size; + int wanted = buf.remaining(); + long possible = sz - pos; + if (wanted > possible) { + wanted = (int) possible; + } + buf.put(data, (int) pos, wanted); + position = pos + wanted; + return wanted; + } + + @Override + public void close() { + closed = true; + } + + @Override + public boolean isOpen() { + return !closed; + } + + // TODO implement writing + @Override + public int write(ByteBuffer b) throws IOException { + throw new NonWritableChannelException(); + } +} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/e926d99b/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java b/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java index 76687d8..d066bea 100644 --- a/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/sevenz/SevenZFileTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.*; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.security.NoSuchAlgorithmException; import java.util.Arrays; @@ -33,6 +34,8 @@ import javax.crypto.Cipher; import org.apache.commons.compress.AbstractTestCase; import org.apache.commons.compress.PasswordRequiredException; +import org.apache.commons.compress.utils.IOUtils; +import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; import org.junit.Test; public class SevenZFileTest extends AbstractTestCase { @@ -239,6 +242,24 @@ public class SevenZFileTest extends AbstractTestCase { } } + @Test + public void getEntriesOfUnarchiveInMemoryTest() throws IOException { + byte[] data = null; + try (FileInputStream fis = new FileInputStream(getFile("bla.7z"))) { + data = IOUtils.toByteArray(fis); + } + try (SevenZFile sevenZFile = new SevenZFile(new SeekableInMemoryByteChannel(data), + "in memory", null)) { + final Iterable<SevenZArchiveEntry> entries = sevenZFile.getEntries(); + final Iterator<SevenZArchiveEntry> iter = entries.iterator(); + SevenZArchiveEntry entry = iter.next(); + assertEquals("test1.xml", entry.getName()); + entry = iter.next(); + assertEquals("test2.xml", entry.getName()); + assertFalse(iter.hasNext()); + } + } + /** * @see "https://issues.apache.org/jira/browse/COMPRESS-348" */ http://git-wip-us.apache.org/repos/asf/commons-compress/blob/e926d99b/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java b/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java index 4569e87..c786549 100644 --- a/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/zip/ZipFileTest.java @@ -34,6 +34,7 @@ import java.util.TreeMap; import java.util.zip.ZipEntry; import org.apache.commons.compress.utils.IOUtils; +import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; import org.junit.After; import org.junit.Test; @@ -75,6 +76,41 @@ public class ZipFileTest { } @Test + public void testCDOrderInMemory() throws Exception { + byte[] data = null; + try (FileInputStream fis = new FileInputStream(getFile("ordertest.zip"))) { + data = IOUtils.toByteArray(fis); + } + + zf = new ZipFile(new SeekableInMemoryByteChannel(data), "in memory", + ZipEncodingHelper.UTF8, true); + final ArrayList<ZipArchiveEntry> l = Collections.list(zf.getEntries()); + assertEntryName(l, 0, "AbstractUnicodeExtraField"); + assertEntryName(l, 1, "AsiExtraField"); + assertEntryName(l, 2, "ExtraFieldUtils"); + assertEntryName(l, 3, "FallbackZipEncoding"); + assertEntryName(l, 4, "GeneralPurposeBit"); + assertEntryName(l, 5, "JarMarker"); + assertEntryName(l, 6, "NioZipEncoding"); + assertEntryName(l, 7, "Simple8BitZipEncoding"); + assertEntryName(l, 8, "UnicodeCommentExtraField"); + assertEntryName(l, 9, "UnicodePathExtraField"); + assertEntryName(l, 10, "UnixStat"); + assertEntryName(l, 11, "UnparseableExtraFieldData"); + assertEntryName(l, 12, "UnrecognizedExtraField"); + assertEntryName(l, 13, "ZipArchiveEntry"); + assertEntryName(l, 14, "ZipArchiveInputStream"); + assertEntryName(l, 15, "ZipArchiveOutputStream"); + assertEntryName(l, 16, "ZipEncoding"); + assertEntryName(l, 17, "ZipEncodingHelper"); + assertEntryName(l, 18, "ZipExtraField"); + assertEntryName(l, 19, "ZipUtil"); + assertEntryName(l, 20, "ZipLong"); + assertEntryName(l, 21, "ZipShort"); + assertEntryName(l, 22, "ZipFile"); + } + + @Test public void testPhysicalOrder() throws Exception { readOrderTest(); final ArrayList<ZipArchiveEntry> l = Collections.list(zf.getEntriesInPhysicalOrder());