Author: orudyy
Date: Wed Oct 5 15:39:15 2016
New Revision: 1763459
URL: http://svn.apache.org/viewvc?rev=1763459&view=rev
Log:
QPID-6803: Re-inplement QpidByteBuffer slice, duplicate and view operations
Removed:
qpid/java/trunk/common/src/main/java/org/apache/qpid/bytebuffer/QpidByteBufferImpl.java
qpid/java/trunk/common/src/main/java/org/apache/qpid/bytebuffer/SlicedQpidByteBuffer.java
qpid/java/trunk/common/src/test/java/org/apache/qpid/bytebuffer/SlicedQpidByteBufferTest.java
Modified:
qpid/java/trunk/common/src/main/java/org/apache/qpid/bytebuffer/QpidByteBuffer.java
qpid/java/trunk/common/src/test/java/org/apache/qpid/bytebuffer/QpidByteBufferTest.java
Modified:
qpid/java/trunk/common/src/main/java/org/apache/qpid/bytebuffer/QpidByteBuffer.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/common/src/main/java/org/apache/qpid/bytebuffer/QpidByteBuffer.java?rev=1763459&r1=1763458&r2=1763459&view=diff
==============================================================================
---
qpid/java/trunk/common/src/main/java/org/apache/qpid/bytebuffer/QpidByteBuffer.java
(original)
+++
qpid/java/trunk/common/src/main/java/org/apache/qpid/bytebuffer/QpidByteBuffer.java
Wed Oct 5 15:39:15 2016
@@ -45,7 +45,7 @@ import javax.net.ssl.SSLException;
import org.apache.qpid.streams.CompositeInputStream;
-public abstract class QpidByteBuffer
+public class QpidByteBuffer
{
private static final AtomicIntegerFieldUpdater<QpidByteBuffer>
DISPOSED_UPDATER = AtomicIntegerFieldUpdater.newUpdater(
@@ -56,15 +56,25 @@ public abstract class QpidByteBuffer
private volatile static BufferPool _bufferPool;
private volatile static int _pooledBufferSize;
private volatile static ByteBuffer _zeroed;
+ private final int _offset;
+
final ByteBufferRef _ref;
volatile ByteBuffer _buffer;
@SuppressWarnings("unused")
private volatile int _disposed;
- QpidByteBuffer(ByteBufferRef ref, ByteBuffer buffer)
+
+ QpidByteBuffer(ByteBufferRef ref)
+ {
+ this(ref, ref.getBuffer(), 0);
+ }
+
+ private QpidByteBuffer(ByteBufferRef ref, ByteBuffer buffer, int offset)
{
_ref = ref;
_buffer = buffer;
+ _offset = offset;
+ _ref.incrementRef();
}
public final boolean isDirect()
@@ -160,11 +170,23 @@ public abstract class QpidByteBuffer
return _buffer.hasRemaining();
}
- public abstract QpidByteBuffer putInt(int index, int value);
+ public QpidByteBuffer putInt(final int index, final int value)
+ {
+ _buffer.putInt(index, value);
+ return this;
+ }
- public abstract QpidByteBuffer putShort(int index, short value);
+ public QpidByteBuffer putShort(final int index, final short value)
+ {
+ _buffer.putShort(index, value);
+ return this;
+ }
- public abstract QpidByteBuffer putChar(int index, char value);
+ public QpidByteBuffer putChar(final int index, final char value)
+ {
+ _buffer.putChar(index, value);
+ return this;
+ }
public final QpidByteBuffer put(final byte b)
{
@@ -172,9 +194,16 @@ public abstract class QpidByteBuffer
return this;
}
- public abstract QpidByteBuffer put(int index, byte b);
+ public QpidByteBuffer put(final int index, final byte b)
+ {
+ _buffer.put(index, b);
+ return this;
+ }
- public abstract short getShort(int index);
+ public short getShort(final int index)
+ {
+ return _buffer.getShort(index);
+ }
public final QpidByteBuffer mark()
{
@@ -187,9 +216,16 @@ public abstract class QpidByteBuffer
return _buffer.getLong();
}
- public abstract QpidByteBuffer putFloat(int index, float value);
+ public QpidByteBuffer putFloat(final int index, final float value)
+ {
+ _buffer.putFloat(index, value);
+ return this;
+ }
- public abstract double getDouble(int index);
+ public double getDouble(final int index)
+ {
+ return _buffer.getDouble(index);
+ }
public final boolean hasArray()
{
@@ -213,7 +249,10 @@ public abstract class QpidByteBuffer
return this;
}
- public abstract byte[] array();
+ public byte[] array()
+ {
+ return _buffer.array();
+ }
public final QpidByteBuffer putShort(final short value)
{
@@ -221,7 +260,10 @@ public abstract class QpidByteBuffer
return this;
}
- public abstract int getInt(int index);
+ public int getInt(final int index)
+ {
+ return _buffer.getInt(index);
+ }
public final int remaining()
{
@@ -287,13 +329,29 @@ public abstract class QpidByteBuffer
put(source.getUnderlyingBuffer().duplicate());
}
- public abstract QpidByteBuffer rewind();
+ public QpidByteBuffer rewind()
+ {
+ _buffer.rewind();
+ return this;
+ }
- public abstract QpidByteBuffer clear();
+ public QpidByteBuffer clear()
+ {
+ _buffer.clear();
+ return this;
+ }
- public abstract QpidByteBuffer putLong(int index, long value);
+ public QpidByteBuffer putLong(final int index, final long value)
+ {
+ _buffer.putLong(index, value);
+ return this;
+ }
- public abstract QpidByteBuffer compact();
+ public QpidByteBuffer compact()
+ {
+ _buffer.compact();
+ return this;
+ }
public final QpidByteBuffer putDouble(final double value)
{
@@ -301,11 +359,22 @@ public abstract class QpidByteBuffer
return this;
}
- public abstract int limit();
+ public int limit()
+ {
+ return _buffer.limit();
+ }
- public abstract QpidByteBuffer reset();
+ public QpidByteBuffer reset()
+ {
+ _buffer.reset();
+ return this;
+ }
- public abstract QpidByteBuffer flip();
+ public QpidByteBuffer flip()
+ {
+ _buffer.flip();
+ return this;
+ }
public final short getShort()
{
@@ -318,9 +387,34 @@ public abstract class QpidByteBuffer
return _buffer.getFloat();
}
- public abstract QpidByteBuffer limit(int newLimit);
+ public QpidByteBuffer limit(final int newLimit)
+ {
+ _buffer.limit(newLimit);
+ return this;
+ }
+
+ /**
+ * Method does not respect mark.
+ *
+ * @return QpidByteBuffer
+ */
+ public QpidByteBuffer duplicate()
+ {
+ ByteBuffer buffer = _ref.getBuffer();
+ if (!(_ref instanceof PooledByteBufferRef))
+ {
+ buffer = buffer.duplicate();
+ }
+
+ buffer.position(_offset );
+ buffer.limit(_offset + _buffer.capacity());
- public abstract QpidByteBuffer duplicate();
+ buffer = buffer.slice();
+
+ buffer.limit(_buffer.limit());
+ buffer.position(_buffer.position());
+ return new QpidByteBuffer(_ref, buffer, _offset);
+ }
public final QpidByteBuffer put(final byte[] src, final int offset, final
int length)
{
@@ -328,18 +422,30 @@ public abstract class QpidByteBuffer
return this;
}
- public abstract long getLong(int index);
+ public long getLong(final int index)
+ {
+ return _buffer.getLong(index);
+ }
- public abstract int capacity();
+ public int capacity()
+ {
+ return _buffer.capacity();
+ }
- public abstract char getChar(int index);
+ public char getChar(final int index)
+ {
+ return _buffer.getChar(index);
+ }
public final byte get()
{
return _buffer.get();
}
- public abstract byte get(int index);
+ public byte get(final int index)
+ {
+ return _buffer.get(index);
+ }
public final QpidByteBuffer get(final byte[] dst)
{
@@ -362,9 +468,16 @@ public abstract class QpidByteBuffer
return this;
}
- public abstract QpidByteBuffer position(int newPosition);
+ public QpidByteBuffer position(final int newPosition)
+ {
+ _buffer.position(newPosition);
+ return this;
+ }
- public abstract int arrayOffset();
+ public int arrayOffset()
+ {
+ return _buffer.arrayOffset();
+ }
public final char getChar()
{
@@ -382,17 +495,50 @@ public abstract class QpidByteBuffer
return this;
}
- public abstract float getFloat(int index);
+ public float getFloat(final int index)
+ {
+ return _buffer.getFloat(index);
+ }
+
+ public QpidByteBuffer slice()
+ {
+ return view(0, _buffer.remaining());
+ }
+
+ public QpidByteBuffer view(int offset, int length)
+ {
+ ByteBuffer buffer = _ref.getBuffer();
+ if (!(_ref instanceof PooledByteBufferRef))
+ {
+ buffer = buffer.duplicate();
+ }
+
+ int newRemaining = Math.min(_buffer.remaining() - offset, length);
- public abstract QpidByteBuffer slice();
+ int newPosition = _offset + _buffer.position() + offset;
+ buffer.limit(newPosition + newRemaining);
+ buffer.position(newPosition);
- public abstract QpidByteBuffer view(int offset, int length);
+ buffer = buffer.slice();
- public abstract int position();
+ return new QpidByteBuffer(_ref, buffer, newPosition);
+ }
- public abstract QpidByteBuffer putDouble(int index, double value);
+ public int position()
+ {
+ return _buffer.position();
+ }
- abstract ByteBuffer getUnderlyingBuffer();
+ public QpidByteBuffer putDouble(final int index, final double value)
+ {
+ _buffer.putDouble(index, value);
+ return this;
+ }
+
+ ByteBuffer getUnderlyingBuffer()
+ {
+ return _buffer;
+ }
public static QpidByteBuffer allocate(boolean direct, int size)
{
@@ -401,7 +547,7 @@ public abstract class QpidByteBuffer
public static QpidByteBuffer allocate(int size)
{
- return new QpidByteBufferImpl(new
NonPooledByteBufferRef(ByteBuffer.allocate(size)));
+ return new QpidByteBuffer(new
NonPooledByteBufferRef(ByteBuffer.allocate(size)));
}
public static QpidByteBuffer allocateDirect(int size)
@@ -447,7 +593,7 @@ public abstract class QpidByteBuffer
{
ref = new NonPooledByteBufferRef(ByteBuffer.allocateDirect(size));
}
- return new QpidByteBufferImpl(ref);
+ return new QpidByteBuffer(ref);
}
public static Collection<QpidByteBuffer> allocateDirectCollection(int size)
@@ -596,7 +742,7 @@ public abstract class QpidByteBuffer
public static QpidByteBuffer wrap(final ByteBuffer wrap)
{
- return new QpidByteBufferImpl(new NonPooledByteBufferRef(wrap));
+ return new QpidByteBuffer(new NonPooledByteBufferRef(wrap));
}
public static QpidByteBuffer wrap(final byte[] data)
Modified:
qpid/java/trunk/common/src/test/java/org/apache/qpid/bytebuffer/QpidByteBufferTest.java
URL:
http://svn.apache.org/viewvc/qpid/java/trunk/common/src/test/java/org/apache/qpid/bytebuffer/QpidByteBufferTest.java?rev=1763459&r1=1763458&r2=1763459&view=diff
==============================================================================
---
qpid/java/trunk/common/src/test/java/org/apache/qpid/bytebuffer/QpidByteBufferTest.java
(original)
+++
qpid/java/trunk/common/src/test/java/org/apache/qpid/bytebuffer/QpidByteBufferTest.java
Wed Oct 5 15:39:15 2016
@@ -20,27 +20,710 @@
package org.apache.qpid.bytebuffer;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import com.google.common.io.ByteStreams;
import org.junit.Assert;
+import org.mockito.internal.util.Primitives;
import org.apache.qpid.test.utils.QpidTestCase;
import org.apache.qpid.util.ByteBufferUtils;
public class QpidByteBufferTest extends QpidTestCase
{
+ private static final int BUFFER_SIZE = 10;
+ private static final int POOL_SIZE = 20;
- public static final int BUFFER_SIZE = 10;
- public static final int POOL_SIZE = 20;
+
+ private QpidByteBuffer _slicedBuffer;
+ private QpidByteBuffer _parent;
@Override
protected void setUp() throws Exception
{
super.setUp();
QpidByteBuffer.initialisePool(BUFFER_SIZE, POOL_SIZE);
+ _parent = QpidByteBuffer.allocateDirect(BUFFER_SIZE);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ super.tearDown();
+ _parent.dispose();
+ if (_slicedBuffer != null)
+ {
+ _slicedBuffer.dispose();
+ }
+ }
+
+ public void testPutGetByIndex() throws Exception
+ {
+ testPutGetByIndex(double.class, 1.0);
+ testPutGetByIndex(float.class, 1.0f);
+ testPutGetByIndex(long.class, 1L);
+ testPutGetByIndex(int.class, 1);
+ testPutGetByIndex(char.class, 'A');
+ testPutGetByIndex(short.class, (short)1);
+ testPutGetByIndex(byte.class, (byte)1);
+ }
+
+ public void testPutGet() throws Exception
+ {
+ testPutGet(double.class, false, 1.0);
+ testPutGet(float.class, false, 1.0f);
+ testPutGet(long.class, false, 1L);
+ testPutGet(int.class, false, 1);
+ testPutGet(char.class, false, 'A');
+ testPutGet(short.class, false, (short)1);
+ testPutGet(byte.class, false, (byte)1);
+
+ testPutGet(int.class, true, 1L);
+ testPutGet(short.class, true, 1);
+ testPutGet(byte.class, true, (short)1);
+ }
+
+ public void testMarkReset() throws Exception
+ {
+ _slicedBuffer = createSlice();
+
+ _slicedBuffer.mark();
+ _slicedBuffer.position(_slicedBuffer.position() + 1);
+ assertEquals("Unexpected position after move", 1,
_slicedBuffer.position());
+
+ _slicedBuffer.reset();
+ assertEquals("Unexpected position after reset", 0,
_slicedBuffer.position());
+ }
+
+ public void testPosition() throws Exception
+ {
+ _slicedBuffer = createSlice();
+
+ assertEquals("Unexpected position for new slice", 0,
_slicedBuffer.position());
+
+ _slicedBuffer.position(1);
+ assertEquals("Unexpected position after advance", 1,
_slicedBuffer.position());
+
+ final int oldLimit = _slicedBuffer.limit();
+ _slicedBuffer.limit(oldLimit - 1);
+ try
+ {
+ _slicedBuffer.position(oldLimit);
+ fail("Exception not thrown");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // pass
+ }
+ }
+
+ public void testBulkPutGet() throws Exception
+ {
+ _slicedBuffer = createSlice();
+
+ final byte[] source = getTestBytes(_slicedBuffer.remaining());
+
+ QpidByteBuffer rv = _slicedBuffer.put(source, 0, source.length);
+ assertEquals("Unexpected builder return value", _slicedBuffer, rv);
+
+ _slicedBuffer.flip();
+ byte[] target = new byte[_slicedBuffer.remaining()];
+ rv = _slicedBuffer.get(target, 0, target.length);
+ assertEquals("Unexpected builder return value", _slicedBuffer, rv);
+
+ Assert.assertArrayEquals("Unexpected bulk put/get result", source,
target);
+
+
+ _slicedBuffer.clear();
+ _slicedBuffer.position(1);
+
+ try
+ {
+ _slicedBuffer.put(source, 0, source.length);
+ fail("Exception not thrown");
+ }
+ catch (BufferOverflowException e)
+ {
+ // pass
+ }
+
+ assertEquals("Position should be unchanged after failed put", 1,
_slicedBuffer.position());
+
+ try
+ {
+ _slicedBuffer.get(target, 0, target.length);
+ fail("Exception not thrown");
+ }
+ catch (BufferUnderflowException e)
+ {
+ // pass
+ }
+
+ assertEquals("Position should be unchanged after failed get", 1,
_slicedBuffer.position());
+
+
+ }
+
+ public void testByteBufferPutGet()
+ {
+ _slicedBuffer = createSlice();
+ final byte[] source = getTestBytes(_slicedBuffer.remaining());
+
+ ByteBuffer sourceByteBuffer = ByteBuffer.wrap(source);
+
+ QpidByteBuffer rv = _slicedBuffer.put(sourceByteBuffer);
+ assertEquals("Unexpected builder return value", _slicedBuffer, rv);
+
+ assertEquals("Unexpected position", _slicedBuffer.capacity(),
_slicedBuffer.position());
+ assertEquals("Unexpected remaining", 0, _slicedBuffer.remaining());
+
+ assertEquals("Unexpected remaining in source ByteBuffer", 0,
sourceByteBuffer.remaining());
+
+ _slicedBuffer.flip();
+
+ ByteBuffer destinationByteBuffer = ByteBuffer.allocate(source.length);
+ _slicedBuffer.get(destinationByteBuffer);
+
+
+ assertEquals("Unexpected remaining", 0, _slicedBuffer.remaining());
+
+ assertEquals("Unexpected remaining in destination ByteBuffer", 0,
destinationByteBuffer.remaining());
+ assertEquals("Unexpected position in destination ByteBuffer",
source.length, destinationByteBuffer.position());
+
+ Assert.assertArrayEquals("Unexpected ByteBuffer put/get result",
source, destinationByteBuffer.array());
+
+ _slicedBuffer.clear();
+ _slicedBuffer.position(1);
+
+ sourceByteBuffer.clear();
+ try
+ {
+ _slicedBuffer.put(sourceByteBuffer);
+ fail("Exception should be thrown");
+ }
+ catch(BufferOverflowException e)
+ {
+ // pass
+ }
+
+ assertEquals("Position should not be changed after failed put", 1,
_slicedBuffer.position());
+ assertEquals("Source position should not changed after failed put",
source.length, sourceByteBuffer.remaining());
+
+ _slicedBuffer.clear();
+ destinationByteBuffer.position(1);
+
+ try
+ {
+ _slicedBuffer.get(destinationByteBuffer);
+ fail("Exception should be thrown");
+ }
+ catch(BufferUnderflowException e )
+ {
+ // pass
+ }
+ }
+
+ public void testQpidByteBufferPutGet()
+ {
+ _slicedBuffer = createSlice();
+ final byte[] source = getTestBytes(_slicedBuffer.remaining());
+
+ QpidByteBuffer sourceQpidByteBuffer = QpidByteBuffer.wrap(source);
+
+ QpidByteBuffer rv = _slicedBuffer.put(sourceQpidByteBuffer);
+ assertEquals("Unexpected builder return value", _slicedBuffer, rv);
+
+ assertEquals("Unexpected position", _slicedBuffer.capacity(),
_slicedBuffer.position());
+ assertEquals("Unexpected remaining", 0, _slicedBuffer.remaining());
+
+ assertEquals("Unexpected remaining in source QpidByteBuffer", 0,
sourceQpidByteBuffer.remaining());
+
+ _slicedBuffer.flip();
+
+ ByteBuffer destinationByteBuffer = ByteBuffer.allocate(source.length);
+ _slicedBuffer.get(destinationByteBuffer);
+
+ assertEquals("Unexpected remaining", 0, _slicedBuffer.remaining());
+
+ assertEquals("Unexpected remaining in destination ByteBuffer", 0,
destinationByteBuffer.remaining());
+ assertEquals("Unexpected position in destination ByteBuffer",
source.length, destinationByteBuffer.position());
+
+ Assert.assertArrayEquals("Unexpected ByteBuffer put/get result",
source, destinationByteBuffer.array());
+
+ _slicedBuffer.clear();
+ _slicedBuffer.position(1);
+
+ sourceQpidByteBuffer.clear();
+ try
+ {
+ _slicedBuffer.put(sourceQpidByteBuffer);
+ fail("Exception should be thrown");
+ }
+ catch(BufferOverflowException e)
+ {
+ // pass
+ }
+
+ assertEquals("Position should not be changed after failed put", 1,
_slicedBuffer.position());
+ assertEquals("Source position should not changed after failed put",
source.length, sourceQpidByteBuffer.remaining());
+ }
+
+ public void testDuplicate()
+ {
+ _slicedBuffer = createSlice();
+ _slicedBuffer.position(1);
+ int originalLimit = _slicedBuffer.limit();
+ _slicedBuffer.limit(originalLimit - 1);
+
+ QpidByteBuffer duplicate = _slicedBuffer.duplicate();
+ try
+ {
+ assertEquals("Unexpected position", _slicedBuffer.position(),
duplicate.position() );
+ assertEquals("Unexpected limit", _slicedBuffer.limit(),
duplicate.limit() );
+ assertEquals("Unexpected capacity", _slicedBuffer.capacity(),
duplicate.capacity() );
+
+ duplicate.position(2);
+ duplicate.limit(originalLimit - 2);
+
+ assertEquals("Unexpected position in the original", 1,
_slicedBuffer.position());
+ assertEquals("Unexpected limit in the original", originalLimit -1,
_slicedBuffer.limit());
+ }
+ finally
+ {
+ duplicate.dispose();
+ }
+ }
+
+ public void testCopyToByteBuffer()
+ {
+ _slicedBuffer = createSlice();
+ byte[] source = getTestBytes(_slicedBuffer.remaining());
+ _slicedBuffer.put(source);
+ _slicedBuffer.flip();
+
+ int originalRemaining = _slicedBuffer.remaining();
+ ByteBuffer destination = ByteBuffer.allocate(source.length);
+ _slicedBuffer.copyTo(destination);
+
+ assertEquals("Unexpected remaining in original QBB",
originalRemaining, _slicedBuffer.remaining());
+ assertEquals("Unexpected remaining in destination", 0,
destination.remaining());
+
+ Assert.assertArrayEquals("Unexpected copyTo result", source,
destination.array());
+ }
+
+ public void testCopyToArray()
+ {
+ _slicedBuffer = createSlice();
+ byte[] source = getTestBytes(_slicedBuffer.remaining());
+ _slicedBuffer.put(source);
+ _slicedBuffer.flip();
+
+ int originalRemaining = _slicedBuffer.remaining();
+ byte[] destination = new byte[source.length];
+ _slicedBuffer.copyTo(destination);
+
+ assertEquals("Unexpected remaining in original QBB",
originalRemaining, _slicedBuffer.remaining());
+
+ Assert.assertArrayEquals("Unexpected copyTo result", source,
destination);
+ }
+
+ public void testPutCopyOf()
+ {
+ _slicedBuffer = createSlice();
+ byte[] source = getTestBytes(_slicedBuffer.remaining());
+
+ QpidByteBuffer sourceQpidByteBuffer = QpidByteBuffer.wrap(source);
+ _slicedBuffer.putCopyOf(sourceQpidByteBuffer);
+
+ assertEquals("Copied buffer should not be changed", source.length,
sourceQpidByteBuffer.remaining());
+ assertEquals("Buffer should be full", 0, _slicedBuffer.remaining());
+ _slicedBuffer.flip();
+
+ byte[] destination = new byte[source.length];
+ _slicedBuffer.get(destination);
+
+ Assert.assertArrayEquals("Unexpected putCopyOf result", source,
destination);
+ }
+
+ public void testCompact()
+ {
+ _slicedBuffer = createSlice();
+ byte[] source = getTestBytes(_slicedBuffer.remaining());
+ _slicedBuffer.put(source);
+
+ _slicedBuffer.position(1);
+ _slicedBuffer.limit(_slicedBuffer.limit() - 1);
+
+ int remaining = _slicedBuffer.remaining();
+ _slicedBuffer.compact();
+
+ assertEquals("Unexpected position", remaining,
_slicedBuffer.position());
+ assertEquals("Unexpected limit", _slicedBuffer.capacity(),
_slicedBuffer.limit());
+
+ _slicedBuffer.flip();
+
+
+ byte[] destination = new byte[_slicedBuffer.remaining()];
+ _slicedBuffer.get(destination);
+
+ byte[] expected = new byte[source.length - 2];
+ System.arraycopy(source, 1, expected, 0, expected.length);
+
+ Assert.assertArrayEquals("Unexpected compact result", expected,
destination);
+ }
+
+ public void testSliceOfSlice()
+ {
+ _slicedBuffer = createSlice();
+ byte[] source = getTestBytes(_slicedBuffer.remaining());
+ _slicedBuffer.put(source);
+
+ _slicedBuffer.position(1);
+ _slicedBuffer.limit(_slicedBuffer.limit() - 1);
+
+ int remaining = _slicedBuffer.remaining();
+ QpidByteBuffer newSlice = _slicedBuffer.slice();
+ try
+ {
+ assertEquals("Unexpected position in original", 1,
_slicedBuffer.position());
+ assertEquals("Unexpected limit in original", source.length - 1,
_slicedBuffer.limit());
+ assertEquals("Unexpected position", 0, newSlice.position());
+ assertEquals("Unexpected limit", remaining, newSlice.limit());
+ assertEquals("Unexpected capacity", remaining,
newSlice.capacity());
+
+ byte[] destination = new byte[newSlice.remaining()];
+ newSlice.get(destination);
+
+ byte[] expected = new byte[source.length - 2];
+ System.arraycopy(source, 1, expected, 0, expected.length);
+ Assert.assertArrayEquals("Unexpected slice result", expected,
destination);
+ }
+ finally
+ {
+ newSlice.dispose();
+ }
+ }
+
+ public void testViewOfSlice()
+ {
+ _slicedBuffer = createSlice();
+ byte[] source = getTestBytes(_slicedBuffer.remaining());
+ _slicedBuffer.put(source);
+
+ _slicedBuffer.position(1);
+ _slicedBuffer.limit(_slicedBuffer.limit() - 1);
+
+ QpidByteBuffer view = _slicedBuffer.view(0, _slicedBuffer.remaining());
+ try
+ {
+ assertEquals("Unexpected position in original", 1,
_slicedBuffer.position());
+ assertEquals("Unexpected limit in original", source.length - 1,
_slicedBuffer.limit());
+
+ assertEquals("Unexpected position", 0, view.position());
+ assertEquals("Unexpected limit", _slicedBuffer.remaining(),
view.limit());
+ assertEquals("Unexpected capacity", _slicedBuffer.remaining(),
view.capacity());
+
+ byte[] destination = new byte[view.remaining()];
+ view.get(destination);
+
+ byte[] expected = new byte[source.length - 2];
+ System.arraycopy(source, 1, expected, 0, expected.length);
+ Assert.assertArrayEquals("Unexpected view result", expected,
destination);
+ }
+ finally
+ {
+ view.dispose();
+ }
+
+ view = _slicedBuffer.view(1, _slicedBuffer.remaining() - 2);
+ try
+ {
+ assertEquals("Unexpected position in original", 1,
_slicedBuffer.position());
+ assertEquals("Unexpected limit in original", source.length - 1,
_slicedBuffer.limit());
+
+ assertEquals("Unexpected position", 0, view.position());
+ assertEquals("Unexpected limit", _slicedBuffer.remaining() - 2,
view.limit());
+ assertEquals("Unexpected capacity", _slicedBuffer.remaining() - 2,
view.capacity());
+
+ byte[] destination = new byte[view.remaining()];
+ view.get(destination);
+
+ byte[] expected = new byte[source.length - 4];
+ System.arraycopy(source, 2, expected, 0, expected.length);
+ Assert.assertArrayEquals("Unexpected view result", expected,
destination);
+ }
+ finally
+ {
+ view.dispose();
+ }
+ }
+
+ public void testAsInputStream() throws Exception
+ {
+ _slicedBuffer = createSlice();
+ byte[] source = getTestBytes(_slicedBuffer.remaining());
+ _slicedBuffer.put(source);
+
+ _slicedBuffer.position(1);
+ _slicedBuffer.limit(_slicedBuffer.limit() - 1);
+
+ ByteArrayOutputStream destination = new ByteArrayOutputStream();
+ try(InputStream is = _slicedBuffer.asInputStream())
+ {
+ ByteStreams.copy(is, destination);
+ }
+
+ byte[] expected = new byte[source.length - 2];
+ System.arraycopy(source, 1, expected, 0, expected.length);
+ Assert.assertArrayEquals("Unexpected view result", expected,
destination.toByteArray());
+ }
+
+ public void testAsByteBuffer() throws Exception
+ {
+ _slicedBuffer = createSlice();
+
+ _slicedBuffer.position(1);
+ _slicedBuffer.limit(_slicedBuffer.limit() - 1);
+
+ _slicedBuffer.mark();
+ int remaining = _slicedBuffer.remaining();
+ byte[] source = getTestBytes(remaining);
+ _slicedBuffer.put(source);
+ _slicedBuffer.reset();
+
+ ByteBuffer buffer = _slicedBuffer.asByteBuffer();
+ assertEquals("Unexpected remaining", remaining, buffer.remaining());
+
+ byte[] target = new byte[remaining];
+ buffer.get(target);
+ Assert.assertArrayEquals("Unexpected asByteBuffer result", source,
target);
+ }
+
+ public void testDecode()
+ {
+ _slicedBuffer = createSlice();
+ final String input = "ABC";
+ _slicedBuffer.put(input.getBytes());
+ _slicedBuffer.flip();
+
+ final CharBuffer charBuffer =
_slicedBuffer.decode(StandardCharsets.US_ASCII);
+ final char[] destination = new char[charBuffer.remaining()];
+ charBuffer.get(destination);
+ Assert.assertArrayEquals("Unexpected char buffer",
input.toCharArray(), destination);
+ }
+
+ private byte[] getTestBytes(final int length)
+ {
+ final byte[] source = new byte[length];
+ for (int i = 0; i < source.length; i++)
+ {
+ source[i] = (byte) ('A' + i);
+ }
+ return source;
+ }
+
+ private QpidByteBuffer createSlice()
+ {
+ _parent.position(1);
+ _parent.limit(_parent.capacity() - 1);
+
+ return _parent.slice();
+ }
+
+ private void testPutGet(final Class<?> primitiveTargetClass, final boolean
unsigned, final Object value) throws Exception
+ {
+ int size = sizeof(primitiveTargetClass);
+
+ _parent.position(1);
+ _parent.limit(size + 1);
+
+ _slicedBuffer = _parent.slice();
+ _parent.limit(_parent.capacity());
+
+ assertEquals("Unexpected position ", 0, _slicedBuffer.position());
+ assertEquals("Unexpected limit ", size, _slicedBuffer.limit());
+ assertEquals("Unexpected capacity ", size, _slicedBuffer.capacity());
+
+ String methodSuffix = getMethodSuffix(primitiveTargetClass, unsigned);
+ Method put = _slicedBuffer.getClass().getMethod("put" + methodSuffix,
Primitives.primitiveTypeOf(value.getClass()));
+ Method get = _slicedBuffer.getClass().getMethod("get" + methodSuffix);
+
+
+ _slicedBuffer.mark();
+ QpidByteBuffer rv = (QpidByteBuffer) put.invoke(_slicedBuffer, value);
+ assertEquals("Unexpected builder return value for type " +
methodSuffix, _slicedBuffer, rv);
+
+ assertEquals("Unexpected position for type " + methodSuffix, size,
_slicedBuffer.position());
+
+ try
+ {
+ invokeMethod(put, value);
+ fail("BufferOverflowException should be thrown for put with
insufficient room for " + methodSuffix);
+ }
+ catch (BufferOverflowException e)
+ {
+ // pass
+ }
+
+ _slicedBuffer.reset();
+
+ assertEquals("Unexpected position after reset", 0,
_slicedBuffer.position());
+
+ Object retrievedValue = get.invoke(_slicedBuffer);
+ assertEquals("Unexpected value retrieved from get method for " +
methodSuffix, value, retrievedValue);
+ try
+ {
+ invokeMethod(get);
+ fail("BufferUnderflowException not thrown for get with
insufficient room for " + methodSuffix);
+ }
+ catch (BufferUnderflowException ite)
+ {
+ // pass
+ }
+ }
+
+ private void testPutGetByIndex(final Class<?> primitiveTargetClass, Object
value) throws Exception
+ {
+ int size = sizeof(primitiveTargetClass);
+
+ _parent.position(1);
+ _parent.limit(size + 1);
+
+ _slicedBuffer = _parent.slice();
+ _parent.limit(_parent.capacity());
+
+ String methodSuffix = getMethodSuffix(primitiveTargetClass, false);
+ Method put = _slicedBuffer.getClass().getMethod("put" + methodSuffix,
int.class, primitiveTargetClass);
+ Method get = _slicedBuffer.getClass().getMethod("get" + methodSuffix,
int.class);
+
+ QpidByteBuffer rv = (QpidByteBuffer) put.invoke(_slicedBuffer, 0,
value);
+ assertEquals("Unexpected builder return value for type " +
methodSuffix, _slicedBuffer, rv);
+
+ Object retrievedValue = get.invoke(_slicedBuffer, 0);
+ assertEquals("Unexpected value retrieved from index get method for " +
methodSuffix, value, retrievedValue);
+
+ try
+ {
+ invokeMethod(put, 1, value);
+ fail("IndexOutOfBoundsException not thrown for indexed " +
methodSuffix + " put");
+ }
+ catch (IndexOutOfBoundsException ite)
+ {
+ // pass
+ }
+
+ try
+ {
+ invokeMethod(put, -1, value);
+ fail("IndexOutOfBoundsException not thrown for indexed " +
methodSuffix + " put with negative index");
+ }
+ catch (IndexOutOfBoundsException ite)
+ {
+ // pass
+ }
+
+ try
+ {
+ invokeMethod(get, 1);
+ fail("IndexOutOfBoundsException not thrown for indexed " +
methodSuffix + " get");
+ }
+ catch (IndexOutOfBoundsException ite)
+ {
+ // pass
+ }
+
+ try
+ {
+ invokeMethod(get, -1);
+ fail("IndexOutOfBoundsException not thrown for indexed " +
methodSuffix + " get with negative index");
+ }
+ catch (IndexOutOfBoundsException ite)
+ {
+ // pass
+ }
+ }
+
+ private void invokeMethod(final Method method, final Object... value)
+ throws Exception
+ {
+ try
+ {
+ method.invoke(_slicedBuffer, value);
+ }
+ catch (InvocationTargetException e)
+ {
+ Throwable cause = e.getCause();
+ if (cause instanceof Exception)
+ {
+ throw (Exception)cause;
+ }
+ fail(String.format("Unexpected throwable on method %s invocation:
%s", method.getName(), cause));
+ }
+ }
+
+
+ private String getMethodSuffix(final Class<?> target, final boolean
unsigned)
+ {
+ StringBuilder name = new StringBuilder();
+ if (unsigned)
+ {
+ name.append("Unsigned");
+ }
+ if ((!target.isAssignableFrom(byte.class) || unsigned))
+ {
+ String simpleName = target.getSimpleName();
+ name.append(simpleName.substring(0,
1).toUpperCase()).append(simpleName.substring(1));
+ }
+
+ return name.toString();
+ }
+
+ private int sizeof(final Class<?> type)
+ {
+ if (type.isAssignableFrom(double.class))
+ {
+ return 8;
+ }
+ else if (type.isAssignableFrom(float.class))
+ {
+ return 4;
+ }
+ else if (type.isAssignableFrom(long.class))
+ {
+ return 8;
+ }
+ else if (type.isAssignableFrom(int.class))
+ {
+ return 4;
+ }
+ else if (type.isAssignableFrom(short.class))
+ {
+ return 2;
+ }
+ else if (type.isAssignableFrom(char.class))
+ {
+ return 2;
+ }
+ else if (type.isAssignableFrom(byte.class))
+ {
+ return 1;
+ }
+ else
+ {
+ throw new UnsupportedOperationException("Unexpected type " + type);
+ }
}
public void testPooledBufferIsZeroedLoan() throws Exception
@@ -158,38 +841,25 @@ public class QpidByteBufferTest extends
QpidByteBuffer directSlice = directBuffer.slice();
assertTrue("Direct slice should be direct too",
directSlice.isDirect());
- assertTrue("Direct slice should be special", directSlice instanceof
SlicedQpidByteBuffer);
assertEquals("Unexpected capacity", 3, directSlice.capacity());
assertEquals("Unexpected limit", 3, directSlice.limit());
assertEquals("Unexpected position", 0, directSlice.position());
directBuffer.dispose();
directSlice.dispose();
-
- final QpidByteBuffer heapBuffer = QpidByteBuffer.allocate(false, 6);
- final QpidByteBuffer heapSlice = heapBuffer.slice();
- assertFalse("Heap slice should not be special", heapSlice instanceof
SlicedQpidByteBuffer);
- heapBuffer.dispose();
- heapSlice.dispose();
}
public void testView() throws Exception
{
- doTestView(true);
- doTestView(false);
- }
-
- private void doTestView(final boolean direct)
- {
byte[] content = "ABCDEF".getBytes();
- QpidByteBuffer buffer = QpidByteBuffer.allocate(direct,
content.length);
+ QpidByteBuffer buffer = QpidByteBuffer.allocate(true, content.length);
buffer.put(content);
buffer.position(2);
buffer.limit(5);
QpidByteBuffer view = buffer.view(0, buffer.remaining());
- assertEquals("Unexpected view direct", direct, view.isDirect());
+ assertTrue("Unexpected view direct", view.isDirect());
assertEquals("Unexpected capacity", 3, view.capacity());
assertEquals("Unexpected limit", 3, view.limit());
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]