added get/put float/double to ByteBuffers, as well as duplicate

This commit is contained in:
Luke Wahlmeier 2016-01-10 03:03:03 -07:00
parent c1df8b949c
commit 9d87e3b2a7
7 changed files with 212 additions and 27 deletions

View File

@ -89,4 +89,12 @@ class ArrayByteBuffer extends ByteBuffer {
+ " limit: " + limit
+ " capacity: " + capacity + ")";
}
@Override
public ByteBuffer duplicate() {
ByteBuffer b = new ArrayByteBuffer(array, arrayOffset, capacity, isReadOnly());
b.limit(this.limit());
b.position(this.position());
return b;
}
}

View File

@ -14,6 +14,7 @@ public abstract class Buffer {
protected int capacity;
protected int position;
protected int limit;
protected boolean readonly;
public final int limit() {
return limit;
@ -61,4 +62,8 @@ public abstract class Buffer {
position = 0;
return this;
}
public boolean isReadOnly() {
return readonly;
}
}

View File

@ -14,10 +14,9 @@ public abstract class ByteBuffer
extends Buffer
implements Comparable<ByteBuffer>
{
private final boolean readOnly;
protected ByteBuffer(boolean readOnly) {
this.readOnly = readOnly;
this.readonly = readOnly;
}
public static ByteBuffer allocate(int capacity) {
@ -39,6 +38,8 @@ public abstract class ByteBuffer
public abstract ByteBuffer asReadOnlyBuffer();
public abstract ByteBuffer slice();
public abstract ByteBuffer duplicate();
protected abstract void doPut(int offset, byte val);
@ -122,7 +123,7 @@ public abstract class ByteBuffer
public ByteBuffer put(byte[] arr) {
return put(arr, 0, arr.length);
}
private void rawPutLong(int position, long val) {
doPut(position , (byte) ((val >> 56) & 0xff));
doPut(position + 1, (byte) ((val >> 48) & 0xff));
@ -145,6 +146,14 @@ public abstract class ByteBuffer
doPut(position , (byte) ((val >> 8) & 0xff));
doPut(position + 1, (byte) ((val ) & 0xff));
}
public ByteBuffer putDouble(int position, double val) {
return putLong(position, Double.doubleToRawLongBits(val));
}
public ByteBuffer putFloat(int position, float val) {
return putInt(position, Float.floatToRawIntBits(val));
}
public ByteBuffer putLong(int position, long val) {
checkPut(position, 8, true);
@ -169,6 +178,14 @@ public abstract class ByteBuffer
return this;
}
public ByteBuffer putDouble(double val) {
return putLong(Double.doubleToRawLongBits(val));
}
public ByteBuffer putFloat(float val) {
return putInt(Float.floatToRawIntBits(val));
}
public ByteBuffer putLong(long val) {
checkPut(position, 8, false);
@ -207,6 +224,14 @@ public abstract class ByteBuffer
public ByteBuffer get(byte[] dst) {
return get(dst, 0, dst.length);
}
public double getDouble(int position) {
return Double.longBitsToDouble(getLong(position));
}
public float getFloat(int position) {
return Float.intBitsToFloat(getInt(position));
}
public long getLong(int position) {
checkGet(position, 8, true);
@ -248,7 +273,15 @@ public abstract class ByteBuffer
return (short) (( ((int) (doGet(position ) & 0xFF)) << 8)
| (((int) (doGet(position + 1) & 0xFF)) ));
}
public double getDouble() {
return Double.longBitsToDouble(getLong());
}
public float getFloat() {
return Float.intBitsToFloat(getInt());
}
public long getLong() {
checkGet(position, 8, false);
@ -274,7 +307,7 @@ public abstract class ByteBuffer
}
protected void checkPut(int position, int amount, boolean absolute) {
if (readOnly) {
if (isReadOnly()) {
throw new ReadOnlyBufferException();
}

View File

@ -102,4 +102,12 @@ class DirectByteBuffer extends ByteBuffer {
+ " limit: " + limit
+ " capacity: " + capacity + ")";
}
@Override
public ByteBuffer duplicate() {
ByteBuffer b = new DirectByteBuffer(address, capacity, isReadOnly());
b.limit(this.limit());
b.position(this.position());
return b;
}
}

View File

@ -46,6 +46,14 @@ class FixedArrayByteBuffer extends DirectByteBuffer {
return new FixedArrayByteBuffer
(address + position, array, arrayOffset + position, remaining(), true);
}
@Override
public ByteBuffer duplicate() {
ByteBuffer b = new FixedArrayByteBuffer(address, array, arrayOffset, capacity, isReadOnly());
b.limit(this.limit());
b.position(this.position());
return b;
}
public String toString() {
return "(FixedArrayByteBuffer with address: " + address

View File

@ -1,50 +1,97 @@
import java.nio.ByteBuffer;
import java.nio.BufferUnderflowException;
import java.nio.BufferOverflowException;
import static avian.testing.Asserts.*;
public class Buffers {
static {
System.loadLibrary("test");
}
private static void expect(boolean v) {
if (! v) throw new RuntimeException();
private static void testArrays(Factory factory1, Factory factory2) {
final int size = 64;
ByteBuffer b1 = factory1.allocate(size);
ByteBuffer b2 = factory2.allocate(size);
String s = "1234567890abcdefghijklmnopqrstuvwxyz";
b1.put(s.getBytes());
b1.flip();
byte[] ba = new byte[s.length()];
b1.get(ba);
assertEquals(s, new String(ba));
b1.position(0);
b2.put(b1);
b2.flip();
b2.get(ba);
assertEquals(s, new String(ba));
b1.position(0);
b2.position(0);
b1.limit(b1.capacity());
b2.limit(b2.capacity());
b1.put(s.getBytes(), 4, 5);
b1.flip();
ba = new byte[5];
b1.get(ba);
assertEquals(s.substring(4, 9), new String(ba));
}
private static void test(Factory factory1, Factory factory2) {
private static void testPrimativeGetAndSet(Factory factory1, Factory factory2) {
{ final int size = 64;
ByteBuffer b1 = factory1.allocate(size);
try {
for (int i = 0; i < size; ++i)
b1.put(i, (byte) 42);
for (int i = 0; i < size; ++i)
expect(b1.get(i) == 42);
assertEquals(b1.get(i), 42);
for (int i = 0; i < size/4; i++)
b1.putFloat(i*4, (float) 19.12);
for (int i = 0; i < size/4; i++)
assertEquals(b1.getFloat(i*4), (float) 19.12);
ByteBuffer b3 = b1.duplicate();
for (int i = 0; i < size/4; i++)
assertEquals(b3.getFloat(), (float) 19.12);
assertEquals(64, b3.position());
for (int i = 0; i < size/8; i++)
b1.putDouble(i*8, (double) 19.12);
for (int i = 0; i < size/8; i++)
assertEquals(b1.getDouble(i*8), (double) 19.12);
b3.position(0);
for (int i = 0; i < size/8; i++)
assertEquals(b3.getDouble(i*8), (double) 19.12);
for (int i = 0; i < size / 2; ++i)
b1.putShort(i * 2, (short) -12345);
for (int i = 0; i < size / 2; ++i)
expect(b1.getShort(i * 2) == -12345);
assertEquals(b1.getShort(i * 2), -12345);
for (int i = 0; i < size / 4; ++i)
b1.putInt(i * 4, 0x12345678);
for (int i = 0; i < size / 4; ++i)
expect(b1.getInt(i * 4) == 0x12345678);
assertEquals(b1.getInt(i * 4), 0x12345678);
for (int i = 0; i < size / 8; ++i)
b1.putLong(i * 8, 0x1234567890ABCDEFL);
for (int i = 0; i < size / 8; ++i)
expect(b1.getLong(i * 8) == 0x1234567890ABCDEFL);
assertEquals(b1.getLong(i * 8), 0x1234567890ABCDEFL);
ByteBuffer b2 = factory2.allocate(size);
try {
b2.put(b1);
for (int i = 0; i < size / 8; ++i)
expect(b2.getLong(i * 8) == 0x1234567890ABCDEFL);
assertTrue(b2.getLong(i * 8) == 0x1234567890ABCDEFL);
} finally {
factory2.dispose(b2);
@ -90,42 +137,51 @@ public class Buffers {
}
};
test(array, array);
test(array, direct);
test(array, native_);
testPrimativeGetAndSet(array, array);
testArrays(array, array);
testPrimativeGetAndSet(array, direct);
testArrays(array, direct);
testPrimativeGetAndSet(array, native_);
testArrays(array, native_);
test(direct, array);
test(direct, direct);
test(direct, native_);
testPrimativeGetAndSet(direct, array);
testArrays(direct, array);
testPrimativeGetAndSet(direct, direct);
testArrays(direct, direct);
testPrimativeGetAndSet(direct, native_);
testArrays(direct, native_);
test(native_, array);
test(native_, direct);
test(native_, native_);
testPrimativeGetAndSet(native_, array);
testArrays(native_, array);
testPrimativeGetAndSet(native_, direct);
testArrays(native_, direct);
testPrimativeGetAndSet(native_, native_);
testArrays(native_, native_);
try {
ByteBuffer.allocate(1).getInt();
expect(false);
assertTrue(false);
} catch (BufferUnderflowException e) {
// cool
}
try {
ByteBuffer.allocate(1).getInt(0);
expect(false);
assertTrue(false);
} catch (IndexOutOfBoundsException e) {
// cool
}
try {
ByteBuffer.allocate(1).putInt(1);
expect(false);
assertTrue(false);
} catch (BufferOverflowException e) {
// cool
}
try {
ByteBuffer.allocate(1).putInt(0, 1);
expect(false);
assertTrue(false);
} catch (IndexOutOfBoundsException e) {
// cool
}

View File

@ -0,0 +1,67 @@
package avian.testing;
import java.util.Collection;
public class Asserts {
public static void assertEquals(byte first, byte second) {
if(first != second) {
throw new RuntimeException(first+" is not equals to: "+second);
}
}
public static void assertEquals(short first, short second) {
if(first != second) {
throw new RuntimeException(first+" is not equals to: "+second);
}
}
public static void assertEquals(int first, int second) {
if(first != second) {
throw new RuntimeException(first+" is not equals to: "+second);
}
}
public static void assertEquals(long first, long second) {
if(first != second) {
throw new RuntimeException(first+" is not equals to: "+second);
}
}
public static void assertEquals(float first, float second) {
if(first != second) {
throw new RuntimeException(first+" is not equals to: "+second);
}
}
public static void assertEquals(double first, double second) {
if(first != second) {
throw new RuntimeException(first+" is not equals to: "+second);
}
}
public static void assertEquals(Object first, Object second) {
if(first == null && second == null) {
return;
}
if(!first.equals(second)) {
throw new RuntimeException(first+" is not equals to: "+second);
}
}
public static void assertTrue(boolean flag) {
if (!flag) {
throw new RuntimeException("Error: "+flag+" is not True");
}
}
public static void assertContains(Enum<?> element, Collection<?> collection) {
if (!collection.contains(element)) {
throw new RuntimeException("expected " + element + " in the collection:"+collection);
}
}
}