From 82398eb822c7c83821cba55b2f80f68239a5e93e Mon Sep 17 00:00:00 2001 From: Bassam Helal Date: Sun, 9 Jan 2022 16:24:50 +0000 Subject: [PATCH 1/2] Overhauled tests for pointers containing numeric type values: * Tests pointers containing all possible built in native numeric types, in addition to pointers containing pointers * Removed legacy code from PointerTest.java and PointerTest.c that is now redundant, what remains are tests and code that will need to be later on improved or kept --- libtest/PointerNumericTest.c | 71 ++ libtest/PointerTest.c | 41 - src/test/java/jnr/ffi/PointerTest.java | 251 +----- .../jnr/ffi/pointer/PointerNumericTest.java | 802 ++++++++++++++++++ 4 files changed, 875 insertions(+), 290 deletions(-) create mode 100755 libtest/PointerNumericTest.c create mode 100755 src/test/java/jnr/ffi/pointer/PointerNumericTest.java diff --git a/libtest/PointerNumericTest.c b/libtest/PointerNumericTest.c new file mode 100755 index 00000000..2201384a --- /dev/null +++ b/libtest/PointerNumericTest.c @@ -0,0 +1,71 @@ +#include +#include + +#ifndef __mips__ +# include +#endif + +#if defined(__mips64) || defined(__PASE__) +# include +#endif + +#include +#include +#include +#include + +// Let's define the stdint.h typedefs ourselves if they can't be found +#if !defined(_STDINT_H_) && !defined(_STDINT_H) && !defined(_SYS__STDINT_H_) && !defined(_H_STDINT) +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef signed long long int64_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +#endif + +typedef long double ldouble; +typedef unsigned long ulong; +typedef void* pointer; +typedef void* ptr; +typedef enum Enum_t {e0, e1, e2, e3} Enum; +typedef bool boolean; + +#define RET(T) T ptr_num_ret_##T(void *p, int offset) { \ + T tmp; memcpy(&tmp, (ptr) (p + offset), sizeof(tmp)); return tmp; \ +} +#define SET(T) void ptr_num_set_##T(void *p, int offset, T value) { \ + memcpy((ptr) (p + offset), &value, sizeof(value)); \ +} + +#define TEST(T) SET(T) RET(T) + +TEST(int8_t); +TEST(int16_t); +TEST(int32_t); +TEST(long); +TEST(int64_t); + +TEST(uint8_t); +TEST(uint16_t); +TEST(uint32_t); +TEST(ulong); +TEST(uint64_t); + +TEST(float); +TEST(double); +TEST(ldouble); + +TEST(boolean); +TEST(pointer); +TEST(Enum); + +void *ptr_num_arr_get(void **array, int index) { + return array[index]; +} + +void ptr_num_arr_set(void **array, int index, void *value) { + array[index] = value; +} diff --git a/libtest/PointerTest.c b/libtest/PointerTest.c index d0179fcd..01168d16 100644 --- a/libtest/PointerTest.c +++ b/libtest/PointerTest.c @@ -85,44 +85,3 @@ ptr_free(void* ptr) { free(ptr); } - -#define swap(p1, p2) do { typeof(*p1) tmp__ = *p1; *p1 = *p2; *p2 = tmp__; } while (0) -void -ptr_reverse_l6(long* l1, long* l2, long* l3, long* l4, long* l5, long* l6) -{ - swap(l1, l6); - swap(l2, l5); - swap(l3, l4); -} - -void -ptr_reverse_l5(long* l1, long* l2, long* l3, long* l4, long* l5) -{ - swap(l1, l5); - (void)(l3); - swap(l2, l4); -} - - -void -ptr_rotate_l5(long* l1, long* l2, long* l3, long* l4, long* l5) -{ - long tmp = *l1; - swap(l5, l1); - swap(l4, l5); - swap(l3, l4); - swap(l2, l3); - *l2 = tmp; -} - -void -ptr_rotate_l6(long* l1, long* l2, long* l3, long* l4, long* l5, long* l6) -{ - long t = *l1; - swap(l6, l1); - swap(l5, l6); - swap(l4, l5); - swap(l3, l4); - swap(l2, l3); - *l2 = t; -} diff --git a/src/test/java/jnr/ffi/PointerTest.java b/src/test/java/jnr/ffi/PointerTest.java index 26a6e6cc..07b0d4b9 100644 --- a/src/test/java/jnr/ffi/PointerTest.java +++ b/src/test/java/jnr/ffi/PointerTest.java @@ -24,10 +24,8 @@ import jnr.ffi.types.int32_t; import jnr.ffi.types.int8_t; import jnr.ffi.types.size_t; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; + import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.nio.ByteOrder; @@ -39,8 +37,6 @@ public class PointerTest { - public PointerTest() { - } public static interface TestLib { Pointer ptr_return_array_element(@In Pointer[] array, int index); void ptr_set_array_element(@Out Pointer[] array, int index, Pointer value); @@ -77,217 +73,15 @@ public Foo(Runtime runtime) { } static TestLib testlib; static Runtime runtime; - public static interface Libc { - Pointer calloc(int nmemb, int size); - Pointer malloc(int size); - void free(Pointer ptr); - void cfree(Pointer ptr); - } @BeforeAll - public static void setUpClass() throws Exception { + public static void beforeAll() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); -// libc = Library.loadLibrary("c", Libc.class); - } - - @AfterAll - public static void tearDownClass() throws Exception { - } - - @BeforeEach - public void setUp() { } - @AfterEach - public void tearDown() { - } - -// @Test -// public void testGetPointerArrayArgument() throws Exception { -// -// Pointer MAGIC0 = new Pointer(0xdeadbeef); -// Pointer MAGIC1 = new Pointer(0xcafebabe); -// Pointer[] array = { MAGIC0, MAGIC1 }; -// -// assertEquals("Incorrect Pointer at index 0", MAGIC0, -// testlib.ptr_return_array_element(array, 0)); -// assertEquals("Incorrect Pointer at index 1", MAGIC1, -// testlib.ptr_return_array_element(array, 1)); -// } -// @Test -// public void testSetPointerArrayArgument() throws Exception { -// -// Pointer MAGIC0 = new Pointer(0xdeadbeef); -// Pointer MAGIC1 = new Pointer(0xcafebabe); -// Pointer[] array = { MAGIC0, MAGIC1 }; -// -// testlib.ptr_set_array_element(array, 0, MAGIC1); -// testlib.ptr_set_array_element(array, 1, MAGIC0); -// assertEquals("Pointer at index 0 not set", MAGIC1, array[0]); -// assertEquals("Pointer at index 1 not set", MAGIC0, array[1]); -// } -// -// @Test -// public void testLongPointerValue() throws Exception { -// long MAGIC0 = 0xdeadbeefL | (Address.SIZE == 64 ? (0xfee1deadL << 32) : 0L); -// assertEquals("Pointer value not equal", MAGIC0, new Pointer(MAGIC0).nativeAddress()); -// } static final int SIZE = 128; - @Test - public void testPointerSetByte() { - - Pointer p = testlib.ptr_malloc(SIZE); - byte MAGIC = (byte) 0xFE; - for (int i = 0; i < SIZE; ++i) { - p.putByte(i, MAGIC); - assertEquals(MAGIC, testlib.ptr_ret_int8_t(p, i), "Byte not set at offset " + i); - } - } - @Test - public void testPointerSetShort() { - - Pointer p = testlib.ptr_malloc(SIZE); - short MAGIC = (short) 0xFEE1; - for (int i = 0; i < (SIZE - 1); i += 2) { - p.putShort(i, MAGIC); - assertEquals(MAGIC, testlib.ptr_ret_int16_t(p, i), "Short not set at offset " + i); - } - } - @Test - public void testPointerSetInt() { - - Pointer p = testlib.ptr_malloc(SIZE); - int MAGIC = (int) 0xFEE1DEAD; - for (int i = 0; i < (SIZE - 3); i += 4) { - p.putInt(i, MAGIC); - assertEquals(MAGIC, testlib.ptr_ret_int32_t(p, i), "Integer not set at offset " + i); - } - } - @Test - public void testPointerSetLongLong() { - - Pointer p = testlib.ptr_malloc(SIZE); - long MAGIC = 0xFEE1DEADABCDEF12L; - final long l = MAGIC; - byte[] bytes = runtime.byteOrder().equals(ByteOrder.BIG_ENDIAN) - ? new byte[]{ - (byte) (l >>> 56), (byte) (l >>> 48), (byte) (l >>> 40), - (byte) (l >>> 32), (byte) (l >>> 24), (byte) (l >>> 16), - (byte) (l >>> 8), (byte) (l >>> 0) - } - : new byte[]{ - (byte) (l >>> 0), (byte) (l >>> 8), (byte) (l >>> 16), - (byte) (l >>> 24), (byte) (l >>> 32), (byte) (l >>> 40), - (byte) (l >>> 48), (byte) (l >>> 56) - }; - - for (int i = 0; i < (SIZE - 7); i += 8) { - p.putLongLong(i, MAGIC); - for (int idx = 0; idx < 8; ++idx) { - assertEquals(bytes[idx], p.getByte(i + idx), "incorrect byte value at offset= " + i + " idx=" + idx); - } - assertEquals(MAGIC, testlib.ptr_ret_int64_t(p, i), "Long not set at offset " + i); - } - } - @Test - public void testPointerSetFloat() { - - Pointer p = testlib.ptr_malloc(SIZE); - float MAGIC = (float) 0xFEE1DEADABCDEF12L; - for (int i = 0; i < (SIZE - 3); i += 4) { - p.putFloat(i, MAGIC); - assertEquals(MAGIC, testlib.ptr_ret_float(p, i), 0.00001, "Float not set at offset " + i); - } - } - @Test - public void testPointerSetDouble() { - - Pointer p = testlib.ptr_malloc(SIZE); - double MAGIC = (double) 0xFEE1DEADABCDEF12L; - - long l = Double.doubleToRawLongBits(MAGIC); - byte[] bytes = runtime.byteOrder().equals(ByteOrder.BIG_ENDIAN) - ? new byte[]{ - (byte) (l >>> 56), (byte) (l >>> 48), (byte) (l >>> 40), - (byte) (l >>> 32), (byte) (l >>> 24), (byte) (l >>> 16), - (byte) (l >>> 8), (byte) (l >>> 0) - } - : new byte[]{ - (byte) (l >>> 0), (byte) (l >>> 8), (byte) (l >>> 16), - (byte) (l >>> 24), (byte) (l >>> 32), (byte) (l >>> 40), - (byte) (l >>> 48), (byte) (l >>> 56) - }; - p.putDouble(0, MAGIC); - for (int i = 0; i < 8; ++i) { - assertEquals(bytes[i], p.getByte(i), "incorrect byte value at idx=" + i); - } - for (int i = 0; i < (SIZE - 7); i += 8) { - p.putDouble(i, MAGIC); - assertEquals(MAGIC, testlib.ptr_ret_double(p, i), 0.0001E16, "Double not set at offset " + i); - } - } - @Test - public void testPointerGetByte() { - - Pointer p = testlib.ptr_malloc(SIZE); - byte MAGIC = (byte) 0xFE; - for (int i = 0; i < SIZE; ++i) { - testlib.ptr_set_int8_t(p, i, MAGIC); - assertEquals(MAGIC, p.getByte(i), "Byte not set at offset " + i); - } - } - @Test - public void testPointerGetShort() { - - Pointer p = testlib.ptr_malloc(SIZE); - short MAGIC = (short) 0xFEE1; - for (int i = 0; i < SIZE - 1; i += 2) { - testlib.ptr_set_int16_t(p, i, MAGIC); - assertEquals(MAGIC, p.getShort(i), "Short not set at offset " + i); - } - } - @Test - public void testPointerGetInt() { - - Pointer p = testlib.ptr_malloc(SIZE); - int MAGIC = (int) 0xFEE1DEAD; - for (int i = 0; i < SIZE - 3; i += 4) { - testlib.ptr_set_int32_t(p, i, MAGIC); - assertEquals(MAGIC, p.getInt(i), "Integer not set at offset " + i); - } - } - @Test - public void testPointerGetLongLong() { - - Pointer p = testlib.ptr_malloc(SIZE); - long MAGIC = 0xFEE1DEADABCDEF12L; - for (int i = 0; i < SIZE - 7; i += 8) { - testlib.ptr_set_int64_t(p, i, MAGIC); - assertEquals(MAGIC, p.getLongLong(i), "Long not set at offset " + i); - } - } - @Test - public void testPointerGetFloat() { - - Pointer p = testlib.ptr_malloc(SIZE); - float MAGIC = (float) 0xFEE1DEADABCDEF12L; - for (int i = 0; i < (SIZE - 3); i += 4) { - testlib.ptr_set_float(p, i, MAGIC); - assertEquals(MAGIC, p.getFloat(i), 0.0001, "Float not set at offset " + i); - } - } - @Test - public void testPointerGetDouble() { - - Pointer p = testlib.ptr_malloc(SIZE); - double MAGIC = (double) 0xFEE1DEADABCDEF12L; - for (int i = 0; i < (SIZE - 7); i += 8) { - testlib.ptr_set_double(p, i, MAGIC); - assertEquals(MAGIC, p.getDouble(i), 0.00001, "Double not set at offset " + i); - } - } @Test public void testMalloc() { Pointer[] pointers = new Pointer[1024]; @@ -299,42 +93,6 @@ public void testMalloc() { } } - @Test - public void testP5() { - Pointer[] p = new Pointer[5]; - long[] v = { 1, 2, 3, 4, 5 }; - for (int i = 0; i < p.length; ++i) { - if ((i % 2) == 0) { - p[i] = Memory.allocate(Runtime.getRuntime(testlib), 8); - } else { - p[i] = Memory.allocateDirect(Runtime.getRuntime(testlib), 8); - } - p[i].putLongLong(0, v[i]); - } - testlib.ptr_reverse_l5(p[0], p[1], p[2], p[3], p[4]); - for (int i = 0; i < p.length; ++i) { - assertEquals(v[v.length - i - 1], p[i].getLongLong(0), "not same value for pointer " + (i + 1)); - } - } - - @Test - public void testP6() { - Pointer[] p = new Pointer[6]; - long[] v = { 1, 2, 3, 4, 5, 6}; - for (int i = 0; i < p.length; ++i) { - if ((i % 2) == 0) { - p[i] = Memory.allocate(Runtime.getRuntime(testlib), 8); - } else { - p[i] = Memory.allocateDirect(Runtime.getRuntime(testlib), 8); - } - p[i].putLongLong(0, v[i]); - } - testlib.ptr_reverse_l6(p[0], p[1], p[2], p[3], p[4], p[5]); - for (int i = 0; i < p.length; ++i) { - assertEquals(v[v.length - i - 1], p[i].getLongLong(0), "not same value for pointer " + (i + 1)); - } - } - @Test public void nullTerminatedStringArray() { Runtime runtime = Runtime.getRuntime(testlib); Pointer[] array = new Pointer[10]; @@ -403,11 +161,6 @@ public void pointerArraySetElement() { assertEquals(0xbeefL, foo.l2.get()); assertEquals(0x1eefcafeL, foo.l3.get()); } -// @Test -// public void testLibcMalloc() { -// Pointer p = libc.malloc(SIZE); -// libc.free(p); -// } @Test public void testTransferTo() { diff --git a/src/test/java/jnr/ffi/pointer/PointerNumericTest.java b/src/test/java/jnr/ffi/pointer/PointerNumericTest.java new file mode 100755 index 00000000..0b917b0c --- /dev/null +++ b/src/test/java/jnr/ffi/pointer/PointerNumericTest.java @@ -0,0 +1,802 @@ +package jnr.ffi.pointer; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.Random; + +import jnr.ffi.Memory; +import jnr.ffi.Pointer; +import jnr.ffi.Runtime; +import jnr.ffi.TstUtil; +import jnr.ffi.annotations.In; + +import static jnr.ffi.NativeType.ADDRESS; +import static jnr.ffi.NativeType.DOUBLE; +import static jnr.ffi.NativeType.FLOAT; +import static jnr.ffi.NativeType.SCHAR; +import static jnr.ffi.NativeType.SINT; +import static jnr.ffi.NativeType.SLONG; +import static jnr.ffi.NativeType.SLONGLONG; +import static jnr.ffi.NativeType.SSHORT; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Tests PointerNumericTest.c + * This is intended to test pointers that point to native numeric types + */ +public class PointerNumericTest { + + public enum Enum {e0, e1, e2, e3} + + public static interface TestLib { + public byte ptr_num_ret_int8_t(Pointer p, int offset); + public void ptr_num_set_int8_t(Pointer p, int offset, byte value); + + public short ptr_num_ret_int16_t(Pointer p, int offset); + public void ptr_num_set_int16_t(Pointer p, int offset, short value); + + public int ptr_num_ret_int32_t(Pointer p, int offset); + public void ptr_num_set_int32_t(Pointer p, int offset, int value); + + public long ptr_num_ret_long(Pointer p, int offset); + public void ptr_num_set_long(Pointer p, int offset, long value); + + public long ptr_num_ret_int64_t(Pointer p, int offset); + public void ptr_num_set_int64_t(Pointer p, int offset, long value); + + public float ptr_num_ret_float(Pointer p, int offset); + public void ptr_num_set_float(Pointer p, int offset, float value); + + public double ptr_num_ret_double(Pointer p, int offset); + public void ptr_num_set_double(Pointer p, int offset, double value); + + public boolean ptr_num_ret_boolean(Pointer p, int offset); + public void ptr_num_set_boolean(Pointer p, int offset, boolean value); + + public Enum ptr_num_ret_Enum(Pointer p, int offset); + public void ptr_num_set_Enum(Pointer p, int offset, Enum value); + + public Pointer ptr_num_ret_pointer(Pointer p, int offset); + public void ptr_num_set_pointer(Pointer p, int offset, Pointer value); + + public Pointer ptr_num_arr_get(Pointer array, int index); + public Pointer ptr_num_arr_get(@In Pointer[] array, int index); + // TODO: 09-Jan-2022 @basshelal: Without this @In annotation we get a SIGSEGV, look into why this is and + // document it! + + public void ptr_num_arr_set(Pointer array, int index, Pointer value); + public void ptr_num_arr_set(@In Pointer[] array, int index, Pointer value); + // TODO: 09-Jan-2022 @basshelal: Without this @In annotation the tests fail because values change, also look + // into this and document it! + } + + /** Number of values to put into a pointer in each test */ + private static final int COUNT = 100_000; + /** Size of array of pointers for array tests */ + private static final int ARRAY_SIZE = 10_000; + private static final Random R = new Random(); + private static TestLib testlib; + + @BeforeAll + public static void beforeAll() { + testlib = TstUtil.loadTestLib(TestLib.class); + } + + private static Pointer malloc(int bytes) { + return Memory.allocateDirect(Runtime.getRuntime(testlib), bytes); + } + + // ========================= Byte =============================== + + @Test + public void testPointerGetByte() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SCHAR).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + byte[] values = new byte[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + byte value = (byte) R.nextInt(); + p.putByte(i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_int8_t(p, i), + "Incorrect byte value at offset " + i); + assertEquals(p.getByte(i), testlib.ptr_num_ret_int8_t(p, i), + "Incorrect byte value at offset " + i); + } + byte[] dest = new byte[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect bytes returned from bulk get method"); + } + + @Test + public void testPointerSetByte() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SCHAR).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + byte[] values = new byte[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + byte value = (byte) R.nextInt(); + testlib.ptr_num_set_int8_t(p, i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_int8_t(p, i), + "Incorrect byte value at offset " + i); + assertEquals(p.getByte(i), testlib.ptr_num_ret_int8_t(p, i), + "Incorrect byte value at offset " + i); + } + byte[] dest = new byte[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect bytes returned from bulk get method"); + } + + // ========================= Short ============================== + + @Test + public void testPointerGetShort() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SSHORT).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + short[] values = new short[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + short value = (short) R.nextInt(); + p.putShort(i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_int16_t(p, i), + "Incorrect short value at offset " + i); + assertEquals(p.getShort(i), testlib.ptr_num_ret_int16_t(p, i), + "Incorrect short value at offset " + i); + } + short[] dest = new short[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect shorts returned from bulk get method"); + } + + @Test + public void testPointerSetShort() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SSHORT).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + short[] values = new short[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + short value = (short) R.nextInt(); + testlib.ptr_num_set_int16_t(p, i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_int16_t(p, i), + "Incorrect short value at offset " + i); + assertEquals(p.getShort(i), testlib.ptr_num_ret_int16_t(p, i), + "Incorrect short value at offset " + i); + } + short[] dest = new short[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect shorts returned from bulk get method"); + } + + // ========================= Int ================================ + + @Test + public void testPointerGetInt() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SINT).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + int[] values = new int[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + int value = R.nextInt(); + p.putInt(i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_int32_t(p, i), + "Incorrect int value at offset " + i); + assertEquals(p.getInt(i), testlib.ptr_num_ret_int32_t(p, i), + "Incorrect int value at offset " + i); + } + int[] dest = new int[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect ints returned from bulk get method"); + } + + @Test + public void testPointerSetInt() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SINT).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + int[] values = new int[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + int value = R.nextInt(); + testlib.ptr_num_set_int32_t(p, i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_int32_t(p, i), + "Incorrect int value at offset " + i); + assertEquals(p.getInt(i), testlib.ptr_num_ret_int32_t(p, i), + "Incorrect int value at offset " + i); + } + int[] dest = new int[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect ints returned from bulk get method"); + } + + // ========================= NativeLong ========================= + + @Test + public void testPointerGetNativeLong() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SLONG).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + long[] values = new long[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + long value = R.nextLong(); + p.putNativeLong(i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_long(p, i), + "Incorrect native long value at offset " + i); + assertEquals(p.getNativeLong(i), testlib.ptr_num_ret_long(p, i), + "Incorrect native long value at offset " + i); + } + long[] dest = new long[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect native longs returned from bulk get method"); + } + + @Test + public void testPointerSetNativeLong() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SLONG).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + long[] values = new long[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + long value = R.nextLong(); + testlib.ptr_num_set_long(p, i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_long(p, i), + "Incorrect native long value at offset " + i); + assertEquals(p.getNativeLong(i), testlib.ptr_num_ret_long(p, i), + "Incorrect native long value at offset " + i); + } + long[] dest = new long[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect native longs returned from bulk get method"); + } + + // ========================= Long =============================== + + @Test + public void testPointerGetLong() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SLONGLONG).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + long[] values = new long[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + long value = R.nextLong(); + p.putLongLong(i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_int64_t(p, i), + "Incorrect long value at offset " + i); + assertEquals(p.getLongLong(i), testlib.ptr_num_ret_int64_t(p, i), + "Incorrect long value at offset " + i); + } + long[] dest = new long[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect longs returned from bulk get method"); + } + + @Test + public void testPointerSetLong() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SLONGLONG).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + long[] values = new long[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + long value = R.nextLong(); + testlib.ptr_num_set_int64_t(p, i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_int64_t(p, i), + "Incorrect long value at offset " + i); + assertEquals(p.getLongLong(i), testlib.ptr_num_ret_int64_t(p, i), + "Incorrect long value at offset " + i); + } + long[] dest = new long[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect longs returned from bulk get method"); + } + + // ========================= Float ============================== + + @Test + public void testPointerGetFloat() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(FLOAT).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + float[] values = new float[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + float value = R.nextFloat(); + p.putFloat(i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_float(p, i), + "Incorrect float value at offset " + i); + assertEquals(p.getFloat(i), testlib.ptr_num_ret_float(p, i), + "Incorrect float value at offset " + i); + } + float[] dest = new float[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect floats returned from bulk get method"); + } + + @Test + public void testPointerSetFloat() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(FLOAT).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + float[] values = new float[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + float value = R.nextFloat(); + testlib.ptr_num_set_float(p, i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_float(p, i), + "Incorrect float value at offset " + i); + assertEquals(p.getFloat(i), testlib.ptr_num_ret_float(p, i), + "Incorrect float value at offset " + i); + } + float[] dest = new float[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect floats returned from bulk get method"); + } + + // ========================= Double ============================= + + @Test + public void testPointerGetDouble() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(DOUBLE).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + double[] values = new double[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + double value = R.nextDouble(); + p.putDouble(i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_double(p, i), + "Incorrect double value at offset " + i); + assertEquals(p.getDouble(i), testlib.ptr_num_ret_double(p, i), + "Incorrect double value at offset " + i); + } + double[] dest = new double[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect doubles returned from bulk get method"); + } + + @Test + public void testPointerSetDouble() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(DOUBLE).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + double[] values = new double[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + double value = R.nextDouble(); + testlib.ptr_num_set_double(p, i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_double(p, i), + "Incorrect double value at offset " + i); + assertEquals(p.getDouble(i), testlib.ptr_num_ret_double(p, i), + "Incorrect double value at offset " + i); + } + double[] dest = new double[total]; + p.get(0, dest, 0, total); + + assertArrayEquals(values, dest, + "Incorrect doubles returned from bulk get method"); + } + + // ========================= Boolean ============================ + + @Test + public void testPointerGetBoolean() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SCHAR).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + boolean[] values = new boolean[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + boolean value = R.nextBoolean(); + byte numericValue = (byte) (value ? 1 : 0); + p.putByte(i, numericValue); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_boolean(p, i), + "Incorrect boolean value at offset " + i); + assertEquals(p.getByte(i) != 0, testlib.ptr_num_ret_boolean(p, i), + "Incorrect boolean value at offset " + i); + } + byte[] dest = new byte[total]; + p.get(0, dest, 0, total); + boolean[] boolDest = new boolean[total]; + for (int i = 0; i < dest.length; i++) { + boolDest[i] = dest[i] != 0; + } + + assertArrayEquals(values, boolDest, + "Incorrect booleans returned from bulk get method"); + } + + @Test + public void testPointerSetBoolean() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SCHAR).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + boolean[] values = new boolean[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + boolean value = R.nextBoolean(); + byte numericValue = (byte) (value ? 1 : 0); + testlib.ptr_num_set_boolean(p, i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = value; + + assertEquals(value, testlib.ptr_num_ret_boolean(p, i), + "Incorrect boolean value at offset " + i); + assertEquals(p.getByte(i) != 0, testlib.ptr_num_ret_boolean(p, i), + "Incorrect boolean value at offset " + i); + } + byte[] dest = new byte[total]; + p.get(0, dest, 0, total); + boolean[] boolDest = new boolean[total]; + for (int i = 0; i < dest.length; i++) { + boolDest[i] = dest[i] != 0; + } + + assertArrayEquals(values, boolDest, + "Incorrect booleans returned from bulk get method"); + } + + // ========================= Enum =============================== + + @Test + public void testPointerGetEnum() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SINT).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + Enum[] values = new Enum[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + int value = R.nextInt(Enum.values().length); + Enum enumValue = Enum.values()[value]; + p.putInt(i, value); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = enumValue; + + assertEquals(enumValue, testlib.ptr_num_ret_Enum(p, i), + "Incorrect enum value at offset " + i); + assertEquals(Enum.values()[p.getInt(i)], testlib.ptr_num_ret_Enum(p, i), + "Incorrect enum value at offset " + i); + } + int[] dest = new int[total]; + p.get(0, dest, 0, total); + Enum[] enumDest = new Enum[total]; + for (int i = 0; i < dest.length; i++) { + enumDest[i] = Enum.values()[dest[i]]; + } + + assertArrayEquals(values, enumDest, + "Incorrect enums returned from bulk get method"); + } + + @Test + public void testPointerSetEnum() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(SINT).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + Enum[] values = new Enum[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + int value = R.nextInt(Enum.values().length); + Enum enumValue = Enum.values()[value]; + testlib.ptr_num_set_Enum(p, i, enumValue); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = enumValue; + + assertEquals(enumValue, testlib.ptr_num_ret_Enum(p, i), + "Incorrect enum value at offset " + i); + assertEquals(Enum.values()[p.getInt(i)], testlib.ptr_num_ret_Enum(p, i), + "Incorrect enum value at offset " + i); + } + int[] dest = new int[total]; + p.get(0, dest, 0, total); + Enum[] enumDest = new Enum[total]; + for (int i = 0; i < dest.length; i++) { + enumDest[i] = Enum.values()[dest[i]]; + } + + assertArrayEquals(values, enumDest, + "Incorrect enums returned from bulk get method"); + } + + // ========================= Pointer ============================ + + @Test + public void testPointerGetPointer() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(ADDRESS).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + Pointer[] values = new Pointer[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + long value = R.nextLong(); + Pointer pointerValue = Pointer.newIntPointer(Runtime.getRuntime(testlib), value); + p.putPointer(i, pointerValue); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = pointerValue; + + assertEquals(pointerValue, testlib.ptr_num_ret_pointer(p, i), + "Incorrect pointer value at offset " + i); + assertEquals(p.getPointer(i), testlib.ptr_num_ret_pointer(p, i), + "Incorrect pointer value at offset " + i); + } + long[] dest = new long[total]; + p.get(0, dest, 0, total); + Pointer[] pointerDest = new Pointer[total]; + + for (int i = 0; i < dest.length; i++) { + pointerDest[i] = Pointer.newIntPointer(Runtime.getRuntime(testlib), dest[i]); + } + + assertArrayEquals(values, pointerDest, + "Incorrect pointers returned from bulk get method"); + } + + @Test + public void testPointerSetPointer() { + final int total = COUNT; + final int sizeInBytes = Runtime.getSystemRuntime().findType(ADDRESS).size(); + final int totalBytes = total * sizeInBytes; + + Pointer p = malloc(totalBytes); + Pointer[] values = new Pointer[total]; + + // skip by sizeInBytes because pointer offset uses byte offset + for (int i = 0; i < totalBytes; i += sizeInBytes) { + long value = R.nextLong(); + Pointer pointerValue = Pointer.newIntPointer(Runtime.getRuntime(testlib), value); + testlib.ptr_num_set_pointer(p, i, pointerValue); + // divide by sizeInBytes to undo the sizeInBytes skipping in the loop + values[i / sizeInBytes] = pointerValue; + + assertEquals(pointerValue, testlib.ptr_num_ret_pointer(p, i), + "Incorrect pointer value at offset " + i); + assertEquals(p.getPointer(i), testlib.ptr_num_ret_pointer(p, i), + "Incorrect pointer value at offset " + i); + } + long[] dest = new long[total]; + p.get(0, dest, 0, total); + Pointer[] pointerDest = new Pointer[total]; + + for (int i = 0; i < dest.length; i++) { + pointerDest[i] = Pointer.newIntPointer(Runtime.getRuntime(testlib), dest[i]); + } + + assertArrayEquals(values, pointerDest, + "Incorrect pointers returned from bulk get method"); + } + + // ========================= Pointer Array ====================== + + @Test + public void testPointerArrayGet() { + final int intSize = Runtime.getRuntime(testlib).findType(SINT).size(); + final int pointerSize = Runtime.getRuntime(testlib).addressSize(); + Pointer ptrArray = malloc(pointerSize * ARRAY_SIZE); + Pointer[] pointers = new Pointer[ARRAY_SIZE]; + int[] values = new int[ARRAY_SIZE]; + + for (int i = 0; i < ARRAY_SIZE; i++) { + Pointer ptr = malloc(intSize); + int value = R.nextInt(); + + ptr.putInt(0, value); + ptrArray.putPointer((long) i * pointerSize, ptr); + + pointers[i] = ptr; + values[i] = value; + } + for (int i = 0; i < ARRAY_SIZE; i++) { + Pointer ptr = testlib.ptr_num_arr_get(ptrArray, i); + + assertEquals(pointers[i], ptr); + assertEquals(ptrArray.getPointer((long) i * pointerSize), ptr); + assertEquals(values[i], ptr.getInt(0)); + } + } + + @Test + public void testPointerArraySet() { + final int intSize = Runtime.getRuntime(testlib).findType(SINT).size(); + final int pointerSize = Runtime.getRuntime(testlib).addressSize(); + Pointer ptrArray = malloc(pointerSize * ARRAY_SIZE); + Pointer[] pointers = new Pointer[ARRAY_SIZE]; + int[] values = new int[ARRAY_SIZE]; + + for (int i = 0; i < ARRAY_SIZE; i++) { + Pointer ptr = malloc(intSize); + int value = R.nextInt(); + + ptr.putInt(0, value); + testlib.ptr_num_arr_set(ptrArray, i, ptr); + + pointers[i] = ptr; + values[i] = value; + } + for (int i = 0; i < ARRAY_SIZE; i++) { + Pointer ptr = ptrArray.getPointer((long) i * pointerSize); + + assertEquals(pointers[i], ptr); + assertEquals(values[i], ptr.getInt(0)); + } + } + + @Test + public void testPointerArrayGetArrayMapping() { + final int byteSize = Runtime.getRuntime(testlib).findType(SINT).size(); + Pointer[] pointers = new Pointer[ARRAY_SIZE]; + int[] values = new int[ARRAY_SIZE]; + for (int i = 0; i < ARRAY_SIZE; i++) { + Pointer ptr = malloc(byteSize); + int value = R.nextInt(); + + ptr.putInt(0, value); + + pointers[i] = ptr; + values[i] = value; + } + for (int i = 0; i < ARRAY_SIZE; i++) { + Pointer ptr = testlib.ptr_num_arr_get(pointers, i); + + assertEquals(pointers[i], ptr); + assertEquals(values[i], ptr.getInt(0)); + } + } + + @Test + public void testPointerArraySetArrayMapping() { + final int byteSize = Runtime.getRuntime(testlib).findType(SINT).size(); + Pointer[] pointers = new Pointer[ARRAY_SIZE]; + int[] values = new int[ARRAY_SIZE]; + + for (int i = 0; i < ARRAY_SIZE; i++) { + Pointer ptr = malloc(byteSize); + int value = R.nextInt(); + + ptr.putInt(0, value); + testlib.ptr_num_arr_set(pointers, i, ptr); + + pointers[i] = ptr; + values[i] = value; + } + for (int i = 0; i < ARRAY_SIZE; i++) { + Pointer ptr = pointers[i]; + assertEquals(values[i], ptr.getInt(0)); + } + } + +} From fb6609d54825cffc02f24f963b86f92431275d70 Mon Sep 17 00:00:00 2001 From: Bassam Helal Date: Mon, 10 Jan 2022 09:19:57 +0000 Subject: [PATCH 2/2] Cleanups, simplifications and clarifications to PointerNumericTest.java ready for PR --- .../jnr/ffi/pointer/PointerNumericTest.java | 196 ++++++++++-------- 1 file changed, 112 insertions(+), 84 deletions(-) diff --git a/src/test/java/jnr/ffi/pointer/PointerNumericTest.java b/src/test/java/jnr/ffi/pointer/PointerNumericTest.java index 0b917b0c..0638c3e2 100755 --- a/src/test/java/jnr/ffi/pointer/PointerNumericTest.java +++ b/src/test/java/jnr/ffi/pointer/PointerNumericTest.java @@ -6,6 +6,7 @@ import java.util.Random; import jnr.ffi.Memory; +import jnr.ffi.NativeType; import jnr.ffi.Pointer; import jnr.ffi.Runtime; import jnr.ffi.TstUtil; @@ -74,30 +75,50 @@ public static interface TestLib { /** Number of values to put into a pointer in each test */ private static final int COUNT = 100_000; + /** Size of array of pointers for array tests */ private static final int ARRAY_SIZE = 10_000; + private static final Random R = new Random(); + private static TestLib testlib; + private static Runtime runtime; @BeforeAll public static void beforeAll() { testlib = TstUtil.loadTestLib(TestLib.class); + runtime = Runtime.getRuntime(testlib); } private static Pointer malloc(int bytes) { - return Memory.allocateDirect(Runtime.getRuntime(testlib), bytes); + return Memory.allocateDirect(runtime, bytes); + } + + private static int sizeOf(NativeType type) { + return runtime.findType(type).size(); } + /* + * The testing strategy we use here is essentially as follows: + * * Allocate a pointer to fit COUNT times the type we are testing, ie 100_000 ints + * * Create a control array that will have COUNT number of the type we are testing ie int[] + * * Loop over all the bytes we just allocated + * * Put a new random value of the type we are testing into the pointer and into the control array + * * Ensure that at that index, the value we just put is found in the pointer using the native method and the JNR + * Pointer methods like Pointer.getInt() + * * After the loop, use the JNR bulk get methods to check that the returned array matches tha control array, + * meaning all ints in the pointer are the same as the ints in the control array + */ + // ========================= Byte =============================== @Test public void testPointerGetByte() { - final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SCHAR).size(); - final int totalBytes = total * sizeInBytes; + final int sizeInBytes = sizeOf(SCHAR); + final int totalBytes = COUNT * sizeInBytes; Pointer p = malloc(totalBytes); - byte[] values = new byte[total]; + byte[] values = new byte[COUNT]; // skip by sizeInBytes because pointer offset uses byte offset for (int i = 0; i < totalBytes; i += sizeInBytes) { @@ -111,8 +132,8 @@ public void testPointerGetByte() { assertEquals(p.getByte(i), testlib.ptr_num_ret_int8_t(p, i), "Incorrect byte value at offset " + i); } - byte[] dest = new byte[total]; - p.get(0, dest, 0, total); + byte[] dest = new byte[COUNT]; + p.get(0, dest, 0, COUNT); assertArrayEquals(values, dest, "Incorrect bytes returned from bulk get method"); @@ -120,12 +141,11 @@ public void testPointerGetByte() { @Test public void testPointerSetByte() { - final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SCHAR).size(); - final int totalBytes = total * sizeInBytes; + final int sizeInBytes = sizeOf(SCHAR); + final int totalBytes = COUNT * sizeInBytes; Pointer p = malloc(totalBytes); - byte[] values = new byte[total]; + byte[] values = new byte[COUNT]; // skip by sizeInBytes because pointer offset uses byte offset for (int i = 0; i < totalBytes; i += sizeInBytes) { @@ -139,8 +159,8 @@ public void testPointerSetByte() { assertEquals(p.getByte(i), testlib.ptr_num_ret_int8_t(p, i), "Incorrect byte value at offset " + i); } - byte[] dest = new byte[total]; - p.get(0, dest, 0, total); + byte[] dest = new byte[COUNT]; + p.get(0, dest, 0, COUNT); assertArrayEquals(values, dest, "Incorrect bytes returned from bulk get method"); @@ -150,12 +170,11 @@ public void testPointerSetByte() { @Test public void testPointerGetShort() { - final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SSHORT).size(); - final int totalBytes = total * sizeInBytes; + final int sizeInBytes = sizeOf(SSHORT); + final int totalBytes = COUNT * sizeInBytes; Pointer p = malloc(totalBytes); - short[] values = new short[total]; + short[] values = new short[COUNT]; // skip by sizeInBytes because pointer offset uses byte offset for (int i = 0; i < totalBytes; i += sizeInBytes) { @@ -169,8 +188,8 @@ public void testPointerGetShort() { assertEquals(p.getShort(i), testlib.ptr_num_ret_int16_t(p, i), "Incorrect short value at offset " + i); } - short[] dest = new short[total]; - p.get(0, dest, 0, total); + short[] dest = new short[COUNT]; + p.get(0, dest, 0, COUNT); assertArrayEquals(values, dest, "Incorrect shorts returned from bulk get method"); @@ -178,12 +197,11 @@ public void testPointerGetShort() { @Test public void testPointerSetShort() { - final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SSHORT).size(); - final int totalBytes = total * sizeInBytes; + final int sizeInBytes = sizeOf(SSHORT); + final int totalBytes = COUNT * sizeInBytes; Pointer p = malloc(totalBytes); - short[] values = new short[total]; + short[] values = new short[COUNT]; // skip by sizeInBytes because pointer offset uses byte offset for (int i = 0; i < totalBytes; i += sizeInBytes) { @@ -197,8 +215,8 @@ public void testPointerSetShort() { assertEquals(p.getShort(i), testlib.ptr_num_ret_int16_t(p, i), "Incorrect short value at offset " + i); } - short[] dest = new short[total]; - p.get(0, dest, 0, total); + short[] dest = new short[COUNT]; + p.get(0, dest, 0, COUNT); assertArrayEquals(values, dest, "Incorrect shorts returned from bulk get method"); @@ -208,12 +226,11 @@ public void testPointerSetShort() { @Test public void testPointerGetInt() { - final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SINT).size(); - final int totalBytes = total * sizeInBytes; + final int sizeInBytes = sizeOf(SINT); + final int totalBytes = COUNT * sizeInBytes; Pointer p = malloc(totalBytes); - int[] values = new int[total]; + int[] values = new int[COUNT]; // skip by sizeInBytes because pointer offset uses byte offset for (int i = 0; i < totalBytes; i += sizeInBytes) { @@ -227,8 +244,8 @@ public void testPointerGetInt() { assertEquals(p.getInt(i), testlib.ptr_num_ret_int32_t(p, i), "Incorrect int value at offset " + i); } - int[] dest = new int[total]; - p.get(0, dest, 0, total); + int[] dest = new int[COUNT]; + p.get(0, dest, 0, COUNT); assertArrayEquals(values, dest, "Incorrect ints returned from bulk get method"); @@ -236,12 +253,11 @@ public void testPointerGetInt() { @Test public void testPointerSetInt() { - final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SINT).size(); - final int totalBytes = total * sizeInBytes; + final int sizeInBytes = sizeOf(SINT); + final int totalBytes = COUNT * sizeInBytes; Pointer p = malloc(totalBytes); - int[] values = new int[total]; + int[] values = new int[COUNT]; // skip by sizeInBytes because pointer offset uses byte offset for (int i = 0; i < totalBytes; i += sizeInBytes) { @@ -255,8 +271,8 @@ public void testPointerSetInt() { assertEquals(p.getInt(i), testlib.ptr_num_ret_int32_t(p, i), "Incorrect int value at offset " + i); } - int[] dest = new int[total]; - p.get(0, dest, 0, total); + int[] dest = new int[COUNT]; + p.get(0, dest, 0, COUNT); assertArrayEquals(values, dest, "Incorrect ints returned from bulk get method"); @@ -267,7 +283,7 @@ public void testPointerSetInt() { @Test public void testPointerGetNativeLong() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SLONG).size(); + final int sizeInBytes = sizeOf(SLONG); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -295,7 +311,7 @@ public void testPointerGetNativeLong() { @Test public void testPointerSetNativeLong() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SLONG).size(); + final int sizeInBytes = sizeOf(SLONG); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -325,7 +341,7 @@ public void testPointerSetNativeLong() { @Test public void testPointerGetLong() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SLONGLONG).size(); + final int sizeInBytes = sizeOf(SLONGLONG); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -353,7 +369,7 @@ public void testPointerGetLong() { @Test public void testPointerSetLong() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SLONGLONG).size(); + final int sizeInBytes = sizeOf(SLONGLONG); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -383,7 +399,7 @@ public void testPointerSetLong() { @Test public void testPointerGetFloat() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(FLOAT).size(); + final int sizeInBytes = sizeOf(FLOAT); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -411,7 +427,7 @@ public void testPointerGetFloat() { @Test public void testPointerSetFloat() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(FLOAT).size(); + final int sizeInBytes = sizeOf(FLOAT); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -441,7 +457,7 @@ public void testPointerSetFloat() { @Test public void testPointerGetDouble() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(DOUBLE).size(); + final int sizeInBytes = sizeOf(DOUBLE); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -469,7 +485,7 @@ public void testPointerGetDouble() { @Test public void testPointerSetDouble() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(DOUBLE).size(); + final int sizeInBytes = sizeOf(DOUBLE); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -499,7 +515,7 @@ public void testPointerSetDouble() { @Test public void testPointerGetBoolean() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SCHAR).size(); + final int sizeInBytes = sizeOf(SCHAR); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -532,7 +548,7 @@ public void testPointerGetBoolean() { @Test public void testPointerSetBoolean() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SCHAR).size(); + final int sizeInBytes = sizeOf(SCHAR); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -541,7 +557,6 @@ public void testPointerSetBoolean() { // skip by sizeInBytes because pointer offset uses byte offset for (int i = 0; i < totalBytes; i += sizeInBytes) { boolean value = R.nextBoolean(); - byte numericValue = (byte) (value ? 1 : 0); testlib.ptr_num_set_boolean(p, i, value); // divide by sizeInBytes to undo the sizeInBytes skipping in the loop values[i / sizeInBytes] = value; @@ -567,7 +582,7 @@ public void testPointerSetBoolean() { @Test public void testPointerGetEnum() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SINT).size(); + final int sizeInBytes = sizeOf(SINT); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -600,7 +615,7 @@ public void testPointerGetEnum() { @Test public void testPointerSetEnum() { final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(SINT).size(); + final int sizeInBytes = sizeOf(SINT); final int totalBytes = total * sizeInBytes; Pointer p = malloc(totalBytes); @@ -634,17 +649,16 @@ public void testPointerSetEnum() { @Test public void testPointerGetPointer() { - final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(ADDRESS).size(); - final int totalBytes = total * sizeInBytes; + final int sizeInBytes = sizeOf(ADDRESS); + final int totalBytes = COUNT * sizeInBytes; Pointer p = malloc(totalBytes); - Pointer[] values = new Pointer[total]; + Pointer[] values = new Pointer[COUNT]; // skip by sizeInBytes because pointer offset uses byte offset for (int i = 0; i < totalBytes; i += sizeInBytes) { long value = R.nextLong(); - Pointer pointerValue = Pointer.newIntPointer(Runtime.getRuntime(testlib), value); + Pointer pointerValue = Pointer.newIntPointer(runtime, value); p.putPointer(i, pointerValue); // divide by sizeInBytes to undo the sizeInBytes skipping in the loop values[i / sizeInBytes] = pointerValue; @@ -654,12 +668,12 @@ public void testPointerGetPointer() { assertEquals(p.getPointer(i), testlib.ptr_num_ret_pointer(p, i), "Incorrect pointer value at offset " + i); } - long[] dest = new long[total]; - p.get(0, dest, 0, total); - Pointer[] pointerDest = new Pointer[total]; + long[] dest = new long[COUNT]; + p.get(0, dest, 0, COUNT); + Pointer[] pointerDest = new Pointer[COUNT]; for (int i = 0; i < dest.length; i++) { - pointerDest[i] = Pointer.newIntPointer(Runtime.getRuntime(testlib), dest[i]); + pointerDest[i] = Pointer.newIntPointer(runtime, dest[i]); } assertArrayEquals(values, pointerDest, @@ -668,17 +682,16 @@ public void testPointerGetPointer() { @Test public void testPointerSetPointer() { - final int total = COUNT; - final int sizeInBytes = Runtime.getSystemRuntime().findType(ADDRESS).size(); - final int totalBytes = total * sizeInBytes; + final int sizeInBytes = sizeOf(ADDRESS); + final int totalBytes = COUNT * sizeInBytes; Pointer p = malloc(totalBytes); - Pointer[] values = new Pointer[total]; + Pointer[] values = new Pointer[COUNT]; // skip by sizeInBytes because pointer offset uses byte offset for (int i = 0; i < totalBytes; i += sizeInBytes) { long value = R.nextLong(); - Pointer pointerValue = Pointer.newIntPointer(Runtime.getRuntime(testlib), value); + Pointer pointerValue = Pointer.newIntPointer(runtime, value); testlib.ptr_num_set_pointer(p, i, pointerValue); // divide by sizeInBytes to undo the sizeInBytes skipping in the loop values[i / sizeInBytes] = pointerValue; @@ -688,12 +701,12 @@ public void testPointerSetPointer() { assertEquals(p.getPointer(i), testlib.ptr_num_ret_pointer(p, i), "Incorrect pointer value at offset " + i); } - long[] dest = new long[total]; - p.get(0, dest, 0, total); - Pointer[] pointerDest = new Pointer[total]; + long[] dest = new long[COUNT]; + p.get(0, dest, 0, COUNT); + Pointer[] pointerDest = new Pointer[COUNT]; for (int i = 0; i < dest.length; i++) { - pointerDest[i] = Pointer.newIntPointer(Runtime.getRuntime(testlib), dest[i]); + pointerDest[i] = Pointer.newIntPointer(runtime, dest[i]); } assertArrayEquals(values, pointerDest, @@ -702,10 +715,17 @@ public void testPointerSetPointer() { // ========================= Pointer Array ====================== + /* + * We have 2 mappings for a C void ** one using plain Pointer, (which we put Pointers into using + * Pointer.putPointer()) and one using Pointer[]. + * In both cases, we need to make sure that we put the same pointers into the array, that means both the address + * of the pointer and the value inside it. + */ + @Test public void testPointerArrayGet() { - final int intSize = Runtime.getRuntime(testlib).findType(SINT).size(); - final int pointerSize = Runtime.getRuntime(testlib).addressSize(); + final int intSize = sizeOf(SINT); + final int pointerSize = runtime.addressSize(); Pointer ptrArray = malloc(pointerSize * ARRAY_SIZE); Pointer[] pointers = new Pointer[ARRAY_SIZE]; int[] values = new int[ARRAY_SIZE]; @@ -723,16 +743,19 @@ public void testPointerArrayGet() { for (int i = 0; i < ARRAY_SIZE; i++) { Pointer ptr = testlib.ptr_num_arr_get(ptrArray, i); - assertEquals(pointers[i], ptr); - assertEquals(ptrArray.getPointer((long) i * pointerSize), ptr); - assertEquals(values[i], ptr.getInt(0)); + assertEquals(pointers[i], ptr, + "Incorrect pointer at index " + i); + assertEquals(ptrArray.getPointer((long) i * pointerSize), ptr, + "Incorrect pointer at index " + i); + assertEquals(values[i], ptr.getInt(0), + "Incorrect pointer value at index " + i); } } @Test public void testPointerArraySet() { - final int intSize = Runtime.getRuntime(testlib).findType(SINT).size(); - final int pointerSize = Runtime.getRuntime(testlib).addressSize(); + final int intSize = sizeOf(SINT); + final int pointerSize = runtime.addressSize(); Pointer ptrArray = malloc(pointerSize * ARRAY_SIZE); Pointer[] pointers = new Pointer[ARRAY_SIZE]; int[] values = new int[ARRAY_SIZE]; @@ -750,18 +773,20 @@ public void testPointerArraySet() { for (int i = 0; i < ARRAY_SIZE; i++) { Pointer ptr = ptrArray.getPointer((long) i * pointerSize); - assertEquals(pointers[i], ptr); - assertEquals(values[i], ptr.getInt(0)); + assertEquals(pointers[i], ptr, + "Incorrect pointer at index " + i); + assertEquals(values[i], ptr.getInt(0), + "Incorrect pointer value at index " + i); } } @Test public void testPointerArrayGetArrayMapping() { - final int byteSize = Runtime.getRuntime(testlib).findType(SINT).size(); + final int intSize = sizeOf(SINT); Pointer[] pointers = new Pointer[ARRAY_SIZE]; int[] values = new int[ARRAY_SIZE]; for (int i = 0; i < ARRAY_SIZE; i++) { - Pointer ptr = malloc(byteSize); + Pointer ptr = malloc(intSize); int value = R.nextInt(); ptr.putInt(0, value); @@ -772,19 +797,21 @@ public void testPointerArrayGetArrayMapping() { for (int i = 0; i < ARRAY_SIZE; i++) { Pointer ptr = testlib.ptr_num_arr_get(pointers, i); - assertEquals(pointers[i], ptr); - assertEquals(values[i], ptr.getInt(0)); + assertEquals(pointers[i], ptr, + "Incorrect pointer at index " + i); + assertEquals(values[i], ptr.getInt(0), + "Incorrect pointer value at index " + i); } } @Test public void testPointerArraySetArrayMapping() { - final int byteSize = Runtime.getRuntime(testlib).findType(SINT).size(); + final int intSize = sizeOf(SINT); Pointer[] pointers = new Pointer[ARRAY_SIZE]; int[] values = new int[ARRAY_SIZE]; for (int i = 0; i < ARRAY_SIZE; i++) { - Pointer ptr = malloc(byteSize); + Pointer ptr = malloc(intSize); int value = R.nextInt(); ptr.putInt(0, value); @@ -795,7 +822,8 @@ public void testPointerArraySetArrayMapping() { } for (int i = 0; i < ARRAY_SIZE; i++) { Pointer ptr = pointers[i]; - assertEquals(values[i], ptr.getInt(0)); + assertEquals(values[i], ptr.getInt(0), + "Incorrect pointer value at index " + i); } }