TMC-IOENC: Refactored Decoder to use ByteBuffer instead of byte[] for better readability/simpler code.

This commit is contained in:
Harald Kuhr 2013-09-08 13:39:13 +02:00
parent 9a27f62dec
commit f2ff00580a
9 changed files with 102 additions and 126 deletions

View File

@ -31,6 +31,7 @@ package com.twelvemonkeys.io.enc;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.ByteBuffer;
/** /**
* Abstract base class for RLE decoding as specified by in the Windows BMP (aka DIB) file format. * Abstract base class for RLE decoding as specified by in the Windows BMP (aka DIB) file format.
@ -86,25 +87,24 @@ abstract class AbstractRLEDecoder implements Decoder {
* Decodes as much data as possible, from the stream into the buffer. * Decodes as much data as possible, from the stream into the buffer.
* *
* @param pStream the input stream containing RLE data * @param pStream the input stream containing RLE data
* @param pBuffer tge buffer to decode the data to * @param pBuffer the buffer to decode the data to
* *
* @return the number of bytes decoded from the stream, to the buffer * @return the number of bytes decoded from the stream, to the buffer
* *
* @throws IOException if an I/O related exception ocurs while reading * @throws IOException if an I/O related exception ocurs while reading
*/ */
public final int decode(InputStream pStream, byte[] pBuffer) throws IOException { public final int decode(InputStream pStream, ByteBuffer pBuffer) throws IOException {
int decoded = 0; while (pBuffer.hasRemaining() && dstY >= 0) {
while (decoded < pBuffer.length && dstY >= 0) {
// NOTE: Decode only full rows, don't decode if y delta // NOTE: Decode only full rows, don't decode if y delta
if (dstX == 0 && srcY == dstY) { if (dstX == 0 && srcY == dstY) {
decodeRow(pStream); decodeRow(pStream);
} }
int length = Math.min(row.length - dstX, pBuffer.length - decoded); int length = Math.min(row.length - dstX, pBuffer.remaining());
System.arraycopy(row, dstX, pBuffer, decoded, length); // System.arraycopy(row, dstX, pBuffer, decoded, length);
pBuffer.put(row, 0, length);
dstX += length; dstX += length;
decoded += length; // decoded += length;
if (dstX == row.length) { if (dstX == row.length) {
dstX = 0; dstX = 0;
@ -120,7 +120,7 @@ abstract class AbstractRLEDecoder implements Decoder {
} }
} }
return decoded; return pBuffer.position();
} }
/** /**

View File

@ -28,9 +28,9 @@
package com.twelvemonkeys.io.enc; package com.twelvemonkeys.io.enc;
import com.twelvemonkeys.io.FastByteArrayOutputStream; import java.io.IOException;
import java.io.InputStream;
import java.io.*; import java.nio.ByteBuffer;
/** /**
* {@code Decoder} implementation for standard base64 encoding. * {@code Decoder} implementation for standard base64 encoding.
@ -62,8 +62,6 @@ public final class Base64Decoder implements Decoder {
final static byte[] PEM_CONVERT_ARRAY; final static byte[] PEM_CONVERT_ARRAY;
private byte[] decodeBuffer = new byte[4]; private byte[] decodeBuffer = new byte[4];
private ByteArrayOutputStream wrapped;
private Object wrappedObject;
static { static {
PEM_CONVERT_ARRAY = new byte[256]; PEM_CONVERT_ARRAY = new byte[256];
@ -93,7 +91,7 @@ public final class Base64Decoder implements Decoder {
return pLength; return pLength;
} }
protected boolean decodeAtom(final InputStream pInput, final OutputStream pOutput, final int pLength) protected boolean decodeAtom(final InputStream pInput, final ByteBuffer pOutput, final int pLength)
throws IOException { throws IOException {
byte byte0 = -1; byte byte0 = -1;
@ -147,16 +145,16 @@ public final class Base64Decoder implements Decoder {
default: default:
switch (length) { switch (length) {
case 2: case 2:
pOutput.write((byte) (byte0 << 2 & 252 | byte1 >>> 4 & 3)); pOutput.put((byte) (byte0 << 2 & 252 | byte1 >>> 4 & 3));
break; break;
case 3: case 3:
pOutput.write((byte) (byte0 << 2 & 252 | byte1 >>> 4 & 3)); pOutput.put((byte) (byte0 << 2 & 252 | byte1 >>> 4 & 3));
pOutput.write((byte) (byte1 << 4 & 240 | byte2 >>> 2 & 15)); pOutput.put((byte) (byte1 << 4 & 240 | byte2 >>> 2 & 15));
break; break;
case 4: case 4:
pOutput.write((byte) (byte0 << 2 & 252 | byte1 >>> 4 & 3)); pOutput.put((byte) (byte0 << 2 & 252 | byte1 >>> 4 & 3));
pOutput.write((byte) (byte1 << 4 & 240 | byte2 >>> 2 & 15)); pOutput.put((byte) (byte1 << 4 & 240 | byte2 >>> 2 & 15));
pOutput.write((byte) (byte2 << 6 & 192 | byte3 & 63)); pOutput.put((byte) (byte2 << 6 & 192 | byte3 & 63));
break; break;
} }
@ -166,34 +164,23 @@ public final class Base64Decoder implements Decoder {
return true; return true;
} }
void decodeBuffer(final InputStream pInput, final ByteArrayOutputStream pOutput, final int pLength) throws IOException { public int decode(final InputStream pStream, final ByteBuffer pBuffer) throws IOException {
do { do {
int k = 72; int k = 72;
int i; int i;
for (i = 0; i + 4 < k; i += 4) { for (i = 0; i + 4 < k; i += 4) {
if(!decodeAtom(pInput, pOutput, 4)) { if(!decodeAtom(pStream, pBuffer, 4)) {
break; break;
} }
} }
if (!decodeAtom(pInput, pOutput, k - i)) { if (!decodeAtom(pStream, pBuffer, k - i)) {
break; break;
} }
} }
while (pOutput.size() + 54 < pLength); // 72 char lines should produce no more than 54 bytes while (pBuffer.remaining() > 54); // 72 char lines should produce no more than 54 bytes
}
public int decode(final InputStream pStream, final byte[] pBuffer) throws IOException { return pBuffer.position();
if (wrappedObject != pBuffer) {
// NOTE: Array not cloned in FastByteArrayOutputStream
wrapped = new FastByteArrayOutputStream(pBuffer);
wrappedObject = pBuffer;
}
wrapped.reset(); // NOTE: This only resets count to 0
decodeBuffer(pStream, wrapped, pBuffer.length);
return wrapped.size();
} }
} }

View File

@ -28,8 +28,9 @@
package com.twelvemonkeys.io.enc; package com.twelvemonkeys.io.enc;
import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
/** /**
* Interface for decoders. * Interface for decoders.
@ -60,5 +61,5 @@ public interface Decoder {
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
* @throws java.io.EOFException if a premature end-of-file is encountered * @throws java.io.EOFException if a premature end-of-file is encountered
*/ */
int decode(InputStream pStream, byte[] pBuffer) throws IOException; int decode(InputStream pStream, ByteBuffer pBuffer) throws IOException;
} }

