Class ByteBufVisitor

java.lang.Object
org.apache.bookkeeper.util.ByteBufVisitor

public class ByteBufVisitor extends Object
This class visits the possible wrapped child buffers of a Netty ByteBuf for a given offset and length.

The Netty ByteBuf API does not provide a method to visit the wrapped child buffers. The ByteBuf.unwrap() method is not suitable for this purpose as it loses the ByteBuf.readerIndex() state, resulting in incorrect offset and length information.

Despite Netty not having a public API for visiting the sub buffers, it is possible to achieve this using the ByteBuf.getBytes(int, ByteBuf, int, int) method. This class uses this method to visit the wrapped child buffers by providing a suitable ByteBuf implementation. This implementation supports the role of the destination buffer for the getBytes call. It requires implementing the ByteBuf.setBytes(int, ByteBuf, int, int) and ByteBuf.setBytes(int, byte[], int, int) methods and other methods required by getBytes such as ByteBuf.hasArray(), ByteBuf.hasMemoryAddress(), ByteBuf.nioBufferCount() and ByteBuf.capacity(). All other methods in the internal ByteBuf implementation are not supported and will throw an exception. This is to ensure correctness and to fail fast if some ByteBuf implementation is not following the expected and supported interface contract.

  • Method Details

    • visitBuffers

      public static <T> void visitBuffers(io.netty.buffer.ByteBuf buffer, int offset, int length, ByteBufVisitor.ByteBufVisitorCallback<T> callback, T context)
      This method traverses the potential nested composite buffers of the provided buffer, given a specific offset and length. The traversal continues until it encounters a buffer that is backed by an array or a memory address, which allows for the inspection of individual buffer segments without the need for data duplication. If no such wrapped buffer is found, the callback function is invoked with the original buffer, offset, and length as parameters.
      Parameters:
      buffer - the buffer to visit
      offset - the offset for the buffer
      length - the length for the buffer
      callback - the callback to call for each visited buffer
      context - the context to pass to the callback
    • visitBuffers

      public static <T> void visitBuffers(io.netty.buffer.ByteBuf buffer, int offset, int length, ByteBufVisitor.ByteBufVisitorCallback<T> callback, T context, int maxDepth)
      See @visitBuffers(ByteBuf, int, int, ByteBufVisitorCallback, Object). This method allows to specify the maximum depth of recursion for visiting wrapped buffers.