package com.webpieces.http2parser.impl.marshallers; import java.nio.ByteBuffer; import org.webpieces.data.api.BufferPool; import org.webpieces.data.api.DataWrapper; import org.webpieces.data.api.DataWrapperGenerator; import org.webpieces.data.api.DataWrapperGeneratorFactory; import com.webpieces.http2parser.api.dto.lib.Http2Frame; import com.webpieces.http2parser.impl.FrameHeaderData; import com.webpieces.http2parser.impl.Http2MementoImpl; public class AbstractFrameMarshaller { protected static final DataWrapperGenerator dataGen = DataWrapperGeneratorFactory.createDataWrapperGenerator(); protected BufferPool bufferPool; public AbstractFrameMarshaller(BufferPool bufferPool) { this.bufferPool = bufferPool; } protected DataWrapper marshalFrame(Http2Frame frame, byte value, DataWrapper payload) { int originalStreamId = frame.getStreamId(); // Clear the MSB because streamId can only be 31 bits int streamId = originalStreamId & 0x7FFFFFFF; if(streamId != originalStreamId) throw new RuntimeException("your stream id is too large per spec. frame="+frame); ByteBuffer header = ByteBuffer.allocate(9); int length = payload.getReadableSize(); header.put((byte) (length >>> 16)); header.putShort((short) length); header.put(frame.getFrameType().getId()); header.put(value); // 1 bit reserved, streamId MSB is always 0, see setStreamId() header.putInt(streamId); header.flip(); DataWrapper frameHeader = dataGen.wrapByteBuffer(header); return dataGen.chainDataWrappers(frameHeader, payload); } public void unmarshalFrame(Http2MementoImpl state, Http2Frame frame) { FrameHeaderData frameHeaderData = state.getFrameHeaderData(); frame.setStreamId(frameHeaderData.getStreamId()); } }