View File

@ -28,9 +28,10 @@
package com.twelvemonkeys.io.enc; package com.twelvemonkeys.io.enc;
import java.io.InputStream;
import java.io.IOException;
import java.io.FilterInputStream; import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
/** /**
* An {@code InputStream} that provides on-the-fly decoding from an underlying * An {@code InputStream} that provides on-the-fly decoding from an underlying
@ -43,12 +44,12 @@ import java.io.FilterInputStream;
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/enc/DecoderStream.java#2 $ * @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/enc/DecoderStream.java#2 $
*/ */
public final class DecoderStream extends FilterInputStream { public final class DecoderStream extends FilterInputStream {
protected final ByteBuffer buffer;
protected int bufferPos;
protected int bufferLimit;
protected final byte[] buffer;
protected final Decoder decoder; protected final Decoder decoder;
// TODO: Consider replacing the wrapped input stream with a channel like this
// ReadableByteChannel inChannel = Channels.newChannel(stream);
/** /**
* Creates a new decoder stream and chains it to the * Creates a new decoder stream and chains it to the
* input stream specified by the {@code pStream} argument. * input stream specified by the {@code pStream} argument.
@ -77,29 +78,22 @@ public final class DecoderStream extends FilterInputStream {
public DecoderStream(final InputStream pStream, final Decoder pDecoder, final int pBufferSize) { public DecoderStream(final InputStream pStream, final Decoder pDecoder, final int pBufferSize) {
super(pStream); super(pStream);
decoder = pDecoder; decoder = pDecoder;
buffer = new byte[pBufferSize]; buffer = ByteBuffer.allocate(pBufferSize);
bufferPos = 0; buffer.flip();
bufferLimit = 0;
} }
public int available() throws IOException { public int available() throws IOException {
return bufferLimit - bufferPos + super.available(); return buffer.remaining();
} }
public int read() throws IOException { public int read() throws IOException {
if (bufferPos == bufferLimit) { if (!buffer.hasRemaining()) {
bufferLimit = fill(); if (fill() < 0) {
return -1;
}
} }
if (bufferLimit < 0) { return buffer.get() & 0xff;
return -1;
}
return buffer[bufferPos++] & 0xff;
}
public int read(final byte pBytes[]) throws IOException {
return read(pBytes, 0, pBytes.length);
} }
public int read(final byte pBytes[], final int pOffset, final int pLength) throws IOException { public int read(final byte pBytes[], final int pOffset, final int pLength) throws IOException {
@ -115,8 +109,10 @@ public final class DecoderStream extends FilterInputStream {
} }
// End of file? // End of file?
if ((bufferLimit - bufferPos) < 0) { if (!buffer.hasRemaining()) {
return -1; if (fill() < 0) {
return -1;
}
} }
// Read until we have read pLength bytes, or have reached EOF // Read until we have read pLength bytes, or have reached EOF
@ -124,21 +120,15 @@ public final class DecoderStream extends FilterInputStream {
int off = pOffset; int off = pOffset;
while (pLength > count) { while (pLength > count) {
int avail = bufferLimit - bufferPos; if (!buffer.hasRemaining()) {
if (fill() < 0) {
if (avail <= 0) {
bufferLimit = fill();
if (bufferLimit < 0) {
break; break;
} }
} }
// Copy as many bytes as possible // Copy as many bytes as possible
int dstLen = Math.min(pLength - count, avail); int dstLen = Math.min(pLength - count, buffer.remaining());
System.arraycopy(buffer, bufferPos, pBytes, off, dstLen); buffer.get(pBytes, off, dstLen);
bufferPos += dstLen;
// Update offset (rest) // Update offset (rest)
off += dstLen; off += dstLen;
@ -152,29 +142,25 @@ public final class DecoderStream extends FilterInputStream {
public long skip(final long pLength) throws IOException { public long skip(final long pLength) throws IOException {
// End of file? // End of file?
if (bufferLimit - bufferPos < 0) { if (!buffer.hasRemaining()) {
return 0; if (fill() < 0) {
return 0; // Yes, 0, not -1
}
} }
// Skip until we have skipped pLength bytes, or have reached EOF // Skip until we have skipped pLength bytes, or have reached EOF
long total = 0; long total = 0;
while (total < pLength) { while (total < pLength) {
int avail = bufferLimit - bufferPos; if (!buffer.hasRemaining()) {
if (fill() < 0) {
if (avail == 0) {
bufferLimit = fill();
if (bufferLimit < 0) {
break; break;
} }
} }
// NOTE: Skipped can never be more than avail, which is // NOTE: Skipped can never be more than avail, which is
// an int, so the cast is safe // an int, so the cast is safe
int skipped = (int) Math.min(pLength - total, avail); int skipped = (int) Math.min(pLength - total, buffer.remaining());
bufferPos += skipped; // Just skip these bytes
total += skipped; total += skipped;
} }
@ -190,19 +176,20 @@ public final class DecoderStream extends FilterInputStream {
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
*/ */
protected int fill() throws IOException { protected int fill() throws IOException {
buffer.clear();
int read = decoder.decode(in, buffer); int read = decoder.decode(in, buffer);
// TODO: Enforce this in test case, leave here to aid debugging // TODO: Enforce this in test case, leave here to aid debugging
if (read > buffer.length) { if (read > buffer.capacity()) {
throw new AssertionError( throw new AssertionError(
String.format( String.format(
"Decode beyond buffer (%d): %d (using %s decoder)", "Decode beyond buffer (%d): %d (using %s decoder)",
buffer.length, read, decoder.getClass().getName() buffer.capacity(), read, decoder.getClass().getName()
) )
); );
} }
bufferPos = 0; buffer.flip();
if (read == 0) { if (read == 0) {
return -1; return -1;

View File

@ -28,9 +28,10 @@
package com.twelvemonkeys.io.enc; package com.twelvemonkeys.io.enc;
import java.io.InputStream;
import java.io.IOException;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
/** /**
* Decoder implementation for 16 bit-chunked Apple PackBits-like run-length * Decoder implementation for 16 bit-chunked Apple PackBits-like run-length
@ -84,13 +85,13 @@ public final class PackBits16Decoder implements Decoder {
* *
* @throws java.io.IOException * @throws java.io.IOException
*/ */
public int decode(final InputStream pStream, final byte[] pBuffer) throws IOException { public int decode(final InputStream pStream, final ByteBuffer pBuffer) throws IOException {
if (reachedEOF) { if (reachedEOF) {
return -1; return -1;
} }
int read = 0; int read = 0;
final int max = pBuffer.length; final int max = pBuffer.capacity();
while (read < max) { while (read < max) {
int n; int n;
@ -126,7 +127,7 @@ public final class PackBits16Decoder implements Decoder {
if (n >= 0) { if (n >= 0) {
// Copy next n + 1 shorts literally // Copy next n + 1 shorts literally
int len = 2 * (n + 1); int len = 2 * (n + 1);
readFully(pStream, pBuffer, read, len); readFully(pStream, pBuffer, len);
read += len; read += len;
} }
// Allow -128 for compatibility, see above // Allow -128 for compatibility, see above
@ -136,8 +137,8 @@ public final class PackBits16Decoder implements Decoder {
byte value2 = readByte(pStream); byte value2 = readByte(pStream);
for (int i = -n + 1; i > 0; i--) { for (int i = -n + 1; i > 0; i--) {
pBuffer[read++] = value1; pBuffer.put(value1);
pBuffer[read++] = value2; pBuffer.put(value2);
} }
} }
// else NOOP (-128) // else NOOP (-128)
@ -160,7 +161,7 @@ public final class PackBits16Decoder implements Decoder {
return (byte) read; return (byte) read;
} }
private static void readFully(final InputStream pStream, final byte[] pBuffer, final int pOffset, final int pLength) throws IOException { private static void readFully(final InputStream pStream, final ByteBuffer pBuffer, final int pLength) throws IOException {
if (pLength < 0) { if (pLength < 0) {
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
} }
@ -168,7 +169,7 @@ public final class PackBits16Decoder implements Decoder {
int read = 0; int read = 0;
while (read < pLength) { while (read < pLength) {
int count = pStream.read(pBuffer, pOffset + read, pLength - read); int count = pStream.read(pBuffer.array(), pBuffer.arrayOffset() + pBuffer.position() + read, pLength - read);
if (count < 0) { if (count < 0) {
throw new EOFException("Unexpected end of PackBits stream"); throw new EOFException("Unexpected end of PackBits stream");

View File

@ -31,6 +31,7 @@ package com.twelvemonkeys.io.enc;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.ByteBuffer;
/** /**
* Decoder implementation for Apple PackBits run-length encoding. * Decoder implementation for Apple PackBits run-length encoding.
@ -98,16 +99,13 @@ public final class PackBitsDecoder implements Decoder {
* *
* @throws java.io.IOException * @throws java.io.IOException
*/ */
public int decode(final InputStream pStream, final byte[] pBuffer) throws IOException { public int decode(final InputStream pStream, final ByteBuffer pBuffer) throws IOException {
if (reachedEOF) { if (reachedEOF) {
return -1; return -1;
} }
int read = 0;
final int max = pBuffer.length;
// TODO: Don't decode more than single runs, because some writers add pad bytes inside the stream... // TODO: Don't decode more than single runs, because some writers add pad bytes inside the stream...
while (read < max) { while (pBuffer.hasRemaining()) {
int n; int n;
if (splitRun) { if (splitRun) {
@ -126,12 +124,12 @@ public final class PackBitsDecoder implements Decoder {
} }
// Split run at or before max // Split run at or before max
if (n >= 0 && n + 1 + read > max) { if (n >= 0 && n + 1 > pBuffer.remaining()) {
leftOfRun = n; leftOfRun = n;
splitRun = true; splitRun = true;
break; break;
} }
else if (n < 0 && -n + 1 + read > max) { else if (n < 0 && -n + 1 > pBuffer.remaining()) {
leftOfRun = n; leftOfRun = n;
splitRun = true; splitRun = true;
break; break;
@ -140,9 +138,7 @@ public final class PackBitsDecoder implements Decoder {
try { try {
if (n >= 0) { if (n >= 0) {
// Copy next n + 1 bytes literally // Copy next n + 1 bytes literally
readFully(pStream, pBuffer, read, n + 1); readFully(pStream, pBuffer, n + 1);
read += n + 1;
} }
// Allow -128 for compatibility, see above // Allow -128 for compatibility, see above
else if (disableNoop || n != -128) { else if (disableNoop || n != -128) {
@ -150,7 +146,7 @@ public final class PackBitsDecoder implements Decoder {
byte value = readByte(pStream); byte value = readByte(pStream);
for (int i = -n + 1; i > 0; i--) { for (int i = -n + 1; i > 0; i--) {
pBuffer[read++] = value; pBuffer.put(value);
} }
} }
// else NOOP (-128) // else NOOP (-128)
@ -160,7 +156,7 @@ public final class PackBitsDecoder implements Decoder {
} }
} }
return read; return pBuffer.position();
} }
static byte readByte(final InputStream pStream) throws IOException { static byte readByte(final InputStream pStream) throws IOException {
@ -173,7 +169,7 @@ public final class PackBitsDecoder implements Decoder {
return (byte) read; return (byte) read;
} }
static void readFully(final InputStream pStream, final byte[] pBuffer, final int pOffset, final int pLength) throws IOException { static void readFully(final InputStream pStream, final ByteBuffer pBuffer, final int pLength) throws IOException {
if (pLength < 0) { if (pLength < 0) {
throw new IndexOutOfBoundsException(String.format("Negative length: %d", pLength)); throw new IndexOutOfBoundsException(String.format("Negative length: %d", pLength));
} }
@ -181,7 +177,7 @@ public final class PackBitsDecoder implements Decoder {
int total = 0; int total = 0;
while (total < pLength) { while (total < pLength) {
int count = pStream.read(pBuffer, pOffset + total, pLength - total); int count = pStream.read(pBuffer.array(), pBuffer.arrayOffset() + pBuffer.position() + total, pLength - total);
if (count < 0) { if (count < 0) {
throw new EOFException("Unexpected end of PackBits stream"); throw new EOFException("Unexpected end of PackBits stream");
@ -189,5 +185,7 @@ public final class PackBitsDecoder implements Decoder {
total += count; total += count;
} }
pBuffer.position(pBuffer.position() + total);
} }
} }

View File

@ -5,6 +5,7 @@ import com.twelvemonkeys.lang.ObjectAbstractTestCase;
import org.junit.Test; import org.junit.Test;
import java.io.*; import java.io.*;
import java.nio.ByteBuffer;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -39,7 +40,7 @@ public abstract class DecoderAbstractTestCase extends ObjectAbstractTestCase {
ByteArrayInputStream bytes = new ByteArrayInputStream(new byte[0]); ByteArrayInputStream bytes = new ByteArrayInputStream(new byte[0]);
try { try {
int count = decoder.decode(bytes, new byte[128]); int count = decoder.decode(bytes, ByteBuffer.allocate(128));
assertEquals("Should not be able to read any bytes", 0, count); assertEquals("Should not be able to read any bytes", 0, count);
} }
catch (EOFException allowed) { catch (EOFException allowed) {

View File

@ -33,6 +33,7 @@ import com.twelvemonkeys.io.enc.Decoder;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.ByteBuffer;
/** /**
* LempelZivWelch (LZW) decompression. LZW is a universal loss-less data compression algorithm * LempelZivWelch (LZW) decompression. LZW is a universal loss-less data compression algorithm
@ -94,10 +95,9 @@ abstract class LZWDecoder implements Decoder {
maxString = 1; maxString = 1;
} }
public int decode(final InputStream stream, final byte[] buffer) throws IOException { public int decode(final InputStream stream, final ByteBuffer buffer) throws IOException {
// Adapted from the pseudo-code example found in the TIFF 6.0 Specification, 1992. // Adapted from the pseudo-code example found in the TIFF 6.0 Specification, 1992.
// See Section 13: "LZW Compression"/"LZW Decoding", page 61+ // See Section 13: "LZW Compression"/"LZW Decoding", page 61+
int bufferPos = 0;
int code; int code;
while ((code = getNextCode(stream)) != EOI_CODE) { while ((code = getNextCode(stream)) != EOI_CODE) {
@ -109,30 +109,30 @@ abstract class LZWDecoder implements Decoder {
break; break;
} }
bufferPos += table[code].writeTo(buffer, bufferPos); table[code].writeTo(buffer);
} }
else { else {
if (isInTable(code)) { if (isInTable(code)) {
bufferPos += table[code].writeTo(buffer, bufferPos); table[code].writeTo(buffer);
addStringToTable(table[oldCode].concatenate(table[code].firstChar)); addStringToTable(table[oldCode].concatenate(table[code].firstChar));
} }
else { else {
String outString = table[oldCode].concatenate(table[oldCode].firstChar); String outString = table[oldCode].concatenate(table[oldCode].firstChar);
bufferPos += outString.writeTo(buffer, bufferPos); outString.writeTo(buffer);
addStringToTable(outString); addStringToTable(outString);
} }
} }
oldCode = code; oldCode = code;
if (bufferPos >= buffer.length - maxString - 1) { if (buffer.remaining() < maxString + 1) {
// Buffer full, stop decoding for now // Buffer full, stop decoding for now
break; break;
} }
} }
return bufferPos; return buffer.position();
} }
private void addStringToTable(final String string) throws IOException { private void addStringToTable(final String string) throws IOException {
@ -301,24 +301,24 @@ abstract class LZWDecoder implements Decoder {
return new String(firstChar, this.firstChar, length + 1, this); return new String(firstChar, this.firstChar, length + 1, this);
} }
public final int writeTo(final byte[] buffer, final int offset) { public final void writeTo(final ByteBuffer buffer) {
if (length == 0) { if (length == 0) {
return 0; return;
} }
else if (length == 1) {
buffer[offset] = value;
return 1; if (length == 1) {
buffer.put(value);
} }
else { else {
String e = this; String e = this;
final int offset = buffer.position();
for (int i = length - 1; i >= 0; i--) { for (int i = length - 1; i >= 0; i--) {
buffer[offset + i] = e.value; buffer.put(offset + i, e.value);
e = e.previous; e = e.previous;
} }
return length; buffer.position(offset + length);
} }
} }
} }

View File

@ -31,6 +31,7 @@ package com.twelvemonkeys.io.enc;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.zip.DataFormatException; import java.util.zip.DataFormatException;
import java.util.zip.Inflater; import java.util.zip.Inflater;
@ -75,11 +76,11 @@ final class InflateDecoder implements Decoder {
buffer = new byte[1024]; buffer = new byte[1024];
} }
public int decode(final InputStream pStream, final byte[] pBuffer) throws IOException { public int decode(final InputStream pStream, final ByteBuffer pBuffer) throws IOException {
try { try {
int decoded; int decoded;
while ((decoded = inflater.inflate(pBuffer, 0, pBuffer.length)) == 0) { while ((decoded = inflater.inflate(pBuffer.array(), pBuffer.arrayOffset(), pBuffer.capacity())) == 0) {
if (inflater.finished() || inflater.needsDictionary()) { if (inflater.finished() || inflater.needsDictionary()) {
return 0; return 0;
} }