void readHeaders(ByteBuffer buffer, byte flags, DecodeCallback callback) throws IOException,
                IndexOutOfBoundsException {
            mHeaders.clear();
            while (buffer.hasRemaining()) {
                int b = buffer.get() & 0xff;
                if (b == 0x80) { // 10000000
                    throw new IOException("Hpack read headers failed: index == 0");
                } else if ((b & 0x80) == 0x80) { // 1NNNNNNN
                    int index = readInt(buffer, b, PREFIX_7_BITS);
                    readIndexedHeader(index - 1);
                } else if (b == 0x40) { // 01000000
                    readLiteralHeaderWithIncrementalIndexingNewName(buffer);
                } else if ((b & 0x40) == 0x40) {  // 01NNNNNN
                    int index = readInt(buffer, b, PREFIX_6_BITS);
                    readLiteralHeaderWithIncrementalIndexingIndexedName(buffer, index - 1);
                } else if ((b & 0x20) == 0x20) {  // 001NNNNN
                    mMaxDynamicTableByteCount = readInt(buffer, b, PREFIX_5_BITS);
                    if (mMaxDynamicTableByteCount < 0
                            || mMaxDynamicTableByteCount > mHeaderTableSizeSetting) {
                        throw new IOException("Hpack read headers failed: Invalid dynamic table " +
                                "size update " + mMaxDynamicTableByteCount);
                    }
                    adjustDynamicTableByteCount();
                } else if (b == 0x10 || b == 0) { // 000?0000 - Ignore never indexed bit.
                    readLiteralHeaderWithoutIndexingNewName(buffer);
                } else { // 000?NNNN - Ignore never indexed bit.
                    int index = readInt(buffer, b, PREFIX_4_BITS);
                    readLiteralHeaderWithoutIndexingIndexedName(buffer, index - 1);
                }
            }
            // Build normal http header part
            String method = null;
            String path = null;
            String host = null;
            String status = null;
            List<Header> headers = new ArrayList<>();
            for (Header header : mHeaders) {
                if (header.name.equals(Header.TARGET_METHOD)) {
                    method = header.value;
                } else if (header.name.equals(Header.TARGET_PATH)) {
                    path = header.value;
                } else if (header.name.equals(Header.TARGET_AUTHORITY)) {
                    host = header.value;
                } else if (header.name.equalsIgnoreCase("host")) {
                    host = header.value;
                } else if (header.name.equalsIgnoreCase(Header.RESPONSE_STATUS)) {
                    status = header.value;
                } else {
                    headers.add(header);
                }
            }
            StringBuilder sb = new StringBuilder();
            if (method != null && path != null) {
                sb.append(method).append(" ").append(path).append(" ").append(HttpProtocol.HTTP_2.toString());
                sb.append(NetBareUtils.LINE_END);
            }
            if (status != null) {
                sb.append(HttpProtocol.HTTP_2.toString()).append(" ").append(status);
                sb.append(NetBareUtils.LINE_END);
            }
            if (host != null) {
                headers.add(0, new Header("Host", host));
            }
            for (Header header : headers) {
                if (header.name.equals(Header.TARGET_SCHEME)) {
                    continue;
                }
                sb.append(header.name).append(": ");
                if (header.value != null) {
                    sb.append(header.value);
                }
                sb.append(NetBareUtils.LINE_END);
            }
            if ((flags & Http2.FLAG_END_HEADERS) != 0) {
                sb.append(NetBareUtils.LINE_END);
            }
            callback.onResult(ByteBuffer.wrap(sb.toString().getBytes()),
                    (flags & Http2.FLAG_END_STREAM) != 0);
        }
Read and write HPACK v10.

https://httpwg.org/specs/rfc7540.html#HeaderBlock

This implementation uses an array for the dynamic table and a list for indexed entries.  Dynamic
entries are added to the array, starting in the last position moving forward.  When the array
fills, it is doubled.

@author Megatron King
@since 2019/1/5 20:13
netbare-core/src/main/java/com/github/megatronking/netbare/http2/Hpack.java