Interface RetainableByteBuffer

All Superinterfaces:
Retainable
All Known Subinterfaces:
Content.Chunk, RetainableByteBuffer.Mutable
All Known Implementing Classes:
AbstractRetainableByteBuffer, ArrayByteBufferPool.Tracking.TrackedBuffer, Content.Chunk.Empty, RetainableByteBuffer.Abstract, RetainableByteBuffer.DynamicCapacity, RetainableByteBuffer.EmptyRetainableByteBuffer, RetainableByteBuffer.FixedCapacity, RetainableByteBuffer.NonRetainableByteBuffer, RetainableByteBuffer.Pooled, RetainableByteBuffer.Wrapper, Trailers

public interface RetainableByteBuffer extends Retainable

An abstraction over ByteBuffers which provides:

When possible and optimal, implementations will avoid data copies. However, copies may be favoured over retaining large buffers with small content.

Accessing data in the buffer can be achieved via:

The RetainableByteBuffer APIs are non-modal, meaning that there is no need for any flip operation between a mutable method and an accessor method. ByteBuffer returned or passed to this API should be in "flush" mode, with valid data between the position and limit. The ByteBuffer returned from getByteBuffer() may used directly and switched to "fill" mode, but it is the callers responsibility to flip back to "flush" mode, before any RetainableByteBuffer APIs are used.

The RetainableByteBuffer APIs hide any notion of unused space before or after valid data. All indexing is relative to the first byte of data in the buffer and no manipulation of data pointers is directly supported.

