/** * Returns a {@link Tuple2} of the stream id, and the frame. This strips the frame length and * stream id header from the abstraction leaking frame. * * @param abstractionLeakingFrame the abstraction leaking frame * @return a {@link Tuple2} of the stream id, and the frame * @throws NullPointerException if {@code abstractionLeakingFrame} is {@code null} */ public static Tuple2<Integer, io.rsocket.framing.Frame> fromAbstractionLeakingFrame( Frame abstractionLeakingFrame) { Objects.requireNonNull(abstractionLeakingFrame, "abstractionLeakingFrame must not be null"); FrameLengthFrame frameLengthFrame = null; StreamIdFrame streamIdFrame = null; try { frameLengthFrame = createFrameLengthFrame(abstractionLeakingFrame.content()); streamIdFrame = frameLengthFrame.mapFrameWithoutFrameLength(StreamIdFrame::createStreamIdFrame); io.rsocket.framing.Frame frame = streamIdFrame.mapFrameWithoutStreamId(FrameFactory::createFrame); return Tuples.of(streamIdFrame.getStreamId(), frame); } finally { disposeQuietly(frameLengthFrame, streamIdFrame); release(abstractionLeakingFrame); } }
/** * Returns the frame length. * * @return the frame length */ public int getFrameLength() { return getByteBuf().getUnsignedMedium(0); }
@Override public String toString() { return "FrameLengthFrame{" + "frameLength=" + getFrameLength() + ", frameWithoutFrameLength=" + mapFrameWithoutFrameLength(ByteBufUtil::hexDump) + '}'; } }
/** * Returns an abstraction leaking frame with the stream id and frame. This adds the frame length * and stream id header to the frame. * * @param byteBufAllocator the {@link ByteBufAllocator} to use * @param streamId the stream id * @param frame the frame * @return an abstraction leaking frame with the stream id and frame * @throws NullPointerException if {@code byteBufAllocator} or {@code frame} is {@code null} */ public static Frame toAbstractionLeakingFrame( ByteBufAllocator byteBufAllocator, int streamId, io.rsocket.framing.Frame frame) { Objects.requireNonNull(byteBufAllocator, "byteBufAllocator must not be null"); Objects.requireNonNull(frame, "frame must not be null"); StreamIdFrame streamIdFrame = null; FrameLengthFrame frameLengthFrame = null; try { streamIdFrame = createStreamIdFrame(byteBufAllocator, streamId, frame); frameLengthFrame = createFrameLengthFrame(byteBufAllocator, streamIdFrame); return frameLengthFrame.mapFrame(byteBuf -> Frame.from(byteBuf.retain())); } finally { disposeQuietly(frame, streamIdFrame, frameLengthFrame); } } }
/** * Returns a test instance of {@link FrameLengthFrame}. * * @return a test instance of {@link FrameLengthFrame} */ public static FrameLengthFrame createTestFrameLengthFrame() { return createFrameLengthFrame(DEFAULT, createTestStreamIdFrame()); }
/** * Creates the frame with a frame length. * * @param byteBuf the {@link ByteBuf} representing the frame * @return the frame with a frame length * @throws NullPointerException if {@code byteBuf} is {@code null} */ public static FrameLengthFrame createFrameLengthFrame(ByteBuf byteBuf) { Objects.requireNonNull(byteBuf, "byteBuf must not be null"); return RECYCLER.get().setByteBuf(byteBuf.retain()); }
/** * Exposes the {@link Frame} without the frame length as a {@link ByteBuf} for mapping to a * different type. * * @param function the function to transform the {@link Frame} without the frame length as a * {@link ByteBuf} to a different type * @param <T> the different type * @return the {@link Frame} without the frame length as a {@link ByteBuf} mapped to a different * type * @throws NullPointerException if {@code function} is {@code null} */ public <T> T mapFrameWithoutFrameLength(Function<ByteBuf, T> function) { Objects.requireNonNull(function, "function must not be null"); return function.apply(getUnsafeFrameWithoutFrameLength()); }
/** * Returns an abstraction leaking frame with the stream id and frame. This adds the frame length * and stream id header to the frame. * * @param byteBufAllocator the {@link ByteBufAllocator} to use * @param streamId the stream id * @param frame the frame * @return an abstraction leaking frame with the stream id and frame * @throws NullPointerException if {@code byteBufAllocator} or {@code frame} is {@code null} */ public static Frame toAbstractionLeakingFrame( ByteBufAllocator byteBufAllocator, int streamId, io.rsocket.framing.Frame frame) { Objects.requireNonNull(byteBufAllocator, "byteBufAllocator must not be null"); Objects.requireNonNull(frame, "frame must not be null"); StreamIdFrame streamIdFrame = null; FrameLengthFrame frameLengthFrame = null; try { streamIdFrame = createStreamIdFrame(byteBufAllocator, streamId, frame); frameLengthFrame = createFrameLengthFrame(byteBufAllocator, streamIdFrame); return frameLengthFrame.mapFrame(byteBuf -> Frame.from(byteBuf.retain())); } finally { disposeQuietly(frame, streamIdFrame, frameLengthFrame); } } }
public static FrameLengthFrame createTestFrameLengthFrame() { return createFrameLengthFrame(DEFAULT, createTestStreamIdFrame()); }
/** * Creates the frame with a frame length. * * @param byteBufAllocator the {@link ByteBufAllocator} to use * @param frame the frame to prepend the frame length to * @return the frame with a frame length * @throws NullPointerException if {@code byteBufAllocator} or {@code frame} is {@code null} */ public static FrameLengthFrame createFrameLengthFrame( ByteBufAllocator byteBufAllocator, Frame frame) { Objects.requireNonNull(byteBufAllocator, "byteBufAllocator must not be null"); Objects.requireNonNull(frame, "frame must not be null"); ByteBuf frameLengthByteBuf = frame.mapFrame( frameByteBuf -> { ByteBuf byteBuf = byteBufAllocator .buffer(FRAME_LENGTH_BYTES) .writeMedium(getLengthAsUnsignedMedium(frameByteBuf)); return Unpooled.wrappedBuffer(byteBuf, frameByteBuf.retain()); }); return RECYCLER.get().setByteBuf(frameLengthByteBuf); }
/** * Exposes the {@link Frame} without the frame length as a {@link ByteBuf} for mapping to a * different type. * * @param function the function to transform the {@link Frame} without the frame length as a * {@link ByteBuf} to a different type * @param <T> the different type * @return the {@link Frame} without the frame length as a {@link ByteBuf} mapped to a different * type * @throws NullPointerException if {@code function} is {@code null} */ public <T> T mapFrameWithoutFrameLength(Function<ByteBuf, T> function) { Objects.requireNonNull(function, "function must not be null"); return function.apply(getUnsafeFrameWithoutFrameLength()); }
/** * Returns a {@link Tuple2} of the stream id, and the frame. This strips the frame length and * stream id header from the abstraction leaking frame. * * @param abstractionLeakingFrame the abstraction leaking frame * @return a {@link Tuple2} of the stream id, and the frame * @throws NullPointerException if {@code abstractionLeakingFrame} is {@code null} */ public static Tuple2<Integer, io.rsocket.framing.Frame> fromAbstractionLeakingFrame( Frame abstractionLeakingFrame) { Objects.requireNonNull(abstractionLeakingFrame, "abstractionLeakingFrame must not be null"); FrameLengthFrame frameLengthFrame = null; StreamIdFrame streamIdFrame = null; try { frameLengthFrame = createFrameLengthFrame(abstractionLeakingFrame.content()); streamIdFrame = frameLengthFrame.mapFrameWithoutFrameLength(StreamIdFrame::createStreamIdFrame); io.rsocket.framing.Frame frame = streamIdFrame.mapFrameWithoutStreamId(FrameFactory::createFrame); return Tuples.of(streamIdFrame.getStreamId(), frame); } finally { disposeQuietly(frameLengthFrame, streamIdFrame); release(abstractionLeakingFrame); } }
@DisplayName("createFrameLengthFrame throws NullPointerException with null byteBufAllocator") @Test void createFrameLengthFrameNullByteBufAllocator() { assertThatNullPointerException() .isThrownBy(() -> createFrameLengthFrame(null, createTestCancelFrame())) .withMessage("byteBufAllocator must not be null"); }
@Override public String toString() { return "FrameLengthFrame{" + "frameLength=" + getFrameLength() + ", frameWithoutFrameLength=" + mapFrameWithoutFrameLength(ByteBufUtil::hexDump) + '}'; } }
/** * Creates the frame with a frame length. * * @param byteBuf the {@link ByteBuf} representing the frame * @return the frame with a frame length * @throws NullPointerException if {@code byteBuf} is {@code null} */ public static FrameLengthFrame createFrameLengthFrame(ByteBuf byteBuf) { Objects.requireNonNull(byteBuf, "byteBuf must not be null"); return RECYCLER.get().setByteBuf(byteBuf.retain()); }
/** * Returns the frame without frame length directly. * * <p><b>Note:</b> this frame without frame length will be outside of the {@link Frame}'s * lifecycle and may be released at any time. It is highly recommended that you {@link * ByteBuf#retain()} the frame without frame length if you store it. * * @return the frame without frame length directly * @see #mapFrameWithoutFrameLength(Function) */ public ByteBuf getUnsafeFrameWithoutFrameLength() { ByteBuf byteBuf = getByteBuf(); return byteBuf .slice(FRAME_LENGTH_BYTES, byteBuf.readableBytes() - FRAME_LENGTH_BYTES) .asReadOnly(); }
/** * Creates the frame with a frame length. * * @param byteBufAllocator the {@link ByteBufAllocator} to use * @param frame the frame to prepend the frame length to * @return the frame with a frame length * @throws NullPointerException if {@code byteBufAllocator} or {@code frame} is {@code null} */ public static FrameLengthFrame createFrameLengthFrame( ByteBufAllocator byteBufAllocator, Frame frame) { Objects.requireNonNull(byteBufAllocator, "byteBufAllocator must not be null"); Objects.requireNonNull(frame, "frame must not be null"); ByteBuf frameLengthByteBuf = frame.mapFrame( frameByteBuf -> { ByteBuf byteBuf = byteBufAllocator .buffer(FRAME_LENGTH_BYTES) .writeMedium(getLengthAsUnsignedMedium(frameByteBuf)); return Unpooled.wrappedBuffer(byteBuf, frameByteBuf.retain()); }); return RECYCLER.get().setByteBuf(frameLengthByteBuf); }
/** * Returns the frame length. * * @return the frame length */ public int getFrameLength() { return getByteBuf().getUnsignedMedium(0); }
/** * Returns the frame without frame length directly. * * <p><b>Note:</b> this frame without frame length will be outside of the {@link Frame}'s * lifecycle and may be released at any time. It is highly recommended that you {@link * ByteBuf#retain()} the frame without frame length if you store it. * * @return the frame without frame length directly * @see #mapFrameWithoutFrameLength(Function) */ public ByteBuf getUnsafeFrameWithoutFrameLength() { ByteBuf byteBuf = getByteBuf(); return byteBuf .slice(FRAME_LENGTH_BYTES, byteBuf.readableBytes() - FRAME_LENGTH_BYTES) .asReadOnly(); }