private int internalTransfer(long offset, ByteBuff b, BiConsumer<ByteBuffer, ByteBuff> transfer) {
    int expectedTransferLen = b.remaining();
    if (expectedTransferLen == 0) {
      return 0;
    }
    BufferIterator it = new BufferIterator(offset, expectedTransferLen);
    while (it.hasNext()) {
      ByteBuffer a = it.next();
      transfer.accept(a, b);
      assert !a.hasRemaining();
    }
    assert expectedTransferLen == it.getSum() : "Expected transfer length (=" + expectedTransferLen
      + ") don't match the actual transfer length(=" + it.getSum() + ")";
    return expectedTransferLen;
  }
Transferring all remaining bytes from b to the buffers array starting at offset, or
transferring bytes from the buffers array at offset to b until b is filled. Notice that
position of ByteBuff b will be advanced.
@param offset   where we start in the big logical array.
@param b        the ByteBuff to transfer from or to
@param transfer the transfer interface.
@return the length of bytes we transferred.
hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferArray.java