aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-06-23 06:17:31 +0200
committerSven Gothel <[email protected]>2023-06-23 06:17:31 +0200
commit3f50232fae03c65d7d84a6ca1e2a7b83cefde6ae (patch)
tree444c86223df979c3b2b3148fcb2e4b1f98a692c2
parentdf5b63babeec8a9de0ab22a917bbd6c192a2ac0f (diff)
NIO NativeBuffer, {Element,Pointer}Buffer: Add limit, clear and flip; Arrange wrap/deref arguments equal; Add equal set of absolute get/set methods
Completing API to simplify usage by generated code. All absolute get/set method check arguments itself and against limit(), allow to drop checks in generated code (size).
-rw-r--r--src/java/com/jogamp/common/nio/AbstractBuffer.java47
-rw-r--r--src/java/com/jogamp/common/nio/ElementBuffer.java291
-rw-r--r--src/java/com/jogamp/common/nio/NativeBuffer.java28
-rw-r--r--src/java/com/jogamp/common/nio/PointerBuffer.java113
4 files changed, 385 insertions, 94 deletions
diff --git a/src/java/com/jogamp/common/nio/AbstractBuffer.java b/src/java/com/jogamp/common/nio/AbstractBuffer.java
index b31929b..a09a93e 100644
--- a/src/java/com/jogamp/common/nio/AbstractBuffer.java
+++ b/src/java/com/jogamp/common/nio/AbstractBuffer.java
@@ -31,12 +31,10 @@
*/
package com.jogamp.common.nio;
-import com.jogamp.common.os.*;
-
import java.nio.Buffer;
import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-import java.nio.LongBuffer;
+
+import com.jogamp.common.os.Platform;
/**
* @author Sven Gothel
@@ -50,6 +48,7 @@ public abstract class AbstractBuffer<B extends AbstractBuffer> implements Native
protected final Buffer buffer;
protected final int elementSize;
protected final int capacity;
+ protected int limit;
protected int position;
static {
@@ -70,6 +69,7 @@ public abstract class AbstractBuffer<B extends AbstractBuffer> implements Native
this.buffer = buffer;
this.elementSize = elementSize;
this.capacity = capacity;
+ this.limit = capacity;
this.position = 0;
}
@@ -81,7 +81,17 @@ public abstract class AbstractBuffer<B extends AbstractBuffer> implements Native
@Override
public final int limit() {
- return capacity;
+ return limit;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public final B limit(final int newLim) {
+ if (0 > newLim || newLim >= capacity) {
+ throw new IllegalArgumentException("New limit "+newLim+" out of bounds [0 .. capacity " +capacity()+"].");
+ }
+ limit = newLim;
+ return (B)this;
}
@Override
@@ -94,11 +104,11 @@ public abstract class AbstractBuffer<B extends AbstractBuffer> implements Native
return position;
}
+ @SuppressWarnings("unchecked")
@Override
public final B position(final int newPos) {
- if (0 > newPos || newPos >= capacity) {
- throw new IndexOutOfBoundsException("Sorry to interrupt, but the position "+newPos+" was out of bounds. " +
- "My capacity is "+capacity()+".");
+ if (0 > newPos || newPos > limit) {
+ throw new IllegalArgumentException("New position "+newPos+" out of bounds [0 .. limit " +limit()+"].");
}
position = newPos;
return (B)this;
@@ -106,14 +116,31 @@ public abstract class AbstractBuffer<B extends AbstractBuffer> implements Native
@Override
public final int remaining() {
- return capacity - position;
+ return limit - position;
}
@Override
public final boolean hasRemaining() {
- return position < capacity;
+ return limit > position;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public final B clear() {
+ limit = capacity;
+ position = 0;
+ return (B) this;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public final B flip() {
+ limit = position;
+ position = 0;
+ return (B) this;
}
+ @SuppressWarnings("unchecked")
@Override
public final B rewind() {
position = 0;
diff --git a/src/java/com/jogamp/common/nio/ElementBuffer.java b/src/java/com/jogamp/common/nio/ElementBuffer.java
index e1e47bb..9bb75de 100644
--- a/src/java/com/jogamp/common/nio/ElementBuffer.java
+++ b/src/java/com/jogamp/common/nio/ElementBuffer.java
@@ -29,6 +29,12 @@
package com.jogamp.common.nio;
import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.nio.ShortBuffer;
/**
* Hardware independent container holding an array of linearly aligned elements,
@@ -44,54 +50,55 @@ public class ElementBuffer extends AbstractBuffer<ElementBuffer> {
}
/** Returns a non direct PointerBuffer in native order, having a backup array */
- public static ElementBuffer allocate(final int elementSize, final int elementCount) {
- return new ElementBuffer(elementSize, ByteBuffer.allocate(elementCount * elementSize));
+ public static ElementBuffer allocate(final int elementSize, final int elemCount) {
+ return new ElementBuffer(elementSize, ByteBuffer.allocate(elemCount * elementSize));
}
/** Returns a direct PointerBuffer in native order, w/o backup array */
- public static ElementBuffer allocateDirect(final int elementSize, final int elementCount) {
- return new ElementBuffer(elementSize, Buffers.newDirectByteBuffer(elementCount * elementSize));
+ public static ElementBuffer allocateDirect(final int elementSize, final int elemCount) {
+ return new ElementBuffer(elementSize, Buffers.newDirectByteBuffer(elemCount * elementSize));
}
public static ElementBuffer wrap(final int elementSize, final ByteBuffer src) {
return new ElementBuffer(elementSize, src);
}
- public static ElementBuffer wrap(final int elementSize, final int elementCount, final ByteBuffer src, final int srcByteOffset) {
+ public static ElementBuffer wrap(final int elementSize, final ByteBuffer src, final int srcByteOffset, final int elemCount) {
final int oldPos = src.position();
final int oldLimit = src.limit();
src.position(srcByteOffset);
- src.limit(srcByteOffset + ( elementSize * elementCount ));
+ src.limit(srcByteOffset + ( elementSize * elemCount ));
final ElementBuffer r = new ElementBuffer(elementSize, src.slice().order(src.order())); // slice and duplicate may change byte order
src.position(oldPos);
src.limit(oldLimit);
return r;
}
- public static ElementBuffer derefPointer(final int elementSize, final int elementCount, final long aptr) {
+ public static ElementBuffer derefPointer(final int elementSize, final long aptr, final int elemCount) {
if( 0 == aptr ) {
throw new NullPointerException("aptr is null");
}
- final ByteBuffer bb = Buffers.getDirectByteBuffer(aptr, elementCount * elementSize);
+ final ByteBuffer bb = Buffers.getDirectByteBuffer(aptr, elemCount * elementSize);
if( null == bb ) {
- throw new InternalError("Couldn't dereference aptr 0x"+Long.toHexString(aptr)+", size "+elementCount+" * "+elementSize);
+ throw new InternalError("Couldn't dereference aptr 0x"+Long.toHexString(aptr)+", size "+elemCount+" * "+elementSize);
}
return new ElementBuffer(elementSize, bb);
}
- public static ElementBuffer derefPointer(final int elementSize, final int elementCount, final ByteBuffer ptrSrc, final int ptrSrcByteOffset) {
- return derefPointer(elementSize, elementCount, PointerBuffer.wrap(ptrSrc, ptrSrcByteOffset, 1).get(0));
+ public static ElementBuffer derefPointer(final int elementSize, final ByteBuffer ptrSrc, final int ptrSrcByteOffset, final int elemCount) {
+ return derefPointer(elementSize, PointerBuffer.wrap(ptrSrc, ptrSrcByteOffset, 1).get(0), elemCount);
}
@Override
public final ElementBuffer put(final ElementBuffer src) {
- if (remaining() < src.remaining()) {
- throw new IndexOutOfBoundsException("remaining[this "+remaining()+" < src "+src.remaining()+"], this "+this+", src "+src);
+ final int elemCount = src.remaining();
+ if (remaining() < elemCount) {
+ throw new IndexOutOfBoundsException("remaining[this "+remaining()+" < src "+elemCount+"], this "+this+", src "+src);
}
if( this.elementSize() != src.elementSize() ) {
throw new IllegalArgumentException("Element-Size mismatch source "+src+", dest "+this);
}
- final ByteBuffer tmp = ByteBuffer.allocate(elementSize);
- while (src.hasRemaining()) {
- put( src.get(tmp) );
- }
+ final int srcPos = src.position();
+ put(src.getByteBuffer(), srcPos, position, elemCount);
+ src.position(srcPos + elemCount);
+ position += elemCount;
return this;
}
@@ -107,8 +114,8 @@ public class ElementBuffer extends AbstractBuffer<ElementBuffer> {
* @return slice of this instance's ByteBuffer
*/
public final ByteBuffer slice(final int offset, final int length) {
- if (0 > offset || offset + length > capacity) {
- throw new IndexOutOfBoundsException("idx "+offset+" + elementCount "+length+" not within [0.."+capacity+"), "+this);
+ if (0 > offset || offset + length > limit()) {
+ throw new IndexOutOfBoundsException("idx "+offset+" + elemCount "+length+" not within [0.."+limit()+"), "+this);
}
final ByteBuffer src = getByteBuffer();
final int oldPos = src.position();
@@ -119,64 +126,157 @@ public class ElementBuffer extends AbstractBuffer<ElementBuffer> {
return ref;
}
- /** Absolute get method. Get element-bytes for `elementCount` elements from this buffer at `srcElemPos` into `destElemBytes` at the given element-index `destElemPos` */
- public final ByteBuffer get(final int srcElemPos, final ByteBuffer destElemBytes, final int destElemPos, final int elementCount) {
- if (0 > srcElemPos || srcElemPos + elementCount > capacity || 0 > elementCount ||
- 0 > destElemPos || elementSize * ( destElemPos + elementCount ) > destElemBytes.limit() )
- {
- throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elementCount "+elementCount+
- ", srcCapacity "+capacity+", destLimit "+(destElemBytes.limit()/elementSize)+", "+this);
+ /** Absolute get method. Get element-bytes for `elemCount` elements from this buffer at `srcElemPos` into `destElemBytes` at the given element-index `destElemPos` */
+ public final ByteBuffer get(final int srcElemPos, final ByteBuffer destElemBytes, final int destElemPos, final int elemCount) {
+ if (0 > srcElemPos || srcElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > destElemPos || elementSize * ( destElemPos + elemCount ) > destElemBytes.limit() ) {
+ throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elemCount "+elemCount+
+ ", srcLimit "+limit()+", destLimit "+(destElemBytes.limit()/elementSize)+", "+this);
}
final ByteBuffer srcElemBytes = getByteBuffer();
final int oldSrcLim = srcElemBytes.limit();
- srcElemBytes.position( srcElemPos * elementSize ).limit( ( srcElemPos + elementCount ) * elementSize ); // remaining = elementCount * elementSize
+ srcElemBytes.position( srcElemPos * elementSize ).limit( ( srcElemPos + elemCount ) * elementSize ); // remaining = elemCount * elementSize
final int oldDestPos = destElemBytes.position();
destElemBytes.position( destElemPos * elementSize );
destElemBytes.put(srcElemBytes).position(oldDestPos);
srcElemBytes.limit(oldSrcLim).rewind();
return destElemBytes;
}
-
/** Absolute get method. Copy the element-bytes from this buffer at the given element-index `srcElemPos`, storing them into `destElemBytes`. */
public final ByteBuffer get(final int srcElemPos, final ByteBuffer destElemBytes) {
return get(srcElemPos, destElemBytes, 0, 1);
}
/** Relative get method. Copy the element-bytes at the current position and increment the position by one, storing the element-bytes into `destElemBytes`. */
public final ByteBuffer get(final ByteBuffer destElemBytes) {
- final ByteBuffer r = get(position, destElemBytes);
+ final ByteBuffer r = get(position, destElemBytes, 0, 1);
position++;
return r;
}
/**
- * Relative bulk get method. Copy the element-bytes <code> [ position .. position+length [</code>
- * to the destination array <code> [ destElements[offset] .. destElements[offset+length] [ </code>
- * and increment the position by <code>length</code>. */
- public final ElementBuffer get(final ByteBuffer[] destElements, int offset, int length) {
- if (destElements.length<offset+length) {
- throw new IndexOutOfBoundsException("dest.length "+destElements.length+" < (offset "+offset+" + length "+length+")");
+ * Relative bulk get method. Copy the element-bytes <code> [ position .. position+elemCount [</code>
+ * to the destination array <code> [ destElements[destElemPos] .. destElements[destElemPos+elemCount] [ </code>
+ * and increment the position by <code>elemCount</code>. */
+ public final ElementBuffer get(final ByteBuffer[] destElements, int destElemPos, int elemCount) {
+ if (destElements.length<destElemPos+elemCount) {
+ throw new IndexOutOfBoundsException("dest.length "+destElements.length+" < (offset "+destElemPos+" + length "+elemCount+")");
}
- if (remaining() < length) {
- throw new IndexOutOfBoundsException("remaining "+remaining()+" < length "+length+", this "+this);
+ if (remaining() < elemCount) {
+ throw new IndexOutOfBoundsException("remaining "+remaining()+" < length "+elemCount+", this "+this);
}
- while(length>0) {
- get(position++, destElements[offset++]);
- length--;
+ while(elemCount>0) {
+ get(position++, destElements[destElemPos++]);
+ elemCount--;
}
return this;
}
- /** Absolute put method. Put element-bytes for `elementCount` elements from `srcElemBytes` at `srcElemPos` into this buffer at the given element-index `destElemPos` */
- public final ElementBuffer put(final ByteBuffer srcElemBytes, final int srcElemPos, final int destElemPos, final int elementCount) {
- if (0 > destElemPos || destElemPos + elementCount > capacity || 0 > elementCount ||
- 0 > srcElemPos || elementSize * ( srcElemPos + elementCount ) > srcElemBytes.limit() )
- {
- throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elementCount "+elementCount+
- ", destCapacity "+capacity+", srcLimit "+(srcElemBytes.limit()/elementSize)+", "+this);
+ /** Absolute get method. Get byte-elements for `elemCount` elements from this buffer at `srcElemPos` into `dest` at the given element-index `destElemPos` */
+ public final ElementBuffer get(final int srcElemPos, final byte[] dest, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_BYTE != elementSize ) { throw new UnsupportedOperationException("'byte' type byte-size "+Buffers.SIZEOF_BYTE+" != elementSize "+elementSize+", "+this); }
+ if (0 > srcElemPos || srcElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > destElemPos || destElemPos + elemCount > dest.length ) {
+ throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elemCount "+elemCount+
+ ", srcLimit "+limit()+", destLimit "+dest.length+", "+this);
+ }
+ final ByteBuffer src = getByteBuffer();
+ final int oldPos = src.position();
+ final int oldLim = src.limit();
+ src.position( srcElemPos ).limit( srcElemPos + elemCount ); // remaining = elemCount
+ src.get(dest, destElemPos, elemCount);
+ src.position( oldPos ).limit( oldLim );
+ return this;
+ }
+ /** Absolute get method. Get short-elements for `elemCount` elements from this buffer at `srcElemPos` into `dest` at the given element-index `destElemPos` */
+ public final ElementBuffer get(final int srcElemPos, final short[] dest, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_SHORT != elementSize ) { throw new UnsupportedOperationException("'short' type byte-size "+Buffers.SIZEOF_SHORT+" != elementSize "+elementSize+", "+this); }
+ if (0 > srcElemPos || srcElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > destElemPos || destElemPos + elemCount > dest.length ) {
+ throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elemCount "+elemCount+
+ ", srcLimit "+limit()+", destLimit "+dest.length+", "+this);
+ }
+ final ShortBuffer src = getByteBuffer().asShortBuffer();
+ src.position( srcElemPos ).limit( srcElemPos + elemCount ); // remaining = elemCount
+ src.get(dest, destElemPos, elemCount);
+ return this;
+ }
+ /** Absolute get method. Get char-elements for `elemCount` elements from this buffer at `srcElemPos` into `dest` at the given element-index `destElemPos` */
+ public final ElementBuffer get(final int srcElemPos, final char[] dest, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_CHAR != elementSize ) { throw new UnsupportedOperationException("'char' type byte-size "+Buffers.SIZEOF_CHAR+" != elementSize "+elementSize+", "+this); }
+ if (0 > srcElemPos || srcElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > destElemPos || destElemPos + elemCount > dest.length ) {
+ throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elemCount "+elemCount+
+ ", srcLimit "+limit()+", destLimit "+dest.length+", "+this);
+ }
+ final CharBuffer src = getByteBuffer().asCharBuffer();
+ src.position( srcElemPos ).limit( srcElemPos + elemCount ); // remaining = elemCount
+ src.get(dest, destElemPos, elemCount);
+ return this;
+ }
+ /** Absolute get method. Get int-elements for `elemCount` elements from this buffer at `srcElemPos` into `dest` at the given element-index `destElemPos` */
+ public final ElementBuffer get(final int srcElemPos, final int[] dest, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_INT != elementSize ) { throw new UnsupportedOperationException("'int' type byte-size "+Buffers.SIZEOF_INT+" != elementSize "+elementSize+", "+this); }
+ if (0 > srcElemPos || srcElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > destElemPos || destElemPos + elemCount > dest.length ) {
+ throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elemCount "+elemCount+
+ ", srcLimit "+limit()+", destLimit "+dest.length+", "+this);
+ }
+ final IntBuffer src = getByteBuffer().asIntBuffer();
+ src.position( srcElemPos ).limit( srcElemPos + elemCount ); // remaining = elemCount
+ src.get(dest, destElemPos, elemCount);
+ return this;
+ }
+ /** Absolute get method. Get float-elements for `elemCount` elements from this buffer at `srcElemPos` into `dest` at the given element-index `destElemPos` */
+ public final ElementBuffer get(final int srcElemPos, final float[] dest, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_FLOAT != elementSize ) { throw new UnsupportedOperationException("'float' type byte-size "+Buffers.SIZEOF_FLOAT+" != elementSize "+elementSize+", "+this); }
+ if (0 > srcElemPos || srcElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > destElemPos || destElemPos + elemCount > dest.length ) {
+ throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elemCount "+elemCount+
+ ", srcLimit "+limit()+", destLimit "+dest.length+", "+this);
+ }
+ final FloatBuffer src = getByteBuffer().asFloatBuffer();
+ src.position( srcElemPos ).limit( srcElemPos + elemCount ); // remaining = elemCount
+ src.get(dest, destElemPos, elemCount);
+ return this;
+ }
+ /** Absolute get method. Get long-elements for `elemCount` elements from this buffer at `srcElemPos` into `dest` at the given element-index `destElemPos` */
+ public final ElementBuffer get(final int srcElemPos, final long[] dest, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_LONG != elementSize ) { throw new UnsupportedOperationException("'long' type byte-size "+Buffers.SIZEOF_LONG+" != elementSize "+elementSize+", "+this); }
+ if (0 > srcElemPos || srcElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > destElemPos || destElemPos + elemCount > dest.length ) {
+ throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elemCount "+elemCount+
+ ", srcLimit "+limit()+", destLimit "+dest.length+", "+this);
+ }
+ final LongBuffer src = getByteBuffer().asLongBuffer();
+ src.position( srcElemPos ).limit( srcElemPos + elemCount ); // remaining = elemCount
+ src.get(dest, destElemPos, elemCount);
+ return this;
+ }
+ /** Absolute get method. Get double-elements for `elemCount` elements from this buffer at `srcElemPos` into `dest` at the given element-index `destElemPos` */
+ public final ElementBuffer get(final int srcElemPos, final double[] dest, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_DOUBLE != elementSize ) { throw new UnsupportedOperationException("'double' type byte-size "+Buffers.SIZEOF_DOUBLE+" != elementSize "+elementSize+", "+this); }
+ if (0 > srcElemPos || srcElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > destElemPos || destElemPos + elemCount > dest.length ) {
+ throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elemCount "+elemCount+
+ ", srcLimit "+limit()+", destLimit "+dest.length+", "+this);
+ }
+ final DoubleBuffer src = getByteBuffer().asDoubleBuffer();
+ src.position( srcElemPos ).limit( srcElemPos + elemCount ); // remaining = elemCount
+ src.get(dest, destElemPos, elemCount);
+ return this;
+ }
+
+
+ /** Absolute put method. Put element-bytes for `elemCount` elements from `srcElemBytes` at `srcElemPos` into this buffer at the given element-index `destElemPos` */
+ public final ElementBuffer put(final ByteBuffer srcElemBytes, final int srcElemPos, final int destElemPos, final int elemCount) {
+ if (0 > destElemPos || destElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > srcElemPos || elementSize * ( srcElemPos + elemCount ) > srcElemBytes.limit() ) {
+ throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elemCount "+elemCount+
+ ", destLimit "+limit()+", srcLimit "+(srcElemBytes.limit()/elementSize)+", "+this);
}
final ByteBuffer destElemBytes = getByteBuffer();
final int oldSrcPos = srcElemBytes.position();
final int oldSrcLim = srcElemBytes.limit();
- srcElemBytes.position( srcElemPos * elementSize ).limit( ( srcElemPos + elementCount ) * elementSize ); // remaining = elementCount * elementSize
+ srcElemBytes.position( srcElemPos * elementSize ).limit( ( srcElemPos + elemCount ) * elementSize ); // remaining = elemCount * elementSize
destElemBytes.position( elementSize * destElemPos );
destElemBytes.put(srcElemBytes).rewind();
srcElemBytes.limit(oldSrcLim).position(oldSrcPos);
@@ -209,6 +309,101 @@ public class ElementBuffer extends AbstractBuffer<ElementBuffer> {
return this;
}
+ /** Absolute put method. Put byte-elements for `elemCount` elements from `src` at `srcElemPos` into this buffer at the given element-index `destElemPos` */
+ public final ElementBuffer put(final byte[] src, final int srcElemPos, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_BYTE != elementSize ) { throw new UnsupportedOperationException("'byte' type byte-size "+Buffers.SIZEOF_BYTE+" != elementSize "+elementSize+", "+this); }
+ if (0 > destElemPos || destElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > srcElemPos || srcElemPos + elemCount > src.length ) {
+ throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elemCount "+elemCount+
+ ", destLimit "+limit()+", srcLimit "+src.length+", "+this);
+ }
+ final ByteBuffer dest = getByteBuffer();
+ final int oldPos = dest.position();
+ final int oldLim = dest.limit();
+ dest.position( destElemPos ).limit( destElemPos + elemCount ); // remaining = elemCount
+ dest.put(src, srcElemPos, elemCount);
+ dest.position( oldPos ).limit( oldLim );
+ return this;
+ }
+ /** Absolute put method. Put short-elements for `elemCount` elements from `src` at `srcElemPos` into this buffer at the given element-index `destElemPos` */
+ public final ElementBuffer put(final short[] src, final int srcElemPos, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_SHORT != elementSize ) { throw new UnsupportedOperationException("'short' type byte-size "+Buffers.SIZEOF_SHORT+" != elementSize "+elementSize+", "+this); }
+ if (0 > destElemPos || destElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > srcElemPos || srcElemPos + elemCount > src.length ) {
+ throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elemCount "+elemCount+
+ ", destLimit "+limit()+", srcLimit "+src.length+", "+this);
+ }
+ final ShortBuffer dest = getByteBuffer().asShortBuffer();
+ dest.position( destElemPos ).limit( destElemPos + elemCount ); // remaining = elemCount
+ dest.put(src, srcElemPos, elemCount);
+ return this;
+ }
+ /** Absolute put method. Put char-elements for `elemCount` elements from `src` at `srcElemPos` into this buffer at the given element-index `destElemPos` */
+ public final ElementBuffer put(final char[] src, final int srcElemPos, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_CHAR != elementSize ) { throw new UnsupportedOperationException("'char' type byte-size "+Buffers.SIZEOF_CHAR+" != elementSize "+elementSize+", "+this); }
+ if (0 > destElemPos || destElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > srcElemPos || srcElemPos + elemCount > src.length ) {
+ throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elemCount "+elemCount+
+ ", destLimit "+limit()+", srcLimit "+src.length+", "+this);
+ }
+ final CharBuffer dest = getByteBuffer().asCharBuffer();
+ dest.position( destElemPos ).limit( destElemPos + elemCount ); // remaining = elemCount
+ dest.put(src, srcElemPos, elemCount);
+ return this;
+ }
+ /** Absolute put method. Put int-elements for `elemCount` elements from `src` at `srcElemPos` into this buffer at the given element-index `destElemPos` */
+ public final ElementBuffer put(final int[] src, final int srcElemPos, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_INT != elementSize ) { throw new UnsupportedOperationException("'int' type byte-size "+Buffers.SIZEOF_INT+" != elementSize "+elementSize+", "+this); }
+ if (0 > destElemPos || destElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > srcElemPos || srcElemPos + elemCount > src.length ) {
+ throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elemCount "+elemCount+
+ ", destLimit "+limit()+", srcLimit "+src.length+", "+this);
+ }
+ final IntBuffer dest = getByteBuffer().asIntBuffer();
+ dest.position( destElemPos ).limit( destElemPos + elemCount ); // remaining = elemCount
+ dest.put(src, srcElemPos, elemCount);
+ return this;
+ }
+ /** Absolute put method. Put float-elements for `elemCount` elements from `src` at `srcElemPos` into this buffer at the given element-index `destElemPos` */
+ public final ElementBuffer put(final float[] src, final int srcElemPos, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_FLOAT != elementSize ) { throw new UnsupportedOperationException("'float' type byte-size "+Buffers.SIZEOF_FLOAT+" != elementSize "+elementSize+", "+this); }
+ if (0 > destElemPos || destElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > srcElemPos || srcElemPos + elemCount > src.length ) {
+ throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elemCount "+elemCount+
+ ", destLimit "+limit()+", srcLimit "+src.length+", "+this);
+ }
+ final FloatBuffer dest = getByteBuffer().asFloatBuffer();
+ dest.position( destElemPos ).limit( destElemPos + elemCount ); // remaining = elemCount
+ dest.put(src, srcElemPos, elemCount);
+ return this;
+ }
+ /** Absolute put method. Put long-elements for `elemCount` elements from `src` at `srcElemPos` into this buffer at the given element-index `destElemPos` */
+ public final ElementBuffer put(final long[] src, final int srcElemPos, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_LONG != elementSize ) { throw new UnsupportedOperationException("'long' type byte-size "+Buffers.SIZEOF_LONG+" != elementSize "+elementSize+", "+this); }
+ if (0 > destElemPos || destElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > srcElemPos || srcElemPos + elemCount > src.length ) {
+ throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elemCount "+elemCount+
+ ", destLimit "+limit()+", srcLimit "+src.length+", "+this);
+ }
+ final LongBuffer dest = getByteBuffer().asLongBuffer();
+ dest.position( destElemPos ).limit( destElemPos + elemCount ); // remaining = elemCount
+ dest.put(src, srcElemPos, elemCount);
+ return this;
+ }
+ /** Absolute put method. Put double-elements for `elemCount` elements from `src` at `srcElemPos` into this buffer at the given element-index `destElemPos` */
+ public final ElementBuffer put(final double[] src, final int srcElemPos, final int destElemPos, final int elemCount) {
+ if( Buffers.SIZEOF_DOUBLE != elementSize ) { throw new UnsupportedOperationException("'double' type byte-size "+Buffers.SIZEOF_DOUBLE+" != elementSize "+elementSize+", "+this); }
+ if (0 > destElemPos || destElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > srcElemPos || srcElemPos + elemCount > src.length ) {
+ throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elemCount "+elemCount+
+ ", destLimit "+limit()+", srcLimit "+src.length+", "+this);
+ }
+ final DoubleBuffer dest = getByteBuffer().asDoubleBuffer();
+ dest.position( destElemPos ).limit( destElemPos + elemCount ); // remaining = elemCount
+ dest.put(src, srcElemPos, elemCount);
+ return this;
+ }
+
@Override
public String toString() {
return "ElementBuffer"+toSubString();
diff --git a/src/java/com/jogamp/common/nio/NativeBuffer.java b/src/java/com/jogamp/common/nio/NativeBuffer.java
index 5ee6af8..76f792e 100644
--- a/src/java/com/jogamp/common/nio/NativeBuffer.java
+++ b/src/java/com/jogamp/common/nio/NativeBuffer.java
@@ -36,27 +36,51 @@ import java.nio.ByteBuffer;
/**
* Hardware independent container for various kinds of buffers.
- *
+ * <p>
+ * Implementations follow {@link Buffer} semantics, e.g.
+ * <pre>
+ * 0 <= position <= limit <= capacity
+ * </pre>
+ * </p>
* @author Sven Gothel
* @author Michael Bien
*/
@SuppressWarnings("rawtypes")
public interface NativeBuffer<B extends NativeBuffer> {
+ /** Returns byte size of one element */
public int elementSize();
+ /** Returns this buffer's element limit. */
public int limit();
+ /** Sets this buffer's element limit. */
+ public B limit(int newLim);
+
+ /** Returns this buffer's element capacity. */
public int capacity();
+ /** Returns this buffer's element position. */
public int position();
+ /** Sets this buffer's element position. */
public B position(int newPos);
+ /** Returns this buffer's remaining element, i.e. limit - position. */
public int remaining();
+ /** Returns {@link #remaining()} > 0 */
public boolean hasRemaining();
+ /** Sets the limit to the capacity and the position to zero. */
+ public B clear();
+
+ /** Sets the limit to the current position and the position to zero. */
+ public B flip();
+
+ /** Sets the position to zero. */
+ public B rewind();
+
/**
* @return true if this buffer has a primitive backup array, otherwise false
*/
@@ -100,8 +124,6 @@ public interface NativeBuffer<B extends NativeBuffer> {
**/
public void storeDirectAddress(final ByteBuffer directDest, final int destOffset);
- public B rewind();
-
/**
* Relative bulk get method. Copy the source values <code> src[position .. capacity] [</code>
* to this buffer and increment the position by <code>capacity-position</code>.
diff --git a/src/java/com/jogamp/common/nio/PointerBuffer.java b/src/java/com/jogamp/common/nio/PointerBuffer.java
index 2a2cdd9..c9499d7 100644
--- a/src/java/com/jogamp/common/nio/PointerBuffer.java
+++ b/src/java/com/jogamp/common/nio/PointerBuffer.java
@@ -96,23 +96,37 @@ public class PointerBuffer extends AbstractBuffer<PointerBuffer> {
return create(src);
}
/**
- * Wraps given {@link ByteBuffer} {@code src} @ {@code srcByteOffset} to contain {@code elementCount} pointers.
+ * Wraps given {@link ByteBuffer} {@code src} @ {@code srcByteOffset} to contain {@code elemCount} pointers.
* @param src
* @param srcByteOffset
- * @param elementCount
+ * @param elemCount
* @return
*/
- public static PointerBuffer wrap(final ByteBuffer src, final int srcByteOffset, final int elementCount) {
+ public static PointerBuffer wrap(final ByteBuffer src, final int srcByteOffset, final int elemCount) {
final int oldPos = src.position();
final int oldLimit = src.limit();
src.position(srcByteOffset);
- src.limit(srcByteOffset + POINTER_SIZE*elementCount);
+ src.limit(srcByteOffset + POINTER_SIZE*elemCount);
final ByteBuffer ref = src.slice().order(src.order()); // slice and duplicate may change byte order
src.position(oldPos);
src.limit(oldLimit);
return create(ref);
}
+ public static PointerBuffer derefPointer(final long aptr, final int elemCount) {
+ if( 0 == aptr ) {
+ throw new NullPointerException("aptr is null");
+ }
+ final ByteBuffer bb = Buffers.getDirectByteBuffer(aptr, elemCount * POINTER_SIZE);
+ if( null == bb ) {
+ throw new InternalError("Couldn't dereference aptr 0x"+Long.toHexString(aptr)+", size "+elemCount+" * "+POINTER_SIZE);
+ }
+ return create(bb);
+ }
+ public static PointerBuffer derefPointer(final ByteBuffer ptrSrc, final int ptrSrcByteOffset, final int elemCount) {
+ return derefPointer(wrap(ptrSrc, ptrSrcByteOffset, 1).get(0), elemCount);
+ }
+
/**
* @return new PointerBuffer sharing the same buffer data of this instance (identity),
* but having an independent position.
@@ -163,8 +177,8 @@ public class PointerBuffer extends AbstractBuffer<PointerBuffer> {
/** Absolute get method. Get the pointer value at the given index */
public final long get(final int idx) {
- if (0 > idx || idx >= capacity) {
- throw new IndexOutOfBoundsException("idx "+idx+" not within [0.."+capacity+"), "+this);
+ if (0 > idx || idx >= limit()) {
+ throw new IndexOutOfBoundsException("idx "+idx+" not within [0.."+limit()+"), "+this);
}
if (Platform.is32Bit()) {
return ((IntBuffer) buffer).get(idx) & 0x00000000FFFFFFFFL;
@@ -178,28 +192,45 @@ public class PointerBuffer extends AbstractBuffer<PointerBuffer> {
position++;
return r;
}
- /**
- * Relative bulk get method. Copy the pointer values <code> [ position .. position+length [</code>
- * to the destination array <code> [ dest[offset] .. dest[offset+length] [ </code>
- * and increment the position by <code>length</code>. */
- public final PointerBuffer get(final long[] dest, int offset, int length) {
- if (dest.length<offset+length) {
- throw new IndexOutOfBoundsException("dest.length "+dest.length+" < (offset "+offset+" + length "+length+")");
- }
- if (remaining() < length) {
- throw new IndexOutOfBoundsException("remaining "+remaining()+" < length "+length+", this "+this);
+
+ /** Absolute get method. Get element-bytes for `elemCount` elements from this buffer at `srcElemPos` into `dest` at the given element-index `destElemPos` */
+ public final PointerBuffer get(final int srcElemPos, final long[] dest, final int destElemPos, final int elemCount) {
+ if (0 > srcElemPos || srcElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > destElemPos || destElemPos + elemCount > dest.length )
+ {
+ throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elemCount "+elemCount+
+ ", srcLimit "+limit()+", destLimit "+dest.length+", "+this);
}
- while(length>0) {
- dest[offset++] = get(position++);
- length--;
+ if (Platform.is32Bit()) {
+ final IntBuffer src = (IntBuffer) buffer;
+ for(int i=0; i<elemCount; ++i) {
+ dest[destElemPos+i] = src.get(srcElemPos+i) & 0x00000000FFFFFFFFL;
+ }
+ } else {
+ final LongBuffer src = (LongBuffer) buffer;
+ final int oldSrcLim = src.limit();
+ final int oldSrcPos = src.position();
+ src.position( srcElemPos ).limit( srcElemPos + elemCount ); // remaining = elemCount
+ src.get(dest, destElemPos, elemCount);
+ src.limit(oldSrcLim).position(oldSrcPos);
}
return this;
}
+ /**
+ * Relative bulk get method. Copy the pointer values <code> [ position .. position+elemCount [</code>
+ * to the destination array <code> [ dest[destElemPos] .. dest[destElemPos+elemCount] [ </code>
+ * and increment the position by <code>elemCount</code>. */
+ public final PointerBuffer get(final long[] dest, final int destElemPos, final int elemCount) {
+ get(position, dest, destElemPos, elemCount);
+ position += elemCount;
+ return this;
+ }
+
/** Absolute put method. Put the pointer value at the given index */
public final PointerBuffer put(final int idx, final long v) {
- if (0 > idx || idx >= capacity) {
- throw new IndexOutOfBoundsException("idx "+idx+" not within [0.."+capacity+"), "+this);
+ if (0 > idx || idx >= limit()) {
+ throw new IndexOutOfBoundsException("idx "+idx+" not within [0.."+limit()+"), "+this);
}
if (Platform.is32Bit()) {
((IntBuffer) buffer).put(idx, (int) v);
@@ -214,22 +245,38 @@ public class PointerBuffer extends AbstractBuffer<PointerBuffer> {
position++;
return this;
}
- /**
- * Relative bulk put method. Put the pointer values <code> [ src[offset] .. src[offset+length] [</code>
- * at the current position and increment the position by <code>length</code>. */
- public final PointerBuffer put(final long[] src, int offset, int length) {
- if (src.length<offset+length) {
- throw new IndexOutOfBoundsException("src.length "+src.length+" < (offset "+offset+" + length "+length+")");
- }
- if (remaining() < length) {
- throw new IndexOutOfBoundsException("remaining "+remaining()+" < length "+length+", this "+this);
+
+ /** Absolute put method. Put element-bytes for `elemCount` elements from `src` at `srcElemPos` into this buffer at the given element-index `destElemPos` */
+ public final PointerBuffer put(final long[] src, final int srcElemPos, final int destElemPos, final int elemCount) {
+ if (0 > destElemPos || destElemPos + elemCount > limit() || 0 > elemCount ||
+ 0 > srcElemPos || srcElemPos + elemCount > src.length )
+ {
+ throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elemCount "+elemCount+
+ ", destLimit "+limit()+", srcLimit "+src.length+", "+this);
}
- while(length>0) {
- put(position++, src[offset++]);
- length--;
+ if (Platform.is32Bit()) {
+ final IntBuffer dest = (IntBuffer) buffer;
+ for(int i=0; i<elemCount; ++i) {
+ dest.put(destElemPos+i, (int) src[srcElemPos+i]);
+ }
+ } else {
+ final LongBuffer dest = (LongBuffer) buffer;
+ final int oldDestLim = dest.limit();
+ final int oldDestPos = dest.position();
+ dest.position( destElemPos ).limit( destElemPos + elemCount ); // remaining = elemCount
+ dest.put(src, srcElemPos, elemCount); // remaining = elemCount
+ dest.limit(oldDestLim).position(oldDestPos);
}
return this;
}
+ /**
+ * Relative bulk put method. Put the pointer values <code> [ src[srcElemPos] .. src[srcElemPos+elemCount] [</code>
+ * at the current position and increment the position by <code>elemCount</code>. */
+ public final PointerBuffer put(final long[] src, final int srcElemPos, final int elemCount) {
+ put(src, srcElemPos, position, elemCount);
+ position += elemCount;
+ return this;
+ }
/** Put the address of the given direct Buffer at the given position
of this pointer array.