From 577239cae78c243f27554ad4988e01b21c4423bb Mon Sep 17 00:00:00 2001 From: Samuel Audet Date: Wed, 12 May 2021 12:15:44 +0900 Subject: [PATCH] * Upon `Pointer.getPointer(Class

)` scale `position`, `limit`, and `capacity` with `sizeof()` (pull #476) --- CHANGELOG.md | 1 + .../java/org/bytedeco/javacpp/Pointer.java | 17 +++++---- .../org/bytedeco/javacpp/PointerTest.java | 36 +++++++++++++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9c62a6a..ada8291e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ + * Upon `Pointer.getPointer(Class

)` scale `position`, `limit`, and `capacity` with `sizeof()` ([pull #476](https://github.com/bytedeco/javacpp/pull/476)) * Fix `Parser` incorrectly translating non-documentation comments as part of documentation comments ([issue #475](https://github.com/bytedeco/javacpp/issues/475)) * Set `Pointer.maxPhysicalBytes` to `4 * Runtime.maxMemory()` by default as workaround for memory-mapped files, ZGC, etc ([issue #468](https://github.com/bytedeco/javacpp/issues/468)) * Ensure `synchronized` code in `Pointer` gets skipped with "org.bytedeco.javacpp.nopointergc" ([issue tensorflow/java#313](https://github.com/tensorflow/java/issues/313)) diff --git a/src/main/java/org/bytedeco/javacpp/Pointer.java b/src/main/java/org/bytedeco/javacpp/Pointer.java index c8e58ade..7d1eb509 100644 --- a/src/main/java/org/bytedeco/javacpp/Pointer.java +++ b/src/main/java/org/bytedeco/javacpp/Pointer.java @@ -895,15 +895,20 @@ public

P getPointer(long i) { return (P)getPointer(getClass(), i); } - /** Returns {@code getPointer(cls, 0)}. */ - public

P getPointer(Class

cls) { - return getPointer(cls, 0); + /** Returns {@code getPointer(type, 0)}. */ + public

P getPointer(Class

type) { + return getPointer(type, 0); } - /** Returns {@code new P(this).offsetAddress(i)}. Throws RuntimeException if constructor is missing. */ - public

P getPointer(Class

cls, long i) { + /** Returns {@code new P(this).offsetAddress(i)} after scaling {@link #position}, {@link #limit}, and {@link #capacity} + * with {@link #sizeof()}. Throws RuntimeException if the cast constructor is missing from the subclass type. */ + public

P getPointer(Class

type, long i) { try { - return cls.getDeclaredConstructor(Pointer.class).newInstance(this).offsetAddress(i); + P p = type.getDeclaredConstructor(Pointer.class).newInstance(this); + p.position = position != 0 ? Math.max(0, position * this.sizeof() / p.sizeof()) : 0; + p.limit = limit != 0 ? Math.max(0, limit * this.sizeof() / p.sizeof()) : 0; + p.capacity = capacity != 0 ? Math.max(0, capacity * this.sizeof() / p.sizeof()) : 0; + return p.offsetAddress(i); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } diff --git a/src/test/java/org/bytedeco/javacpp/PointerTest.java b/src/test/java/org/bytedeco/javacpp/PointerTest.java index 71683b01..36767e60 100644 --- a/src/test/java/org/bytedeco/javacpp/PointerTest.java +++ b/src/test/java/org/bytedeco/javacpp/PointerTest.java @@ -169,6 +169,10 @@ static class TestFunction extends FunctionPointer { assertEquals(pointer.address() + 10, p2.address()); assertEquals(array.length - 10, p2.limit()); assertEquals(array.length - 10, p2.capacity()); + Pointer p3 = pointer.getPointer(Pointer.class, 20); + assertEquals(pointer.address() + 20, p3.address()); + assertEquals(1 * array.length - 20, p3.limit()); + assertEquals(1 * array.length - 20, p3.capacity()); for (int i = 0; i < array.length; i++) { array[i] = (byte)i; @@ -279,6 +283,10 @@ static class TestFunction extends FunctionPointer { assertEquals(pointer.address() + 20, p2.address()); assertEquals(array.length - 10, p2.limit()); assertEquals(array.length - 10, p2.capacity()); + Pointer p3 = pointer.getPointer(Pointer.class, 20); + assertEquals(pointer.address() + 20, p3.address()); + assertEquals(2 * array.length - 20, p3.limit()); + assertEquals(2 * array.length - 20, p3.capacity()); for (int i = 0; i < array.length; i++) { array[i] = (short)i; @@ -367,6 +375,10 @@ static class TestFunction extends FunctionPointer { assertEquals(pointer.address() + 40, p2.address()); assertEquals(array.length - 10, p2.limit()); assertEquals(array.length - 10, p2.capacity()); + Pointer p3 = pointer.getPointer(Pointer.class, 20); + assertEquals(pointer.address() + 20, p3.address()); + assertEquals(4 * array.length - 20, p3.limit()); + assertEquals(4 * array.length - 20, p3.capacity()); for (int i = 0; i < array.length; i++) { array[i] = i; @@ -455,6 +467,10 @@ static class TestFunction extends FunctionPointer { assertEquals(pointer.address() + 80, p2.address()); assertEquals(array.length - 10, p2.limit()); assertEquals(array.length - 10, p2.capacity()); + Pointer p3 = pointer.getPointer(Pointer.class, 20); + assertEquals(pointer.address() + 20, p3.address()); + assertEquals(8 * array.length - 20, p3.limit()); + assertEquals(8 * array.length - 20, p3.capacity()); for (int i = 0; i < array.length; i++) { array[i] = i; @@ -543,6 +559,10 @@ static class TestFunction extends FunctionPointer { assertEquals(pointer.address() + 40, p2.address()); assertEquals(array.length - 10, p2.limit()); assertEquals(array.length - 10, p2.capacity()); + Pointer p3 = pointer.getPointer(Pointer.class, 20); + assertEquals(pointer.address() + 20, p3.address()); + assertEquals(4 * array.length - 20, p3.limit()); + assertEquals(4 * array.length - 20, p3.capacity()); for (int i = 0; i < array.length; i++) { array[i] = i; @@ -631,6 +651,10 @@ static class TestFunction extends FunctionPointer { assertEquals(pointer.address() + 80, p2.address()); assertEquals(array.length - 10, p2.limit()); assertEquals(array.length - 10, p2.capacity()); + Pointer p3 = pointer.getPointer(Pointer.class, 20); + assertEquals(pointer.address() + 20, p3.address()); + assertEquals(8 * array.length - 20, p3.limit()); + assertEquals(8 * array.length - 20, p3.capacity()); for (int i = 0; i < array.length; i++) { array[i] = i; @@ -719,6 +743,10 @@ static class TestFunction extends FunctionPointer { assertEquals(pointer.address() + 20, p2.address()); assertEquals(array.length - 10, p2.limit()); assertEquals(array.length - 10, p2.capacity()); + Pointer p3 = pointer.getPointer(Pointer.class, 20); + assertEquals(pointer.address() + 20, p3.address()); + assertEquals(2 * array.length - 20, p3.limit()); + assertEquals(2 * array.length - 20, p3.capacity()); for (int i = 0; i < array.length; i++) { array[i] = (char)i; @@ -807,6 +835,10 @@ static class TestFunction extends FunctionPointer { assertEquals(pointer.address() + 10, p2.address()); assertEquals(array.length - 10, p2.limit()); assertEquals(array.length - 10, p2.capacity()); + LongPointer p3 = pointer.getPointer(LongPointer.class, 20); + assertEquals(pointer.address() + 8 * 20, p3.address()); + assertEquals(array.length / 8 - 20, p3.limit()); + assertEquals(array.length / 8 - 20, p3.capacity()); for (int i = 0; i < array.length; i++) { array[i] = i % 2 != 0; @@ -894,6 +926,10 @@ static class TestFunction extends FunctionPointer { assertEquals(pointer.address() + 10 * pointerSize, p2.address()); assertEquals(array.length - 10, p2.limit()); assertEquals(array.length - 10, p2.capacity()); + BytePointer p3 = pointer.getPointer(BytePointer.class, 20); + assertEquals(pointer.address() + 20, p3.address()); + assertEquals(pointerSize * array.length - 20, p3.limit()); + assertEquals(pointerSize * array.length - 20, p3.capacity()); for (int i = 0; i < array.length; i++) { final int j = i;