From 9239a178822dd939df3fe126f044bf8c29b3700a Mon Sep 17 00:00:00 2001 From: Samuel Audet Date: Wed, 30 Oct 2019 15:33:55 +0900 Subject: [PATCH] * Provide `ByteIndexer` with value getters and setters for unsigned `byte` or `short`, `half`, `bfloat16`, and `boolean` types as well --- CHANGELOG.md | 1 + .../javacpp/indexer/ByteArrayIndexer.java | 80 +++++++++++++++++++ .../javacpp/indexer/ByteBufferIndexer.java | 40 ++++++++++ .../bytedeco/javacpp/indexer/ByteIndexer.java | 25 ++++++ .../javacpp/indexer/ByteRawIndexer.java | 40 ++++++++++ .../org/bytedeco/javacpp/IndexerTest.java | 16 +++- 6 files changed, 201 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8eea76055..a4777704c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ + * Provide `ByteIndexer` with value getters and setters for unsigned `byte` or `short`, `half`, `bfloat16`, and `boolean` types as well * Introduce `PointerScope.extend()` to prevent deallocation on the next call to `close()` * Make `Generator` avoid ambiguous conversion errors from `UniquePtrAdapter` to `std::unique_ptr` ([pull #353](https://github.com/bytedeco/javacpp/pull/353)) * Fix `Parser` using fully qualified names for `@Name` annotations of nested classes ([issue #352](https://github.com/bytedeco/javacpp/issues/352)) diff --git a/src/main/java/org/bytedeco/javacpp/indexer/ByteArrayIndexer.java b/src/main/java/org/bytedeco/javacpp/indexer/ByteArrayIndexer.java index 988b01c1d..80eb33605 100644 --- a/src/main/java/org/bytedeco/javacpp/indexer/ByteArrayIndexer.java +++ b/src/main/java/org/bytedeco/javacpp/indexer/ByteArrayIndexer.java @@ -227,5 +227,85 @@ ByteBuffer getBuffer() { return this; } + @Override public int getUByte(long i) { + if (RAW != null) { + return RAW.getByte(array, checkIndex(i, array.length - 1)) & 0xFF; + } else { + return getBuffer().get((int)i) & 0xFF; + } + } + @Override public ByteIndexer putUByte(long i, int b) { + if (RAW != null) { + RAW.putByte(array, checkIndex(i, array.length - 1), (byte)b); + } else { + getBuffer().put((int)i, (byte)b); + } + return this; + } + + @Override public int getUShort(long i) { + if (RAW != null) { + return RAW.getShort(array, checkIndex(i, array.length - 1)) & 0xFFFF; + } else { + return getBuffer().getShort((int)i) & 0xFFFF; + } + } + @Override public ByteIndexer putUShort(long i, int s) { + if (RAW != null) { + RAW.putShort(array, checkIndex(i, array.length - 1), (short)s); + } else { + getBuffer().putShort((int)i, (short)s); + } + return this; + } + + @Override public float getHalf(long i) { + if (RAW != null) { + return HalfIndexer.toFloat(RAW.getShort(array, checkIndex(i, array.length - 1))); + } else { + return HalfIndexer.toFloat(getBuffer().getShort((int)i)); + } + } + @Override public ByteIndexer putHalf(long i, float h) { + if (RAW != null) { + RAW.putShort(array, checkIndex(i, array.length - 1), (short)HalfIndexer.fromFloat(h)); + } else { + getBuffer().putShort((int)i, (short)HalfIndexer.fromFloat(h)); + } + return this; + } + + @Override public float getBfloat16(long i) { + if (RAW != null) { + return Bfloat16Indexer.toFloat(RAW.getShort(array, checkIndex(i, array.length - 1))); + } else { + return Bfloat16Indexer.toFloat(getBuffer().getShort((int)i)); + } + } + @Override public ByteIndexer putBfloat16(long i, float h) { + if (RAW != null) { + RAW.putShort(array, checkIndex(i, array.length - 1), (short)Bfloat16Indexer.fromFloat(h)); + } else { + getBuffer().putShort((int)i, (short)Bfloat16Indexer.fromFloat(h)); + } + return this; + } + + @Override public boolean getBoolean(long i) { + if (RAW != null) { + return RAW.getByte(array, checkIndex(i, array.length - 1)) != 0; + } else { + return getBuffer().get((int)i) != 0; + } + } + @Override public ByteIndexer putBoolean(long i, boolean b) { + if (RAW != null) { + RAW.putByte(array, checkIndex(i, array.length - 1), b ? (byte)1 : (byte)0); + } else { + getBuffer().put((int)i, b ? (byte)1 : (byte)0); + } + return this; + } + @Override public void release() { array = null; } } diff --git a/src/main/java/org/bytedeco/javacpp/indexer/ByteBufferIndexer.java b/src/main/java/org/bytedeco/javacpp/indexer/ByteBufferIndexer.java index b86b1a7d9..6638c40c8 100644 --- a/src/main/java/org/bytedeco/javacpp/indexer/ByteBufferIndexer.java +++ b/src/main/java/org/bytedeco/javacpp/indexer/ByteBufferIndexer.java @@ -168,5 +168,45 @@ public ByteBufferIndexer(ByteBuffer buffer, long[] sizes, long[] strides) { return this; } + @Override public int getUByte(long i) { + return buffer.get((int)i) & 0xFF; + } + @Override public ByteIndexer putUByte(long i, int b) { + buffer.put((int)i, (byte)b); + return this; + } + + @Override public int getUShort(long i) { + return buffer.getShort((int)i) & 0xFFFF; + } + @Override public ByteIndexer putUShort(long i, int s) { + buffer.putShort((int)i, (short)s); + return this; + } + + @Override public float getHalf(long i) { + return HalfIndexer.toFloat(buffer.getShort((int)i)); + } + @Override public ByteIndexer putHalf(long i, float h) { + buffer.putShort((int)i, (short)HalfIndexer.fromFloat(h)); + return this; + } + + @Override public float getBfloat16(long i) { + return Bfloat16Indexer.toFloat(buffer.getShort((int)i)); + } + @Override public ByteIndexer putBfloat16(long i, float h) { + buffer.putShort((int)i, (short)Bfloat16Indexer.fromFloat(h)); + return this; + } + + @Override public boolean getBoolean(long i) { + return buffer.get((int)i) != 0; + } + @Override public ByteIndexer putBoolean(long i, boolean b) { + buffer.put((int)i, b ? (byte)1 : (byte)0); + return this; + } + @Override public void release() { buffer = null; } } diff --git a/src/main/java/org/bytedeco/javacpp/indexer/ByteIndexer.java b/src/main/java/org/bytedeco/javacpp/indexer/ByteIndexer.java index 6ed1f0876..e46d7b1a1 100644 --- a/src/main/java/org/bytedeco/javacpp/indexer/ByteIndexer.java +++ b/src/main/java/org/bytedeco/javacpp/indexer/ByteIndexer.java @@ -172,6 +172,31 @@ public static ByteIndexer create(final BytePointer pointer, long[] sizes, long[] /** Sets the {@code char} value at {@code array/buffer[i]} */ public abstract ByteIndexer putChar(long i, char c); + /** Returns the {@code byte} value at {@code array/buffer[i]}, treated as unsigned */ + public abstract int getUByte(long i); + /** Sets the {@code byte} value at {@code array/buffer[i]}, treated as unsigned */ + public abstract ByteIndexer putUByte(long i, int b); + + /** Returns the {@code short} value at {@code array/buffer[i]}, treated as unsigned */ + public abstract int getUShort(long i); + /** Sets the {@code short} value at {@code array/buffer[i]}, treated as unsigned */ + public abstract ByteIndexer putUShort(long i, int s); + + /** Returns the {@code short} value at {@code array/buffer[i]}, treated as half-precision float */ + public abstract float getHalf(long i); + /** Sets the {@code short} value at {@code array/buffer[i]}, treated as half-precision float */ + public abstract ByteIndexer putHalf(long i, float h); + + /** Returns the {@code short} value at {@code array/buffer[i]}, treated as bfloat16 */ + public abstract float getBfloat16(long i); + /** Sets the {@code short} value at {@code array/buffer[i]}, treated as bfloat16 */ + public abstract ByteIndexer putBfloat16(long i, float h); + + /** Returns the {@code boolean} value at {@code array/buffer[i]} */ + public abstract boolean getBoolean(long i); + /** Sets the {@code boolean} value at {@code array/buffer[i]} */ + public abstract ByteIndexer putBoolean(long i, boolean b); + @Override public double getDouble(long... indices) { return get(indices); } @Override public ByteIndexer putDouble(long[] indices, double b) { return put(indices, (byte)b); } } diff --git a/src/main/java/org/bytedeco/javacpp/indexer/ByteRawIndexer.java b/src/main/java/org/bytedeco/javacpp/indexer/ByteRawIndexer.java index 56aef9dee..297ffea8c 100644 --- a/src/main/java/org/bytedeco/javacpp/indexer/ByteRawIndexer.java +++ b/src/main/java/org/bytedeco/javacpp/indexer/ByteRawIndexer.java @@ -174,5 +174,45 @@ public ByteRawIndexer(BytePointer pointer, long[] sizes, long[] strides) { return this; } + @Override public int getUByte(long i) { + return RAW.getByte(base + checkIndex(i, size - 1)) & 0xFF; + } + @Override public ByteIndexer putUByte(long i, int b) { + RAW.putByte(base + checkIndex(i, size - 1), (byte)b); + return this; + } + + @Override public int getUShort(long i) { + return RAW.getShort(base + checkIndex(i, size - 1)) & 0xFFFF; + } + @Override public ByteIndexer putUShort(long i, int s) { + RAW.putShort(base + checkIndex(i, size - 1), (short)s); + return this; + } + + @Override public float getHalf(long i) { + return HalfIndexer.toFloat(RAW.getShort(base + checkIndex(i, size - 1))); + } + @Override public ByteIndexer putHalf(long i, float h) { + RAW.putShort(base + checkIndex(i, size - 1), (short)HalfIndexer.fromFloat(h)); + return this; + } + + @Override public float getBfloat16(long i) { + return Bfloat16Indexer.toFloat(RAW.getShort(base + checkIndex(i, size - 1))); + } + @Override public ByteIndexer putBfloat16(long i, float h) { + RAW.putShort(base + checkIndex(i, size - 1), (short)Bfloat16Indexer.fromFloat(h)); + return this; + } + + @Override public boolean getBoolean(long i) { + return RAW.getByte(base + checkIndex(i, size - 1)) != 0; + } + @Override public ByteIndexer putBoolean(long i, boolean b) { + RAW.putByte(base + checkIndex(i, size - 1), b ? (byte)1 : (byte)0); + return this; + } + @Override public void release() { pointer = null; } } diff --git a/src/test/java/org/bytedeco/javacpp/IndexerTest.java b/src/test/java/org/bytedeco/javacpp/IndexerTest.java index 9832866fa..8b84af317 100644 --- a/src/test/java/org/bytedeco/javacpp/IndexerTest.java +++ b/src/test/java/org/bytedeco/javacpp/IndexerTest.java @@ -124,6 +124,7 @@ public class IndexerTest { fail("IndexOutOfBoundsException should have been thrown."); } catch (IndexOutOfBoundsException e) { } + byte byteValue = 0x02; short shortValue = 0x0203; int intValue = 0x02030405; long longValue = 0x0203040506070809L; @@ -134,6 +135,9 @@ public class IndexerTest { } float floatValue = Float.intBitsToFloat(intValue); double doubleValue = Double.longBitsToDouble(longValue); + float halfValue = HalfIndexer.toFloat(shortValue); + float bfloat16Value = Bfloat16Indexer.toFloat(shortValue); + boolean booleanValue = byteValue != 0; assertEquals(shortValue, arrayIndexer.getShort(1)); assertEquals(intValue, arrayIndexer.getInt(1)); @@ -141,6 +145,11 @@ public class IndexerTest { assertEquals(floatValue, arrayIndexer.getFloat(1), 0.0); assertEquals(doubleValue, arrayIndexer.getDouble(1), 0.0); assertEquals(shortValue, arrayIndexer.getChar(1)); + assertEquals(byteValue, arrayIndexer.getUByte(1)); + assertEquals(shortValue, arrayIndexer.getUShort(1)); + assertEquals(halfValue, arrayIndexer.getHalf(1), 0.0); + assertEquals(bfloat16Value, arrayIndexer.getBfloat16(1), 0.0); + assertEquals(booleanValue, arrayIndexer.getBoolean(1)); System.out.println("arrayIndexer" + arrayIndexer); System.out.println("directIndexer" + directIndexer); @@ -157,7 +166,12 @@ public class IndexerTest { assertEquals(longValue, directIndexer.getLong(1)); assertEquals(floatValue, directIndexer.getFloat(1), 0.0); assertEquals(doubleValue, directIndexer.getDouble(1), 0.0); - assertEquals((char)shortValue, directIndexer.getChar(1)); + assertEquals(shortValue, directIndexer.getChar(1)); + assertEquals(byteValue, directIndexer.getUByte(1)); + assertEquals(shortValue, directIndexer.getUShort(1)); + assertEquals(halfValue, directIndexer.getHalf(1), 0.0); + assertEquals(bfloat16Value, directIndexer.getBfloat16(1), 0.0); + assertEquals(booleanValue, directIndexer.getBoolean(1)); System.gc();