GlueGen: src/java/com/jogamp/common/nio/PointerBuffer.java Source File

GlueGen v2.6.0-rc-20250722 GlueGen, Native Binding Generator for Java™ (public API).

PointerBuffer.java
Go to the documentation of this file.
1/**
2 * Copyright 2010-2023 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29/*
30 * Created on Saturday, March 27 2010 11:55
31 */
32package com.jogamp.common.nio;
33
34import java.nio.Buffer;
35import java.nio.ByteBuffer;
36import java.nio.IntBuffer;
37import java.nio.LongBuffer;
38
39import com.jogamp.common.os.Platform;
40import com.jogamp.common.util.LongObjectHashMap;
41
42/**
43 * Hardware independent container holding an array of native pointer,
44 * while its {@link #getDirectBufferAddress()} is-a pointer-pointer type value.
45 * <p>
46 * An instance maps an array of pointers of referenced Buffer objects, represented as longs.
47 * </p>
48 * <p>
49 * The native values (NIO direct ByteBuffer) might be 32bit or 64bit wide,
50 * depending of the CPU pointer width, see {@link #POINTER_SIZE}.
51 * </p>
52 * @author Sven Gothel
53 * @author Michael Bien
54 */
55 public class PointerBuffer extends AbstractBuffer<PointerBuffer> {
56 protected LongObjectHashMap dataMap = null;
57
58 /** no backup array, use for direct usage only */
59 static PointerBuffer create(final ByteBuffer bb) {
60 return Platform.is32Bit() ? new PointerBuffer( bb.asIntBuffer() ) : new PointerBuffer( bb.asLongBuffer() );
61 }
62
63 /** supports backup array */
64 PointerBuffer(final IntBuffer b) {
65 super(b, POINTER_SIZE, b.capacity());
66 }
67
68 /** supports backup array */
69 PointerBuffer(final LongBuffer b) {
70 super(b, POINTER_SIZE, b.capacity());
71 }
72
73 private final void validateDataMap() {
74 if(null == dataMap) {
75 dataMap = new LongObjectHashMap();
76 dataMap.setKeyNotFoundValue(null);
77 }
78 }
79
80 /** Returns a non direct PointerBuffer, having a backup array */
81 public static PointerBuffer allocate(final int size) {
82 if (Platform.is32Bit()) {
83 return new PointerBuffer(IntBuffer.wrap(new int[size]));
84 } else {
85 return new PointerBuffer(LongBuffer.wrap(new long[size]));
86 }
87 }
88
89 /** Returns a direct PointerBuffer in native order, w/o backup array */
90 public static PointerBuffer allocateDirect(final int size) {
91 return create(Buffers.newDirectByteBuffer(POINTER_SIZE * size));
92 }
93
94 /** Wraps given {@link ByteBuffer} {@code src} up to it {@link ByteBuffer#capacity()}/{@link #POINTER_SIZE} pointers. */
95 public static PointerBuffer wrap(final ByteBuffer src) {
96 return create(src);
97 }
98 /**
99 * Wraps given {@link ByteBuffer} {@code src} @ {@code srcByteOffset} to contain {@code elemCount} pointers.
100 * @param src
101 * @param srcByteOffset
102 * @param elemCount
103 * @return
104 */
105 public static PointerBuffer wrap(final ByteBuffer src, final int srcByteOffset, final int elemCount) {
106 final int oldPos = src.position();
107 final int oldLimit = src.limit();
108 src.position(srcByteOffset);
109 src.limit(srcByteOffset + POINTER_SIZE*elemCount);
110 final ByteBuffer ref = src.slice().order(src.order()); // slice and duplicate may change byte order
111 src.position(oldPos);
112 src.limit(oldLimit);
113 return create(ref);
114 }
115
116 public static PointerBuffer derefPointer(final long aptr, final int elemCount) {
117 if( 0 == aptr ) {
118 throw new NullPointerException("aptr is null");
119 }
120 final ByteBuffer bb = Buffers.getDirectByteBuffer(aptr, elemCount * POINTER_SIZE);
121 if( null == bb ) {
122 throw new InternalError("Couldn't dereference aptr 0x"+Long.toHexString(aptr)+", size "+elemCount+" * "+POINTER_SIZE);
123 }
124 return create(bb);
125 }
126 public static PointerBuffer derefPointer(final ByteBuffer ptrSrc, final int ptrSrcByteOffset, final int elemCount) {
127 return derefPointer(wrap(ptrSrc, ptrSrcByteOffset, 1).get(0), elemCount);
128 }
129
130 /**
131 * @return new PointerBuffer sharing the same buffer data of this instance (identity),
132 * but having an independent position.
133 */
134 public final PointerBuffer duplicate() {
135 PointerBuffer npb;
136 if (Platform.is32Bit()) {
137 npb = new PointerBuffer((IntBuffer)buffer);
138 } else {
139 npb = new PointerBuffer((LongBuffer)buffer);
140 }
141 if(null != dataMap) {
142 npb.dataMap = (LongObjectHashMap) dataMap.clone();
143 }
144 npb.position = position;
145 return npb;
146 }
147
148 @Override
149 public final PointerBuffer put(final PointerBuffer src) {
150 if (remaining() < src.remaining()) {
151 throw new IndexOutOfBoundsException("remaining[this "+remaining()+" < src "+src.remaining()+"], this "+this+", src "+src);
152 }
153 if( null == src.dataMap && null == dataMap ) {
154 // fast path no dataMap usage on both
155 while (src.hasRemaining()) {
156 put(src.get());
157 }
158 } else {
159 while (src.hasRemaining()) {
160 final long addr = src.get();
161 put(addr);
162 if( null != src.dataMap) {
163 final Buffer bb = (Buffer) src.dataMap.get(addr);
164 if(null!=bb) {
165 validateDataMap();
166 dataMap.put(addr, bb);
167 } else if( null != dataMap ) {
168 dataMap.remove(addr);
169 }
170 } else if( null != dataMap ) {
171 dataMap.remove(addr);
172 }
173 }
174 }
175 return this;
176 }
177
178 /** Absolute get method. Get the pointer value at the given index */
179 public final long get(final int idx) {
180 if (0 > idx || idx >= limit()) {
181 throw new IndexOutOfBoundsException("idx "+idx+" not within [0.."+limit()+"), "+this);
182 }
183 if (Platform.is32Bit()) {
184 return ((IntBuffer) buffer).get(idx) & 0x00000000FFFFFFFFL;
185 } else {
186 return ((LongBuffer) buffer).get(idx);
187 }
188 }
189 /** Relative get method. Get the pointer value at the current position and increment the position by one. */
190 public final long get() {
191 final long r = get(position);
192 position++;
193 return r;
194 }
195
196 /** Absolute get method. Get element-bytes for `elemCount` elements from this buffer at `srcElemPos` into `dest` at the given element-index `destElemPos` */
197 public final PointerBuffer get(final int srcElemPos, final long[] dest, final int destElemPos, final int elemCount) {
198 if (0 > srcElemPos || srcElemPos + elemCount > limit() || 0 > elemCount ||
199 0 > destElemPos || destElemPos + elemCount > dest.length )
200 {
201 throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elemCount "+elemCount+
202 ", srcLimit "+limit()+", destLimit "+dest.length+", "+this);
203 }
204 if (Platform.is32Bit()) {
205 final IntBuffer src = (IntBuffer) buffer;
206 for(int i=0; i<elemCount; ++i) {
207 dest[destElemPos+i] = src.get(srcElemPos+i) & 0x00000000FFFFFFFFL;
208 }
209 } else {
210 final LongBuffer src = (LongBuffer) buffer;
211 final int oldSrcLim = src.limit();
212 final int oldSrcPos = src.position();
213 src.position( srcElemPos ).limit( srcElemPos + elemCount ); // remaining = elemCount
214 src.get(dest, destElemPos, elemCount);
215 src.limit(oldSrcLim).position(oldSrcPos);
216 }
217 return this;
218 }
219
220 /**
221 * Relative bulk get method. Copy the pointer values <code> [ position .. position+elemCount [</code>
222 * to the destination array <code> [ dest[destElemPos] .. dest[destElemPos+elemCount] [ </code>
223 * and increment the position by <code>elemCount</code>. */
224 public final PointerBuffer get(final long[] dest, final int destElemPos, final int elemCount) {
225 get(position, dest, destElemPos, elemCount);
226 position += elemCount;
227 return this;
228 }
229
230 /** Absolute put method. Put the pointer value at the given index */
231 public final PointerBuffer put(final int idx, final long v) {
232 if (0 > idx || idx >= limit()) {
233 throw new IndexOutOfBoundsException("idx "+idx+" not within [0.."+limit()+"), "+this);
234 }
235 if (Platform.is32Bit()) {
236 ((IntBuffer) buffer).put(idx, (int) v);
237 } else {
238 ((LongBuffer) buffer).put(idx, v);
239 }
240 return this;
241 }
242 /** Relative put method. Put the pointer value at the current position and increment the position by one. */
243 public final PointerBuffer put(final long value) {
244 put(position, value);
245 position++;
246 return this;
247 }
248
249 /** Absolute put method. Put element-bytes for `elemCount` elements from `src` at `srcElemPos` into this buffer at the given element-index `destElemPos` */
250 public final PointerBuffer put(final long[] src, final int srcElemPos, final int destElemPos, final int elemCount) {
251 if (0 > destElemPos || destElemPos + elemCount > limit() || 0 > elemCount ||
252 0 > srcElemPos || srcElemPos + elemCount > src.length )
253 {
254 throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elemCount "+elemCount+
255 ", destLimit "+limit()+", srcLimit "+src.length+", "+this);
256 }
257 if (Platform.is32Bit()) {
258 final IntBuffer dest = (IntBuffer) buffer;
259 for(int i=0; i<elemCount; ++i) {
260 dest.put(destElemPos+i, (int) src[srcElemPos+i]);
261 }
262 } else {
263 final LongBuffer dest = (LongBuffer) buffer;
264 final int oldDestLim = dest.limit();
265 final int oldDestPos = dest.position();
266 dest.position( destElemPos ).limit( destElemPos + elemCount ); // remaining = elemCount
267 dest.put(src, srcElemPos, elemCount); // remaining = elemCount
268 dest.limit(oldDestLim).position(oldDestPos);
269 }
270 return this;
271 }
272 /**
273 * Relative bulk put method. Put the pointer values <code> [ src[srcElemPos] .. src[srcElemPos+elemCount] [</code>
274 * at the current position and increment the position by <code>elemCount</code>. */
275 public final PointerBuffer put(final long[] src, final int srcElemPos, final int elemCount) {
276 put(src, srcElemPos, position, elemCount);
277 position += elemCount;
278 return this;
279 }
280
281 /** Put the address of the given direct Buffer at the given position
282 of this pointer array.
283 Adding a reference of the given direct Buffer to this object.
284
285 @throws IllegalArgumentException if bb is null or not a direct buffer
286 */
287 public final PointerBuffer referenceBuffer(final int index, final Buffer bb) {
288 if(null==bb) {
289 throw new IllegalArgumentException("Buffer is null");
290 }
291 if(!Buffers.isDirect(bb)) {
292 throw new IllegalArgumentException("Buffer is not direct");
293 }
294 final long mask = Platform.is32Bit() ? 0x00000000FFFFFFFFL : 0xFFFFFFFFFFFFFFFFL ;
295 final long bbAddr = Buffers.getDirectBufferAddressImpl(bb) & mask;
296 if(0==bbAddr) {
297 throw new RuntimeException("Couldn't determine native address of given Buffer: "+bb);
298 }
299 validateDataMap();
300 put(index, bbAddr);
301 dataMap.put(bbAddr, bb);
302 return this;
303 }
304
305 /** Put the address of the given direct Buffer at the end
306 of this pointer array.
307 Adding a reference of the given direct Buffer to this object. */
308 public final PointerBuffer referenceBuffer(final Buffer bb) {
309 referenceBuffer(position, bb);
310 position++;
311 return this;
312 }
313
314 public final Buffer getReferencedBuffer(final int index) {
315 if(null != dataMap) {
316 final long addr = get(index);
317 return (Buffer) dataMap.get(addr);
318 }
319 return null;
320 }
321
322 public final Buffer getReferencedBuffer() {
323 final Buffer bb = getReferencedBuffer(position);
324 position++;
325 return bb;
326 }
327
328 @Override
329 public String toString() {
330 return "PointerBuffer"+toSubString();
331 }
332}
com.jogamp.common.nio.AbstractBuffer
Definition: AbstractBuffer.java:44
com.jogamp.common.nio.AbstractBuffer.hasRemaining
final boolean hasRemaining()
Definition: AbstractBuffer.java:123
com.jogamp.common.nio.AbstractBuffer< PointerBuffer >::toSubString
String toSubString()
Definition: AbstractBuffer.java:212
com.jogamp.common.nio.AbstractBuffer.position
int position
Definition: AbstractBuffer.java:52
com.jogamp.common.nio.AbstractBuffer< PointerBuffer >::buffer
final Buffer buffer
Definition: AbstractBuffer.java:48
com.jogamp.common.nio.AbstractBuffer< PointerBuffer >::POINTER_SIZE
static final int POINTER_SIZE
Platform dependent pointer size in bytes, i.e.
Definition: AbstractBuffer.java:46
com.jogamp.common.nio.AbstractBuffer< PointerBuffer >::limit
int limit
Definition: AbstractBuffer.java:51
com.jogamp.common.nio.AbstractBuffer< PointerBuffer >::remaining
final int remaining()
Definition: AbstractBuffer.java:118
com.jogamp.common.nio.Buffers
Utility methods allowing easy java.nio.Buffer manipulations.
Definition: Buffers.java:70
com.jogamp.common.nio.Buffers.newDirectByteBuffer
static ByteBuffer newDirectByteBuffer(final int numElements)
Allocates a new direct ByteBuffer with the specified number of elements.
Definition: Buffers.java:92
com.jogamp.common.nio.Buffers.isDirect
static boolean isDirect(final Object buf)
Helper routine to tell whether a buffer is direct or not.
Definition: Buffers.java:392
com.jogamp.common.nio.PointerBuffer
Hardware independent container holding an array of native pointer, while its getDirectBufferAddress()...
Definition: PointerBuffer.java:55
com.jogamp.common.nio.PointerBuffer.toString
String toString()
Definition: PointerBuffer.java:329
com.jogamp.common.nio.PointerBuffer.put
final PointerBuffer put(final long[] src, final int srcElemPos, final int elemCount)
Relative bulk put method.
Definition: PointerBuffer.java:275
com.jogamp.common.nio.PointerBuffer.getReferencedBuffer
final Buffer getReferencedBuffer(final int index)
Definition: PointerBuffer.java:314
com.jogamp.common.nio.PointerBuffer.allocateDirect
static PointerBuffer allocateDirect(final int size)
Returns a direct PointerBuffer in native order, w/o backup array.
Definition: PointerBuffer.java:90
com.jogamp.common.nio.PointerBuffer.wrap
static PointerBuffer wrap(final ByteBuffer src, final int srcByteOffset, final int elemCount)
Wraps given ByteBuffer src @ srcByteOffset to contain elemCount pointers.
Definition: PointerBuffer.java:105
com.jogamp.common.nio.PointerBuffer.dataMap
LongObjectHashMap dataMap
Definition: PointerBuffer.java:56
com.jogamp.common.nio.PointerBuffer.put
final PointerBuffer put(final int idx, final long v)
Absolute put method.
Definition: PointerBuffer.java:231
com.jogamp.common.nio.PointerBuffer.allocate
static PointerBuffer allocate(final int size)
Returns a non direct PointerBuffer, having a backup array.
Definition: PointerBuffer.java:81
com.jogamp.common.nio.PointerBuffer.derefPointer
static PointerBuffer derefPointer(final ByteBuffer ptrSrc, final int ptrSrcByteOffset, final int elemCount)
Definition: PointerBuffer.java:126
com.jogamp.common.nio.PointerBuffer.derefPointer
static PointerBuffer derefPointer(final long aptr, final int elemCount)
Definition: PointerBuffer.java:116
com.jogamp.common.nio.PointerBuffer.wrap
static PointerBuffer wrap(final ByteBuffer src)
Wraps given ByteBuffer src up to it ByteBuffer#capacity()/POINTER_SIZE pointers.
Definition: PointerBuffer.java:95
com.jogamp.common.nio.PointerBuffer.referenceBuffer
final PointerBuffer referenceBuffer(final int index, final Buffer bb)
Put the address of the given direct Buffer at the given position of this pointer array.
Definition: PointerBuffer.java:287
com.jogamp.common.nio.PointerBuffer.put
final PointerBuffer put(final PointerBuffer src)
Definition: PointerBuffer.java:149
com.jogamp.common.nio.PointerBuffer.put
final PointerBuffer put(final long value)
Relative put method.
Definition: PointerBuffer.java:243
com.jogamp.common.nio.PointerBuffer.referenceBuffer
final PointerBuffer referenceBuffer(final Buffer bb)
Put the address of the given direct Buffer at the end of this pointer array.
Definition: PointerBuffer.java:308
com.jogamp.common.nio.PointerBuffer.duplicate
final PointerBuffer duplicate()
Definition: PointerBuffer.java:134
com.jogamp.common.nio.PointerBuffer.put
final PointerBuffer put(final long[] src, final int srcElemPos, final int destElemPos, final int elemCount)
Absolute put method.
Definition: PointerBuffer.java:250
com.jogamp.common.nio.PointerBuffer.getReferencedBuffer
final Buffer getReferencedBuffer()
Definition: PointerBuffer.java:322
com.jogamp.common.nio.PointerBuffer.get
final long get(final int idx)
Absolute get method.
Definition: PointerBuffer.java:179
com.jogamp.common.os.Platform
Utility class for querying platform specific properties.
Definition: Platform.java:58
com.jogamp.common.os.Platform.is32Bit
static boolean is32Bit()
Returns true if this JVM/ARCH is 32bit.
Definition: Platform.java:423
com.jogamp.common.util.LongObjectHashMap
Fast HashMap for primitive data.
Definition: LongObjectHashMap.java:62
com.jogamp.common.util.LongObjectHashMap.clone
Object clone()
Disclaimer: If the value type doesn't implement clone(), only the reference is copied.
Definition: LongObjectHashMap.java:158
com.jogamp.common.util.LongObjectHashMap.get
Object get(final long key)
Returns the value to which the specified key is mapped, or getKeyNotFoundValue if this map contains n...
Definition: LongObjectHashMap.java:226
com.jogamp.common.util.LongObjectHashMap.put
Object put(final long key, final Object value)
Maps the key to the specified value.
Definition: LongObjectHashMap.java:242
com.jogamp.common.util.LongObjectHashMap.remove
Object remove(final long key)
Removes the key-value mapping from this map.
Definition: LongObjectHashMap.java:298
com.jogamp.common.util.LongObjectHashMap.setKeyNotFoundValue
Object setKeyNotFoundValue(final Object newKeyNotFoundValue)
Sets the new key not found value.
Definition: LongObjectHashMap.java:361