All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.qt.QNativePointer Maven / Gradle / Ivy

There is a newer version: 6.3.0
Show newest version
/****************************************************************************
**
** Copyright (C) 1992-2009 Nokia. All rights reserved.
** Copyright (C) 2009-2021 Dr. Peter Droste, Omix Visualization GmbH & Co. KG. All rights reserved.
**
** This file is part of Qt Jambi.
**
** ** $BEGIN_LICENSE$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
** 
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
** $END_LICENSE$

**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
package io.qt;

import java.lang.ref.WeakReference;
import java.nio.Buffer;
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;
import java.util.ArrayList;
import java.util.List;

import io.qt.core.QIODevice;

/**
 *   QNativePointer encapsulates a native C++ pointer. The class
 *   provides the functionality that you would get if you had direct
 *   access to the pointer through function calls. It is as such a
 *   low-level memory manager that should be used sparsely; its
 *   intended and legitimate use is for JNI bindings not handled by
 *   generator. Examples can be found in the
 *   generator example.
 *   

* QNativePointer does type checking of pointers. Also, if the * pointer is pointing to an array, you must also specify the array * length; array bounds checking is enforced by QNativePointer. Any * number of indirections are allowed (i.e., arrays can have any * number of dimensions). *

* The QNativePointer will by default delete the internal pointer * when being garbage collected. However, if the ownership of the * pointer is given to a c++ class, you do not want this behavior. * The AutoDeleteMode enum values defines the ways in which * deletion of the pointer can be handled. *

* The data types that can be pointed to are defined by the Type * enum. An allocation of an Integer pointer can, for example, be * done like this: *

* * QNativePointer ptr = * new QNativePointer(QNativePointer.Type.Int);
* ptr.setIntValue(10);
*
*

* An array of length 5 is created in the following way: *

* * QNativePointer ptr = new QNativePointer(QNativePointer.Type.Int, 5);
* for (int i = 0; i < 5, ++i) * ptr.setIntAt(i, i*i);
*
*

* If you are creating a multi dimensional array, you have two * possibilities. You can make QNativePointers of the Pointer type or * specify the number indirections of a single QNativePointer. * We recommend the second alternative * since it creates type safe pointers. Here is an example using the first alternative: *

* * QNativePointer ptr = new QNativePointer(QNativePointer.Type.Pointer, 2);
* QNativePointer charArray1 = new QNativePointer(QNativePointer.Type.Char, 5);
* ptr.setPointerAt(0, carArray1); *
*

* And here is the code for the second: *

* * QNativePointer ptr = new QNativePointer(Type.Char, 5, 2);
* ptr.setPointerAt(0, createCharPointer(myString)); *
*/ public final class QNativePointer { static { io.qt.QtUtilities.initializePackage("io.qt.internal"); } // Keep this in sync with the values in common/nativepointer.h /** * The Type enum describe the Java types that can be used by * a QNativePointer. * */ public enum Type implements QtEnumerator{ /** Java Boolean*/ Boolean, /** Java Byte*/ Byte, /** Java Char*/ Char, /** Java Short*/ Short, /** Java Int*/ Int, /** Java Long*/ Long, /** Java Float*/ Float, /** Java Double*/ Double, /** Another QNativePointer of any type*/ Pointer, /** Java String*/ String; public static Type resolve(int type) { switch (type) { case 0: return Type.Boolean; case 1: return Type.Byte; case 2: return Type.Char; case 3: return Type.Short; case 4: return Type.Int; case 5: return Type.Long; case 6: return Type.Float; case 7: return Type.Double; case 8: return Type.Pointer; case 9: return Type.String; default: throw new QNoSuchEnumValueException(type); } } } /** * The AutoDeleteMode enum describes how garbage collection of the * QNativePointer handles the deletion of the native pointer. By default, * the mode is set to Delete or DeleteArray. */ public enum AutoDeleteMode implements QtEnumerator{ /** * Use this deletion mode if you do not want to delete the c++ pointer * when the QNativePointer object is garbage collected. */ None, /** * Free must be used if the pointer was allocated using c++ free(). * Currently, no pointers in Qt Jambi is allocated in this manner. */ Free, /** * The pointer is allocated with c++ new. * This should be used for all pointers in Qt Jambi */ Delete, /** * This must be the mode of deletion if the pointer is an array. */ DeleteArray; public static AutoDeleteMode resolve(int type) { switch (type) { case 0: return None; case 1: return Free; case 2: return Delete; case 3: return DeleteArray; default: throw new QNoSuchEnumValueException(type); } } } /** * Creates a native pointer of the specified type. * The object has an indirection of 1 and the internal pointer * will be deleted when the QNativePointer object is deleted. * * @param type the type of pointer to create. */ public QNativePointer(Type type) { this(type, 1); } /** * Creates a native pointer to an array with size * length of the specified type. The pointer will * have an indirection of 1 and be deleted when the QNativePointer * is garbage collected. * * @param type the type of pointer to create. * @param size the size of the array. */ public QNativePointer(Type type, long size) { this(type, size, 1); } /** * Creates a native pointer of the specified type. * It will be an array if size is larger than one and * have an indirection of indirections. For instance, * the following Java statement will create a **char * pointer with the first array dimension of length 5: * QNativePointer ptr = new * QNativePointer(QNativePointer.Type.Int, 5, 2); * * @param type the type of pointer to create. * @param size the length of the array. * @param indirections the number of indirections for the pointer. */ public QNativePointer(Type type, long size, int indirections) { this(type, size, indirections, false); } private QNativePointer(Type type, long size, int indirections, boolean isReadOnly) { if (indirections < 1) throw new IllegalArgumentException("level of indirection must be at least 1"); if (size == 0) throw new IllegalArgumentException("size must be at least 1"); data.m_ptr = createPointer(type.ordinal(), size, indirections); data.m_type = type; data.m_knownSize = size; data.m_indirections = indirections; data.m_autodelete = size == 1 ? AutoDeleteMode.Delete : AutoDeleteMode.DeleteArray; data.m_isReadonly = isReadOnly; } @NativeAccess private QNativePointer(int type, long size, int indirections, long ptr, boolean isReadOnly) { data.m_ptr = ptr; data.m_type = Type.resolve(type); data.m_knownSize = size; data.m_indirections = indirections; data.m_autodelete = AutoDeleteMode.None; data.m_isReadonly = isReadOnly; } @NativeAccess private QNativePointer(int type, long size, int indirections, boolean isReadOnly) { this(Type.resolve(type), size, indirections, isReadOnly); } @NativeAccess private QNativePointer(Buffer buffer, long ptr) { data.m_ptr = ptr; if(buffer instanceof ByteBuffer) data.m_type = Type.Byte; else if(buffer instanceof IntBuffer) data.m_type = Type.Int; else if(buffer instanceof ShortBuffer) data.m_type = Type.Short; else if(buffer instanceof LongBuffer) data.m_type = Type.Long; else if(buffer instanceof CharBuffer) data.m_type = Type.Char; else if(buffer instanceof FloatBuffer) data.m_type = Type.Float; else if(buffer instanceof DoubleBuffer) data.m_type = Type.Double; else data.m_type = Type.Pointer; data.m_knownSize = buffer.capacity(); data.m_indirections = 1; if(buffer.isDirect()) { QtJambi_LibraryUtilities.internal.registerCleaner(buffer, data::reset); data.m_autodelete = AutoDeleteMode.None; data.m_isReadonly = buffer.isReadOnly(); }else { data.m_autodelete = data.m_knownSize == 1 ? AutoDeleteMode.Delete : AutoDeleteMode.DeleteArray; data.m_isReadonly = false; } } private QNativePointer() { data.m_knownSize = -1; data.m_autodelete = AutoDeleteMode.None; }; /** * If the native pointer is of boolean type, this function returns * its value. If it is an array of booleans, the first element is * returned. * * @return the value of the pointer. */ public boolean booleanValue() { return booleanAt(0); } /** * If the native pointer is of byte type, this function returns * its value. If it is an array of bytes, the first element is * returned. * * @return the value of the pointer. */ public byte byteValue() { return byteAt(0); } /** * If the native pointer is of char type, this function returns * its value. If it is an array of chars, the first element is * returned. * * @return the value of the pointer. */ public char charValue() { return charAt(0); } /** * If the native pointer is of short type, this function returns * its value. If it is an array of shorts, the first element is * returned. * * @return the value of the pointer. */ public short shortValue() { return shortAt(0); } /** * If the native pointer is of int type, this function returns * its value. If it is an array of ints, the first element is * returned. * * @return the value of the pointer. */ public int intValue() { return intAt(0); } /** * If the native pointer is of long type, this function returns * its value. If it is an array of longs, the first element is * returned. * * @return the value of the pointer. */ public long longValue() { return longAt(0); } /** * If the native pointer is of float type, this function returns * its value. If it is an array of floats, the first element is * returned. * * @return the value of the pointer. */ public float floatValue() { return floatAt(0); } /** * If the native pointer is of double type, this function returns * its value. If it is an array of doubles, the first element is * returned. * * @return the value of the pointer. */ public double doubleValue() { return doubleAt(0); } /** * If the native pointer is of boolean type, this function returns * its values as array. * * @return the values of the pointer. */ public boolean[] booleanArray() { verifyAccess(Type.Boolean, 0); if(this.data.m_knownSize>Integer.MAX_VALUE) { throw new IndexOutOfBoundsException("The pointer's size exceeds allowed array size."); } boolean[] result = new boolean[(int)this.data.m_knownSize]; for (int i = 0; i < result.length; i++) { result[i] = booleanAt(i); } return result; } /** * If the native pointer is of byte type, this function returns * its values as array. * * @return the values of the pointer. */ public byte[] byteArray() { verifyAccess(Type.Byte, 0); if(this.data.m_knownSize>Integer.MAX_VALUE) { throw new IndexOutOfBoundsException("The pointer's size exceeds allowed array size."); } byte[] result = new byte[(int)this.data.m_knownSize]; copyBackB(data.m_ptr, result); return result; } /** * If the native pointer is of char type, this function returns * its values as array. * * @return the values of the pointer. */ public char[] charArray() { verifyAccess(Type.Char, 0); if(this.data.m_knownSize>Integer.MAX_VALUE) { throw new IndexOutOfBoundsException("The pointer's size exceeds allowed array size."); } char[] result = new char[(int)this.data.m_knownSize]; for (int i = 0; i < result.length; i++) { result[i] = charAt(i); } return result; } /** * If the native pointer is of short type, this function returns * its values as array. * * @return the values of the pointer. */ public short[] shortArray() { verifyAccess(Type.Short, 0); if(this.data.m_knownSize>Integer.MAX_VALUE) { throw new IndexOutOfBoundsException("The pointer's size exceeds allowed array size."); } short[] result = new short[(int)this.data.m_knownSize]; copyBackS(data.m_ptr, result); return result; } /** * If the native pointer is of int type, this function returns * its values as array. * * @return the values of the pointer. */ public int[] intArray() { verifyAccess(Type.Int, 0); if(this.data.m_knownSize>Integer.MAX_VALUE) { throw new IndexOutOfBoundsException("The pointer's size exceeds allowed array size."); } int[] result = new int[(int)this.data.m_knownSize]; copyBackI(data.m_ptr, result); return result; } /** * If the native pointer is of long type, this function returns * its values as array. * * @return the values of the pointer. */ public long[] longArray() { verifyAccess(Type.Long, 0); if(this.data.m_knownSize>Integer.MAX_VALUE) { throw new IndexOutOfBoundsException("The pointer's size exceeds allowed array size."); } long[] result = new long[(int)this.data.m_knownSize]; copyBackJ(data.m_ptr, result); return result; } /** * If the native pointer is of float type, this function returns * its values as array. * * @return the values of the pointer. */ public float[] floatArray() { verifyAccess(Type.Float, 0); if(this.data.m_knownSize>Integer.MAX_VALUE) { throw new IndexOutOfBoundsException("The pointer's size exceeds allowed array size."); } float[] result = new float[(int)this.data.m_knownSize]; copyBackF(data.m_ptr, result); return result; } /** * If the native pointer is of double type, this function returns * its values as array. * * @return the values of the pointer. */ public double[] doubleArray() { verifyAccess(Type.Double, 0); if(this.data.m_knownSize>Integer.MAX_VALUE) { throw new IndexOutOfBoundsException("The pointer's size exceeds allowed array size."); } double[] result = new double[(int)this.data.m_knownSize]; copyBackD(data.m_ptr, result); return result; } /** * If the native pointer is of pointer type, this function returns * its value matching the given valueType. * @param valueType the type of the value * * @return the value of the pointer. */ @SuppressWarnings("unchecked") public T[] objectArray(Class valueType) { if(data.m_knownSize>1) { verifyAccess(Type.Byte, 0); }else { verifyAccess(Type.Pointer, 0); } if(this.data.m_knownSize>Integer.MAX_VALUE) { throw new IndexOutOfBoundsException("The pointer's size exceeds allowed array size."); } Object[] array = (Object[])java.lang.reflect.Array.newInstance(valueType, (int)this.data.m_knownSize); for (int i = 0; i < array.length; i++) { array[i] = objectAt(valueType, i); } return (T[])array; } /** * If the native pointer is of pointer type, this function returns * its value. If it is an array of pointers, the first element is * returned. * * @return the value of the pointer. */ public QNativePointer pointerValue() { return pointerAt(0); } /** * If the native pointer is of pointer type, this function returns * its value matching the given valueType. If it is an array of pointers, the first element is * returned. * @param valueType the type of the value * * @return the value of the pointer. */ public T object(Class valueType) { return objectAt(valueType, 0); } /** * If the native pointer is of string type, this function returns * its value. If it is an array of strings, the first element is * returned. * * @return the value of the pointer. */ public String stringValue() { return stringAt(0); } /** * If the native pointer is of string type, this function returns * its values as array. * * @return the values of the pointer. */ public String[] stringArray() { verifyAccess(Type.String, 0); if(this.data.m_knownSize>Integer.MAX_VALUE) { throw new IndexOutOfBoundsException("The pointer's size exceeds allowed array size."); } String[] result = new String[(int)this.data.m_knownSize]; for (int i = 0; i < result.length; i++) { result[i] = stringAt(i); } return result; } /** * Sets the value of this pointer to value. * The type of the pointer must be boolean. * * @param value the value to which the pointer is set. */ public void setBooleanValue(boolean value) { setBooleanAt(0, value); } /** * Sets the value of this pointer to value. * The type of the pointer must be byte. * * @param value the value to which the pointer is set. */ public void setByteValue(byte value) { setByteAt(0, value); } /** * Sets the value of this pointer to value. * The type of the pointer must be char. * * @param value the value to which the pointer is set. */ public void setCharValue(char value) { setCharAt(0, value); } /** * Sets the value of this pointer to value. * The type of the pointer must be short. * * @param value the value to which the pointer is set. */ public void setShortValue(short value) { setShortAt(0, value); } /** * Sets the value of this pointer to value. * The type of the pointer must be int. * * @param value the value to which the pointer is set. */ public void setIntValue(int value) { setIntAt(0, value); } /** * Sets the value of this pointer to value. * The type of the pointer must be long. * * @param value the value to which the pointer is set. */ public void setLongValue(long value) { setLongAt(0, value); } /** * Sets the value of this pointer to value. * The type of the pointer must be float. * * @param value the value to which the pointer is set. */ public void setFloatValue(float value) { setFloatAt(0, value); } /** * Sets the value of this pointer to value. * The type of the pointer must double. * * @param value the value to which the pointer is set. */ public void setDoubleValue(double value) { setDoubleAt(0, value); } /** * Sets the value of this pointer to value. * The pointer must be of pointer type. * * @param value the value to which the pointer is set. */ public void setPointerValue(QNativePointer value) { setPointerAt(0, value); } /** * Sets the value of this pointer to value. * The pointer must be of pointer type. * * @param value the value to which the pointer is set. */ public void setObjectValue(T value) { setObjectAt(0, value); } /** * Sets the value of this pointer to value. * The pointer must point to a string. * * @param value the value to which the pointer is set. */ public void setStringValue(String value) { setStringAt(0, value); } /** * Returns the value of the native pointer at the specified * position. If pos is larger than 1, QNativePointer * will check that the position is within the array bounds. * * @param pos the array index */ public boolean booleanAt(long pos) { verifyAccess(Type.Boolean, pos); return readBoolean(data.m_ptr, pos); } /** * Returns the value of the native pointer at the specified * position. If pos is larger than 1, QNativePointer * will check that the position is within the array bounds. * * @param pos the array index */ public byte byteAt(long pos) { verifyAccess(Type.Byte, pos); return readByte(data.m_ptr, pos); } /** * Returns the value of the native pointer at the specified * position. If pos is larger than 1, QNativePointer * will check that the position is within the array bounds. * * @param pos the array index */ public char charAt(long pos) { verifyAccess(Type.Char, pos); return readChar(data.m_ptr, pos); } /** * Returns the value of the native pointer at the specified * position. If pos is larger than 1, QNativePointer * will check that the position is within the array bounds. * * @param pos the array index */ public short shortAt(long pos) { verifyAccess(Type.Short, pos); return readShort(data.m_ptr, pos); } /** * Returns the value of the native pointer at the specified * position. If pos is larger than 1, QNativePointer * will check that the position is within the array bounds. * * @param pos the array index */ public int intAt(long pos) { verifyAccess(Type.Int, pos); return readInt(data.m_ptr, pos); } /** * Returns the value of the native pointer at the specified * position. If pos is larger than 1, QNativePointer * will check that the position is within the array bounds. * * @param pos the array index */ public long longAt(long pos) { verifyAccess(Type.Long, pos); return readLong(data.m_ptr, pos); } /** * Returns the value of the native pointer at the specified * position. If pos is larger than 1, QNativePointer * will check that the position is within the array bounds. * * @param pos the array index */ public float floatAt(long pos) { verifyAccess(Type.Float, pos); return readFloat(data.m_ptr, pos); } /** * Returns the value of the native pointer at the specified * position. If pos is larger than 1, QNativePointer * will check that the position is within the array bounds. * * @param pos the array index */ public double doubleAt(long pos) { verifyAccess(Type.Double, pos); return readDouble(data.m_ptr, pos); } public ByteBuffer byteBuffer() { verifyAccess(Type.Byte, 0); return toByteBuffer(data.m_ptr, data.m_knownSize, data.m_isReadonly); } public CharBuffer charBuffer() { verifyAccess(Type.Char, 0); return toByteBuffer(data.m_ptr, data.m_knownSize, data.m_isReadonly).asCharBuffer(); } public ShortBuffer shortBuffer() { verifyAccess(Type.Short, 0); return toByteBuffer(data.m_ptr, data.m_knownSize, data.m_isReadonly).asShortBuffer(); } public IntBuffer intBuffer() { verifyAccess(Type.Int, 0); return toByteBuffer(data.m_ptr, data.m_knownSize, data.m_isReadonly).asIntBuffer(); } public LongBuffer longBuffer() { verifyAccess(Type.Long, 0); return toByteBuffer(data.m_ptr, data.m_knownSize, data.m_isReadonly).asLongBuffer(); } public FloatBuffer floatBuffer() { verifyAccess(Type.Float, 0); return toByteBuffer(data.m_ptr, data.m_knownSize, data.m_isReadonly).asFloatBuffer(); } public DoubleBuffer doubleBuffer() { verifyAccess(Type.Double, 0); return toByteBuffer(data.m_ptr, data.m_knownSize, data.m_isReadonly).asDoubleBuffer(); } /** * Returns the value of the native pointer at the specified * position. If pos is larger than 1, QNativePointer * will check that the position is within the array bounds. * * @param pos the array index */ public QNativePointer pointerAt(long pos) { verifyAccess(Type.Pointer, pos); long ptr = readPointer(data.m_ptr, pos); return fromNative(ptr, data.m_type, -1, data.m_indirections - 1, data.m_isReadonly); } /** * Returns the value of the native pointer matching the given valueType at the specified * position. If pos is larger than 1, QNativePointer * will check that the position is within the array bounds. * @param valueType the type of the value * @param pos the array index * * @return the value of the pointer. */ public T objectAt(Class valueType, long pos) { if(data.m_knownSize>1 && pos>0) { verifyAccess(Type.Byte, pos); }else { verifyAccess(Type.Pointer, pos); } T object = readObject(data.m_ptr, valueType, pos, data.m_isReadonly); if(data.m_autodelete!=AutoDeleteMode.None) { if(data.m_dependentObjects==null) { data.m_dependentObjects = new ArrayList<>(); } data.m_dependentObjects.add(new WeakReference(object)); } return object; } /** * Returns the value of the native pointer at the specified * position. If pos is larger than 1, QNativePointer * will check that the position is within the array bounds. * * @param pos the array index */ public String stringAt(long pos) { verifyAccess(Type.String, pos); return readString(data.m_ptr, pos); } /** * Sets the value of the array element at pos to * which this native pointer points. * * @param pos the array index * @param value the value to set the index to */ public void setBooleanAt(long pos, boolean value) { verifyWriteAccess(Type.Boolean, pos); writeBoolean(data.m_ptr, pos, value); } /** * Sets the value of the array element at pos to * which this native pointer points. * * @param pos the array index * @param value the value to set the index to */ public void setByteAt(long pos, byte value) { verifyWriteAccess(Type.Byte, pos); writeByte(data.m_ptr, pos, value); } /** * Sets the value of the array element at pos to * which this native pointer points. * * @param pos the array index * @param value the value to set the index to */ public void setCharAt(long pos, char value) { verifyWriteAccess(Type.Char, pos); writeChar(data.m_ptr, pos, value); } /** * Sets the value of the array element at pos to * which this native pointer points. * * @param pos the array index * @param value the value to set the index to */ public void setShortAt(long pos, short value) { verifyWriteAccess(Type.Short, pos); writeShort(data.m_ptr, pos, value); } /** * Sets the value of the array element at pos to * which this native pointer points. * * @param pos the array index * @param value the value to set the index to */ public void setIntAt(long pos, int value) { verifyWriteAccess(Type.Int, pos); writeInt(data.m_ptr, pos, value); } /** * Sets the value of the array element at pos to * which this native pointer points. * * @param pos the array index * @param value the value to set the index to */ public void setLongAt(long pos, long value) { verifyWriteAccess(Type.Long, pos); writeLong(data.m_ptr, pos, value); } /** * Sets the value of the array element at pos to * which this native pointer points. * * @param pos the array index * @param value the value to set the index to */ public void setFloatAt(long pos, float value) { verifyWriteAccess(Type.Float, pos); writeFloat(data.m_ptr, pos, value); } /** * Sets the value of the array element at pos to * which this native pointer points. * * @param pos the array index * @param value the value to set the index to */ public void setDoubleAt(long pos, double value) { verifyWriteAccess(Type.Double, pos); writeDouble(data.m_ptr, pos, value); } /** * Sets the value of the array element at pos to * which this native pointer points. * * @param pos the array index * @param value the value to set the index to */ public void setPointerAt(long pos, QNativePointer value) { verifyWriteAccess(Type.Pointer, pos); if(value != null) value.setAutoDeleteMode(AutoDeleteMode.None); writePointer(data.m_ptr, pos, value == null ? 0 : value.data.m_ptr); } /** * Sets the value of the array element at pos to * which this native pointer points. * * @param pos the array index * @param value the value to set the index to */ public void setObjectAt(long pos, T value) { if(data.m_knownSize>1 && pos>0) { verifyWriteAccess(Type.Byte, pos); }else { verifyWriteAccess(Type.Pointer, pos); } Class valueType = value.getClass(); writeObject(data.m_ptr, data.m_knownSize, valueType, pos, value); } /** * Sets the value of the array element at pos to * which this native pointer points. * * @param pos the array index * @param value the value to set the index to */ public void setStringAt(long pos, String value) { verifyWriteAccess(Type.String, pos); writeString(data.m_ptr, pos, value); } /** * Returns the type of the native pointer. * * @return the data type of the native pointer */ public Type type() { return data.m_type; } /** * Returns the number of indirections of the pointer. * * @return the number of indirections of the pointer */ public int indirections() { return data.m_indirections; } public long knownSize() { return data.m_knownSize; } @NativeAccess private long byteSize() { if(data.m_knownSize==-1 && data.m_indirections==1 && data.m_type==Type.Pointer) { return -1; } if(data.m_indirections>1 && data.m_type==Type.Pointer) { if(data.m_knownSize>0) return data.m_knownSize * 8; else return -1; } if(data.m_knownSize>0 && data.m_indirections==1) { switch(data.m_type) { case Boolean: case Byte: return data.m_knownSize; case Short: case Char: return data.m_knownSize * 2; case Float: case Int: return data.m_knownSize * 4; case Double: case Long: case Pointer: return data.m_knownSize * 8; case String: return -1; default: break; } } return -1; } /** * Returns true if the native pointer is 0; otherwise false. * * @return true if the native pointer is 0. */ public boolean isNull() { return data.isNull(); } /** * Returns the auto-delete mode of the pointer. * * @return the auto-delete mode of this QNativePointer */ public AutoDeleteMode autoDeleteMode() { return data.m_autodelete; } /** * This function sets the auto delete mode of the QNativePointer. * * The internal pointer is deleted by default when the * QNativePointer object is garbage collected, so you only need to * call this function when you want to keep the pointer valid * after the Java object is garbage collected. * * @param autodelete the new auto delete mode. */ public void setAutoDeleteMode(AutoDeleteMode autodelete) { data.m_autodelete = autodelete; } /** * This function deletes the internal pointer. * * Currently, all QNativePointers should be deleted using the * delete() function. * After the pointer has been deleted, you cannot use the same * QNativePointer to allocate further data. Note also that the * pointer will by default be deleted upon garbage collection. */ public void free() { data.free(); } /** * This function deletes the internal pointer. * * After the pointer has been deleted, you cannot allocate it * again. The pointer is by default deleted when the * QNativePointer object is garbage collected. */ public void delete() { data.delete(); } /** * This function deletes elements in the array of this * QNativePointer. * * After the pointer has been deleted, you cannot use this * QNativePointer object again. */ public void deleteArray() { data.deleteArray(); } /** * Returns the native pointer. * * The returned long is the void * value in c++. * * @return the native pointer. */ public long pointer() { return data.m_ptr; } /** * This function creates a QNativePointer from an existing c++ * pointer. The long is the void * (i.e., address) * value of the pointer. There are several ways of acquiring a native pointer. For instance, * QNativePointer internal pointer is returned by pointer(), and * QtJambiObject.nativeId() returns the c++ pointer to its Qt object. * * @param ptr the void * value of the pointer. * @param type the Type of the pointer * @param indirections the number of pointer indirections * @return a QNativePointer object with ptr as the native pointer */ public static QNativePointer fromNative(long ptr, Type type, long size, int indirections, boolean readOnly) { QNativePointer nativePointer = new QNativePointer(); nativePointer.data.m_ptr = ptr; nativePointer.data.m_knownSize = size; nativePointer.data.m_type = type; nativePointer.data.m_indirections = indirections; nativePointer.data.m_isReadonly = readOnly; return nativePointer; } @SafeVarargs public static QNativePointer fromArray(T... array) { Class arrayClass = array.getClass(); Class componentType = arrayClass.getComponentType(); return fromArray(componentType, array); } private static native QNativePointer fromArray(Class valueType, T[] array); public static native QNativePointer fromObject(T object); public static native QNativePointer fromBuffer(Buffer buffer); public static QNativePointer fromArray(int data[]) { QNativePointer np = new QNativePointer(QNativePointer.Type.Int, data.length); copyFromI(np.data.m_ptr, data); return np; } public static QNativePointer fromArray(byte data[]) { QNativePointer np = new QNativePointer(QNativePointer.Type.Byte, data.length); copyFromB(np.data.m_ptr, data); return np; } public static QNativePointer fromArray(float data[]) { QNativePointer np = new QNativePointer(QNativePointer.Type.Float, data.length); copyFromF(np.data.m_ptr, data); return np; } public static QNativePointer fromArray(double data[]) { QNativePointer np = new QNativePointer(QNativePointer.Type.Double, data.length); copyFromD(np.data.m_ptr, data); return np; } public static QNativePointer fromArray(boolean data[]) { QNativePointer np = new QNativePointer(QNativePointer.Type.Boolean, data.length); for (int i=0; i= 0 && pos >= data.m_knownSize) throw new IndexOutOfBoundsException("size: " + data.m_knownSize + ", access at: " + pos); if (data.m_indirections > 1) { if (type != Type.Pointer) throw new ClassCastException("accessing pointer with " + data.m_indirections + " levels of indirection as " + type); } else if (type != data.m_type) { throw new ClassCastException("type: " + data.m_type + ", accessed as: " + type); } } public QIODevice openAsDevice(QIODevice.OpenModeFlag... openMode) { return openAsDevice(new QIODevice.OpenMode(openMode)); } public QIODevice openAsDevice(QIODevice.OpenMode openMode) { if(data.m_isInvalid) throw new IllegalStateException(); if (isNull()) throw new NullPointerException("native pointer is null"); if(openMode.isSet(QIODevice.OpenModeFlag.WriteOnly)) { if(data.m_isReadonly){ throw new ReadOnlyNativePointerException(); } } QIODevice ioDevice = ioDevice(); if(ioDevice.open(openMode)) { return ioDevice; }else { return null; } } private native QIODevice ioDevice(); private static native boolean readBoolean(long ptr, long pos); private static native byte readByte(long ptr, long pos); private static native char readChar(long ptr, long pos); private static native short readShort(long ptr, long pos); private static native int readInt(long ptr, long pos); private static native long readLong(long ptr, long pos); private static native float readFloat(long ptr, long pos); private static native double readDouble(long ptr, long pos); private static native ByteBuffer toByteBuffer(long ptr, long capacity, boolean readOnly); private static native long readPointer(long ptr, long pos); private static native T readObject(long ptr, Class valueType, long pos, boolean readOnly); private static native String readString(long ptr, long pos); private static native void writeBoolean(long ptr, long pos, boolean value); private static native void writeByte(long ptr, long pos, byte value); private static native void writeChar(long ptr, long pos, char value); private static native void writeShort(long ptr, long pos, short value); private static native void writeInt(long ptr, long pos, int value); private static native void writeLong(long ptr, long pos, long value); private static native void writeFloat(long ptr, long pos, float value); private static native void writeDouble(long ptr, long pos, double value); private static native void writePointer(long ptr, long pos, long value); private static native void writeObject(long ptr, long knownSize, Class valueType, long pos, QtObjectInterface value); private static native void writeString(long ptr, long pos, String value); private static native long createPointer(int type, long size, int indirections); private static native void deletePointer(long ptr, int type, int deleteMode); private final Data data = new Data(); { QtJambi_LibraryUtilities.internal.registerCleaner(this, this.data::dispose); } public final void invalidate() { data.dispose(); } private static class Data{ private long m_ptr; private Type m_type; private long m_knownSize; private AutoDeleteMode m_autodelete; private int m_indirections; private boolean m_isReadonly; private boolean m_isInvalid = false; private boolean m_verification_enabled = true; private List> m_dependentObjects; void dispose() { if(m_dependentObjects!=null) { for(WeakReference object : m_dependentObjects) { QtJambi_LibraryUtilities.internal.invalidateObject(object.get()); } m_dependentObjects = null; } switch (m_autodelete) { case Free: free(); break; case Delete: delete(); break; case DeleteArray: deleteArray(); break; case None: break; default: break; } m_ptr = 0; m_autodelete = AutoDeleteMode.None; m_isInvalid = true; } private void free() { if (isNull()) return; deletePointer(m_ptr, m_type.ordinal(), 0); m_ptr = 0; } private void delete() { if (isNull()) return; deletePointer(m_ptr, m_type.ordinal(), 1); m_ptr = 0; } private void deleteArray() { if (isNull()) return; deletePointer(m_ptr, m_type.ordinal(), 2); m_ptr = 0; } private boolean isNull() { return m_ptr == 0; } void reset() { m_ptr = 0; } } public static class ReadOnlyNativePointerException extends UnsupportedOperationException{ private static final long serialVersionUID = -8238568644716457250L; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy