Get a straight ByteBuffer slice position relative to the original ByteBuffer

Is there a way to get a direct zero position ByteBufferrelative to another, given only two objects ByteBuffer, if it is known that this is a subsequence of another buffer?

I know that this can be done using an indirect array with support ByteBufferusing the method arrayOffset():

int getRelativeBufferOffset(ByteBuffer parentBuffer, ByteBuffer childBuffer)
{
  return childBuffer.arrayOffset() - parentBuffer.arrayOffset();
}

void example()
{
  ByteBuffer buffer1 = ByteBuffer.allocate(10000);
  buffer1 .position(22);
  ByteBuffer buffer2 = buffer1.slice();
  buffer2.position(55);
  ByteBuffer buffer3 = buffer2.slice();

  // returns 22
  getRelativeBufferOffset(buffer1, buffer2);

  // returns 55
  getRelativeBufferOffset(buffer2, buffer3);

  // returns 77
  getRelativeBufferOffset(buffer1, buffer3);
}

I think there is nothing free for direct buffers. To get something like this, the best option I can think of is an extension ByteBufferto store the reference to the buffer from which it was created (parent buffer), and the zero position relative to the parent zero position in which it was created.

EDIT: , , ByteBuffer, . , - .

+4
1

, . , , . , . "" , , ,

class SlicedBuffer {
    int getBuffer() { ... }
    Buffer getParent() { ... }
    int getOffsetToParent() { ... }
}

, , .

, , ,

// Many things...
// ... can go ...
// ... wrong when...
// ... using reflection

:

import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;

public class DirectByteBufferSliceOffsetsTest
{
    public static void main(String[] args)
    {
        testArray();
        testDirect();
    }

    private static void testArray()
    {
        System.out.println("Array: ");

        ByteBuffer buffer1 = ByteBuffer.allocate(10000);
        buffer1.position(22);
        ByteBuffer buffer2 = buffer1.slice();
        buffer2.position(55);
        ByteBuffer buffer3 = buffer2.slice();

        // prints 22
        System.out.println(getRelativeBufferOffsetArray(buffer1, buffer2));

        // prints 55
        System.out.println(getRelativeBufferOffsetArray(buffer2, buffer3));

        // prints 77
        System.out.println(getRelativeBufferOffsetArray(buffer1, buffer3));
    }

    private static int getRelativeBufferOffsetArray(
        ByteBuffer parentBuffer, ByteBuffer childBuffer)
    {
        return childBuffer.arrayOffset() - parentBuffer.arrayOffset();
    }


    private static void testDirect()
    {
        System.out.println("Direct: ");

        ByteBuffer buffer1 = ByteBuffer.allocateDirect(10000);
        buffer1.position(22);
        ByteBuffer buffer2 = buffer1.slice();
        buffer2.position(55);
        ByteBuffer buffer3 = buffer2.slice();

        // prints 22
        System.out.println(getRelativeBufferOffsetDirect(buffer1, buffer2));

        // prints 55
        System.out.println(getRelativeBufferOffsetDirect(buffer2, buffer3));

        // prints 77
        System.out.println(getRelativeBufferOffsetDirect(buffer1, buffer3));
    }

    private static int getRelativeBufferOffsetDirect(
        ByteBuffer parentBuffer, ByteBuffer childBuffer)
    {
        long parentAddress = getAddress(parentBuffer);
        long childAddress = getAddress(childBuffer);
        int offset = (int)(childAddress - parentAddress);
        return offset;
    }

    private static long getAddress(Buffer buffer)
    {
        Field f = null;
        try
        {
            f = Buffer.class.getDeclaredField("address");
            f.setAccessible(true);
            return f.getLong(buffer);
        }
        catch (NoSuchFieldException e)
        {
            // Many things...
            e.printStackTrace();
        }
        catch (SecurityException e)
        {
            // ... can go ...
            e.printStackTrace();
        }
        catch (IllegalArgumentException e)
        {
            // ... wrong when...
            e.printStackTrace();
        }
        catch (IllegalAccessException e)
        {
            // ... using reflection
            e.printStackTrace();
        }
        finally
        {
            if (f != null)
            {
                f.setAccessible(false);
            }
        }
        return 0;
    }
}
+1

All Articles