in src/main/java/com/twitter/whiskey/util/ZlibInflater.java [187:269]
public int inflate(byte[] b, int off, int len) throws DataFormatException {
if (finished) {
if (in.hasRemaining()) throw new DataFormatException("zlib stream ended unexpectedly");
return 0;
}
if (!in.hasRemaining()) return 0;
if (determineWrapper) {
// First two bytes are needed to decide if it's a ZLIB stream.
if (accumulator.remaining() + len < 2) {
buffer();
return 0;
}
byte[] cmf_flg = new byte[2];
cmf_flg[0] = readByte();
cmf_flg[1] = readByte();
boolean nowrap = !looksLikeZlib(cmf_flg[0], cmf_flg[1]);
inflater = new Inflater(nowrap);
inflater.inflate(cmf_flg, 0, 2);
determineWrapper = false;
}
if (crc != null) {
switch (gzipState) {
case FOOTER_START:
if (readGZIPFooter()) {
finished = true;
}
return 0;
default:
if (gzipState != GzipState.HEADER_END) {
if (!readGZIPHeader()) {
return 0;
}
}
}
// Some bytes may have been consumed, and so we must re-set the number of readable bytes.
// readableBytes = in.readableBytes();
}
inflater.setInput(in.array(), in.arrayOffset() + in.position(), in.remaining());
boolean readFooter = false;
int totalWritten = 0;
while (off < len && !inflater.needsInput()) {
int bytesWritten = inflater.inflate(b, off, len);
if (bytesWritten > 0) {
totalWritten += bytesWritten;
if (crc != null) {
crc.update(b, off, bytesWritten);
}
off += bytesWritten;
} else {
if (inflater.needsDictionary()) {
inflater.setDictionary(dictionary);
}
}
if (inflater.finished()) {
if (crc == null) {
finished = true; // Do not decode anymore.
} else {
readFooter = true;
}
break;
}
}
in.position(in.position() + in.remaining() - inflater.getRemaining());
if (readFooter) {
gzipState = GzipState.FOOTER_START;
if (readGZIPFooter()) {
finished = true;
}
}
return totalWritten;
}