public static int encodeMetadata( final ByteBuf byteBuf, final FrameType frameType, final int metadataOffset, final @Nullable ByteBuf metadata) { int length = 0; if (metadata != null) { final int metadataLength = metadata.readableBytes(); int typeAndFlags = byteBuf.getShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET); typeAndFlags |= FLAGS_M; byteBuf.setShort(FRAME_TYPE_AND_FLAGS_FIELD_OFFSET, (short) typeAndFlags); if (hasMetadataLengthField(frameType)) { encodeLength(byteBuf, metadataOffset, metadataLength); length += FRAME_LENGTH_SIZE; } byteBuf.setBytes(metadataOffset + length, metadata, metadata.readerIndex(), metadataLength); length += metadataLength; } return length; }
public static ByteBuf sliceFrameData(final ByteBuf byteBuf) { final FrameType frameType = frameType(byteBuf); final int frameLength = frameLength(byteBuf); final int dataLength = dataLength(byteBuf, frameType); final int dataOffset = dataOffset(byteBuf, frameType, frameLength); ByteBuf result = Unpooled.EMPTY_BUFFER; if (0 < dataLength) { result = byteBuf.slice(dataOffset, dataLength); } return result; }
public static @Nullable Integer metadataLength( ByteBuf byteBuf, FrameType frameType, int frameLength) { if (!hasMetadataLengthField(frameType)) { return frameLength - metadataOffset(byteBuf); } else { return decodeMetadataLength(byteBuf, metadataOffset(byteBuf)); } }
static int dataLength(final ByteBuf byteBuf, final FrameType frameType, final int payloadOffset) { final int frameLength = frameLength(byteBuf); final int metadataLength = metadataFieldLength(byteBuf, frameType, frameLength); return frameLength - metadataLength - payloadOffset; }
public static int payloadLength(final ByteBuf byteBuf) { final int frameLength = frameLength(byteBuf); final int payloadOffset = payloadOffset(byteBuf); return frameLength - payloadOffset; }
public static int dataLength(final ByteBuf byteBuf, final FrameType frameType) { return dataLength(byteBuf, frameType, payloadOffset(byteBuf)); }
public static @Nullable ByteBuf sliceFrameMetadata(final ByteBuf byteBuf) { final FrameType frameType = frameType(byteBuf); final int frameLength = frameLength(byteBuf); final @Nullable Integer metadataLength = metadataLength(byteBuf, frameType, frameLength); if (metadataLength == null) { return null; } int metadataOffset = metadataOffset(byteBuf); if (hasMetadataLengthField(frameType)) { metadataOffset += FRAME_LENGTH_SIZE; } ByteBuf result = Unpooled.EMPTY_BUFFER; if (0 < metadataLength) { result = byteBuf.slice(metadataOffset, metadataLength); } return result; }
public static int encode( final ByteBuf byteBuf, final int streamId, int flags, final FrameType type, final int initialRequestN, final @Nullable ByteBuf metadata, final ByteBuf data) { if (Frame.isFlagSet(flags, FrameHeaderFlyweight.FLAGS_M) != (metadata != null)) { throw new IllegalArgumentException("metadata flag set incorrectly"); } final int frameLength = computeFrameLength( type, metadata != null ? metadata.readableBytes() : null, data.readableBytes()); int length = FrameHeaderFlyweight.encodeFrameHeader(byteBuf, frameLength, flags, type, streamId); byteBuf.setInt(INITIAL_REQUEST_N_FIELD_OFFSET, initialRequestN); length += Integer.BYTES; length += FrameHeaderFlyweight.encodeMetadata(byteBuf, type, length, metadata); length += FrameHeaderFlyweight.encodeData(byteBuf, length, data); return length; }
@Override public String toString() { FrameType type = FrameHeaderFlyweight.frameType(content); StringBuilder payload = new StringBuilder(); @Nullable ByteBuf metadata = FrameHeaderFlyweight.sliceFrameMetadata(content); ByteBuf data = FrameHeaderFlyweight.sliceFrameData(content); if (0 < data.readableBytes()) { payload.append(String.format("data: \"%s\" ", data.toString(StandardCharsets.UTF_8))); long streamId = FrameHeaderFlyweight.streamId(content);
@Test public void validResumeFrame() { ByteBuf token = Unpooled.wrappedBuffer(new byte[] {2, 3}); ByteBuf metadata = Unpooled.wrappedBuffer(new byte[] {1, 2, 3, 4}); ByteBuf data = Unpooled.wrappedBuffer(new byte[] {5, 4, 3}); SetupFrameFlyweight.encode( byteBuf, SetupFrameFlyweight.FLAGS_RESUME_ENABLE, 5, 500, token, "metadata_type", "data_type", metadata, data); token.resetReaderIndex(); metadata.resetReaderIndex(); data.resetReaderIndex(); assertEquals(FrameType.SETUP, FrameHeaderFlyweight.frameType(byteBuf)); assertEquals("metadata_type", SetupFrameFlyweight.metadataMimeType(byteBuf)); assertEquals("data_type", SetupFrameFlyweight.dataMimeType(byteBuf)); assertEquals(metadata, FrameHeaderFlyweight.sliceFrameMetadata(byteBuf)); assertEquals(data, FrameHeaderFlyweight.sliceFrameData(byteBuf)); assertEquals( SetupFrameFlyweight.FLAGS_RESUME_ENABLE, FrameHeaderFlyweight.flags(byteBuf) & SetupFrameFlyweight.FLAGS_RESUME_ENABLE); }
computeFrameHeaderLength( frameType, metadata != null ? metadata.readableBytes() : null, data.readableBytes()); int length = encodeFrameHeader(byteBuf, frameLength, flags, outFrameType, streamId); length += encodeMetadata(byteBuf, frameType, length, metadata); length += encodeData(byteBuf, length, data);
@Test public void validFrame() { ByteBuf metadata = Unpooled.wrappedBuffer(new byte[] {1, 2, 3, 4}); ByteBuf data = Unpooled.wrappedBuffer(new byte[] {5, 4, 3}); SetupFrameFlyweight.encode(byteBuf, 0, 5, 500, "metadata_type", "data_type", metadata, data); metadata.resetReaderIndex(); data.resetReaderIndex(); assertEquals(FrameType.SETUP, FrameHeaderFlyweight.frameType(byteBuf)); assertEquals("metadata_type", SetupFrameFlyweight.metadataMimeType(byteBuf)); assertEquals("data_type", SetupFrameFlyweight.dataMimeType(byteBuf)); assertEquals(metadata, FrameHeaderFlyweight.sliceFrameMetadata(byteBuf)); assertEquals(data, FrameHeaderFlyweight.sliceFrameData(byteBuf)); }
public static Frame from(int streamId) { final Frame frame = RECYCLER.get(); frame.setRefCnt(1); frame.content = ByteBufAllocator.DEFAULT.buffer( FrameHeaderFlyweight.computeFrameHeaderLength(FrameType.CANCEL, null, 0)); frame.content.writerIndex( FrameHeaderFlyweight.encode( frame.content, streamId, 0, FrameType.CANCEL, null, Unpooled.EMPTY_BUFFER)); return frame; } }
public static int encode(final ByteBuf byteBuf, int flags, final ByteBuf data) { final int frameLength = computeFrameLength(data.readableBytes()); int length = FrameHeaderFlyweight.encodeFrameHeader(byteBuf, frameLength, flags, FrameType.KEEPALIVE, 0); // We don't support resumability, last position is always zero byteBuf.setLong(length, 0); length += Long.BYTES; length += FrameHeaderFlyweight.encodeData(byteBuf, length, data); return length; }
/** * Return the flags field for the frame * * @return frame flags field value */ public int flags() { return FrameHeaderFlyweight.flags(content); }
@Test public void headerSize() { int frameLength = 123456; FrameHeaderFlyweight.encodeFrameHeader(byteBuf, frameLength, 0, FrameType.SETUP, 0); assertEquals(frameLength, FrameHeaderFlyweight.frameLength(byteBuf)); }
@Test public void dataLength() { ByteBuf data = Unpooled.wrappedBuffer(new byte[] {1, 2, 3, 4, 5}); int length = FrameHeaderFlyweight.encode( byteBuf, 0, FLAGS_M, FrameType.SETUP, Unpooled.EMPTY_BUFFER, data); assertEquals( 5, FrameHeaderFlyweight.dataLength( byteBuf, FrameType.SETUP, FrameHeaderFlyweight.FRAME_HEADER_LENGTH)); }
@Test public void dataSlice() { ByteBuf data = Unpooled.wrappedBuffer(new byte[] {1, 2, 3, 4, 5}); FrameHeaderFlyweight.encode( byteBuf, 0, FLAGS_M, FrameType.REQUEST_RESPONSE, Unpooled.EMPTY_BUFFER, data); data.resetReaderIndex(); assertEquals(data, FrameHeaderFlyweight.sliceFrameData(byteBuf)); }
@Test public void metadataSlice() { ByteBuf metadata = Unpooled.wrappedBuffer(new byte[] {1, 2, 3, 4}); FrameHeaderFlyweight.encode( byteBuf, 0, FLAGS_M, FrameType.REQUEST_RESPONSE, metadata, Unpooled.EMPTY_BUFFER); metadata.resetReaderIndex(); assertEquals(metadata, FrameHeaderFlyweight.sliceFrameMetadata(byteBuf)); }
@Test public void metadataLength() { ByteBuf metadata = Unpooled.wrappedBuffer(new byte[] {1, 2, 3, 4}); FrameHeaderFlyweight.encode( byteBuf, 0, FLAGS_M, FrameType.SETUP, metadata, Unpooled.EMPTY_BUFFER); assertEquals( 4, FrameHeaderFlyweight.decodeMetadataLength(byteBuf, FrameHeaderFlyweight.FRAME_HEADER_LENGTH) .longValue()); }