Repository: commons-compress Updated Branches: refs/heads/master daeb07457 -> d8fc27b40
move channel/ByteBuffer readFully to IOUtils Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/94197a7b Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/94197a7b Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/94197a7b Branch: refs/heads/master Commit: 94197a7b6c5c616b19ee532da23d8911d5deefd6 Parents: daeb074 Author: Stefan Bodewig <bode...@apache.org> Authored: Wed Oct 12 17:58:32 2016 +0200 Committer: Stefan Bodewig <bode...@apache.org> Committed: Wed Oct 12 17:58:32 2016 +0200 ---------------------------------------------------------------------- .../compress/archivers/sevenz/SevenZFile.java | 14 ++---- .../apache/commons/compress/utils/IOUtils.java | 32 ++++++++++++++ .../commons/compress/utils/IOUtilsTest.java | 45 +++++++++++++++++++- 3 files changed, 79 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/94197a7b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java index e4115a1..f173273 100644 --- a/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java +++ b/src/main/java/org/apache/commons/compress/archivers/sevenz/SevenZFile.java @@ -1029,18 +1029,10 @@ public class SevenZFile implements Closeable { return skipped; } - private int readFully(ByteBuffer buf) throws IOException { - final int expectedLength = buf.rewind().remaining(); - int read = 0; - while (read < expectedLength) { - int readNow = channel.read(buf); - if (readNow <= 0) { - break; - } - read += readNow; - } + private void readFully(ByteBuffer buf) throws IOException { + buf.rewind(); + IOUtils.readFully(channel, buf); buf.flip(); - return read; } @Override http://git-wip-us.apache.org/repos/asf/commons-compress/blob/94197a7b/src/main/java/org/apache/commons/compress/utils/IOUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/utils/IOUtils.java b/src/main/java/org/apache/commons/compress/utils/IOUtils.java index d7979f1..8ab0ace 100644 --- a/src/main/java/org/apache/commons/compress/utils/IOUtils.java +++ b/src/main/java/org/apache/commons/compress/utils/IOUtils.java @@ -20,9 +20,12 @@ package org.apache.commons.compress.utils; import java.io.ByteArrayOutputStream; import java.io.Closeable; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.ReadableByteChannel; /** * Utility functions @@ -166,6 +169,35 @@ public final class IOUtils { return count; } + /** + * Reads {@code b.remaining()} bytes from the given channel + * starting at the current channel's position. + * + * <p>This method reads repeatedly from the channel until the + * requested number of bytes are read. This method blocks until + * the requested number of bytes are read, the end of the channel + * is detected, or an exception is thrown.</p> + * + * @param channel the channel to read from + * @param b the buffer into which the data is read. + * @throws IOException - if an I/O error occurs. + * @throws EOFException - if the channel reaches the end before reading all the bytes. + */ + public static void readFully(ReadableByteChannel channel, ByteBuffer b) throws IOException { + final int expectedLength = b.remaining(); + int read = 0; + while (read < expectedLength) { + int readNow = channel.read(b); + if (readNow <= 0) { + break; + } + read += readNow; + } + if (read < expectedLength) { + throw new EOFException(); + } + } + // toByteArray(InputStream) copied from: // commons/proper/io/trunk/src/main/java/org/apache/commons/io/IOUtils.java?revision=1428941 // January 8th, 2013 http://git-wip-us.apache.org/repos/asf/commons-compress/blob/94197a7b/src/test/java/org/apache/commons/compress/utils/IOUtilsTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/compress/utils/IOUtilsTest.java b/src/test/java/org/apache/commons/compress/utils/IOUtilsTest.java index 47bd0b0..042acad 100644 --- a/src/test/java/org/apache/commons/compress/utils/IOUtilsTest.java +++ b/src/test/java/org/apache/commons/compress/utils/IOUtilsTest.java @@ -18,9 +18,12 @@ package org.apache.commons.compress.utils; import java.io.ByteArrayInputStream; +import java.io.EOFException; import java.io.FilterInputStream; import java.io.InputStream; import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.ReadableByteChannel; import org.junit.Assert; import org.junit.Test; @@ -77,6 +80,47 @@ public class IOUtilsTest { }); } + @Test + public void readFullyOnChannelReadsFully() throws IOException { + ByteBuffer b = ByteBuffer.allocate(20); + final byte[] source = new byte[20]; + for (byte i = 0; i < 20; i++) { + source[i] = i; + } + readFully(source, b); + Assert.assertArrayEquals(source, b.array()); + } + + @Test(expected = EOFException.class) + public void readFullyOnChannelThrowsEof() throws IOException { + ByteBuffer b = ByteBuffer.allocate(21); + final byte[] source = new byte[20]; + for (byte i = 0; i < 20; i++) { + source[i] = i; + } + readFully(source, b); + } + + private static void readFully(final byte[] source, ByteBuffer b) throws IOException { + IOUtils.readFully(new ReadableByteChannel() { + private int idx; + @Override + public int read(ByteBuffer buf) { + if (idx >= source.length) { + return -1; + } + buf.put(source[idx++]); + return 1; + } + @Override + public void close() { } + @Override + public boolean isOpen() { + return true; + } + }, b); + } + private void skip(final StreamWrapper wrapper) throws Exception { final ByteArrayInputStream in = new ByteArrayInputStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 @@ -85,5 +129,4 @@ public class IOUtilsTest { Assert.assertEquals(10, IOUtils.skip(sut, 10)); Assert.assertEquals(11, sut.read()); } - }