module hunt.http.codec.http.decode.HeaderBlockParser; import hunt.io.ByteBuffer; import hunt.http.codec.http.hpack.HpackDecoder; import hunt.http.HttpMetaData; import hunt.io.BufferUtils; class HeaderBlockParser { private HpackDecoder hpackDecoder; private ByteBuffer blockBuffer; this(HpackDecoder hpackDecoder) { this.hpackDecoder = hpackDecoder; } HttpMetaData parse(ByteBuffer buffer, int blockLength) { // We must wait for the all the bytes of the header block to arrive. // If they are not all available, accumulate them. // When all are available, decode them. int accumulated = blockBuffer is null ? 0 : blockBuffer.position(); int remaining = blockLength - accumulated; if (buffer.remaining() < remaining) { if (blockBuffer is null) { blockBuffer = BufferUtils.allocate(blockLength); BufferUtils.clearToFill(blockBuffer); } blockBuffer.put(buffer); return null; } else { int limit = buffer.limit(); buffer.limit(buffer.position() + remaining); ByteBuffer toDecode; if (blockBuffer !is null) { blockBuffer.put(buffer); BufferUtils.flipToFlush(blockBuffer, 0); toDecode = blockBuffer; } else { toDecode = buffer; } HttpMetaData result = hpackDecoder.decode(toDecode); buffer.limit(limit); if(blockBuffer !is null) { blockBuffer = null; } return result; } } }