private boolean readGZIPHeader()

in src/main/java/com/twitter/whiskey/util/ZlibInflater.java [301:408]


    private boolean readGZIPHeader() throws DataFormatException {
        switch (gzipState) {
            case HEADER_START:
                if (bytesRemaining() < 10) {
                    buffer();
                    return false;
                }
                // read magic numbers
                int magic0 = readByte();
                int magic1 = readByte();

                if (magic0 != 31) {
                    throw new DataFormatException("Input is not in the GZIP format");
                }
                crc.update(magic0);
                crc.update(magic1);

                int method = readUnsignedByte();
                if (method != Deflater.DEFLATED) {
                    throw new DataFormatException("Unsupported compression method "
                        + method + " in the GZIP header");
                }
                crc.update(method);

                flags = readUnsignedByte();
                crc.update(flags);

                if ((flags & FRESERVED) != 0) {
                    throw new DataFormatException(
                        "Reserved flags are set in the GZIP header");
                }

                // mtime (int)
                crc.update(readByte());
                crc.update(readByte());
                crc.update(readByte());
                crc.update(readByte());

                crc.update(readUnsignedByte()); // extra flags
                crc.update(readUnsignedByte()); // operating system

                gzipState = GzipState.FLG_READ;
            case FLG_READ:
                if ((flags & FEXTRA) != 0) {
                    if (bytesRemaining() < 2) {
                        buffer();
                        return false;
                    }
                    int xlen1 = readUnsignedByte();
                    int xlen2 = readUnsignedByte();
                    crc.update(xlen1);
                    crc.update(xlen2);

                    xlen |= xlen1 << 8 | xlen2;
                    if (xlen != -1) {
                        xtra = new byte[xlen];
                    }
                }
                gzipState = GzipState.XLEN_READ;
            case XLEN_READ:
                while (xlen > 0) {
                    if (bytesRemaining() == 0) return false;
                    xtra[xtra.length - xlen--] = readByte();
                }
                if (xlen == 0) crc.update(xtra);
                gzipState = GzipState.SKIP_FNAME;
            case SKIP_FNAME:
                if ((flags & FNAME) != 0) {
                    while (bytesRemaining() > 0) {
                        int b = readUnsignedByte();
                        crc.update(b);
                        if (b == 0x00) {
                            gzipState = GzipState.SKIP_COMMENT;
                            break;
                        }
                    }
                    // No buffering required, since above loop consumes all available bytes
                    if (gzipState == GzipState.SKIP_FNAME) return false;
                }
            case SKIP_COMMENT:
                if ((flags & FCOMMENT) != 0) {
                    while (bytesRemaining() > 0) {
                        int b = readUnsignedByte();
                        crc.update(b);
                        if (b == 0x00) {
                            break;
                        }
                    }
                    // No buffering required, since above loop consumes all available bytes
                    if (gzipState == GzipState.SKIP_COMMENT) return false;
                }
                gzipState = GzipState.PROCESS_FHCRC;
            case PROCESS_FHCRC:
                if ((flags & FHCRC) != 0) {
                    if (bytesRemaining() < 4) {
                        buffer();
                        return false;
                    }
                    verifyCrc();
                }
                crc.reset();
                gzipState = GzipState.HEADER_END;
            case HEADER_END:
                return true;
            default:
                throw new IllegalStateException();
        }
    }