public int inflate()

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;
    }