aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-06-23 07:09:24 +0200
committerSven Gothel <[email protected]>2023-06-23 07:09:24 +0200
commit23f4c6347ea24cf619dba573e83790e73d81d5ad (patch)
tree104fadd83f6c9718b15428e9eb2ed2f8554f4ba4
parent829d69ca42d2022790b136a5f689c34919a7c775 (diff)
GlueGen Struct [16]: Add support for pointer-pointer and function-pointer values
See documentation and unit test test2.h, Test2FuncPtr.java and Test3PtrStorage.java
-rw-r--r--doc/GlueGen_Mapping.html93
-rw-r--r--doc/GlueGen_Mapping.md86
-rwxr-xr-xmake/scripts/runtest.sh3
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java368
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/Test2FuncPtr.java16
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/Test3PtrStorage.java139
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/test2.c38
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg9
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/test2.h43
9 files changed, 592 insertions, 203 deletions
diff --git a/doc/GlueGen_Mapping.html b/doc/GlueGen_Mapping.html
index 69aa11f..dd63718 100644
--- a/doc/GlueGen_Mapping.html
+++ b/doc/GlueGen_Mapping.html
@@ -421,6 +421,7 @@
<li><a href="#overview">Overview</a></li>
<li><a href="#primitive-mapping">Primitive Mapping</a>
<ul>
+ <li><a href="#pointer-mapping">Pointer Mapping</a></li>
<li><a href="#string-mapping">String Mapping</a></li>
<li><a href="#alignment-for-compound-data">Alignment for Compound
Data</a></li>
@@ -436,8 +437,12 @@
Table</a></li>
<li><a href="#struct-java-signature-examples">Struct Java Signature
Examples</a></li>
- <li><a href="#struct-function-pointer-support">Struct Function Pointer
+ <li><a href="#struct-pointer-pointer-support">Struct Pointer-Pointer
Support</a></li>
+ <li><a href="#struct-function-pointer-support">Struct Function-Pointer
+ Support</a></li>
+ <li><a href="#java-callback-from-native-c-api-support">Java Callback
+ from Native C-API Support</a></li>
</ul></li>
<li><a href="#platform-header-files">Platform Header Files</a></li>
<li><a href="#pre-defined-macros">Pre-Defined Macros</a></li>
@@ -730,6 +735,15 @@ since we don't differentiate the OS and it's bit size is ambiguous.</li>
to <em>PointerBuffer</em>, to reflect the architecture depending storage
size.</li>
</ul>
+<h3 id="pointer-mapping">Pointer Mapping</h3>
+<p><em>Pointer</em> values itself are represented as <code>long</code>
+values on the Java side while using the native pointer-size, e.g. 32-bit
+or 64-bit, on the native end.</p>
+<p>They may simply be accessible via <code>long</code> or
+<code>long[]</code> primitives in Java, or are exposed via
+<code>com.jogamp.common.nio.PointerBuffer</code>.</p>
+<p>See <a href="#struct-pointer-pointer-support">Struct Pointer-Pointer
+Support</a> below.</p>
<h3 id="string-mapping">String Mapping</h3>
<h4 id="function-return-string-values">Function return String
values</h4>
@@ -926,20 +940,28 @@ fields</p>
<ul>
<li>See <a href="#primitive-mapping"><em>Primitive Mapping</em></a>
above.</li>
+<li>See <a href="#pointer-mapping"><em>Pointer Mapping</em></a> for
+<em>pointer-to-pointer</em> values above and <a
+href="#struct-pointer-pointer-support">Struct Pointer-Pointer
+Support</a> below.</li>
<li>See <a href="#string-mapping"><em>String Mapping</em></a>
above.</li>
</ul></li>
-<li><em>Struct</em>, i.e. another compound variable</li>
+<li><em>Struct</em>, i.e. an aggregated or referenced compound
+variable</li>
<li><em>Function Pointer</em>, a <em>typedef</em>'ed and set callable
-function pointer</li>
+function pointer, see <a href="#struct-function-pointer-support">Struct
+Function-Pointer Support</a> below.</li>
+<li><em>Java Callback from Native Code</em>, see <a
+href="#java-callback-from-native-c-api-support">section below</a></li>
</ul>
<p>A field may be a direct aggregation, i.e. instance, within the struct
including an array or a reference to a single element or array via a
pointer.</p>
-<p>Both, <em>primitive</em> and <em>struct</em> field type mappings only
-produce pure Java code, utilizing the <em>GlueGen Runtime</em>. Hence no
-additional native code must be compiled nor a resulting additional
-library loaded to use the mapping.</p>
+<p>Both, <em>primitive</em>, <em>struct</em> and <em>pointer</em> field
+type mappings only produce pure Java code, utilizing the <em>GlueGen
+Runtime</em>. Hence no additional native code must be compiled nor a
+resulting additional library loaded to use the mapping.</p>
<p>Only when mapping <em>function-pointer</em> within <em>structs</em>,
additional native glue-code is produced to call the underlying native
function which has to be compiled and its library loaded.</p>
@@ -1686,7 +1708,33 @@ IndexOutOfBoundsException is thrown</li>
<li>this instance of chaining</li>
</ul></li>
</ul>
-<h3 id="struct-function-pointer-support">Struct Function Pointer
+<h3 id="struct-pointer-pointer-support">Struct Pointer-Pointer
+Support</h3>
+<p>See primitive <a href="#pointer-mapping"><em>Pointer Mapping</em></a>
+above.</p>
+<p><em>Pointer</em> are exposed in the following examples</p>
+<pre><code>typedef struct {
+ int32_t* int32PtrArray[10];
+ int32_t** int32PtrPtr;
+
+ ...
+} T2_PointerStorage;</code></pre>
+<p>or via and undefined forward-declared struct</p>
+<pre><code>typedef struct T2_UndefStruct* T2_UndefStructPtr;
+
+typedef struct {
+ ...
+
+ T2_UndefStructPtr undefStructPtr;
+ T2_UndefStructPtr undefStructPtrArray[10];
+ T2_UndefStructPtr* undefStructPtrPtr;
+ const T2_UndefStructPtr* constUndefStructPtrPtr;
+} T2_PointerStorage;</code></pre>
+<p>and the following GlueGen configuration</p>
+<pre><code>Opaque long T2_UndefStruct*
+Ignore T2_UndefStruct</code></pre>
+<p><em>TODO: Enhance documentation</em></p>
+<h3 id="struct-function-pointer-support">Struct Function-Pointer
Support</h3>
<p>GlueGen supports function pointers as struct fields,<br />
generating function calls as methods as well function-pointer opaque
@@ -1703,10 +1751,22 @@ typedef int32_t ( * T2_CustomFuncA)(void* aptr);
typedef int32_t ( * T2_CustomFuncB)(T2_UserData* pUserData);
typedef struct {
- const T2_CustomFuncA CustomFuncA1;
- T2_CustomFuncB CustomFuncB1;
+ ...
+
+ T2_CustomFuncA customFuncAVariantsArray[10];
+ T2_CustomFuncA* customFuncAVariantsArrayPtr;
+
+ T2_CustomFuncB customFuncBVariantsArray[10];
+ T2_CustomFuncB* customFuncBVariantsArrayPtr;
+} T2_PointerStorage;
+
+typedef struct {
+ ...
+
+ const T2_CustomFuncA CustomFuncA1;
+ T2_CustomFuncB CustomFuncB1;
} T2_InitializeOptions;</code></pre>
-<p>and the following GlueGen <em>no-magic</em> configuration</p>
+<p>and the following GlueGen configuration</p>
<pre><code>Opaque long void*
EmitStruct T2_UserData
@@ -1745,6 +1805,17 @@ StructPackage T2_InitializeOptions com.jogamp.gluegen.test.junit.generation</cod
/** Interface to C language function: &lt;br&gt; &lt;code&gt;int32_t CustomFuncB1(T2_UserData * pUserData)&lt;/code&gt;&lt;br&gt; */
public final int CustomFuncB1(T2_UserData pUserData) { .. } </code></pre>
+<h3 id="java-callback-from-native-c-api-support">Java Callback from
+Native C-API Support</h3>
+<p>GlueGen supports registering Java callback methods to native C-API
+functions in the form:</p>
+<pre><code>typedef int32_t ( * T_CallbackFunc)(size_t id, size_t msg_len, const char* msg, void* userParam);
+
+void AddMessageCallback(T_CallbackFunc func, void* userParam);
+void RemoveMessageCallback(T_CallbackFunc func, void* userParam);
+void InjectMessageCallback(size_t id, size_t msg_len, const char* msg);</code></pre>
+<p><em>TODO: Work in progress</em></p>
+<h4 id="example-1">Example</h4>
<h2 id="platform-header-files">Platform Header Files</h2>
<p>GlueGen provides convenient platform headers,<br />
which can be included in your C header files for native compilation and
diff --git a/doc/GlueGen_Mapping.md b/doc/GlueGen_Mapping.md
index 87124e7..2a0de78 100644
--- a/doc/GlueGen_Mapping.md
+++ b/doc/GlueGen_Mapping.md
@@ -80,6 +80,15 @@ Gluegen has build-in types (terminal symbols) for:
* Anonymous void-pointer _void\*_ are mapped to NIO _Buffer_.
* Pointers to pointer-size types like _intptr\_t\*_, _uintptr\_t\*_, _ptrdiff\_t\*_ and _size\_t\*_ are mapped to _PointerBuffer_, to reflect the architecture depending storage size.
+### Pointer Mapping
+*Pointer* values itself are represented as `long` values on the Java side
+while using the native pointer-size, e.g. 32-bit or 64-bit, on the native end.
+
+They may simply be accessible via `long` or `long[]` primitives in Java,
+or are exposed via `com.jogamp.common.nio.PointerBuffer`.
+
+See [Struct Pointer-Pointer Support](#struct-pointer-pointer-support) below.
+
### String Mapping
#### Function return String values
@@ -199,14 +208,16 @@ A *Struct* is a C compound type declaration, which can be mapped to a Java class
A *Struct* may utilize the following data types for its fields
* *Primitive*, i.e. *char*, *int32_t*, ...
* See [*Primitive Mapping*](#primitive-mapping) above.
+ * See [*Pointer Mapping*](#pointer-mapping) for *pointer-to-pointer* values above and [Struct Pointer-Pointer Support](#struct-pointer-pointer-support) below.
* See [*String Mapping*](#string-mapping) above.
-* *Struct*, i.e. another compound variable
-* *Function Pointer*, a *typedef*'ed and set callable function pointer
+* *Struct*, i.e. an aggregated or referenced compound variable
+* *Function Pointer*, a *typedef*'ed and set callable function pointer, see [Struct Function-Pointer Support](#struct-function-pointer-support) below.
+* *Java Callback from Native Code*, see [section below](#java-callback-from-native-c-api-support)
A field may be a direct aggregation, i.e. instance, within the struct including an array
or a reference to a single element or array via a pointer.
-Both, *primitive* and *struct* field type mappings only produce pure Java code, utilizing the *GlueGen Runtime*.
+Both, *primitive*, *struct* and *pointer* field type mappings only produce pure Java code, utilizing the *GlueGen Runtime*.
Hence no additional native code must be compiled nor a resulting additional library loaded to use the mapping.
Only when mapping *function-pointer* within *structs*, additional native glue-code is produced to
@@ -537,7 +548,42 @@ A similar mapping is produced for `struct` types, i.e. *compounds*.
Returns:
* this instance of chaining
-### Struct Function Pointer Support
+### Struct Pointer-Pointer Support
+See primitive [*Pointer Mapping*](#pointer-mapping) above.
+
+*Pointer* are exposed in the following examples
+```
+typedef struct {
+ int32_t* int32PtrArray[10];
+ int32_t** int32PtrPtr;
+
+ ...
+} T2_PointerStorage;
+```
+
+or via and undefined forward-declared struct
+```
+typedef struct T2_UndefStruct* T2_UndefStructPtr;
+
+typedef struct {
+ ...
+
+ T2_UndefStructPtr undefStructPtr;
+ T2_UndefStructPtr undefStructPtrArray[10];
+ T2_UndefStructPtr* undefStructPtrPtr;
+ const T2_UndefStructPtr* constUndefStructPtrPtr;
+} T2_PointerStorage;
+```
+
+and the following GlueGen configuration
+```
+Opaque long T2_UndefStruct*
+Ignore T2_UndefStruct
+```
+
+*TODO: Enhance documentation*
+
+### Struct Function-Pointer Support
GlueGen supports function pointers as struct fields,
generating function calls as methods as well function-pointer opaque getter and setter as `long` types.
The latter only in case if mutable, i.e. non-const.
@@ -554,12 +600,24 @@ typedef int32_t ( * T2_CustomFuncA)(void* aptr);
typedef int32_t ( * T2_CustomFuncB)(T2_UserData* pUserData);
typedef struct {
- const T2_CustomFuncA CustomFuncA1;
- T2_CustomFuncB CustomFuncB1;
+ ...
+
+ T2_CustomFuncA customFuncAVariantsArray[10];
+ T2_CustomFuncA* customFuncAVariantsArrayPtr;
+
+ T2_CustomFuncB customFuncBVariantsArray[10];
+ T2_CustomFuncB* customFuncBVariantsArrayPtr;
+} T2_PointerStorage;
+
+typedef struct {
+ ...
+
+ const T2_CustomFuncA CustomFuncA1;
+ T2_CustomFuncB CustomFuncB1;
} T2_InitializeOptions;
```
-and the following GlueGen *no-magic* configuration
+and the following GlueGen configuration
```
Opaque long void*
@@ -606,6 +664,20 @@ and similar to `T2_CustomFuncB customFuncB1`
public final int CustomFuncB1(T2_UserData pUserData) { .. }
```
+### Java Callback from Native C-API Support
+GlueGen supports registering Java callback methods to native C-API functions in the form:
+```
+typedef int32_t ( * T_CallbackFunc)(size_t id, size_t msg_len, const char* msg, void* userParam);
+
+void AddMessageCallback(T_CallbackFunc func, void* userParam);
+void RemoveMessageCallback(T_CallbackFunc func, void* userParam);
+void InjectMessageCallback(size_t id, size_t msg_len, const char* msg);
+```
+
+*TODO: Work in progress*
+
+#### Example
+
## Platform Header Files
GlueGen provides convenient platform headers,
diff --git a/make/scripts/runtest.sh b/make/scripts/runtest.sh
index cf1aa6d..40cd4c5 100755
--- a/make/scripts/runtest.sh
+++ b/make/scripts/runtest.sh
@@ -151,8 +151,9 @@ function onetest() {
#onetest com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter 2>&1 | tee -a $LOG
#onetest com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter 2>&1 | tee -a $LOG
#onetest com.jogamp.gluegen.test.junit.generation.Test1p2LoadJNIAndImplLib 2>&1 | tee -a $LOG
-#onetest com.jogamp.gluegen.test.junit.generation.Test1p2DynamicLibraryBundle 2>&1 | tee -a $LOG
+onetest com.jogamp.gluegen.test.junit.generation.Test1p2DynamicLibraryBundle 2>&1 | tee -a $LOG
onetest com.jogamp.gluegen.test.junit.generation.Test2FuncPtr 2>&1 | tee -a $LOG
+onetest com.jogamp.gluegen.test.junit.generation.Test3PtrStorage 2>&1 | tee -a $LOG
#onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen01 2>&1 | tee -a $LOG
#onetest com.jogamp.gluegen.test.junit.structgen.TestStructGen02 2>&1 | tee -a $LOG
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index 110bf50..4fcec8f 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -1052,7 +1052,7 @@ public class JavaEmitter implements GlueEmitter {
}
javaUnit.emitln(" /** Returns new instance dereferencing ByteBuffer at given native address `addr` with size {@link #size()}. */");
javaUnit.emitln(" public static " + containingJTypeName + " derefPointer(final long addr) {");
- javaUnit.emitln(" return create( ElementBuffer.derefPointer(size(), 1, addr).getByteBuffer() );");
+ javaUnit.emitln(" return create( ElementBuffer.derefPointer(size(), addr, 1).getByteBuffer() );");
javaUnit.emitln(" }");
javaUnit.emitln();
if( !cfg.manuallyImplement(JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, containingJTypeName)) ) {
@@ -1091,12 +1091,13 @@ public class JavaEmitter implements GlueEmitter {
final boolean immutableField = immutableStruct || cfg.immutableAccess(fqStructFieldName1);
if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: %s / %s (opaque %b), %s (opaque %b), immutable[struct %b, field %b]%n", (i+1),
- (i+1), field, fqStructFieldName1, isOpaqueField, fieldType.getDebugString(), isOpaqueFieldType,
+ System.err.printf("SE.ac.%02d: field %s / %s / rename %s -> %s / opaque %b, fieldType %s (opaque %b), immutable[struct %b, field %b]%n", (i+1),
+ field, fqStructFieldName1, renamed, fieldName, isOpaqueField, fieldType.getDebugString(), isOpaqueFieldType,
immutableStruct, immutableField);
+ System.err.printf("SE.ac.%02d: opaqueFieldType %s%n", (i+1), opaqueFieldType);
}
if ( fieldType.isFunctionPointer() && !isOpaqueField ) {
- final FunctionSymbol func = new FunctionSymbol(field.getName(), fieldType.asPointer().getTargetType().asFunction());
+ final FunctionSymbol func = new FunctionSymbol(field.getName(), fieldType.getTargetFunction());
func.rename(renamed); // null is OK
final String javaTypeName = "long";
final String capFieldName = capitalizeString(fieldName);
@@ -1251,11 +1252,16 @@ public class JavaEmitter implements GlueEmitter {
relationship = "being";
} else if( fieldType.isPointer() ) {
isArray = true;
- referencedType = fieldType.getBaseType();
+ referencedType = fieldType.getTargetType();
relationship = "referencing";
} else if( fieldType.isArray() ) {
isArray = true;
- referencedType = null;
+ final Type t = fieldType.getArrayBaseOrPointerTargetType();
+ if( t != fieldType && t.isPointer() ) {
+ referencedType = t;
+ } else {
+ referencedType = null;
+ }
relationship = "being";
} else {
isArray = false;
@@ -1614,25 +1620,21 @@ public class JavaEmitter implements GlueEmitter {
final boolean immutableAccess,
final String fqStructFieldName) throws Exception {
final Type fieldType = field.getType();
- final JavaType javaType;
- try {
- javaType = typeToJavaType(fieldType, machDescJava);
- } catch (final Exception e) {
- throw new GlueGenException("Error occurred while creating array/pointer accessor for field \"" +
- fqStructFieldName + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag(), e);
- }
+ final TypeInfo opaqueTypeInfo = cfg.typeInfo(fieldType);
+ final boolean isOpaque = null != opaqueTypeInfo;
+ final Type baseElemType = fieldType.getArrayBaseOrPointerTargetType();
if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: fieldName %s, fqName %s%n", (i+1), fieldName, fqStructFieldName);
- System.err.printf("SE.ac.%02d: structCType %s, %s%n", (i+1), structCType.toString(), structCType.getSignature(null).toString());
- System.err.printf("SE.ac.%02d: fieldType %s, %s%n", (i+1), fieldType.toString(), fieldType.getSignature(null).toString());
- System.err.printf("SE.ac.%02d: javaType %s, %s%n", (i+1), javaType.toString(), javaType.getSignature(null).toString());
+ System.err.printf("SE.ac.%02d: fieldName %s, fqName %s%n", (i+1), fieldName, fqStructFieldName);
+ System.err.printf("SE.ac.%02d: structCType %s, %s%n", (i+1), structCType.toString(), structCType.getSignature(null).toString());
+ System.err.printf("SE.ac.%02d: fieldType %s, %s%n", (i+1), fieldType.toString(), fieldType.getSignature(null).toString());
+ System.err.printf("SE.ac.%02d: opaqueInfo %b, %s%n", (i+1), isOpaque, opaqueTypeInfo);
+ System.err.printf("SE.ac.%02d: baseElemType %s, %s%n", (i+1), baseElemType.toString(), baseElemType.getSignature(null).toString());
}
//
// Collect all required information including considering Opaque types
//
final String containingJTypeName = containingJType.getName();
- final boolean isOpaque = isOpaque(fieldType);
final boolean isStringOnly = cfg.returnsStringOnly(fqStructFieldName); // exclude alternative ByteBuffer representation to String
final boolean isString = isStringOnly || cfg.returnsString(fqStructFieldName);
if( isString ) {
@@ -1648,11 +1650,12 @@ public class JavaEmitter implements GlueEmitter {
final boolean staticElemCount;
final JavaType baseJElemType;
final String baseJElemTypeName;
- final boolean primCElemFixedSize; // Is Primitive element size fixed? If not, use md.*_Size[]
- final String baseCElemSizeDenominator;
+ final boolean primElemFixedSize; // Is Primitive element size fixed? If not, use md.*_Size[]
+ final boolean baseIsPointer; // Is Primitive element a pointer?
+ final String baseElemSizeDenominator;
final boolean useGetCStringLength;
final boolean maxOneElement; // zero or one element
- if( isOpaque || javaType.isPrimitive() ) {
+ if( isOpaque && opaqueTypeInfo.pointerDepth() <= 1 || ( fieldType.isPrimitive() && !baseElemType.isFunctionPointer() ) ) {
// Overridden by JavaConfiguration.typeInfo(..), i.e. Opaque!
// Emulating array w/ 1 element
isPrimitive = true;
@@ -1663,37 +1666,27 @@ public class JavaEmitter implements GlueEmitter {
ownership = Ownership.Parent;
staticElemCount = true;
baseJElemType = null;
- baseJElemTypeName = compatiblePrimitiveJavaTypeName(fieldType, javaType, machDescJava);
- primCElemFixedSize = false;
- baseCElemSizeDenominator = fieldType.isPointer() ? "pointer" : baseJElemTypeName ;
+ baseJElemTypeName = compatiblePrimitiveJavaTypeName(fieldType, machDescJava);
+ primElemFixedSize = false;
+ baseIsPointer = fieldType.isPointer();
+ baseElemSizeDenominator = baseIsPointer ? "pointer" : baseJElemTypeName ;
useGetCStringLength = false;
maxOneElement = true;
} else {
- final ArrayType arrayType = fieldType.asArray();
- final Type baseCElemType;
- if( null != arrayType ) {
+ if( fieldType.arrayDimension() > 0 ) {
final int[][] arrayLengthRes = new int[1][];
final boolean[] _useFixedArrayLen = { false };
- elemCountExpr = getArrayArrayLengthExpr(arrayType, fqStructFieldName, _useFixedArrayLen, arrayLengthRes);
+ elemCountExpr = getArrayArrayLengthExpr(fieldType.asArray(), fqStructFieldName, _useFixedArrayLen, arrayLengthRes);
// final int arrayLength = arrayLengthRes[0][0];
constElemCount = _useFixedArrayLen[0];
ownership = Ownership.Parent; // a fixed linear array
staticElemCount = constElemCount;
- baseCElemType = arrayType.getBaseType();
+ // baseCElemType = pointerType.getBaseType();
isPointer = false;
useGetCStringLength = false;
} else {
- final PointerType pointerType = fieldType.asPointer();
final String _elemCountExpr = cfg.returnedArrayLength(fqStructFieldName);
- baseCElemType = pointerType.getBaseType();
isPointer = true;
- if( 1 != pointerType.pointerDepth() ) {
- final String msg = "SKIP ptr-ptr (depth "+pointerType.pointerDepth()+"): "+fqStructFieldName +": "+fieldType;
- unit.emitln(" // "+msg);
- unit.emitln();
- LOG.log(WARNING, structCType.getASTLocusTag(), msg);
- return;
- }
if( null == _elemCountExpr && isString ) {
useGetCStringLength = true;
unit.addTailCode(optStringMaxStrnlenCode);
@@ -1746,7 +1739,8 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" // "+msg);
unit.emitln();
LOG.log(WARNING, structCType.getASTLocusTag(), msg);
- return;
+ throw new InternalError(msg);
+ // return; // FIXME: Remove block unreachable
}
boolean _maxOneElement = cfg.maxOneElement(fqStructFieldName);
if( !_maxOneElement ) {
@@ -1756,41 +1750,45 @@ public class JavaEmitter implements GlueEmitter {
}
maxOneElement = _maxOneElement;
if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: baseCType ownership %s, %s%n", (i+1), ownership, baseCElemType.getSignature(null).toString());
+ System.err.printf("SE.ac.%02d: ownership %s%n", (i+1), ownership);
}
- if( !baseCElemType.hasSize() ) { // like 'void*' -> 'void'
- final String msg = "SKIP unsized field in struct: "+fqStructFieldName+": fieldType "+fieldType.getSignature(null).toString()+", baseType "+baseCElemType.getSignature(null).toString();
+ if( !baseElemType.hasSize() ) { // like 'void*' -> 'void'
+ final String msg = "SKIP unsized field in struct: "+fqStructFieldName+": fieldType "+fieldType.getSignature(null).toString()+", baseType "+baseElemType.getSignature(null).toString();
unit.emitln(" // "+msg);
unit.emitln();
LOG.log(WARNING, structCType.getASTLocusTag(), msg);
return;
}
- isPrimitive = baseCElemType.isPrimitive();
- isConstValue = baseCElemType.isConst();
- try {
- baseJElemType = typeToJavaType(baseCElemType, machDescJava);
- } catch (final Exception e ) {
- throw new GlueGenException("Error occurred while creating array/pointer accessor for field \"" +
- fqStructFieldName + "\", baseType "+baseCElemType.getDebugString()+", topType "+fieldType.getDebugString(),
- fieldType.getASTLocusTag(), e);
+ baseIsPointer = baseElemType.isPointer();
+ isConstValue = baseElemType.isConst();
+ if( baseIsPointer ) {
+ baseJElemType = javaType(Long.TYPE); // forced mapping pointer-pointer -> long
+ } else {
+ try {
+ baseJElemType = typeToJavaType(baseElemType, machDescJava);
+ } catch (final Exception e ) {
+ throw new GlueGenException("Error occurred while creating array/pointer accessor for field \"" +
+ fqStructFieldName + "\", baseType "+baseElemType.getDebugString()+", topType "+fieldType.getDebugString(),
+ fieldType.getASTLocusTag(), e);
+ }
}
baseJElemTypeName = baseJElemType.getName();
- primCElemFixedSize = isPrimitive ? baseCElemType.getSize().hasFixedNativeSize() : false;
- baseCElemSizeDenominator = baseCElemType.isPointer() ? "pointer" : baseJElemTypeName ;
+ isPrimitive = baseJElemType.isPrimitive() || baseElemType.isPrimitive() || baseElemType.isFunctionPointer();
+ primElemFixedSize = isPrimitive ? baseElemType.getSize().hasFixedNativeSize() : false;
+ baseElemSizeDenominator = baseIsPointer ? "pointer" : baseJElemTypeName ;
}
if( GlueGen.debug() ) {
System.err.printf("SE.ac.%02d: baseJElemType %s%n", (i+1), (null != baseJElemType ? baseJElemType.getDebugString() : null));
}
// Collect fixed primitive-type mapping metrics
- final Class<? extends Buffer> primJElemTypeBufferClazz;
final String primJElemTypeBufferName;
final int primElemSize;
final String primElemSizeExpr;
final boolean isByteBuffer;
if( isPrimitive ) {
- primJElemTypeBufferClazz = Buffers.typeNameToBufferClass(baseJElemTypeName);
+ final Class<? extends Buffer> primJElemTypeBufferClazz = Buffers.typeNameToBufferClass(baseJElemTypeName);
if( null == primJElemTypeBufferClazz ) {
final String msg = "Failed to map '"+baseJElemTypeName+"' to Buffer class, field "+field+", j-type "+baseJElemType;
unit.emitln(" // ERROR: "+msg);
@@ -1801,13 +1799,12 @@ public class JavaEmitter implements GlueEmitter {
primJElemTypeBufferName = primJElemTypeBufferClazz.getSimpleName();
primElemSize = Buffers.sizeOfBufferElem(primJElemTypeBufferClazz);
isByteBuffer = null != primJElemTypeBufferClazz ? ByteBuffer.class.isAssignableFrom(primJElemTypeBufferClazz) : false;
- if( primCElemFixedSize ) {
+ if( primElemFixedSize ) {
primElemSizeExpr = String.valueOf(primElemSize);
} else {
- primElemSizeExpr = "md."+baseCElemSizeDenominator+"SizeInBytes()";
+ primElemSizeExpr = "md."+baseElemSizeDenominator+"SizeInBytes()";
}
} else {
- primJElemTypeBufferClazz = null;
primJElemTypeBufferName = null;
primElemSize = 0;
isByteBuffer = false;
@@ -1839,12 +1836,12 @@ public class JavaEmitter implements GlueEmitter {
if( GlueGen.debug() ) {
System.err.printf("SE.ac.%02d: baseJElemTypeName %s%n", (i+1), baseJElemTypeName);
System.err.printf("SE.ac.%02d: elemCountExpr: %s (const %b, ownership %s), ownArrayLenCpde %b, maxOneElement %b, "+
- "Primitive[buffer %s, fixedSize %b, elemSize %d, sizeDenom %s, sizeExpr %s, isByteBuffer %b], "+
- "isString[%b, only %b, strnlen %b], isPointer %b, isPrimitive %b, isOpaque %b, constVal %b, immutableAccess %b%n",
+ "Primitive[is %b, aptr %b, buffer %s, fixedSize %b, elemSize %d, sizeDenom %s, sizeExpr %s, isByteBuffer %b], "+
+ "isString[%b, only %b, strnlen %b], isPointer %b, isOpaque %b, constVal %b, immutableAccess %b%n",
(i+1), elemCountExpr, constElemCount, ownership, ownElemCountHandling, maxOneElement,
- primJElemTypeBufferName, primCElemFixedSize, primElemSize, baseCElemSizeDenominator, primElemSizeExpr, isByteBuffer,
+ isPrimitive, baseIsPointer, primJElemTypeBufferName, primElemFixedSize, primElemSize, baseElemSizeDenominator, primElemSizeExpr, isByteBuffer,
isString, isStringOnly, useGetCStringLength,
- isPointer, isPrimitive, isOpaque, isConstValue, immutableAccess);
+ isPointer, isOpaque, isConstValue, immutableAccess);
}
//
@@ -1889,7 +1886,11 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" return this;");
unit.emitln(" }");
unit.emitln(" @SuppressWarnings(\"unused\")");
- unit.emitln(" private ElementBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
+ if( baseIsPointer ) {
+ unit.emitln(" private PointerBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
+ } else {
+ unit.emitln(" private ElementBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
+ }
unit.emitln();
}
}
@@ -1917,12 +1918,17 @@ public class JavaEmitter implements GlueEmitter {
throw new InternalError("Native ownership but adding potential memory-replacement for '"+fqStructFieldName+"': "+fieldType.getSignature(null).toString());
}
unit.emitln(" {");
- unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", 1);");
- unit.emit (" eb.getByteBuffer()");
- if( !isByteBuffer ) {
- unit.emit(".as"+primJElemTypeBufferName+"()");
+ if( baseIsPointer ) {
+ unit.emitln(" final PointerBuffer eb = PointerBuffer.allocateDirect(1);");
+ unit.emitln(" eb.put(0, src);");
+ } else {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", 1);");
+ unit.emit (" eb.getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".put(0, src);");
}
- unit.emitln(".put(0, src);");
unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
unit.emitln(" _eb"+capitalFieldName+" = eb;");
emitSetElemCount(unit, setElemCountLengthFunc, "1", !useGetCStringLength, capitalFieldName, structCType, " ");
@@ -1932,12 +1938,17 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" {");
unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
unit.emitln(" if( 1 == elemCount ) {");
- unit.emitln(" ElementBuffer.derefPointer("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
- unit.emit (" .getByteBuffer()");
- if( !isByteBuffer ) {
- unit.emit(".as"+primJElemTypeBufferName+"()");
+ if( baseIsPointer ) {
+ unit.emitln(" PointerBuffer.derefPointer(getBuffer(), "+fieldName+"_offset[mdIdx], 1)");
+ unit.emitln(" .put(0, src);");
+ } else {
+ unit.emitln(" ElementBuffer.derefPointer("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], 1)");
+ unit.emit (" .getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".put(0, src);");
}
- unit.emitln(".put(0, src);");
unit.emitln(" } else {");
if( constElemCount || Ownership.Native == ownership ) {
unit.emitln(" throw new RuntimeException(\"Primitive '"+fieldName+"' of "+ownership+" ownership and maxOneElement has "
@@ -1946,12 +1957,17 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" return this;");
unit.emitln(" }");
} else {
- unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", 1);");
- unit.emit (" eb.getByteBuffer()");
- if( !isByteBuffer ) {
- unit.emit(".as"+primJElemTypeBufferName+"()");
+ if( baseIsPointer ) {
+ unit.emitln(" final PointerBuffer eb = PointerBuffer.allocateDirect(1);");
+ unit.emitln(" eb.put(0, src);");
+ } else {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", 1);");
+ unit.emit (" eb.getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".put(0, src);");
}
- unit.emitln(".put(0, src);");
unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
unit.emitln(" _eb"+capitalFieldName+" = eb;");
emitSetElemCount(unit, setElemCountLengthFunc, "1", !useGetCStringLength, capitalFieldName, structCType, " ");
@@ -1964,12 +1980,16 @@ public class JavaEmitter implements GlueEmitter {
generateSetterSignature(unit, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, null, baseJElemTypeName,
null, constElemCount, maxOneElement, elemCountExpr, null, null);
unit.emitln(" {");
- unit.emitln(" ElementBuffer.wrap("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
- unit.emit (" .getByteBuffer()");
- if( !isByteBuffer ) {
- unit.emit(".as"+primJElemTypeBufferName+"()");
+ if( baseIsPointer ) {
+ unit.emitln(" PointerBuffer.wrap(getBuffer(), "+fieldName+"_offset[mdIdx], 1).put(0, src);");
+ } else {
+ unit.emitln(" ElementBuffer.wrap("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], 1)");
+ unit.emit (" .getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".put(0, src);");
}
- unit.emitln(".put(0, src);");
unit.emitln(" return this;");
unit.emitln(" }");
} // else SKIP setter for constValue Array
@@ -1988,7 +2008,7 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
unit.emitln(" if( srcBytes.length + 1 != elemCount ) { throw new IllegalArgumentException(\"strlen+1 \"+(srcBytes.length+1)+\" != "
+(constElemCount?"const":"")+" elemCount \"+elemCount+\" of "+ownership+" ownership\"); };");
- unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
} else {
unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", srcBytes.length + 1);");
}
@@ -2014,14 +2034,13 @@ public class JavaEmitter implements GlueEmitter {
throw new InternalError("Native ownership but adding potential memory-replacement for '"+fqStructFieldName+"': "+fieldType.getSignature(null).toString());
}
unit.emitln(" {");
- unit.emitln(SetReplaceArrayArgsCheck);
- unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", length);");
- unit.emit (" eb.getByteBuffer()");
- if( !isByteBuffer ) {
- unit.emit(".as"+primJElemTypeBufferName+"()");
+ // JAU01 unit.emitln(SetReplaceArrayArgsCheck);
+ if( baseIsPointer ) {
+ unit.emitln(" final PointerBuffer eb = PointerBuffer.allocateDirect(length);");
+ } else {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", length);");
}
- unit.emitln(".put(src, srcPos, length).rewind();");
- unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" eb.put(src, srcPos, 0, length).storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
unit.emitln(" _eb"+capitalFieldName+" = eb;");
emitSetElemCount(unit, setElemCountLengthFunc, "length", !useGetCStringLength, capitalFieldName, structCType, " ");
unit.emitln(" return this;");
@@ -2031,19 +2050,23 @@ public class JavaEmitter implements GlueEmitter {
generateSetterSignature(unit, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, null,
baseJElemTypeName+"[]", SetSubArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetSubArrayApiDocDetail, SetSubArrayApiDocArgs);
unit.emitln(" {");
- unit.emitln(SetSubArrayArgsCheck);
+ // JAU01 unit.emitln(SetSubArrayArgsCheck);
unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
- unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
- if( isPointer ) {
- unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ // JAU01 unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
+ if( baseIsPointer ) {
+ if( isPointer ) {
+ unit.emitln(" final PointerBuffer eb = PointerBuffer.derefPointer(getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
+ } else {
+ unit.emitln(" final PointerBuffer eb = PointerBuffer.wrap(getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
+ }
} else {
- unit.emitln(" final ElementBuffer eb = ElementBuffer.wrap("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
- }
- unit.emit (" ( ("+primJElemTypeBufferName+") eb.getByteBuffer()");
- if( !isByteBuffer ) {
- unit.emit(".as"+primJElemTypeBufferName+"()");
+ if( isPointer ) {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
+ } else {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.wrap("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
+ }
}
- unit.emitln(".position(destPos) ).put(src, srcPos, length).rewind();");
+ unit.emitln(" eb.put(src, srcPos, destPos, length);");
unit.emitln(" return this;");
unit.emitln(" }");
} else /* if( !constElemCount && isPointer ) */ {
@@ -2053,34 +2076,33 @@ public class JavaEmitter implements GlueEmitter {
throw new InternalError("Native ownership but adding potential memory-replacement for '"+fqStructFieldName+"': "+fieldType.getSignature(null).toString());
}
unit.emitln(" {");
- unit.emitln(SetArrayArgsCheck);
+ // JAU01 unit.emitln(SetArrayArgsCheck);
unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
unit.emitln(" if( subset || destPos + length == elemCount ) {");
- unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"subset \"+subset+\", destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
- unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
- unit.emit (" ( ("+primJElemTypeBufferName+") eb.getByteBuffer()");
- if( !isByteBuffer ) {
- unit.emit(".as"+primJElemTypeBufferName+"()");
+ // JAU01 unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"subset \"+subset+\", destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
+ if( baseIsPointer ) {
+ unit.emitln(" final PointerBuffer eb = PointerBuffer.derefPointer(getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
+ } else {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
}
- unit.emitln(".position(destPos) ).put(src, srcPos, length).rewind();");
+ unit.emitln(" eb.put(src, srcPos, destPos, length);");
unit.emitln(" } else {");
unit.emitln(" final int newElemCount = destPos + length;");
- unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", newElemCount);");
- unit.emit (" final "+primJElemTypeBufferName+" ebBB = eb.getByteBuffer()");
- if( !isByteBuffer ) {
- unit.emit(".as"+primJElemTypeBufferName+"()");
- }
- unit.emitln(";");
- unit.emitln(" if( 0 < destPos ) {");
- unit.emitln(" final ElementBuffer pre_eb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
- unit.emit (" final "+primJElemTypeBufferName+" pre_ebBB = ("+primJElemTypeBufferName+") pre_eb.getByteBuffer()");
- if( !isByteBuffer ) {
- unit.emit(".as"+primJElemTypeBufferName+"()");
+ if( baseIsPointer ) {
+ unit.emitln(" final PointerBuffer eb = PointerBuffer.allocateDirect(newElemCount);");
+ unit.emitln(" if( 0 < destPos ) {");
+ unit.emitln(" final PointerBuffer pre_eb = PointerBuffer.derefPointer(getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
+ unit.emitln(" pre_eb.position(0).limit(destPos);");
+ unit.emitln(" eb.put(pre_eb).rewind();");
+ unit.emitln(" }");
+ } else {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", newElemCount);");
+ unit.emitln(" if( 0 < destPos ) {");
+ unit.emitln(" final ElementBuffer pre_eb = ElementBuffer.derefPointer("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
+ unit.emitln(" eb.put(pre_eb.getByteBuffer(), 0, 0, destPos);");
+ unit.emitln(" }");
}
- unit.emitln(".position(0).limit(destPos);");
- unit.emitln(" ebBB.put(pre_ebBB);");
- unit.emitln(" }");
- unit.emitln(" ebBB.put(src, srcPos, length).rewind();");
+ unit.emitln(" eb.put(src, srcPos, destPos, length);");
unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
unit.emitln(" _eb"+capitalFieldName+" = eb;");
emitSetElemCount(unit, setElemCountLengthFunc, "newElemCount", !useGetCStringLength, capitalFieldName, structCType, " ");
@@ -2114,7 +2136,7 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" {");
unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
unit.emitln(" if( 1 == elemCount ) {");
- unit.emitln(" ElementBuffer.derefPointer("+baseJElemTypeName+".size(), 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
+ unit.emitln(" ElementBuffer.derefPointer("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], 1)");
unit.emitln(" .put(0, src.getBuffer());");
unit.emitln(" } else {");
if( constElemCount || Ownership.Native == ownership ) {
@@ -2138,7 +2160,7 @@ public class JavaEmitter implements GlueEmitter {
generateSetterSignature(unit, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, null, baseJElemTypeName,
null, constElemCount, maxOneElement, elemCountExpr, null, null);
unit.emitln(" {");
- unit.emitln(" ElementBuffer.wrap("+baseJElemTypeName+".size(), 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
+ unit.emitln(" ElementBuffer.wrap("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], 1)");
unit.emitln(" .put(0, src.getBuffer());");
unit.emitln(" return this;");
unit.emitln(" }");
@@ -2174,9 +2196,9 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
if( isPointer ) {
- unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
} else {
- unit.emitln(" final ElementBuffer eb = ElementBuffer.wrap("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.wrap("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
}
unit.emitln(" for(int i=0; i<length; ++i) {");
unit.emitln(" eb.put(destPos+i, src[srcPos+i].getBuffer());");
@@ -2194,7 +2216,7 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
unit.emitln(" if( subset || destPos + length == elemCount ) {");
unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"subset \"+subset+\", destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
- unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
unit.emitln(" for(int i=0; i<length; ++i) {");
unit.emitln(" eb.put(destPos+i, src[srcPos+i].getBuffer());");
unit.emitln(" }");
@@ -2203,7 +2225,7 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+baseJElemTypeName+".size(), newElemCount);");
unit.emitln(" if( 0 < destPos ) {");
- unit.emitln(" final ElementBuffer pre_eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" final ElementBuffer pre_eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
unit.emitln(" eb.put(pre_eb.getByteBuffer(), 0, 0, destPos);");
unit.emitln(" }");
unit.emitln(" for(int i=0; i<length; ++i) {");
@@ -2224,9 +2246,9 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
unit.emitln(" if( destPos + 1 > elemCount ) { throw new IndexOutOfBoundsException(\"destPos \"+destPos+\" + 1 > elemCount \"+elemCount); };");
if( isPointer ) {
- unit.emitln(" ElementBuffer.derefPointer("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx])");
+ unit.emitln(" ElementBuffer.derefPointer("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], elemCount)");
} else {
- unit.emitln(" ElementBuffer.wrap("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx])");
+ unit.emitln(" ElementBuffer.wrap("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], elemCount)");
}
unit.emitln(" .put(destPos, src.getBuffer());");
unit.emitln(" return this;");
@@ -2243,14 +2265,22 @@ public class JavaEmitter implements GlueEmitter {
generateGetterSignature(unit, false, false, fieldName, fieldType, ownership, baseJElemTypeName, capitalFieldName,
null, constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail);
unit.emitln(" {");
- if( isPointer ) {
- unit.emitln(" return ElementBuffer.derefPointer("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
+ if( baseIsPointer ) {
+ if( isPointer ) {
+ unit.emit (" return PointerBuffer.derefPointer(getBuffer(), "+fieldName+"_offset[mdIdx], 1)");
+ } else {
+ unit.emit (" return PointerBuffer.wrap(getBuffer(), "+fieldName+"_offset[mdIdx], 1)");
+ }
} else {
- unit.emitln(" return ElementBuffer.wrap("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
- }
- unit.emit (" .getByteBuffer()");
- if( !isByteBuffer ) {
- unit.emit(".as"+primJElemTypeBufferName+"()");
+ if( isPointer ) {
+ unit.emitln(" return ElementBuffer.derefPointer("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], 1)");
+ } else {
+ unit.emitln(" return ElementBuffer.wrap("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], 1)");
+ }
+ unit.emit (" .getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
}
unit.emitln(".get(0);");
unit.emitln(" }");
@@ -2263,9 +2293,9 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" {");
unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
if( isPointer ) {
- unit.emitln(" final ByteBuffer bb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer();");
+ unit.emitln(" final ByteBuffer bb = ElementBuffer.derefPointer("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], elemCount).getByteBuffer();");
} else {
- unit.emitln(" final ByteBuffer bb = ElementBuffer.wrap("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer();");
+ unit.emitln(" final ByteBuffer bb = ElementBuffer.wrap("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], elemCount).getByteBuffer();");
}
unit.emitln(" final byte[] ba = new byte[elemCount];");
unit.emitln(" int i = -1;");
@@ -2281,14 +2311,14 @@ public class JavaEmitter implements GlueEmitter {
if( doneString && isStringOnly ) {
generateArrayFieldNote(unit, " /** SKIP getter for String alternative (ByteBuffer)", " */", fieldName, fieldType, ownership, constElemCount, maxOneElement, elemCountExpr, false, false);
unit.emitln();
- } else {
+ } else if( !baseIsPointer ) {
generateGetterSignature(unit, false, false, fieldName, fieldType, ownership, primJElemTypeBufferName, capitalFieldName,
null, constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail);
unit.emitln(" {");
if( isPointer ) {
- unit.emitln(" return ElementBuffer.derefPointer("+primElemSizeExpr+", "+getElemCountFuncExpr+", getBuffer(), "+fieldName+"_offset[mdIdx])");
+ unit.emitln(" return ElementBuffer.derefPointer("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], "+getElemCountFuncExpr+")");
} else {
- unit.emitln(" return ElementBuffer.wrap("+primElemSizeExpr+", "+getElemCountFuncExpr+", getBuffer(), "+fieldName+"_offset[mdIdx])");
+ unit.emitln(" return ElementBuffer.wrap("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], "+getElemCountFuncExpr+")");
}
unit.emit (" .getByteBuffer()");
if( !isByteBuffer ) {
@@ -2302,20 +2332,21 @@ public class JavaEmitter implements GlueEmitter {
generateGetterSignature(unit, false, false, fieldName, fieldType, ownership, baseJElemTypeName+"[]", capitalFieldName,
"final int srcPos, "+baseJElemTypeName+" dest[], "+GetArrayArgs, constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail);
unit.emitln(" {");
- unit.emitln(GetArrayArgsCheck);
unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
- unit.emitln(" if( srcPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"srcPos \"+srcPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
- unit.emit (" ( ("+primJElemTypeBufferName+")( ");
- if( isPointer ) {
- unit.emit("ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer()");
+ if( baseIsPointer ) {
+ if( isPointer ) {
+ unit.emit (" PointerBuffer.derefPointer(getBuffer(), "+fieldName+"_offset[mdIdx], elemCount)");
+ } else {
+ unit.emit (" PointerBuffer.wrap(getBuffer(), "+fieldName+"_offset[mdIdx], elemCount)");
+ }
} else {
- unit.emit("ElementBuffer.wrap("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer()");
- }
- if( !isByteBuffer ) {
- unit.emit(".as"+primJElemTypeBufferName+"()");
+ if( isPointer ) {
+ unit.emit(" ElementBuffer.derefPointer("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], elemCount)");
+ } else {
+ unit.emit(" ElementBuffer.wrap("+primElemSizeExpr+", getBuffer(), "+fieldName+"_offset[mdIdx], elemCount)");
+ }
}
- unit.emitln(".position(srcPos) ) )");
- unit.emitln(" .get(dest, destPos, length).rewind();");
+ unit.emitln(".get(srcPos, dest, destPos, length);");
unit.emitln(" return dest;");
unit.emitln(" }");
unit.emitln();
@@ -2329,9 +2360,9 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" {");
unit.emitln(" return "+baseJElemTypeName+".create(");
if( isPointer ) {
- unit.emitln(" ElementBuffer.derefPointer("+baseJElemTypeName+".size(), 1, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer() );");
+ unit.emitln(" ElementBuffer.derefPointer("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], 1).getByteBuffer() );");
} else {
- unit.emitln(" ElementBuffer.wrap("+baseJElemTypeName+".size(), 1, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer() );");
+ unit.emitln(" ElementBuffer.wrap("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], 1).getByteBuffer() );");
}
unit.emitln(" }");
unit.emitln();
@@ -2343,9 +2374,9 @@ public class JavaEmitter implements GlueEmitter {
unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
unit.emitln(" if( srcPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"srcPos \"+srcPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
if( isPointer ) {
- unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
} else {
- unit.emitln(" final ElementBuffer eb = ElementBuffer.wrap("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.wrap("+baseJElemTypeName+".size(), getBuffer(), "+fieldName+"_offset[mdIdx], elemCount);");
}
unit.emitln(" for(int i=0; i<length; ++i) {");
unit.emitln(" dest[destPos+i] = "+baseJElemTypeName+".create( eb.slice(srcPos+i, 1) );");
@@ -2438,6 +2469,8 @@ public class JavaEmitter implements GlueEmitter {
if (cType.pointerDepth() == 1 || cType.arrayDimension() == 1) {
if (targetType.isVoid()) {
return JavaType.createForCVoidPointer();
+ } else if( targetType.isFunctionPointer() ) {
+ return javaType(Long.TYPE);
} else if (targetType.isInt()) {
final SizeThunk targetSizeThunk = targetType.getSize();
if( null != targetSizeThunk && SizeThunk.POINTER == targetSizeThunk ) {
@@ -2586,14 +2619,6 @@ public class JavaEmitter implements GlueEmitter {
}
}
- private static boolean isIntegerType(final Class<?> c) {
- return ((c == Byte.TYPE) ||
- (c == Short.TYPE) ||
- (c == Character.TYPE) ||
- (c == Integer.TYPE) ||
- (c == Long.TYPE));
- }
-
private StructLayout getLayout() {
if (layout == null) {
layout = StructLayout.create(0);
@@ -2627,21 +2652,18 @@ public class JavaEmitter implements GlueEmitter {
}
private String compatiblePrimitiveJavaTypeName(final Type fieldType,
- final JavaType javaType,
final MachineDataInfo curMachDesc) {
- final Class<?> c = javaType.getJavaClass();
- if (!isIntegerType(c)) {
- // FIXME
- throw new GlueGenException("Can't yet handle opaque definitions of structs' fields to non-integer types (byte, short, int, long, etc.): type: "+fieldType+", javaType "+javaType+", javaClass "+c,
- fieldType.getASTLocusTag());
+ if ( !fieldType.isInt() && !fieldType.isPointer() && !fieldType.isArray() ) {
+ throw new GlueGenException("Can't yet handle opaque definitions of structs' fields to non-integer types (byte, short, int, long, etc.): type: "+
+ fieldType, fieldType.getASTLocusTag());
}
switch ((int) fieldType.getSize(curMachDesc)) {
case 1: return "byte";
case 2: return "short";
case 4: return "int";
case 8: return "long";
- default: throw new GlueGenException("Can't handle opaque definitions if the starting type isn't compatible with integral types",
- fieldType.getASTLocusTag());
+ default: throw new GlueGenException("Can't handle opaque definitions if the starting type isn't compatible with integral types, type "+
+ fieldType.getDebugString(), fieldType.getASTLocusTag());
}
}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test2FuncPtr.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test2FuncPtr.java
index 66c7178..3503fa3 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test2FuncPtr.java
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test2FuncPtr.java
@@ -114,6 +114,14 @@ public class Test2FuncPtr extends BaseClass {
Assert.assertEquals(404, ud2.getBalance());
Assert.assertEquals("Jane Doe", ud2.getName());
}
+ // Check func-ptr are original
+ {
+ final long[] funcBOrigs = options.getCustomFuncBVariants(0, new long[2], 0, 2);
+ final long funcB1 = options.getCustomFuncB1();
+ final long funcB2 = options.getCustomFuncB2();
+ Assert.assertEquals(funcBOrigs[0], funcB1);
+ Assert.assertEquals(funcBOrigs[1], funcB2);
+ }
Assert.assertEquals(101, options.CustomFuncB1(ud1));
Assert.assertEquals(404, options.CustomFuncB1(ud2));
Assert.assertEquals(-101, options.CustomFuncB2(ud1));
@@ -125,6 +133,14 @@ public class Test2FuncPtr extends BaseClass {
options.setCustomFuncB1(funcB2);
options.setCustomFuncB2(funcB1);
}
+ // Check func-ptr are switched
+ {
+ final long[] funcBOrigs = options.getCustomFuncBVariants(0, new long[2], 0, 2);
+ final long funcB1 = options.getCustomFuncB1();
+ final long funcB2 = options.getCustomFuncB2();
+ Assert.assertEquals(funcBOrigs[1], funcB1);
+ Assert.assertEquals(funcBOrigs[0], funcB2);
+ }
Assert.assertEquals(-101, options.CustomFuncB1(ud1));
Assert.assertEquals(-404, options.CustomFuncB1(ud2));
Assert.assertEquals(101, options.CustomFuncB2(ud1));
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test3PtrStorage.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test3PtrStorage.java
new file mode 100644
index 0000000..2bf82a8
--- /dev/null
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test3PtrStorage.java
@@ -0,0 +1,139 @@
+/**
+ * Copyright 2023 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.gluegen.test.junit.generation;
+
+import java.io.IOException;
+import java.nio.IntBuffer;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.nio.ElementBuffer;
+import com.jogamp.common.os.NativeLibrary;
+import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest2Impl;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+
+/**
+ * Test {@link Bindingtest2} with {@link T2_PointerStorage} instance and pointer pointer..
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class Test3PtrStorage extends BaseClass {
+
+ static NativeLibrary dynamicLookupHelper;
+
+ /**
+ * Verifies loading of the new library.
+ */
+ @BeforeClass
+ public static void chapter__TestLoadLibrary() throws Exception {
+ BindingJNILibLoader.loadBindingtest2();
+ dynamicLookupHelper = NativeLibrary.open("test2", false, false, Test2FuncPtr.class.getClassLoader(), true);
+ Assert.assertNotNull("NativeLibrary.open(test2) failed", dynamicLookupHelper);
+
+ Bindingtest2Impl.resetProcAddressTable(dynamicLookupHelper);
+ }
+
+ /**
+ * Verifies unloading of the new library.
+ */
+ @AfterClass
+ public static void chapter0XTestUnloadLibrary() throws Exception {
+ Assert.assertNotNull(dynamicLookupHelper);
+ dynamicLookupHelper.close();
+ dynamicLookupHelper = null;
+ }
+
+
+ /**
+ * Test {@link Bindingtest2} with {@link T2_PointerStorage} instance and pointer pointer
+ */
+ @Test
+ public void chapter01() throws Exception {
+ Assert.assertEquals(false, T2_PointerStorage.usesNativeCode());
+
+ final Bindingtest2 bt2 = new Bindingtest2Impl();
+ final T2_PointerStorage store = bt2.createT2PointerStorage();
+ // final T2_PointerStorage store = T2_PointerStorage.create();
+ final long[] int32PtrArray = store.getInt32PtrArray(0, new long[10], 0, 10); // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
+ {
+ Assert.assertEquals(10, int32PtrArray.length);
+ System.err.print("int32PtrArray[10] = { ");
+ for(int i=0; i<int32PtrArray.length; ++i) {
+ Assert.assertNotEquals(0, int32PtrArray[i]);
+ final ElementBuffer eb = ElementBuffer.derefPointer(Buffers.SIZEOF_INT, int32PtrArray[i], 1);
+ final IntBuffer ib = eb.getByteBuffer().asIntBuffer();
+ Assert.assertEquals(1, ib.limit());
+ final int value = ib.get(0);
+ Assert.assertEquals(i, value);
+ System.err.print(value+", ");
+ }
+ System.err.println("}");
+ }
+ Assert.assertEquals(0, store.getInt32PtrPtrElemCount());
+ store.setInt32PtrPtr(false, int32PtrArray, 3, 0, 7); // -> 3, 4, 5, 6, 7, 8, 9
+ store.setInt32PtrPtr(true, int32PtrArray, 8, 3, 2); // -> 3, 4, 5, 8, 9, 8, 9
+ store.setInt32PtrPtr(true, int32PtrArray, 0, 5, 2); // -> 3, 4, 5, 8, 9, 0, 1
+ final long[] int32PtrPtr = store.getInt32PtrPtr(0, new long[7], 0, 7); // 3, 4, 5, 8, 9, 0, 1
+ {
+ System.err.print("int32PtrPtr[7] = { ");
+ for(int i=0; i<int32PtrPtr.length; ++i) {
+ Assert.assertNotEquals(0, int32PtrPtr[i]);
+ final ElementBuffer eb = ElementBuffer.derefPointer(Buffers.SIZEOF_INT, int32PtrPtr[i], 1);
+ final IntBuffer ib = eb.getByteBuffer().asIntBuffer();
+ Assert.assertEquals(1, ib.limit());
+ final int value = ib.get(0);
+ final int exp;
+ switch( i ) {
+ case 0: exp = 3; break;
+ case 1: exp = 4; break;
+ case 2: exp = 5; break;
+ case 3: exp = 8; break;
+ case 4: exp = 9; break;
+ case 5: exp = 0; break;
+ case 6: exp = 1; break;
+ default: exp = 99;
+ }
+ Assert.assertEquals(exp, value);
+ System.err.print(value+", ");
+ }
+ System.err.println("}");
+ }
+ bt2.destroyT2PointerStorage(store);
+ }
+
+ public static void main(final String args[]) throws IOException {
+ final String tstname = Test3PtrStorage.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c
index 75eafcf..e5c1fe2 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c
@@ -1,9 +1,14 @@
-#include "test2.h"
-
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+typedef struct {
+ int value;
+} T2_UndefStruct;
+
+#include "test2.h"
+
static int32_t CustomFuncA1(void* aptr) {
(void)aptr;
return 0xa001;
@@ -33,6 +38,8 @@ int Initialize(T2_InitializeOptions* Options) {
*( (T2_CustomFuncA*) &Options->CustomFuncA2 ) = CustomFuncA2; // yuck: real yuck
Options->CustomFuncB1 = CustomFuncB1;
Options->CustomFuncB2 = CustomFuncB2;
+ Options->customFuncBVariants[0] = CustomFuncB1;
+ Options->customFuncBVariants[1] = CustomFuncB2;
Options->OverrideThreadAffinity = NULL;
}
@@ -52,4 +59,31 @@ int Release(T2_InitializeOptions* Options) {
Options->CustomFuncB2 = NULL;
}
+static int32_t StaticInt32Array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+static T2_UndefStruct StaticUndefStructArray[] = { { 0 }, { 1 }, { 2 }, { 3 }, { 4 }, { 5 }, { 6 }, { 7 }, { 8 }, { 9 } };
+
+T2_PointerStorage * createT2PointerStorage() {
+ T2_PointerStorage * s = calloc(1, sizeof(T2_PointerStorage));
+ for(int i=0; i<10; ++i) {
+ s->int32PtrArray[i] = &StaticInt32Array[i];
+ }
+ s->undefStructPtr = &StaticUndefStructArray[0];
+ for(int i=0; i<10; ++i) {
+ s->undefStructPtrArray[i] = &StaticUndefStructArray[i];
+ }
+
+ for(int i=0; i<10; ++i) {
+ s->customFuncAVariantsArray[i] = ( i %2 == 0 ) ? CustomFuncA1 : CustomFuncA2;
+ }
+ for(int i=0; i<10; ++i) {
+ s->customFuncBVariantsArray[i] = ( i %2 == 0 ) ? CustomFuncB1 : CustomFuncB2;
+ }
+ return s;
+}
+
+void destroyT2PointerStorage(T2_PointerStorage * s) {
+ assert(NULL!=s);
+ memset(s, 0, sizeof(T2_PointerStorage));
+ free(s);
+}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg
index 7c31341..d40ac9a 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg
@@ -20,7 +20,10 @@ ForceProcAddressGen __ALL__
# LocalProcAddressCallingConvention __ALL__ MYAPIENTRY
Opaque long void*
-Opaque long T2_Anonymous*
+
+# Undefined struct forward declaration, implementation secret: 'struct T2_UndefStruct;'
+Opaque long T2_UndefStruct*
+Ignore T2_UndefStruct
EmitStruct T2_ThreadAffinity
StructPackage T2_ThreadAffinity com.jogamp.gluegen.test.junit.generation
@@ -29,6 +32,9 @@ EmitStruct T2_UserData
StructPackage T2_UserData com.jogamp.gluegen.test.junit.generation
ReturnsStringOnly T2_UserData.name
+EmitStruct T2_PointerStorage
+StructPackage T2_PointerStorage com.jogamp.gluegen.test.junit.generation
+
EmitStruct T2_InitializeOptions
StructPackage T2_InitializeOptions com.jogamp.gluegen.test.junit.generation
ReturnsStringOnly T2_InitializeOptions.ProductName
@@ -40,6 +46,7 @@ MaxOneElement T2_InitializeOptions.OverrideThreadAffinity
CustomCCode #include "test2.h"
Import com.jogamp.gluegen.test.junit.generation.Bindingtest2
+Import com.jogamp.gluegen.test.junit.generation.T2_PointerStorage
Import com.jogamp.gluegen.test.junit.generation.T2_InitializeOptions
Import com.jogamp.gluegen.test.junit.generation.T2_ThreadAffinity
Import com.jogamp.gluegen.test.junit.generation.T2_UserData
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h
index 0817dd9..75c7ffa 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h
@@ -2,24 +2,44 @@
#include <gluegen_stdint.h>
#include <gluegen_stddef.h>
-typedef struct T2_Anonymous* T2_AnonPtr;
+// Opaque long T2_UndefStruct*
+// struct T2_UndefStruct; // undefined struct forward declaration, implementation secret
+typedef struct T2_UndefStruct* T2_UndefStructPtr;
-typedef struct {
- int32_t ApiVersion;
- uint64_t NetworkWork;
- T2_AnonPtr anonPtr;
-} T2_ThreadAffinity;
+typedef int32_t ( * T2_CustomFuncA)(void* aptr);
typedef struct {
int32_t balance;
const char* name;
} T2_UserData;
-typedef int32_t ( * T2_CustomFuncA)(void* aptr);
-
typedef int32_t ( * T2_CustomFuncB)(T2_UserData* pUserData);
typedef struct {
+ int32_t* int32PtrArray[10];
+ int32_t** int32PtrPtr;
+
+ T2_UndefStructPtr undefStructPtr;
+ T2_UndefStructPtr undefStructPtrArray[10];
+ T2_UndefStructPtr* undefStructPtrPtr;
+ const T2_UndefStructPtr* constUndefStructPtrPtr;
+
+ T2_CustomFuncA customFuncAVariantsArray[10];
+ T2_CustomFuncA* customFuncAVariantsArrayPtr;
+
+ T2_CustomFuncB customFuncBVariantsArray[10];
+ T2_CustomFuncB* customFuncBVariantsArrayPtr;
+} T2_PointerStorage;
+
+T2_PointerStorage * createT2PointerStorage();
+void destroyT2PointerStorage(T2_PointerStorage * s);
+
+typedef struct {
+ int32_t ApiVersion;
+ uint64_t NetworkWork;
+} T2_ThreadAffinity;
+
+typedef struct {
const char* ProductName;
const char* ProductVersion;
@@ -30,9 +50,16 @@ typedef struct {
const T2_CustomFuncA CustomFuncA2;
T2_CustomFuncB CustomFuncB1;
T2_CustomFuncB CustomFuncB2;
+ T2_CustomFuncB customFuncBVariants[2];
T2_ThreadAffinity* OverrideThreadAffinity;
} T2_InitializeOptions;
extern int Initialize(T2_InitializeOptions* Options);
extern int Release(T2_InitializeOptions* Options);
+
+typedef int32_t ( * T2_CallbackFunc)(size_t id, size_t msg_len, const char* msg, void* userParam);
+
+void AddMessageCallback(T2_CallbackFunc func, void* userParam);
+void RemoveMessageCallback(T2_CallbackFunc func, void* userParam);
+void InjectMessageCallback(size_t id, size_t msg_len, const char* msg);