Repository: commons-compress Updated Branches: refs/heads/COMPRESS-380 782b15622 -> 32d507b02
COMPRESS-380 directly read uncompressed data from the underlying stream Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/32d507b0 Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/32d507b0 Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/32d507b0 Branch: refs/heads/COMPRESS-380 Commit: 32d507b028b15fd21775f25c83f41059cdc58e75 Parents: 782b156 Author: Stefan Bodewig <bode...@apache.org> Authored: Tue Jan 9 12:00:50 2018 +0100 Committer: Stefan Bodewig <bode...@apache.org> Committed: Tue Jan 9 12:00:50 2018 +0100 ---------------------------------------------------------------------- .../compressors/deflate64/HuffmanDecoder.java | 30 ++++++++++++++------ .../commons/compress/utils/BitInputStream.java | 9 ++++++ 2 files changed, 31 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/32d507b0/src/main/java/org/apache/commons/compress/compressors/deflate64/HuffmanDecoder.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/compressors/deflate64/HuffmanDecoder.java b/src/main/java/org/apache/commons/compress/compressors/deflate64/HuffmanDecoder.java index 506b35d..75f02fa 100644 --- a/src/main/java/org/apache/commons/compress/compressors/deflate64/HuffmanDecoder.java +++ b/src/main/java/org/apache/commons/compress/compressors/deflate64/HuffmanDecoder.java @@ -104,15 +104,13 @@ class HuffmanDecoder implements Closeable { private boolean finalBlock = false; private DecoderState state; private BitInputStream reader; + private final InputStream in; private final DecodingMemory memory = new DecodingMemory(); HuffmanDecoder(InputStream in) { - this(new BitInputStream(in, ByteOrder.LITTLE_ENDIAN)); - } - - private HuffmanDecoder(BitInputStream reader) { - this.reader = reader; + this.reader = new BitInputStream(in, ByteOrder.LITTLE_ENDIAN); + this.in = in; state = new InitialState(); } @@ -200,9 +198,19 @@ class HuffmanDecoder implements Closeable { // as len is an int and (blockLength - read) is >= 0 the min must fit into an int as well int max = (int) Math.min(blockLength - read, len); for (int i = 0; i < max; i++) { - byte next = (byte) (readBits(Byte.SIZE) & 0xFF); - b[off + i] = memory.add(next); - read++; + if (reader.bitsCached() > 0) { + byte next = (byte) (readBits(Byte.SIZE) & 0xFF); + b[off + i] = memory.add(next); + read++; + } else { + int readNow = in.read(b, off + i, max - i); + if (readNow == -1) { + throw new EOFException("Truncated Deflate64 Stream"); + } + memory.add(b, off + i, readNow); + read += readNow; + i += readNow; + } } return max; } @@ -463,6 +471,12 @@ class HuffmanDecoder implements Closeable { return b; } + void add(byte[] b, int off, int len) { + for (int i = off; i < off + len; i++) { + add(b[i]); + } + } + void recordToBuffer(int distance, int length, byte[] buff) { if (distance > memory.length) { throw new IllegalStateException("Illegal distance parameter: " + distance); http://git-wip-us.apache.org/repos/asf/commons-compress/blob/32d507b0/src/main/java/org/apache/commons/compress/utils/BitInputStream.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/utils/BitInputStream.java b/src/main/java/org/apache/commons/compress/utils/BitInputStream.java index 7f29ac0..d847eb9 100644 --- a/src/main/java/org/apache/commons/compress/utils/BitInputStream.java +++ b/src/main/java/org/apache/commons/compress/utils/BitInputStream.java @@ -101,6 +101,15 @@ public class BitInputStream implements Closeable { } /** + * Returns the number of bits that can be read from this input + * stream without readong from the underlying input stream at all. + * @since 1.16 + */ + public int bitsCached() { + return bitsCachedSize; + } + + /** * Returns an estimate of the number of bits that can be read from * this input stream without blocking by the next invocation of a * method for this input stream.