diff options
author | Sven Gothel <[email protected]> | 2023-06-23 06:17:31 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-06-23 06:17:31 +0200 |
commit | 3f50232fae03c65d7d84a6ca1e2a7b83cefde6ae (patch) | |
tree | 444c86223df979c3b2b3148fcb2e4b1f98a692c2 | |
parent | df5b63babeec8a9de0ab22a917bbd6c192a2ac0f (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.java | 47 | ||||
-rw-r--r-- | src/java/com/jogamp/common/nio/ElementBuffer.java | 291 | ||||
-rw-r--r-- | src/java/com/jogamp/common/nio/NativeBuffer.java | 28 | ||||
-rw-r--r-- | src/java/com/jogamp/common/nio/PointerBuffer.java | 113 |
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. |