The buffer may be large and the size() is represented as a long in new APIs. However, APIs that are tied to a single backing ByteBuffer may use integer representations of size and indexes.

  • Field Details

    • EMPTY

      static final RetainableByteBuffer EMPTY
      A Zero-capacity, non-retainable RetainableByteBuffer.
  • Method Details

    • wrap

      static RetainableByteBuffer.Mutable wrap(ByteBuffer byteBuffer)

      Returns a non-retainable RetainableByteBuffer that wraps the given ByteBuffer.

      Use this method to wrap user-provided ByteBuffers, or ByteBuffers that hold constant bytes, to make them look like RetainableByteBuffers.

      The returned RetainableByteBuffer Retainable.canRetain() method always returns false.

      RetainableByteBuffers returned by this method are not suitable to be wrapped in other Retainable implementations that may delegate calls to Retainable.retain().

      Parameters:
      byteBuffer - the ByteBuffer to wrap
      Returns:
      a RetainableByteBuffer.FixedCapacity buffer wrapping the passed ByteBuffer
      See Also:
    • wrap

      static RetainableByteBuffer.Mutable wrap(ByteBuffer byteBuffer, Retainable retainable)

      Returns a RetainableByteBuffer that wraps the given ByteBuffer and Retainable.

      Parameters:
      byteBuffer - the ByteBuffer to wrap
      retainable - the associated Retainable.
      Returns:
      a RetainableByteBuffer.FixedCapacity buffer wrapping the passed ByteBuffer
      See Also:
    • wrap

      static RetainableByteBuffer.Mutable wrap(ByteBuffer byteBuffer, Runnable releaser)

      Returns a RetainableByteBuffer that wraps the given ByteBuffer and Runnable releaser.

      Parameters:
      byteBuffer - the ByteBuffer to wrap
      releaser - a Runnable to call when the buffer is released.
      Returns:
      a RetainableByteBuffer.FixedCapacity buffer wrapping the passed ByteBuffer
    • isMutable

      default boolean isMutable()
      Check if the underlying implementation is mutable. Note that the immutable RetainableByteBuffer API may be backed by a mutable ByteBuffer or the RetainableByteBuffer.Mutable API may be backed by an immutable ByteBuffer.
      Returns:
      whether this buffers implementation is mutable
      See Also:
    • asMutable

      Access this buffer via the RetainableByteBuffer.Mutable API. Note that the RetainableByteBuffer.Mutable API may be backed by an immutable ByteBuffer.
      Returns:
      An RetainableByteBuffer.Mutable representation of this buffer with same data and pointers.
      Throws:
      ReadOnlyBufferException - If the buffer is not RetainableByteBuffer.Mutable or the backing ByteBuffer is read-only.
      See Also:
    • appendTo

      default boolean appendTo(ByteBuffer buffer)
      Appends and consumes the contents of this buffer to the passed buffer, limited by the capacity of the target buffer.
      Parameters:
      buffer - The buffer to append bytes to, whose limit will be updated.
      Returns:
      true if all bytes in this buffer are able to be appended.
      See Also:
    • appendTo

      default boolean appendTo(RetainableByteBuffer buffer)
      Appends and consumes the contents of this buffer to the passed buffer, limited by the capacity of the target buffer.
      Parameters:
      buffer - The buffer to append bytes to, whose limit will be updated.
      Returns:
      true if all bytes in this buffer are able to be appended.
      See Also:
    • copy

      default RetainableByteBuffer copy()
      Creates a deep copy of this RetainableByteBuffer that is entirely independent
      Returns:
      A copy of this RetainableByteBuffer
    • get

      default byte get() throws BufferUnderflowException
      Consumes and returns a byte from this RetainableByteBuffer
      Returns:
      the byte
      Throws:
      BufferUnderflowException - if the buffer is empty.
      See Also:
    • get

      default byte get(long index) throws IndexOutOfBoundsException
      Returns a byte from this RetainableByteBuffer at a specific index
      Parameters:
      index - The index relative to the current start of unconsumed data in the buffer.
      Returns:
      the byte
      Throws:
      IndexOutOfBoundsException - if the index is too large.
    • get

      default int get(byte[] bytes, int offset, int length)
      Consumes and copies the bytes from this RetainableByteBuffer to the given byte array.
      Parameters:
      bytes - the byte array to copy the bytes into
      offset - the offset within the byte array
      length - the maximum number of bytes to copy
      Returns:
      the number of bytes actually copied
    • getByteBuffer

      ByteBuffer getByteBuffer() throws BufferOverflowException
      Get the wrapped, not null, ByteBuffer.

      If the implementation contains multiple buffers, they are coalesced to a single buffer before being returned. If the content is too large for a single ByteBuffer, then the content should be access with writeTo(Content.Sink, boolean).

      Returns:
      the wrapped, not null, ByteBuffer
      Throws:
      BufferOverflowException - if the contents is too large for a single ByteBuffer
    • isDirect

      default boolean isDirect()
      Returns:
      whether the ByteBuffer is direct
    • remaining

      default int remaining()
      Returns:
      the number of remaining bytes in the ByteBuffer
      See Also:
    • hasRemaining

      default boolean hasRemaining()
      Returns:
      whether the ByteBuffer has remaining bytes
    • isEmpty

      default boolean isEmpty()
      Returns:
      whether the ByteBuffer has remaining bytes left for reading
    • size

      default long size()
      Returns:
      the number of remaining bytes in the ByteBuffer
      See Also:
    • maxSize

      default long maxSize()
      Returns:
      the maximum size in bytes.
      See Also:
    • capacity

      default int capacity()
      Returns:
      the capacity
      See Also:
    • clear

      default void clear()
      See Also:
    • space

      default long space()
      Returns:
      the number of bytes that can be added, appended or put into this buffer, assuming it is mutable.
    • isFull

      default boolean isFull()
      Returns:
      true if no more bytes can be added, appended or put to this buffer, assuming it is mutable.
    • skip

      default long skip(long length)

      Skips, advancing the ByteBuffer position, the given number of bytes.

      Parameters:
      length - the maximum number of bytes to skip
      Returns:
      the number of bytes actually skipped
    • limit

      default void limit(long size)

      Limit this buffer's contents to the size.

      Parameters:
      size - the new size of the buffer
    • slice

      default RetainableByteBuffer slice()
      Get a slice of the buffer.
      Returns:
      A sliced RetainableByteBuffer sharing this buffers data and reference count, but with independent position. The buffer is retained by this call.
      See Also:
    • slice

      default RetainableByteBuffer slice(long length)
      Get a partial slice of the buffer. This is equivalent to slice().limit(long), but may be implemented more efficiently.
      Parameters:
      length - The number of bytes to slice, which may beyond the limit and less than the capacity, in which case it will ensure some spare capacity in the slice.
      Returns:
      A sliced RetainableByteBuffer sharing the first length bytes of this buffers data and reference count, but with independent position. The buffer is retained by this call.
    • take

      default RetainableByteBuffer take(long length)
      Take the contents of this buffer, from the head, leaving remaining bytes in this buffer. This is similar to slice(long) followed by a skip(long), but avoids shared data.
      Parameters:
      length - The number of bytes to take
      Returns:
      A buffer with the contents of this buffer after limiting bytes, avoiding copies if possible, but with no shared internal buffers.
    • takeFrom

      default RetainableByteBuffer takeFrom(long skip)
      Take the contents of this buffer, from the tail, leaving remaining bytes in this buffer.
      Parameters:
      skip - The number of bytes to skip before taking the tail.
      Returns:
      A buffer with the contents of this buffer after skipping bytes, avoiding copies if possible, but with no shared internal buffers.
    • take

      default RetainableByteBuffer take()
      Take the contents of this buffer, leaving it clear.
      Returns:
      A buffer with the contents of this buffer, avoiding copies if possible.
      See Also:
    • takeByteArray

      default byte[] takeByteArray()
      Take the contents of this buffer, leaving it clear and independent.
      Returns:
      A possibly newly allocated array with the contents of this buffer, avoiding copies if possible.
    • putTo

      default void putTo(ByteBuffer toInfillMode) throws BufferOverflowException
      Consumes and puts the contents of this retainable byte buffer at the end of the given byte buffer.
      Parameters:
      toInfillMode - the destination buffer, whose position is updated.
      Throws:
      BufferOverflowException - – If there is insufficient space in this buffer for the remaining bytes in the source buffer
      See Also:
    • writeTo

      default void writeTo(Content.Sink sink, boolean last, Callback callback)
      Asynchronously writes and consumes the contents of this retainable byte buffer into the given sink.
      Parameters:
      sink - the destination sink.
      last - true if this is the last write.
      callback - the callback to call upon the write completion.
      See Also:
    • writeTo

      default void writeTo(Content.Sink sink, boolean last) throws IOException
      Writes and consumes the contents of this retainable byte buffer into the given sink.
      Parameters:
      sink - the destination sink.
      last - true if this is the last write.
      Throws:
      IOException
      See Also:
    • toDetailString

      default String toDetailString()
      Returns:
      A string showing the info and detail about this buffer, as well as a summary of the contents