From 9d87e3b2a71cd0b5f3e7ae24c215bb93b54dab9b Mon Sep 17 00:00:00 2001 From: Luke Wahlmeier Date: Sun, 10 Jan 2016 03:03:03 -0700 Subject: [PATCH] added get/put float/double to ByteBuffers, as well as duplicate --- classpath/java/nio/ArrayByteBuffer.java | 8 ++ classpath/java/nio/Buffer.java | 5 + classpath/java/nio/ByteBuffer.java | 43 +++++++- classpath/java/nio/DirectByteBuffer.java | 8 ++ classpath/java/nio/FixedArrayByteBuffer.java | 8 ++ test/Buffers.java | 100 +++++++++++++++---- test/avian/testing/Asserts.java | 67 +++++++++++++ 7 files changed, 212 insertions(+), 27 deletions(-) create mode 100644 test/avian/testing/Asserts.java diff --git a/classpath/java/nio/ArrayByteBuffer.java b/classpath/java/nio/ArrayByteBuffer.java index c78fa04726..d0e41a2e0c 100644 --- a/classpath/java/nio/ArrayByteBuffer.java +++ b/classpath/java/nio/ArrayByteBuffer.java @@ -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; + } } diff --git a/classpath/java/nio/Buffer.java b/classpath/java/nio/Buffer.java index 204ec848fb..f03e178a2b 100644 --- a/classpath/java/nio/Buffer.java +++ b/classpath/java/nio/Buffer.java @@ -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; + } } diff --git a/classpath/java/nio/ByteBuffer.java b/classpath/java/nio/ByteBuffer.java index e150e07e7e..fddb06481b 100644 --- a/classpath/java/nio/ByteBuffer.java +++ b/classpath/java/nio/ByteBuffer.java @@ -14,10 +14,9 @@ public abstract class ByteBuffer extends Buffer implements Comparable { - 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(); } diff --git a/classpath/java/nio/DirectByteBuffer.java b/classpath/java/nio/DirectByteBuffer.java index 58ce7c42c4..ede7074a5b 100644 --- a/classpath/java/nio/DirectByteBuffer.java +++ b/classpath/java/nio/DirectByteBuffer.java @@ -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; + } } diff --git a/classpath/java/nio/FixedArrayByteBuffer.java b/classpath/java/nio/FixedArrayByteBuffer.java index 1f0a9e45c4..d433e321af 100644 --- a/classpath/java/nio/FixedArrayByteBuffer.java +++ b/classpath/java/nio/FixedArrayByteBuffer.java @@ -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 diff --git a/test/Buffers.java b/test/Buffers.java index 3704ae8dd7..63a24ec928 100644 --- a/test/Buffers.java +++ b/test/Buffers.java @@ -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 } diff --git a/test/avian/testing/Asserts.java b/test/avian/testing/Asserts.java new file mode 100644 index 0000000000..ed0ce5ec95 --- /dev/null +++ b/test/avian/testing/Asserts.java @@ -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); + } + } +}