summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--make/build-test.xml4
-rwxr-xr-xmake/scripts/java-win32.bat5
-rwxr-xr-xmake/scripts/java-win64.bat5
-rwxr-xr-xmake/scripts/runtest-x32.bat3
-rwxr-xr-xmake/scripts/runtest-x64.bat3
-rw-r--r--src/java/com/jogamp/common/nio/StructAccessor.java6
-rw-r--r--src/java/com/jogamp/gluegen/CMethodBindingEmitter.java37
-rw-r--r--src/java/com/jogamp/gluegen/JavaConfiguration.java74
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java1158
-rw-r--r--src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java64
-rw-r--r--src/java/com/jogamp/gluegen/JavaType.java70
-rw-r--r--src/java/com/jogamp/gluegen/MethodBinding.java12
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/ArrayType.java7
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/FunctionType.java20
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/PointerType.java12
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/StructLayout.java12
-rw-r--r--src/java/com/jogamp/gluegen/cgram/types/Type.java97
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java467
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java16
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java17
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/test1-common.cfg42
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/test1.c110
-rw-r--r--src/junit/com/jogamp/gluegen/test/junit/generation/test1.h78
23 files changed, 1886 insertions, 433 deletions
diff --git a/make/build-test.xml b/make/build-test.xml
index bb36243..f9092d0 100644
--- a/make/build-test.xml
+++ b/make/build-test.xml
@@ -601,6 +601,8 @@ chmod 644 ${results}/* \${line.separator}
<include name="${build_t.gen.rootrel}/native/Bindingtest1p1Impl_JNI.c"/>
<include name="${build_t.gen.rootrel}/native/TK_Engine_JNI.c"/>
<include name="${build_t.gen.rootrel}/native/TK_Surface_JNI.c"/>
+ <include name="${build_t.gen.rootrel}/native/TK_ModelConst_JNI.c"/>
+ <include name="${build_t.gen.rootrel}/native/TK_ModelMutable_JNI.c"/>
</patternset>
<c.build c.compiler.src.files="junit.test1p1.c.src.files"
@@ -625,6 +627,8 @@ chmod 644 ${results}/* \${line.separator}
<include name="${build_t.gen.rootrel}/native/Bindingtest1p2Impl_JNI.c"/>
<include name="${build_t.gen.rootrel}/native/TK_Engine_JNI.c"/>
<include name="${build_t.gen.rootrel}/native/TK_Surface_JNI.c"/>
+ <include name="${build_t.gen.rootrel}/native/TK_ModelConst_JNI.c"/>
+ <include name="${build_t.gen.rootrel}/native/TK_ModelMutable_JNI.c"/>
</patternset>
<c.build c.compiler.src.files="junit.test1p2.c.src.files"
diff --git a/make/scripts/java-win32.bat b/make/scripts/java-win32.bat
index b59a0cf..9b12e4c 100755
--- a/make/scripts/java-win32.bat
+++ b/make/scripts/java-win32.bat
@@ -5,11 +5,12 @@ set JAVA_HOME=c:\jdk1.7.0_45_x32
set ANT_PATH=C:\apache-ant-1.8.2
set BLD_DIR=..\%BLD_SUB%
-set LIB_DIR=..\%BLD_SUB%\obj;..\%BLD_SUB%\test\build\natives
+REM set LIB_DIR=..\%BLD_SUB%\obj;..\%BLD_SUB%\test\build\natives
+set LIB_DIR=..\%BLD_SUB%\test\build\natives
set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%LIB_DIR%;%PATH%
-set CP_ALL=.;%BLD_DIR%\gluegen-rt.jar;%BLD_DIR%\test\build\gluegen-test.jar;lib\junit.jar;%ANT_PATH%\lib\ant.jar;%ANT_PATH%\lib\ant-junit.jar
+set CP_ALL=.;lib\junit.jar;%ANT_PATH%\lib\ant.jar;%ANT_PATH%\lib\ant-junit.jar;lib/semantic-versioning/semver.jar;%BLD_DIR%\gluegen-rt.jar;%BLD_DIR%\gluegen.jar;%BLD_DIR%\gluegen-test-util.jar;%BLD_DIR%\test\build\gluegen-test.jar
echo CP_ALL %CP_ALL%
diff --git a/make/scripts/java-win64.bat b/make/scripts/java-win64.bat
index cb610e0..904acff 100755
--- a/make/scripts/java-win64.bat
+++ b/make/scripts/java-win64.bat
@@ -5,11 +5,12 @@ set JAVA_HOME=c:\jdk1.7.0_45_x64
set ANT_PATH=C:\apache-ant-1.8.2
set BLD_DIR=..\%BLD_SUB%
-set LIB_DIR=..\%BLD_SUB%\obj;..\%BLD_SUB%\test\build\natives
+REM set LIB_DIR=..\%BLD_SUB%\obj;..\%BLD_SUB%\test\build\natives
+set LIB_DIR=..\%BLD_SUB%\test\build\natives
set PATH=%JAVA_HOME%\bin;%ANT_PATH%\bin;c:\mingw\bin;%LIB_DIR%;%PATH%
-set CP_ALL=.;%BLD_DIR%\gluegen-rt.jar;%BLD_DIR%\test\build\gluegen-test.jar;lib\junit.jar;%ANT_PATH%\lib\ant.jar;%ANT_PATH%\lib\ant-junit.jar
+set CP_ALL=.;lib\junit.jar;%ANT_PATH%\lib\ant.jar;%ANT_PATH%\lib\ant-junit.jar;lib/semantic-versioning/semver.jar;%BLD_DIR%\gluegen-rt.jar;%BLD_DIR%\gluegen.jar;%BLD_DIR%\gluegen-test-util.jar;%BLD_DIR%\test\build\gluegen-test.jar
echo CP_ALL %CP_ALL%
diff --git a/make/scripts/runtest-x32.bat b/make/scripts/runtest-x32.bat
index 5e358a8..2c5e8e2 100755
--- a/make/scripts/runtest-x32.bat
+++ b/make/scripts/runtest-x32.bat
@@ -1,6 +1,7 @@
-scripts\java-win32.bat com.jogamp.common.GlueGenVersion
+REM scripts\java-win32.bat com.jogamp.common.GlueGenVersion
REM scripts\java-win32.bat com.jogamp.common.util.TestVersionInfo
REM scripts\java-win32.bat com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter
+scripts\java-win32.bat com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter
REM scripts\java-win32.bat com.jogamp.common.os.TestElfReader01
REM scripts\java-win32.bat com.jogamp.common.util.TestIOUtilURIHandling
diff --git a/make/scripts/runtest-x64.bat b/make/scripts/runtest-x64.bat
index 6451e5d..6b42c28 100755
--- a/make/scripts/runtest-x64.bat
+++ b/make/scripts/runtest-x64.bat
@@ -1,6 +1,7 @@
-scripts\java-win64.bat com.jogamp.common.GlueGenVersion
+REM scripts\java-win64.bat com.jogamp.common.GlueGenVersion
REM scripts\java-win64.bat com.jogamp.common.util.TestVersionInfo
REM scripts\java-win64.bat com.jogamp.gluegen.test.junit.generation.Test1p1JavaEmitter
+scripts\java-win64.bat com.jogamp.gluegen.test.junit.generation.Test1p2ProcAddressEmitter
REM scripts\java-win64.bat com.jogamp.common.os.TestElfReader01
REM scripts\java-win64.bat com.jogamp.common.util.TestIOUtil01
diff --git a/src/java/com/jogamp/common/nio/StructAccessor.java b/src/java/com/jogamp/common/nio/StructAccessor.java
index d6df083..b1593fe 100644
--- a/src/java/com/jogamp/common/nio/StructAccessor.java
+++ b/src/java/com/jogamp/common/nio/StructAccessor.java
@@ -117,7 +117,7 @@ public class StructAccessor {
public final int getIntAt(int byteOffset, int nativeSizeInBytes) {
switch(nativeSizeInBytes) {
case 2:
- return (int) bb.getShort(byteOffset) & 0x0000FFFF ;
+ return bb.getShort(byteOffset) & 0x0000FFFF ;
case 4:
return bb.getInt(byteOffset);
case 8:
@@ -137,7 +137,7 @@ public class StructAccessor {
bb.putInt(byteOffset, v);
break;
case 8:
- bb.putLong(byteOffset, (long)v & 0x00000000FFFFFFFFL );
+ bb.putLong(byteOffset, v & 0x00000000FFFFFFFFL );
break;
default:
throw new InternalError("invalid nativeSizeInBytes "+nativeSizeInBytes);
@@ -178,7 +178,7 @@ public class StructAccessor {
public final long getLongAt(int byteOffset, int nativeSizeInBytes) {
switch(nativeSizeInBytes) {
case 4:
- return (long) bb.getInt(byteOffset) & 0x00000000FFFFFFFFL;
+ return bb.getInt(byteOffset) & 0x00000000FFFFFFFFL;
case 8:
return bb.getLong(byteOffset);
default:
diff --git a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
index 0e373d0..1c9d043 100644
--- a/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
+++ b/src/java/com/jogamp/gluegen/CMethodBindingEmitter.java
@@ -909,7 +909,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
writer.print(CMethodBindingEmitter.cThisArgumentName());
} else {
writer.print("(");
- Type cArgType = binding.getCArgumentType(i);
+ final Type cArgType = binding.getCArgumentType(i);
boolean needsDataCopy = javaArgTypeNeedsDataCopy(javaArgType);
boolean needsArrayOffset = !needsDataCopy && (
javaArgType.isArray() ||
@@ -921,8 +921,8 @@ public class CMethodBindingEmitter extends FunctionEmitter {
// if this is a pointer to an unsigned type, add unsigned to the name to avoid compiler warnings
if(cArgType.isPointer()) {
- Type typeLast = ((PointerType)cArgType).getLastTargetType();
- if(typeLast.isInt() && (((IntType)typeLast).isPrimitiveUnsigned())) {
+ final Type baseType = cArgType.getBaseElementType();
+ if(baseType.isInt() && (((IntType)baseType).isPrimitiveUnsigned())) {
writer.print("unsigned ");
}
}
@@ -955,8 +955,18 @@ public class CMethodBindingEmitter extends FunctionEmitter {
return binding.getNumArguments();
}
- protected void emitBodyCallCFunction(PrintWriter writer) {
+ private boolean isCStructFunctionPointer = false;
+
+ /**
+ * If method originates from a struct, see {@link MethodBinding#hasContainingType()},
+ * it can either purposed to call a native static function (default)
+ * or a struct's function pointer.
+ */
+ protected void setIsCStructFunctionPointer(final boolean v) {
+ isCStructFunctionPointer = v;
+ }
+ protected void emitBodyCallCFunction(PrintWriter writer) {
// Make the call to the actual C function
writer.print(" ");
@@ -967,7 +977,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
if (!cReturnType.isVoid()) {
writer.print("_res = ");
}
- if (binding.hasContainingType()) {
+ if ( isCStructFunctionPointer && binding.hasContainingType() ) {
// Call through function pointer
writer.print(CMethodBindingEmitter.cThisArgumentName() + "->");
}
@@ -1019,8 +1029,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
// See whether capacity has been specified
if (returnValueCapacityExpression != null) {
- writer.print(
- returnValueCapacityExpression.format(argumentNameArray()));
+ writer.print( returnValueCapacityExpression.format( argumentNameArray() ) );
} else {
if (cReturnType.isPointer() &&
cReturnType.asPointer().getTargetType().isCompound()) {
@@ -1030,7 +1039,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
"for function \"" + binding + "\": " +
"Structs to be emitted should have been laid out by this point " +
"(type " + cReturnType.asPointer().getTargetType().getName() + " / " +
- cReturnType.asPointer().getTargetType() + " was not)"
+ cReturnType.asPointer().getTargetType() + " was not) for "+binding
);
}
}
@@ -1073,7 +1082,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
throw new RuntimeException(
"Could not emit native code for function \"" + binding +
- "\": array return values for non-char types not implemented yet");
+ "\": array return values for non-char types not implemented yet, for "+binding);
// FIXME: This is approximately what will be required here
//
@@ -1095,8 +1104,8 @@ public class CMethodBindingEmitter extends FunctionEmitter {
//writer.print(arrayRes);
//writer.println(";");
} else {
- System.err.print("Unhandled return type: "+javaReturnType.getDumpString());
- throw new RuntimeException("Unhandled return type");
+ System.err.print("Unhandled return type: "+javaReturnType.getDebugString());
+ throw new RuntimeException("Unhandled return type: "+javaReturnType.getDebugString()+" for "+binding);
}
}
}
@@ -1474,11 +1483,7 @@ public class CMethodBindingEmitter extends FunctionEmitter {
}
protected String byteOffsetArgName(int i) {
- return byteOffsetArgName(binding.getArgumentName(i));
- }
-
- protected String byteOffsetArgName(String s) {
- return s + "_byte_offset";
+ return JavaMethodBindingEmitter.byteOffsetArgName(binding.getArgumentName(i));
}
protected String isNIOArgName(int i) {
diff --git a/src/java/com/jogamp/gluegen/JavaConfiguration.java b/src/java/com/jogamp/gluegen/JavaConfiguration.java
index 552b237..771576e 100644
--- a/src/java/com/jogamp/gluegen/JavaConfiguration.java
+++ b/src/java/com/jogamp/gluegen/JavaConfiguration.java
@@ -492,11 +492,21 @@ public class JavaConfiguration {
return returnsString.contains(functionName);
}
- /** Provides a Java MessageFormat expression indicating the number
- of elements in the returned array from the specified function
- name. Indicates that the given return value, which must be a
- pointer to a CompoundType, is actually an array of the
- CompoundType rather than a pointer to a single object. */
+ /**
+ * Returns a MessageFormat string of the Java expression calculating
+ * the number of elements in the returned array from the specified function
+ * name. The literal <code>1</code> indicates a single object.
+ * <p>
+ * If symbol references a struct fields, see {@link #canonicalStructFieldSymbol(String, String)},
+ * it describes field's array-length or element-count referenced by a pointer.
+ * </p>
+ * <p>
+ * In case of struct fields, this array length will also be used
+ * for the native C function, i.e. multiplied w/ <code>sizeof(C-Type)</code>
+ * and passed down to native code, <b>if</b> not overriden by
+ * either {@link #returnValueCapacity(String)} or {@link #returnValueLength(String)}!
+ * </p>
+ */
public String returnedArrayLength(String functionName) {
return returnedArrayLengths.get(functionName);
}
@@ -623,18 +633,29 @@ public class JavaConfiguration {
return forcedStructs;
}
- /** Returns a MessageFormat string of the C expression calculating
- the capacity of the java.nio.ByteBuffer being returned from a
- native method, or null if no expression has been specified. */
+ /**
+ * Returns a MessageFormat string of the C expression calculating
+ * the capacity of the java.nio.ByteBuffer being returned from a
+ * native method, or null if no expression has been specified.
+ * <p>
+ * If symbol references a struct fields, see {@link #canonicalStructFieldSymbol(String, String)},
+ * it describes field's array-length or element-count referenced by a pointer.
+ * </p>
+ */
public String returnValueCapacity(String functionName) {
return returnValueCapacities.get(functionName);
}
- /** Returns a MessageFormat string of the C expression calculating
- the length of the array being returned from a native method, or
- null if no expression has been specified. */
- public String returnValueLength(String functionName) {
- return returnValueLengths.get(functionName);
+ /**
+ * Returns a MessageFormat string of the C expression calculating
+ * the length of the array being returned from a native method.
+ * <p>
+ * If symbol references a struct fields, see {@link #canonicalStructFieldSymbol(String, String)},
+ * it describes field's array-length or element-count referenced by a pointer.
+ * </p>
+ */
+ public String returnValueLength(String symbol) {
+ return returnValueLengths.get(symbol);
}
/** Returns a List of Strings of expressions declaring temporary C
@@ -727,8 +748,21 @@ public class JavaConfiguration {
}
}
- /** Returns true if this #define, function, struct, or field within
- a struct should be ignored during glue code generation. */
+ /**
+ * Returns the canonical configuration name for a struct field name,
+ * i.e. 'struct-name'.'field-name'
+ */
+ public static String canonicalStructFieldSymbol(String structName, String fieldName) {
+ return structName+"."+fieldName;
+ }
+
+ /**
+ * Returns true if this #define, function, struct, or field within
+ * a struct should be ignored during glue code generation of interfaces and implementation.
+ * <p>
+ * For struct fields see {@link #canonicalStructFieldSymbol(String, String)}.
+ * </p>
+ */
public boolean shouldIgnoreInInterface(String symbol) {
if(DEBUG_IGNORES) {
dumpIgnoresOnce();
@@ -754,6 +788,13 @@ public class JavaConfiguration {
return shouldIgnoreInImpl_Int(symbol);
}
+ /**
+ * Returns true if this #define, function, struct, or field within
+ * a struct should be ignored during glue code generation of implementation only.
+ * <p>
+ * For struct fields see {@link #canonicalStructFieldSymbol(String, String)}.
+ * </p>
+ */
public boolean shouldIgnoreInImpl(String symbol) {
return shouldIgnoreInImpl_Int(symbol);
}
@@ -1195,7 +1236,6 @@ public class JavaConfiguration {
}
}
- @SuppressWarnings("unchecked")
protected void readExtendedIntfImplSymbols(StringTokenizer tok, String filename, int lineNo, boolean forInterface, boolean forImplementation, boolean onlyList) {
File javaFile;
BufferedReader javaReader;
@@ -1299,7 +1339,7 @@ public class JavaConfiguration {
try {
String containingStruct = tok.nextToken();
String name = tok.nextToken();
- ignores.add(Pattern.compile(containingStruct + " " + name));
+ ignores.add(Pattern.compile(containingStruct + "\\." + name));
} catch (NoSuchElementException e) {
throw new RuntimeException("Error parsing \"IgnoreField\" command at line " + lineNo +
" in file \"" + filename + "\"", e);
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index 822c1c9..3125edf 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -659,21 +659,20 @@ public class JavaEmitter implements GlueEmitter {
(binding.needsNIOWrappingOrUnwrapping() || hasPrologueOrEpilogue),
!cfg.useNIODirectOnly(binding.getName()),
machDescJava);
- prepCEmitter(binding, cEmitter);
+ prepCEmitter(binding.getName(), binding.getJavaReturnType(), cEmitter);
allEmitters.add(cEmitter);
}
}
}
- protected void prepCEmitter(MethodBinding binding, CMethodBindingEmitter cEmitter)
+ protected void prepCEmitter(String returnSizeLookupName, JavaType javaReturnType, CMethodBindingEmitter cEmitter)
{
// See whether we need an expression to help calculate the
// length of any return type
- JavaType javaReturnType = binding.getJavaReturnType();
if (javaReturnType.isNIOBuffer() ||
javaReturnType.isCompoundTypeWrapper()) {
// See whether capacity has been specified
- String capacity = cfg.returnValueCapacity(binding.getName());
+ final String capacity = cfg.returnValueCapacity(returnSizeLookupName);
if (capacity != null) {
cEmitter.setReturnValueCapacityExpression( new MessageFormat(capacity) );
}
@@ -688,13 +687,13 @@ public class JavaEmitter implements GlueEmitter {
}
// See whether length has been specified
- String len = cfg.returnValueLength(binding.getName());
+ final String len = cfg.returnValueLength(returnSizeLookupName);
if (len != null) {
cEmitter.setReturnValueLengthExpression( new MessageFormat(len) );
}
}
- cEmitter.setTemporaryCVariableDeclarations(cfg.temporaryCVariableDeclarations(binding.getName()));
- cEmitter.setTemporaryCVariableAssignments(cfg.temporaryCVariableAssignments(binding.getName()));
+ cEmitter.setTemporaryCVariableDeclarations(cfg.temporaryCVariableDeclarations(returnSizeLookupName));
+ cEmitter.setTemporaryCVariableAssignments(cfg.temporaryCVariableAssignments(returnSizeLookupName));
}
/**
@@ -827,32 +826,35 @@ public class JavaEmitter implements GlueEmitter {
}
@Override
- public void emitStruct(CompoundType structType, String alternateName) throws Exception {
- String name = structType.getName();
- if (name == null && alternateName != null) {
- name = alternateName;
+ public void emitStruct(final CompoundType structCType, final String alternateName) throws Exception {
+ final String structCTypeName;
+ {
+ String _name = structCType.getName();
+ if (_name == null && alternateName != null) {
+ _name = alternateName;
+ }
+ structCTypeName = _name;
}
- if (name == null) {
- final String structName = structType.getStructName();
+ if (structCTypeName == null) {
+ final String structName = structCType.getStructName();
if ( null != structName && cfg.shouldIgnoreInInterface(structName) ) {
return;
}
-
- LOG.log(WARNING, "skipping emission of unnamed struct \"{0}\"", structType);
+ LOG.log(WARNING, "skipping emission of unnamed struct \"{0}\"", structCType);
return;
}
- if (cfg.shouldIgnoreInInterface(name)) {
+ if (cfg.shouldIgnoreInInterface(structCTypeName)) {
return;
}
- Type containingCType = canonicalize(new PointerType(SizeThunk.POINTER, structType, 0));
- JavaType containingType = typeToJavaType(containingCType, false, null);
- if (!containingType.isCompoundTypeWrapper()) {
+ final Type containingCType = canonicalize(new PointerType(SizeThunk.POINTER, structCType, 0));
+ final JavaType containingJType = typeToJavaType(containingCType, null);
+ if (!containingJType.isCompoundTypeWrapper()) {
return;
}
- String containingTypeName = containingType.getName();
+ final String containingJTypeName = containingJType.getName();
this.requiresStaticInitialization = false; // reset
@@ -874,23 +876,36 @@ public class JavaEmitter implements GlueEmitter {
// which complies w/ Java types.
boolean needsNativeCode = false;
+
// Native code for calls through function pointers gets emitted
// into the abstract base class; Java code which accesses fields
// gets emitted into the concrete classes
- for (int i = 0; i < structType.getNumFields(); i++) {
- if (structType.getField(i).getType().isFunctionPointer()) {
- needsNativeCode = true;
- break;
+ for (int i = 0; i < structCType.getNumFields(); i++) {
+ final Field field = structCType.getField(i);
+ final Type fieldType = field.getType();
+
+ final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, field.getName());
+
+ if (!cfg.shouldIgnoreInInterface(cfgFieldName0)) {
+
+ final String renamed = cfg.getJavaSymbolRename(cfgFieldName0);
+ final String fieldName = renamed==null ? field.getName() : renamed;
+ final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, fieldName);
+
+ if ( fieldType.isFunctionPointer() || fieldType.isPointer() || requiresGetCStringLength(fieldType, cfgFieldName1) ) {
+ needsNativeCode = true;
+ break;
+ }
}
}
- final String structClassPkg = cfg.packageForStruct(name);
+ final String structClassPkgName = cfg.packageForStruct(structCTypeName);
final PrintWriter javaWriter;
final PrintWriter jniWriter;
try {
javaWriter = openFile(cfg.javaOutputDir() + File.separator +
- CodeGenUtils.packageAsPath(structClassPkg) +
- File.separator + containingTypeName + ".java", containingTypeName);
+ CodeGenUtils.packageAsPath(structClassPkgName) +
+ File.separator + containingJTypeName + ".java", containingJTypeName);
if( null == javaWriter ) {
// suppress output if openFile deliberately returns null.
return;
@@ -901,9 +916,9 @@ public class JavaEmitter implements GlueEmitter {
if (cfg.nativeOutputUsesJavaHierarchy()) {
nRoot += File.separator + CodeGenUtils.packageAsPath(cfg.packageName());
}
- jniWriter = openFile(nRoot + File.separator + containingTypeName + "_JNI.c", containingTypeName);
+ jniWriter = openFile(nRoot + File.separator + containingJTypeName + "_JNI.c", containingJTypeName);
CodeGenUtils.emitAutogeneratedWarning(jniWriter, this);
- emitCHeader(jniWriter, structClassPkg, containingTypeName);
+ emitCHeader(jniWriter, structClassPkgName, containingJTypeName);
} else {
jniWriter = null;
}
@@ -912,7 +927,7 @@ public class JavaEmitter implements GlueEmitter {
}
javaWriter.println();
- javaWriter.println("package " + structClassPkg + ";");
+ javaWriter.println("package " + structClassPkgName + ";");
javaWriter.println();
javaWriter.println("import java.nio.*;");
javaWriter.println();
@@ -929,13 +944,13 @@ public class JavaEmitter implements GlueEmitter {
javaWriter.println(";");
}
javaWriter.println();
- List<String> javadoc = cfg.javadocForClass(containingTypeName);
+ List<String> javadoc = cfg.javadocForClass(containingJTypeName);
for (String doc : javadoc) {
javaWriter.println(doc);
}
- javaWriter.print("public class " + containingTypeName + " ");
+ javaWriter.print("public class " + containingJTypeName + " ");
boolean firstIteration = true;
- List<String> userSpecifiedInterfaces = cfg.implementedInterfaces(containingTypeName);
+ List<String> userSpecifiedInterfaces = cfg.implementedInterfaces(containingJTypeName);
for (String userInterface : userSpecifiedInterfaces) {
if (firstIteration) {
javaWriter.print("implements ");
@@ -951,85 +966,90 @@ public class JavaEmitter implements GlueEmitter {
javaWriter.println(" private static final int mdIdx = MachineDescriptionRuntime.getStatic().ordinal();");
javaWriter.println();
// generate all offset and size arrays
- generateOffsetAndSizeArrays(javaWriter, " ", containingTypeName, structType, null, null); /* w/o offset */
+ generateOffsetAndSizeArrays(javaWriter, " ", containingJTypeName, structCType, null, null); /* w/o offset */
if( GlueGen.debug() ) {
- System.err.printf("SE.__: t %s: %s%n", structType, containingTypeName);
+ System.err.printf("SE.__: structCType %s%n", structCType.getDebugString());
+ System.err.printf("SE.__: contCTypeName %s%n", containingCType.getDebugString());
+ System.err.printf("SE.__: contJTypeName %s%n", containingJType.getDebugString());
}
- for (int i = 0; i < structType.getNumFields(); i++) {
- final Field field = structType.getField(i);
+ for (int i = 0; i < structCType.getNumFields(); i++) {
+ final Field field = structCType.getField(i);
final Type fieldType = field.getType();
-
- if (!cfg.shouldIgnoreInInterface(name + " " + field.getName())) {
- final String renamed = cfg.getJavaSymbolRename(field.getName());
+ final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, field.getName());
+ if ( !cfg.shouldIgnoreInInterface(cfgFieldName0) ) {
+ final String renamed = cfg.getJavaSymbolRename(cfgFieldName0);
final String fieldName = null==renamed ? field.getName() : renamed;
+ final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, fieldName);
if (fieldType.isFunctionPointer()) {
// no offset/size for function pointer ..
if( GlueGen.debug() ) {
- System.err.printf("SE.os.%02d: t %s: %s / %s (%s)%n", (i+1), fieldType, field, fieldName, "SKIP FuncPtr");
+ System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "SKIP FuncPtr");
}
} else if (fieldType.isCompound()) {
// FIXME: will need to support this at least in order to
// handle the union in jawt_Win32DrawingSurfaceInfo (fabricate
// a name?)
if (fieldType.getName() == null) {
- throw new RuntimeException("Anonymous structs as fields not supported yet (field \"" +
- field + "\" in type \"" + name + "\")");
+ throw new RuntimeException("Anonymous structs as fields not supported yet, field \"" +
+ cfgFieldName1 + "\", "+fieldType.getDebugString());
}
if( GlueGen.debug() ) {
- System.err.printf("SE.os.%02d: t %s: %s / %s (%s)%n", (i+1), fieldType, field, fieldName, "compound");
+ System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "compound");
}
generateOffsetAndSizeArrays(javaWriter, " ", fieldName, fieldType, field, null);
} else if (fieldType.isArray()) {
final Type baseElementType = field.getType().asArray().getBaseElementType();
if( GlueGen.debug() ) {
- System.err.printf("SE.os.%02d: t %s: %s / %s - baseType %s (%s)%n", (i+1), fieldType, field, fieldName, baseElementType, "array");
+ System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "array");
+ System.err.printf("SE.os.%02d: baseType %s%n", (i+1), baseElementType.getDebugString());
}
generateOffsetAndSizeArrays(javaWriter, " ", fieldName, fieldType, field, null);
} else {
final JavaType externalJavaType;
try {
- externalJavaType = typeToJavaType(fieldType, false, machDescJava);
+ externalJavaType = typeToJavaType(fieldType, machDescJava);
} catch (Exception e) {
- System.err.println("Error occurred while creating accessor for field \"" +
- field.getName() + "\" in type \"" + name + "\"");
- throw(e);
+ throw new RuntimeException("Error occurred while creating accessor for field \"" +
+ cfgFieldName1 + "\", "+fieldType.getDebugString(), e);
}
if( GlueGen.debug() ) {
- System.err.printf("SE.os.%02d: t %s: %s / %s - javaType %s (%s)%n", (i+1), fieldType, field, fieldName, externalJavaType.getDumpString(), "MISC");
+ System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, fieldName, fieldType.getDebugString(), "MISC");
+ System.err.printf("SE.os.%02d: javaType %s%n", (i+1), externalJavaType.getDebugString());
}
if (externalJavaType.isPrimitive()) {
// Primitive type
generateOffsetAndSizeArrays(javaWriter, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, null, null);
} else if (externalJavaType.isCPrimitivePointerType()) {
- // FIXME: Primitive Pointer type
- generateOffsetAndSizeArrays(javaWriter, "// Skipped C-Primitive-Ptr-Type: ", fieldName, fieldType, field, externalJavaType.getDumpString());
+ if( requiresGetCStringLength(fieldType, cfgFieldName1) ) {
+ generateOffsetAndSizeArrays(javaWriter, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, null, "// "+externalJavaType.getDebugString());
+ } else {
+ generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, field, "// "+externalJavaType.getDebugString());
+ }
} else {
- // FIXME ???
- generateOffsetAndSizeArrays(javaWriter, "// Skipped Complicated Field: ", fieldName, fieldType, field, externalJavaType.getDumpString());
- LOG.log(WARNING, "Complicated fields (field \"{0}\" of type \"{1}\") not implemented yet: {2}",
- new Object[]{field, name, externalJavaType.getDumpString()});
- // throw new RuntimeException("Complicated fields (field \"" + field + "\" of type \"" + t +
- // "\") not implemented yet");
+ generateOffsetAndSizeArrays(javaWriter, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, null, "// "+externalJavaType.getDebugString());
}
}
} else if( GlueGen.debug() ) {
- System.err.printf("SE.os.%02d: t %s: %s (IGNORED)%n", (i+1), fieldType, field);
+ System.err.printf("SE.os.%02d: %s, %s (IGNORED)%n", (i+1), field, fieldType.getDebugString());
}
}
javaWriter.println();
javaWriter.println(" public static int size() {");
- javaWriter.println(" return "+containingTypeName+"_size[mdIdx];");
+ javaWriter.println(" return "+containingJTypeName+"_size[mdIdx];");
javaWriter.println(" }");
javaWriter.println();
- javaWriter.println(" public static " + containingTypeName + " create() {");
+ javaWriter.println(" public static " + containingJTypeName + " create() {");
javaWriter.println(" return create(Buffers.newDirectByteBuffer(size()));");
javaWriter.println(" }");
javaWriter.println();
- javaWriter.println(" public static " + containingTypeName + " create(java.nio.ByteBuffer buf) {");
- javaWriter.println(" return new " + containingTypeName + "(buf);");
+ javaWriter.println(" public static " + containingJTypeName + " create(java.nio.ByteBuffer buf) {");
+ javaWriter.println(" return new " + containingJTypeName + "(buf);");
javaWriter.println(" }");
javaWriter.println();
- javaWriter.println(" " + containingTypeName + "(java.nio.ByteBuffer buf) {");
+ javaWriter.println(" " + containingJTypeName + "(java.nio.ByteBuffer buf) {");
javaWriter.println(" accessor = new StructAccessor(buf);");
javaWriter.println(" }");
javaWriter.println();
@@ -1037,168 +1057,52 @@ public class JavaEmitter implements GlueEmitter {
javaWriter.println(" return accessor.getBuffer();");
javaWriter.println(" }");
- for (int i = 0; i < structType.getNumFields(); i++) {
- final Field field = structType.getField(i);
+ Set<MethodBinding> methodBindingSet = new HashSet<MethodBinding>();
+
+ for (int i = 0; i < structCType.getNumFields(); i++) {
+ final Field field = structCType.getField(i);
final Type fieldType = field.getType();
- if (!cfg.shouldIgnoreInInterface(name + " " + field.getName())) {
- final String renamed = cfg.getJavaSymbolRename(field.getName());
+ final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, field.getName());
+ if (!cfg.shouldIgnoreInInterface(cfgFieldName0)) {
+ final String renamed = cfg.getJavaSymbolRename(cfgFieldName0);
final String fieldName = renamed==null ? field.getName() : renamed;
+ final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(structCTypeName, fieldName);
+ if( GlueGen.debug() ) {
+ System.err.printf("SE.ac.%02d: %s / %s, %s%n", (i+1), field, cfgFieldName1, fieldType.getDebugString());
+ }
if (fieldType.isFunctionPointer()) {
- if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: t %s: %s / %s (%s)%n", (i+1), fieldType, field, fieldName, "funcPtr");
- }
- try {
- // Emit method call and associated native code
- final FunctionType funcType = fieldType.asPointer().getTargetType().asFunction();
- final FunctionSymbol funcSym = new FunctionSymbol(fieldName, funcType);
- final MethodBinding binding = bindFunction(funcSym, containingType, containingCType, machDescJava);
- binding.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis
- javaWriter.println();
-
- // Emit public Java entry point for calling this function pointer
- JavaMethodBindingEmitter emitter =
- new JavaMethodBindingEmitter(binding,
- javaWriter,
- cfg.runtimeExceptionType(),
- cfg.unsupportedExceptionType(),
- true,
- cfg.tagNativeBinding(),
- false, // eraseBufferAndArrayTypes
- true, // FIXME: should unify this with the general emission code
- true, // FIXME: should unify this with the general emission code
- false,
- false, // FIXME: should unify this with the general emission code
- false, // FIXME: should unify this with the general emission code
- false, // FIXME: should unify this with the general emission code
- false,
- cfg);
- emitter.addModifier(JavaMethodBindingEmitter.PUBLIC);
- emitter.emit();
-
- // Emit private native Java entry point for calling this function pointer
- emitter =
- new JavaMethodBindingEmitter(binding,
- javaWriter,
- cfg.runtimeExceptionType(),
- cfg.unsupportedExceptionType(),
- false,
- cfg.tagNativeBinding(),
- true,
- true, // FIXME: should unify this with the general emission code
- true, // FIXME: should unify this with the general emission code
- true,
- true, // FIXME: should unify this with the general emission code
- false, // FIXME: should unify this with the general emission code
- false, // FIXME: should unify this with the general emission code
- false,
- cfg);
- emitter.addModifier(JavaMethodBindingEmitter.PRIVATE);
- emitter.addModifier(JavaMethodBindingEmitter.NATIVE);
- emitter.emit();
-
- // Emit (private) C entry point for calling this function pointer
- CMethodBindingEmitter cEmitter =
- new CMethodBindingEmitter(binding,
- jniWriter,
- structClassPkg,
- containingTypeName,
- true, // FIXME: this is optional at this point
- false,
- true,
- false, // FIXME: should unify this with the general emission code
- machDescJava);
- prepCEmitter(binding, cEmitter);
- cEmitter.emit();
- } catch (Exception e) {
- System.err.println("While processing field " + field + " of type " + name + ":");
- throw(e);
- }
+ generateFunctionPointerCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName,
+ containingCType, containingJType, i,
+ new FunctionSymbol(fieldName, fieldType.asPointer().getTargetType().asFunction()), cfgFieldName1);
} else if (fieldType.isCompound()) {
// FIXME: will need to support this at least in order to
// handle the union in jawt_Win32DrawingSurfaceInfo (fabricate a name?)
if (fieldType.getName() == null) {
throw new RuntimeException("Anonymous structs as fields not supported yet (field \"" +
- field + "\" in type \"" + name + "\")");
+ field + "\" in type \"" + structCTypeName + "\")");
}
- if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: t %s: %s / %s (%s)%n", (i+1), fieldType, field, fieldName, "compound");
- }
-
javaWriter.println();
- generateGetterSignature(javaWriter, false, fieldType.getName(), capitalizeString(fieldName));
+ generateGetterSignature(javaWriter, fieldType, false, fieldType.getName(), capitalizeString(fieldName), null, null);
javaWriter.println(" {");
javaWriter.println(" return " + fieldType.getName() + ".create( accessor.slice( " +
fieldName+"_offset[mdIdx], "+fieldName+"_size[mdIdx] ) );");
javaWriter.println(" }");
- } else if (fieldType.isArray()) {
- final Type baseElementType = field.getType().asArray().getBaseElementType();
- final JavaType paramType = typeToJavaType(baseElementType, false, machDescJava);
-
- final String paramTypeName = paramType.getName();
- final String capitalized = capitalizeString(fieldName);
- if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: t %s: %s / %s - baseType %s, paramType %s (%s)%n", (i+1), fieldType, field, fieldName, baseElementType, paramType.getDumpString(), "array");
- }
-
- // Setter
- javaWriter.println();
- generateSetterSignature(javaWriter, false, containingTypeName, capitalized, paramTypeName+"[]");
- javaWriter.println(" {");
- if(baseElementType.isPrimitive()) {
- javaWriter.print (" accessor.set" + capitalizeString(paramTypeName) + "sAt(" + fieldName+"_offset[mdIdx], val);");
- javaWriter.println(" return this;");
- } else {
- javaWriter.println(" final int elemSize = "+paramTypeName+".size();");
- javaWriter.println(" final ByteBuffer destB = getBuffer();");
- javaWriter.println(" int offset = "+fieldName+"_offset[mdIdx];");
- javaWriter.println(" final int total = "+fieldType.asArray().getLength()+" * elemSize;");
- javaWriter.println(" if( total > "+fieldName+"_size[mdIdx] ) { throw new IndexOutOfBoundsException(\"total \"+total+\" > size \"+"+fieldName+"_size[mdIdx]+\", elemSize \"+elemSize+\" * "+fieldType.asArray().getLength()+"\"); };");
- javaWriter.println(" final int limes = offset + total;");
- javaWriter.println(" if( limes >= destB.limit() ) { throw new IndexOutOfBoundsException(\"limes \"+limes+\" >= buffer.limit \"+destB.limit()+\", elemOff \"+offset+\", elemSize \"+elemSize+\" * "+fieldType.asArray().getLength()+"\"); };");
- javaWriter.println(" for(int e=0; e<"+fieldType.asArray().getLength()+"; e++) {");
- javaWriter.println(" final "+paramTypeName+" source = val[e];");
- javaWriter.println(" final ByteBuffer sourceB = source.getBuffer();");
- javaWriter.println(" for(int f=0; f<elemSize; f++) {");
- javaWriter.println(" if( offset >= limes ) { throw new IndexOutOfBoundsException(\"elem-byte[\"+e+\"][\"+f+\"]: offset \"+offset+\" >= limes \"+limes+\", elemSize \"+elemSize+\" * "+fieldType.asArray().getLength()+"\"); };");
- javaWriter.println(" destB.put(offset++, sourceB.get(f));");
- javaWriter.println(" }");
- javaWriter.println(" }");
- javaWriter.println(" return this;");
- }
- javaWriter.println(" }");
- javaWriter.println();
- // Getter
- generateGetterSignature(javaWriter, false, paramTypeName+"[]", capitalized);
- javaWriter.println(" {");
- if(baseElementType.isPrimitive()) {
- javaWriter.print (" return accessor.get" + capitalizeString(paramTypeName) + "sAt(" + fieldName+"_offset[mdIdx], new " +paramTypeName+"["+fieldType.asArray().getLength()+"]);");
- } else {
- javaWriter.println(" final "+paramTypeName+"[] res = new "+paramTypeName+"["+fieldType.asArray().getLength()+"];");
- javaWriter.println(" int offset = "+fieldName+"_offset[mdIdx];");
- javaWriter.println(" final int elemSize = "+paramTypeName+".size();");
- javaWriter.println(" for(int e=0; e<"+fieldType.asArray().getLength()+"; e++) {");
- javaWriter.println(" res[e] = "+paramTypeName+".create(accessor.slice(offset, elemSize));");
- javaWriter.println(" offset += elemSize;");
- javaWriter.println(" }");
- javaWriter.println(" return res;");
- }
- javaWriter.println(" }");
+ } else if ( fieldType.isArray() || fieldType.isPointer() ) {
+ generateArrayGetterSetterCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName,
+ containingCType, containingJType,
+ i, field, fieldName, cfgFieldName1);
} else {
final JavaType javaType;
-
try {
- javaType = typeToJavaType(fieldType, false, machDescJava);
+ javaType = typeToJavaType(fieldType, machDescJava);
} catch (Exception e) {
System.err.println("Error occurred while creating accessor for field \"" +
- field.getName() + "\" in type \"" + name + "\"");
+ field.getName() + "\", "+fieldType.getDebugString());
throw(e);
}
- if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: t %s: %s / %s - javaType %s (%s)%n", (i+1), fieldType, field, fieldName, javaType.getDumpString(), "MISC");
- }
if (javaType.isPrimitive()) {
// Primitive type
final boolean fieldTypeNativeSizeFixed = fieldType.getSize().hasFixedNativeSize();
@@ -1213,26 +1117,27 @@ public class JavaEmitter implements GlueEmitter {
final String sizeDenominator = fieldType.isPointer() ? "pointer" : javaTypeName ;
if(GlueGen.debug()) {
- System.err.println("Java.StructEmitter.Primitive: "+field.getName()+", "+fieldType.getName(true)+", "+javaTypeName+", "+
- ", fixedSize "+fieldTypeNativeSizeFixed+", opaque "+isOpaque(fieldType)+", isPointer "+fieldType.isPointer()+", isCompound "+fieldType.isCompound()+
- ", sizeDenominator "+sizeDenominator);
+ System.err.println("Java.StructEmitter.Primitive: "+field.getName()+", "+fieldType.getDebugString()+", "+javaTypeName+", "+
+ ", fixedSize "+fieldTypeNativeSizeFixed+", opaque "+isOpaque(fieldType)+", sizeDenominator "+sizeDenominator);
}
- javaWriter.println();
- // Setter
- generateSetterSignature(javaWriter, false, containingTypeName, capFieldName, javaTypeName);
- javaWriter.println(" {");
- if( fieldTypeNativeSizeFixed ) {
- javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val);");
- } else {
- javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());");
+ if( !fieldType.isConst() ) {
+ // Setter
+ javaWriter.println();
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capFieldName, null, javaTypeName, null, null);
+ javaWriter.println(" {");
+ if( fieldTypeNativeSizeFixed ) {
+ javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val);");
+ } else {
+ javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());");
+ }
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
}
- javaWriter.println(" return this;");
- javaWriter.println(" }");
- javaWriter.println();
// Getter
- generateGetterSignature(javaWriter, false, javaTypeName, capFieldName);
+ javaWriter.println();
+ generateGetterSignature(javaWriter, fieldType, false, javaTypeName, capFieldName, null, null);
javaWriter.println(" {");
javaWriter.print (" return ");
if( fieldTypeNativeSizeFixed ) {
@@ -1241,30 +1146,31 @@ public class JavaEmitter implements GlueEmitter {
javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], MachineDescriptionRuntime.getStatic().md."+sizeDenominator+"SizeInBytes());");
}
javaWriter.println(" }");
- } else if (javaType.isCPrimitivePointerType()) {
- // FIXME: Primitive Pointer type
+ } else {
javaWriter.println();
- javaWriter.println(" /** "+fieldName +": "+javaType.getDumpString()+" */");
+ javaWriter.println(" /** UNKNOWN: "+cfgFieldName1 +": "+fieldType.getDebugString()+", "+javaType.getDebugString()+" */");
}
}
}
}
- emitCustomJavaCode(javaWriter, containingTypeName);
+ emitCustomJavaCode(javaWriter, containingJTypeName);
if (needsNativeCode) {
javaWriter.println();
- emitJavaInitCode(javaWriter, containingTypeName);
+ emitJavaInitCode(javaWriter, containingJTypeName);
javaWriter.println();
}
javaWriter.println("}");
javaWriter.flush();
javaWriter.close();
if (needsNativeCode) {
- emitCInitCode(jniWriter, structClassPkg, containingTypeName);
+ emitCInitCode(jniWriter, structClassPkgName, containingJTypeName);
jniWriter.flush();
jniWriter.close();
}
if( GlueGen.debug() ) {
- System.err.printf("SE.XX: t %s: %s%n", structType, containingTypeName);
+ System.err.printf("SE.XX: structCType %s%n", structCType.getDebugString());
+ System.err.printf("SE.XX: contCTypeName %s%n", containingCType.getDebugString());
+ System.err.printf("SE.XX: contJTypeName %s%n", containingJType.getDebugString());
}
}
@Override
@@ -1298,12 +1204,39 @@ public class JavaEmitter implements GlueEmitter {
// Internals only below this point
//
- private void generateGetterSignature(PrintWriter writer, boolean abstractMethod, String returnTypeName, String capitalizedFieldName) {
- writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "()");
+ private void generateGetterSignature(final PrintWriter writer, final Type origFieldType, final boolean abstractMethod,
+ final String returnTypeName, final String capitalizedFieldName,
+ final String customArgs, final String arrayLengthExpr) {
+ writer.print(" /** Getter for native field: "+origFieldType.getDebugString());
+ if( null != arrayLengthExpr ) {
+ writer.print(", with array length of <code>"+arrayLengthExpr+"</code>");
+ }
+ writer.println(" */");
+ writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "(");
+ if( null != customArgs ) {
+ writer.print(customArgs);
+ }
+ writer.print(")");
}
- private void generateSetterSignature(PrintWriter writer, boolean abstractMethod, String returnTypeName, String capitalizedFieldName, String paramTypeName) {
- writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " set" + capitalizedFieldName + "(" + paramTypeName + " val)");
+ private void generateSetterSignature(final PrintWriter writer, final Type origFieldType, final boolean abstractMethod,
+ final String returnTypeName, final String capitalizedFieldName,
+ final String customArgsPre, final String paramTypeName, final String customArgsPost,
+ final String arrayLengthExpr) {
+ writer.print(" /** Setter for native field: "+origFieldType.getDebugString());
+ if( null != arrayLengthExpr ) {
+ writer.print(", with array length of <code>"+arrayLengthExpr+"</code>");
+ }
+ writer.println(" */");
+ writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " set" + capitalizedFieldName + "(");
+ if( null != customArgsPre ) {
+ writer.print(customArgsPre+", ");
+ }
+ writer.print(paramTypeName + " val");
+ if( null != customArgsPost ) {
+ writer.print(", "+customArgsPost);
+ }
+ writer.print(")");
}
private void generateOffsetAndSizeArrays(PrintWriter writer, String prefix, String fieldName, Type fieldType, Field field, String postfix) {
@@ -1336,31 +1269,682 @@ public class JavaEmitter implements GlueEmitter {
}
}
- private JavaType typeToJavaType(Type cType, boolean outgoingArgument, MachineDescription curMachDesc) {
+ private void generateFunctionPointerCode(final Set<MethodBinding> methodBindingSet,
+ final PrintWriter javaWriter, final PrintWriter jniWriter,
+ final String structCTypeName, final String structClassPkgName,
+ final Type containingCType, final JavaType containingJType,
+ final int i, final FunctionSymbol funcSym, final String returnSizeLookupName) {
+ // Emit method call and associated native code
+ final MethodBinding mb = bindFunction(funcSym, containingJType, containingCType, machDescJava);
+ mb.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis
+
+ // JavaTypes representing C pointers in the initial
+ // MethodBinding have not been lowered yet to concrete types
+ final List<MethodBinding> bindings = expandMethodBinding(mb);
+
+ final boolean useNIOOnly = true;
+ final boolean useNIODirectOnly = true;
+
+ for (final MethodBinding binding : bindings) {
+ if(!methodBindingSet.add(binding)) {
+ // skip .. already exisiting binding ..
+ continue;
+ }
+ javaWriter.println();
+ // Emit public Java entry point for calling this function pointer
+ JavaMethodBindingEmitter emitter =
+ new JavaMethodBindingEmitter(binding,
+ javaWriter,
+ cfg.runtimeExceptionType(),
+ cfg.unsupportedExceptionType(),
+ true,
+ cfg.tagNativeBinding(),
+ false, // eraseBufferAndArrayTypes
+ useNIOOnly,
+ useNIODirectOnly,
+ false,
+ false, // FIXME: should unify this with the general emission code
+ false, // forIndirectBufferAndArrayImplementation
+ false, // FIXME: should unify this with the general emission code
+ false,
+ cfg);
+ emitter.addModifier(JavaMethodBindingEmitter.PUBLIC);
+ emitter.emit();
+
+ // Emit private native Java entry point for calling this function pointer
+ emitter =
+ new JavaMethodBindingEmitter(binding,
+ javaWriter,
+ cfg.runtimeExceptionType(),
+ cfg.unsupportedExceptionType(),
+ false,
+ cfg.tagNativeBinding(),
+ true, // eraseBufferAndArrayTypes
+ useNIOOnly,
+ useNIODirectOnly,
+ true,
+ true, // FIXME: should unify this with the general emission code
+ false, // forIndirectBufferAndArrayImplementation
+ false, // FIXME: should unify this with the general emission code
+ false,
+ cfg);
+ emitter.addModifier(JavaMethodBindingEmitter.PRIVATE);
+ emitter.addModifier(JavaMethodBindingEmitter.NATIVE);
+ emitter.emit();
+
+ // Emit (private) C entry point for calling this function pointer
+ CMethodBindingEmitter cEmitter =
+ new CMethodBindingEmitter(binding,
+ jniWriter,
+ structClassPkgName,
+ containingJType.getName(),
+ true, // FIXME: this is optional at this point
+ false,
+ true,
+ false, // forIndirectBufferAndArrayImplementation
+ machDescJava);
+ cEmitter.setIsCStructFunctionPointer(true);
+ prepCEmitter(returnSizeLookupName, binding.getJavaReturnType(), cEmitter);
+ cEmitter.emit();
+ }
+ }
+
+ private void generateArrayPointerCode(final Set<MethodBinding> methodBindingSet,
+ final PrintWriter javaWriter, final PrintWriter jniWriter,
+ final String structCTypeName, final String structClassPkgName,
+ final Type containingCType, final JavaType containingJType,
+ final int i, final FunctionSymbol funcSym,
+ final String returnSizeLookupName, final String docArrayLenExpr, final String nativeArrayLenExpr) {
+ // Emit method call and associated native code
+ final MethodBinding mb = bindFunction(funcSym, containingJType, containingCType, machDescJava);
+ mb.findThisPointer(); // FIXME: need to provide option to disable this on per-function basis
+
+ // JavaTypes representing C pointers in the initial
+ // MethodBinding have not been lowered yet to concrete types
+ final List<MethodBinding> bindings = expandMethodBinding(mb);
+
+ final boolean useNIOOnly = true;
+ final boolean useNIODirectOnly = true;
+
+ for (final MethodBinding binding : bindings) {
+ if(!methodBindingSet.add(binding)) {
+ // skip .. already exisiting binding ..
+ continue;
+ }
+ JavaMethodBindingEmitter emitter;
+
+ // Emit private native Java entry point for calling this function pointer
+ emitter =
+ new JavaMethodBindingEmitter(binding,
+ javaWriter,
+ cfg.runtimeExceptionType(),
+ cfg.unsupportedExceptionType(),
+ false,
+ cfg.tagNativeBinding(),
+ true, // eraseBufferAndArrayTypes
+ useNIOOnly,
+ useNIODirectOnly,
+ true,
+ true, // FIXME: should unify this with the general emission code
+ false, // forIndirectBufferAndArrayImplementation
+ false, // FIXME: should unify this with the general emission code
+ false,
+ cfg);
+ if( null != docArrayLenExpr ) {
+ emitter.setReturnedArrayLengthExpression(docArrayLenExpr, true);
+ }
+ emitter.addModifier(JavaMethodBindingEmitter.PRIVATE);
+ emitter.addModifier(JavaMethodBindingEmitter.NATIVE);
+ emitter.emit();
+
+ // Emit (private) C entry point for calling this function pointer
+ CMethodBindingEmitter cEmitter =
+ new CMethodBindingEmitter(binding,
+ jniWriter,
+ structClassPkgName,
+ containingJType.getName(),
+ true, // FIXME: this is optional at this point
+ false,
+ true,
+ false, // forIndirectBufferAndArrayImplementation
+ machDescJava);
+ cEmitter.setIsCStructFunctionPointer(false);
+ final String lenExprSet;
+ if( null != nativeArrayLenExpr ) {
+ JavaType javaReturnType = binding.getJavaReturnType();
+ if (javaReturnType.isNIOBuffer() ||
+ javaReturnType.isCompoundTypeWrapper()) {
+ final Type retType = funcSym.getReturnType();
+ final Type baseType = retType.getBaseElementType();
+ lenExprSet = nativeArrayLenExpr+" * sizeof("+baseType.getName()+")";
+ cEmitter.setReturnValueCapacityExpression( new MessageFormat(lenExprSet) );
+ } else if (javaReturnType.isArray() ||
+ javaReturnType.isArrayOfCompoundTypeWrappers()) {
+ lenExprSet = nativeArrayLenExpr;
+ cEmitter.setReturnValueLengthExpression( new MessageFormat(lenExprSet) );
+ } else {
+ lenExprSet = null;
+ }
+ } else {
+ lenExprSet = null;
+ }
+ prepCEmitter(returnSizeLookupName, binding.getJavaReturnType(), cEmitter);
+ cEmitter.emit();
+ }
+ }
+
+ private String getArrayArrayLengthExpr(final ArrayType type, final String returnSizeLookupName, final boolean hasFixedTypeLen[], final int[][] lengthRes) {
+ final int[] length = new int[type.arrayDimension()];
+ lengthRes[0] = length;
+ final StringBuilder lengthExpr = new StringBuilder();
+ hasFixedTypeLen[0] = true;
+ ArrayType typeIter = type;
+ for(int i=0; i<length.length; i++) {
+ if( null!=typeIter && typeIter.hasLength() ) {
+ length[i] = typeIter.getLength();
+ if( 0 < i ) {
+ lengthExpr.append("*");
+ }
+ lengthExpr.append(length[i]);
+ } else {
+ length[i] = -1;
+ hasFixedTypeLen[0] = false;
+ }
+ if( null != typeIter ) {
+ typeIter = typeIter.getElementType().asArray();
+ }
+ }
+ final String cfgVal = cfg.returnedArrayLength(returnSizeLookupName);
+ if( null != cfgVal ) {
+ if( hasFixedTypeLen[0] ) {
+ System.err.println("WARNING: struct array field '"+returnSizeLookupName+"' of '"+type+"' length '"+Arrays.toString(length)+"' overwritten by cfg-expression: "+cfgVal);
+ }
+ return cfgVal;
+ }
+ if( hasFixedTypeLen[0] ) {
+ return lengthExpr.toString();
+ } else {
+ System.err.println("WARNING: struct array field '"+returnSizeLookupName+"' length '"+Arrays.toString(length)+"' without fixed- nor configured-size: "+type.getDebugString());
+ return null;
+ }
+ }
+ private String getPointerArrayLengthExpr(final PointerType type, final String returnSizeLookupName) {
+ final String cfgVal = cfg.returnedArrayLength(returnSizeLookupName);
+ if( null != cfgVal ) {
+ return cfgVal;
+ }
+ return null;
+ }
+
+ private static final String dummyFuncTypeName = "null *";
+ private static final Type int32Type = new IntType("int32_t", SizeThunk.INT32, false, CVAttributes.CONST);
+ // private static final Type int8Type = new IntType("char", SizeThunk.INT8, false, 0);
+ // private static final Type int8PtrType = new PointerType(SizeThunk.POINTER, int8Type, 0);
+ private static final String nativeArrayLengthArg = "arrayLength";
+ private static final String nativeArrayLengthONE = "1";
+ private static final String nativeArrayElemOffsetArg = "elem_offset";
+
+ private boolean requiresGetCStringLength(final Type fieldType, final String returnSizeLookupName) {
+ if( !cfg.returnsString(returnSizeLookupName) ) {
+ return false;
+ }
+ final PointerType pointerType = fieldType.asPointer();
+ if( null != pointerType ) {
+ return null == getPointerArrayLengthExpr(pointerType, returnSizeLookupName);
+ }
+ return false;
+ }
+
+ private void generateArrayGetterSetterCode(final Set<MethodBinding> methodBindingSet,
+ final PrintWriter javaWriter, final PrintWriter jniWriter,
+ final String structCTypeName, final String structClassPkgName,
+ final Type containingCType, final JavaType containingJType,
+ final int i, final Field field, final String fieldName, final String returnSizeLookupName) throws Exception {
+ final Type fieldType = field.getType();
+ final JavaType javaType;
+ try {
+ javaType = typeToJavaType(fieldType, machDescJava);
+ } catch (Exception e) {
+ throw new RuntimeException("Error occurred while creating array/pointer accessor for field \"" +
+ returnSizeLookupName + "\", "+fieldType.getDebugString(), e);
+ }
+ if( GlueGen.debug() ) {
+ System.err.printf("SE.ac.%02d: javaType %s%n", (i+1), javaType.getDebugString());
+ }
+
+ //
+ // Collect all required information including considering Opaque types
+ //
+ final String containingJTypeName = containingJType.getName();
+ final boolean isOpaque = isOpaque(fieldType);
+ final boolean isString = cfg.returnsString(returnSizeLookupName); // FIXME: Allow custom Charset ? US-ASCII, UTF-8 or UTF-16 ?
+ final boolean useGetCStringLength;
+ final String arrayLengthExpr;
+ final int[] arrayLengths;
+ final boolean useFixedTypeLen[] = { false };
+ final boolean isPointer;
+ final boolean isPrimitive;
+ final boolean isConst;
+ final JavaType baseJElemType;
+ final String baseJElemTypeName;
+ final boolean hasSingleElement;
+ final String capitalFieldName;
+ final String baseJElemTypeNameC;
+ final String baseJElemTypeNameU;
+ final boolean isByteBuffer;
+ {
+ final Type baseCElemType;
+ final ArrayType arrayType = fieldType.asArray();
+ String _arrayLengthExpr = null;
+ if( isOpaque || javaType.isPrimitive() ) {
+ // Overridden by JavaConfiguration.typeInfo(..), i.e. Opaque!
+ // Emulating array w/ 1 element
+ isPrimitive = true;
+ _arrayLengthExpr = nativeArrayLengthONE;
+ arrayLengths = new int[] { 1 };
+ baseCElemType = null;
+ isPointer = false;
+ isConst = fieldType.isConst();
+ baseJElemType = null;
+ baseJElemTypeName = compatiblePrimitiveJavaTypeName(fieldType, javaType, machDescJava);
+ } else {
+ if( null != arrayType ) {
+ final int[][] lengthRes = new int[1][];
+ _arrayLengthExpr = getArrayArrayLengthExpr(arrayType, returnSizeLookupName, useFixedTypeLen, lengthRes);
+ arrayLengths = lengthRes[0];
+ baseCElemType = arrayType.getBaseElementType();
+ isPointer = false;
+ } else {
+ final PointerType pointerType = fieldType.asPointer();
+ _arrayLengthExpr = getPointerArrayLengthExpr(pointerType, returnSizeLookupName);
+ arrayLengths = null;
+ baseCElemType = pointerType.getBaseElementType();
+ isPointer = true;
+ if( 1 != pointerType.pointerDepth() ) {
+ javaWriter.println();
+ final String msg = "SKIP ptr-ptr (depth "+pointerType.pointerDepth()+"): "+returnSizeLookupName +": "+fieldType;
+ javaWriter.println(" // "+msg);
+ System.err.println("WARNING: "+msg);
+ return;
+ }
+ }
+ if( GlueGen.debug() ) {
+ System.err.printf("SE.ac.%02d: baseCType %s%n", (i+1), baseCElemType.getDebugString());
+ }
+ isPrimitive = baseCElemType.isPrimitive();
+ isConst = baseCElemType.isConst();
+ try {
+ baseJElemType = typeToJavaType(baseCElemType, machDescJava);
+ } catch (Exception e ) {
+ throw new RuntimeException("Error occurred while creating array/pointer accessor for field \"" +
+ returnSizeLookupName + "\", baseType "+baseCElemType.getDebugString()+", topType "+fieldType.getDebugString(), e);
+ }
+ baseJElemTypeName = baseJElemType.getName();
+
+ if( baseCElemType.isPrimitive() && !baseCElemType.getSize().hasFixedNativeSize() ) {
+ javaWriter.println();
+ final String msg = "SKIP primitive w/ platform dependent sized type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
+ javaWriter.println(" // "+msg);
+ System.err.println("WARNING: "+msg);
+ return;
+ }
+ }
+ if( GlueGen.debug() ) {
+ System.err.printf("SE.ac.%02d: baseJElemType %s%n", (i+1), (null != baseJElemType ? baseJElemType.getDebugString() : null));
+ }
+ capitalFieldName = capitalizeString(fieldName);
+ baseJElemTypeNameC = capitalizeString(baseJElemTypeName);
+ baseJElemTypeNameU = baseJElemTypeName.toUpperCase();
+ isByteBuffer = "Byte".equals(baseJElemTypeNameC);
+ if( null == _arrayLengthExpr && isString && isPointer ) {
+ useGetCStringLength = true;
+ _arrayLengthExpr = "getCStringLengthImpl(pString)+1";
+ this.requiresStaticInitialization = true;
+ LOG.log(INFO, "StaticInit Trigger.3 \"{0}\"", returnSizeLookupName);
+ } else {
+ useGetCStringLength = false;
+ }
+ arrayLengthExpr = _arrayLengthExpr;
+ if( null == arrayLengthExpr ) {
+ javaWriter.println();
+ final String msg = "SKIP unsized array in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
+ javaWriter.println(" // "+msg);
+ System.err.println("WARNING: "+msg);
+ return;
+ }
+ boolean _hasSingleElement=false;
+ try {
+ _hasSingleElement = 1 ==Integer.parseInt(_arrayLengthExpr);
+ } catch (Exception e ) {}
+ hasSingleElement = _hasSingleElement;
+ }
+ if( GlueGen.debug() ) {
+ System.err.printf("SE.ac.%02d: baseJElemTypeName %s, array-lengths %s%n", (i+1), baseJElemTypeName, Arrays.toString(arrayLengths));
+ System.err.printf("SE.ac.%02d: arrayLengthExpr: %s, hasSingleElement %b, isByteBuffer %b, isString %b, isPointer %b, isPrimitive %b, isOpaque %b, isConst %b, useGetCStringLength %b%n",
+ (i+1), arrayLengthExpr, hasSingleElement, isByteBuffer, isString, isPointer, isPrimitive, isOpaque, isConst, useGetCStringLength);
+ }
+
+ //
+ // Emit ..
+ //
+ if( !hasSingleElement && useFixedTypeLen[0] ) {
+ javaWriter.println();
+ generateGetterSignature(javaWriter, fieldType, false, "final int", capitalFieldName+"ArrayLength", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" return "+arrayLengthExpr+";");
+ javaWriter.println(" }");
+ }
+ if( !isConst ) {
+ // Setter
+ javaWriter.println();
+ if( isPrimitive ) {
+ // Setter Primitive
+ if( isPointer ) {
+ // Setter Primitive Pointer
+ final String msg = "SKIP setter for primitive-pointer type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
+ javaWriter.println(" // "+msg);
+ System.err.println("INFO: "+msg);
+ } else {
+ // Setter Primitive Array
+ if( hasSingleElement ) {
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, null, baseJElemTypeName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" accessor.set" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], val);");
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ } else {
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, "final int offset", baseJElemTypeName+"[]", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" if( offset + val.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + val.length \"+val.length+\" > array-length \"+arrayLength); };");
+ javaWriter.println(" final int elemSize = Buffers.SIZEOF_"+baseJElemTypeNameU+";");
+ javaWriter.println(" final ByteBuffer destB = getBuffer();");
+ javaWriter.println(" final int bTotal = arrayLength * elemSize;");
+ javaWriter.println(" if( bTotal > "+fieldName+"_size[mdIdx] ) { throw new IndexOutOfBoundsException(\"bTotal \"+bTotal+\" > size \"+"+fieldName+"_size[mdIdx]+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" int bOffset = "+fieldName+"_offset[mdIdx];");
+ javaWriter.println(" final int bLimes = bOffset + bTotal;");
+ javaWriter.println(" if( bLimes > destB.limit() ) { throw new IndexOutOfBoundsException(\"bLimes \"+bLimes+\" > buffer.limit \"+destB.limit()+\", elemOff \"+bOffset+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" bOffset += elemSize * offset;");
+ javaWriter.println(" accessor.set" + baseJElemTypeNameC + "sAt(bOffset, val);");
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ }
+ }
+ } else {
+ // Setter Struct
+ if( isPointer ) {
+ // Setter Struct Pointer
+ final String msg = "SKIP setter for complex-pointer type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
+ javaWriter.println(" // "+msg);
+ System.err.println("INFO: "+msg);
+ } else {
+ // Setter Struct Array
+ if( hasSingleElement ) {
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, null, baseJElemTypeName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int elemSize = "+baseJElemTypeName+".size();");
+ javaWriter.println(" final ByteBuffer destB = getBuffer();");
+ javaWriter.println(" if( elemSize > "+fieldName+"_size[mdIdx] ) { throw new IndexOutOfBoundsException(\"elemSize \"+elemSize+\" > size \"+"+fieldName+"_size[mdIdx]); };");
+ javaWriter.println(" int bOffset = "+fieldName+"_offset[mdIdx];");
+ javaWriter.println(" final int bLimes = bOffset + elemSize;");
+ javaWriter.println(" if( bLimes > destB.limit() ) { throw new IndexOutOfBoundsException(\"bLimes \"+bLimes+\" > buffer.limit \"+destB.limit()+\", elemOff \"+bOffset+\", elemSize \"+elemSize); };");
+ javaWriter.println(" final ByteBuffer sourceB = val.getBuffer();");
+ javaWriter.println(" for(int f=0; f<elemSize; f++) {");
+ javaWriter.println(" if( bOffset >= bLimes ) { throw new IndexOutOfBoundsException(\"elem-byte[0][\"+f+\"]: bOffset \"+bOffset+\" >= bLimes \"+bLimes+\", elemSize \"+elemSize); };");
+ javaWriter.println(" destB.put(bOffset++, sourceB.get(f));");
+ javaWriter.println(" }");
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ } else {
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, "final int offset", baseJElemTypeName+"[]", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" if( offset + val.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + val.length \"+val.length+\" > array-length \"+arrayLength); };");
+ javaWriter.println(" final int elemSize = "+baseJElemTypeName+".size();");
+ javaWriter.println(" final ByteBuffer destB = getBuffer();");
+ javaWriter.println(" final int bTotal = arrayLength * elemSize;");
+ javaWriter.println(" if( bTotal > "+fieldName+"_size[mdIdx] ) { throw new IndexOutOfBoundsException(\"bTotal \"+bTotal+\" > size \"+"+fieldName+"_size[mdIdx]+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" int bOffset = "+fieldName+"_offset[mdIdx];");
+ javaWriter.println(" final int bLimes = bOffset + bTotal;");
+ javaWriter.println(" if( bLimes > destB.limit() ) { throw new IndexOutOfBoundsException(\"bLimes \"+bLimes+\" > buffer.limit \"+destB.limit()+\", elemOff \"+bOffset+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" bOffset += elemSize * offset;");
+ javaWriter.println(" for(int index=0; index<val.length; index++) {");
+ javaWriter.println(" final ByteBuffer sourceB = val[index].getBuffer();");
+ javaWriter.println(" for(int f=0; f<elemSize; f++) {");
+ javaWriter.println(" if( bOffset >= bLimes ) { throw new IndexOutOfBoundsException(\"elem-byte[\"+(offset+index)+\"][\"+f+\"]: bOffset \"+bOffset+\" >= bLimes \"+bLimes+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" destB.put(bOffset++, sourceB.get(f));");
+ javaWriter.println(" }");
+ javaWriter.println(" }");
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ javaWriter.println();
+ generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, capitalFieldName, "final int index", baseJElemTypeName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" final int elemSize = "+baseJElemTypeName+".size();");
+ javaWriter.println(" final ByteBuffer destB = getBuffer();");
+ javaWriter.println(" final int bTotal = arrayLength * elemSize;");
+ javaWriter.println(" if( bTotal > "+fieldName+"_size[mdIdx] ) { throw new IndexOutOfBoundsException(\"bTotal \"+bTotal+\" > size \"+"+fieldName+"_size[mdIdx]+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" int bOffset = "+fieldName+"_offset[mdIdx];");
+ javaWriter.println(" final int bLimes = bOffset + bTotal;");
+ javaWriter.println(" if( bLimes > destB.limit() ) { throw new IndexOutOfBoundsException(\"bLimes \"+bLimes+\" > buffer.limit \"+destB.limit()+\", elemOff \"+bOffset+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" bOffset += elemSize * index;");
+ javaWriter.println(" final ByteBuffer sourceB = val.getBuffer();");
+ javaWriter.println(" for(int f=0; f<elemSize; f++) {");
+ javaWriter.println(" if( bOffset >= bLimes ) { throw new IndexOutOfBoundsException(\"elem-byte[\"+index+\"][\"+f+\"]: bOffset \"+bOffset+\" >= bLimes \"+bLimes+\", elemSize \"+elemSize+\" * \"+arrayLength); };");
+ javaWriter.println(" destB.put(bOffset++, sourceB.get(f));");
+ javaWriter.println(" }");
+ javaWriter.println(" return this;");
+ javaWriter.println(" }");
+ }
+ }
+ }
+ }
+ // Getter
+ javaWriter.println();
+ if( isPrimitive ) {
+ // Getter Primitive
+ if( isPointer ) {
+ // Getter Primitive Pointer
+ final FunctionType ft = new FunctionType(dummyFuncTypeName, SizeThunk.POINTER, fieldType, 0);
+ ft.addArgument(containingCType.getCVVariant(containingCType.getCVAttributes() | CVAttributes.CONST),
+ CMethodBindingEmitter.cThisArgumentName());
+ ft.addArgument(int32Type, nativeArrayLengthArg);
+ final FunctionSymbol fs = new FunctionSymbol("get"+capitalFieldName, ft);
+ jniWriter.println();
+ jniWriter.print("static "+fs.toString());
+ jniWriter.println("{");
+ jniWriter.println(" return "+CMethodBindingEmitter.cThisArgumentName()+"->"+field.getName()+";");
+ jniWriter.println("}");
+ jniWriter.println();
+ generateArrayPointerCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName,
+ containingCType, containingJType, i, fs, returnSizeLookupName, arrayLengthExpr, nativeArrayLengthArg);
+ javaWriter.println();
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeNameC+"Buffer", capitalFieldName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ if( useGetCStringLength ) {
+ javaWriter.println(" final int arrayLength = get"+capitalFieldName+"ArrayLength();");
+ } else {
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ }
+ javaWriter.println(" final ByteBuffer _res = get"+capitalFieldName+"0(getBuffer(), arrayLength);");
+ javaWriter.println(" if (_res == null) return null;");
+ javaWriter.print(" return Buffers.nativeOrder(_res)");
+ if( !isByteBuffer ) {
+ javaWriter.print(".as"+baseJElemTypeNameC+"Buffer()");
+ }
+ javaWriter.println(";");
+ javaWriter.println(" }");
+ if( isString && isByteBuffer ) {
+ javaWriter.println();
+ generateGetterSignature(javaWriter, fieldType, false, "String", capitalFieldName+"AsString", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ if( useGetCStringLength ) {
+ javaWriter.println(" final int arrayLength = get"+capitalFieldName+"ArrayLength();");
+ } else {
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ }
+ javaWriter.println(" final ByteBuffer bb = get"+capitalFieldName+"0(getBuffer(), arrayLength);");
+ javaWriter.println(" if (bb == null) return null;");
+ javaWriter.println(" final byte[] ba = new byte[arrayLength];");
+ javaWriter.println(" int i = -1;");
+ javaWriter.println(" while( ++i < arrayLength ) {");
+ javaWriter.println(" ba[i] = bb.get(i);");
+ javaWriter.println(" if( (byte)0 == ba[i] ) break;");
+ javaWriter.println(" }");
+ javaWriter.println(" return new String(ba, 0, i);");
+ javaWriter.println(" }");
+ }
+ if( useGetCStringLength ) {
+ javaWriter.println();
+ generateGetterSignature(javaWriter, fieldType, false, "final int", capitalFieldName+"ArrayLength", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final long pString = PointerBuffer.wrap( accessor.slice(" + fieldName+"_offset[mdIdx], PointerBuffer.ELEMENT_SIZE) ).get(0);");
+ javaWriter.println(" return "+arrayLengthExpr+";");
+ javaWriter.println(" }");
+ }
+ } else {
+ // Getter Primitive Array
+ if( hasSingleElement ) {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName, capitalFieldName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx]);");
+ javaWriter.println(" }");
+ javaWriter.println();
+ } else {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeNameC+"Buffer", capitalFieldName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.print(" return accessor.slice(" + fieldName+"_offset[mdIdx], Buffers.SIZEOF_"+baseJElemTypeNameU+" * "+arrayLengthExpr+")");
+ if( !isByteBuffer ) {
+ javaWriter.print(".as"+baseJElemTypeNameC+"Buffer()");
+ }
+ javaWriter.println(";");
+ javaWriter.println(" }");
+ javaWriter.println();
+ if( isString && isByteBuffer ) {
+ generateGetterSignature(javaWriter, fieldType, false, "String", capitalFieldName+"AsString", null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int offset = " + fieldName+"_offset[mdIdx];");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" final ByteBuffer bb = getBuffer();");
+ javaWriter.println(" final byte[] ba = new byte[arrayLength];");
+ javaWriter.println(" int i = -1;");
+ javaWriter.println(" while( ++i < arrayLength ) {");
+ javaWriter.println(" ba[i] = bb.get(offset+i);");
+ javaWriter.println(" if( (byte)0 == ba[i] ) break;");
+ javaWriter.println(" }");
+ javaWriter.println(" return new String(ba, 0, i);");
+ javaWriter.println(" }");
+ } else {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName+"[]", capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + result.length \"+result.length+\" > array-length \"+arrayLength); };");
+ javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "sAt(" + fieldName+"_offset[mdIdx] + (Buffers.SIZEOF_"+baseJElemTypeNameU+" * offset), result);");
+ javaWriter.println(" }");
+ javaWriter.println();
+ }
+ }
+ }
+ } else {
+ // Getter Struct
+ if( isPointer ) {
+ // Getter Struct Pointer
+ final FunctionType ft = new FunctionType(dummyFuncTypeName, SizeThunk.POINTER, fieldType, 0);
+ ft.addArgument(containingCType.getCVVariant(containingCType.getCVAttributes() | CVAttributes.CONST),
+ CMethodBindingEmitter.cThisArgumentName());
+ ft.addArgument(int32Type, nativeArrayElemOffsetArg);
+ final FunctionSymbol fs = new FunctionSymbol("get"+capitalFieldName, ft);
+ jniWriter.println();
+ jniWriter.print("static "+fs.toString());
+ jniWriter.println("{");
+ jniWriter.println(" return "+CMethodBindingEmitter.cThisArgumentName()+"->"+field.getName()+"+"+nativeArrayElemOffsetArg+";");
+ jniWriter.println("}");
+ jniWriter.println();
+ generateArrayPointerCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName,
+ containingCType, containingJType, i, fs, returnSizeLookupName, arrayLengthExpr, nativeArrayLengthONE);
+ javaWriter.println();
+ if( hasSingleElement ) {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName, capitalFieldName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final ByteBuffer source = getBuffer();");
+ javaWriter.println(" final ByteBuffer _res = get"+capitalFieldName+"0(source, 0);");
+ javaWriter.println(" if (_res == null) return null;");
+ javaWriter.println(" return "+baseJElemTypeName+".create(_res);");
+ javaWriter.println(" }");
+ } else {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName+"[]", capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + result.length \"+result.length+\" > array-length \"+arrayLength); };");
+ javaWriter.println(" final ByteBuffer source = getBuffer();");
+ javaWriter.println(" for(int index=0; index<result.length; index++) {");
+ javaWriter.println(" final ByteBuffer _res = get"+capitalFieldName+"0(source, offset+index);");
+ javaWriter.println(" if (_res == null) return null;");
+ javaWriter.println(" result[index] = "+baseJElemTypeName+".create(_res);");
+ javaWriter.println(" }");
+ javaWriter.println(" return result;");
+ javaWriter.println(" }");
+ }
+ } else {
+ // Getter Struct Array
+ if( hasSingleElement ) {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName, capitalFieldName, null, arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" return "+baseJElemTypeName+".create(accessor.slice("+fieldName+"_offset[mdIdx], "+baseJElemTypeName+".size()));");
+ javaWriter.println(" }");
+ } else {
+ generateGetterSignature(javaWriter, fieldType, false, baseJElemTypeName+"[]", capitalFieldName, "final int offset, "+baseJElemTypeName+" result[]", arrayLengthExpr);
+ javaWriter.println(" {");
+ javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ javaWriter.println(" if( offset + result.length > arrayLength ) { throw new IndexOutOfBoundsException(\"offset \"+offset+\" + result.length \"+result.length+\" > array-length \"+arrayLength); };");
+ javaWriter.println(" final int elemSize = "+baseJElemTypeName+".size();");
+ javaWriter.println(" int bOffset = "+fieldName+"_offset[mdIdx] + ( elemSize * offset );");
+ javaWriter.println(" for(int index=0; index<result.length; index++) {");
+ javaWriter.println(" result[index] = "+baseJElemTypeName+".create(accessor.slice(bOffset, elemSize));");
+ javaWriter.println(" bOffset += elemSize;");
+ javaWriter.println(" }");
+ javaWriter.println(" return result;");
+ javaWriter.println(" }");
+ }
+ }
+ }
+ }
+
+ private static final boolean DEBUG_TYPEC2JAVA = false;
+ private JavaType typeToJavaType(final Type cType, final MachineDescription curMachDesc) {
+ final JavaType jt = typeToJavaTypeImpl(cType, curMachDesc);
+ if( DEBUG_TYPEC2JAVA ) {
+ System.err.println("typeToJavaType: "+cType.getDebugString()+" -> "+jt.getDebugString());
+ }
+ return jt;
+ }
+ private boolean isJNIEnvPointer(final Type cType) {
+ final PointerType opt = cType.asPointer();
+ return (opt != null) &&
+ (opt.getTargetType().getName() != null) &&
+ (opt.getTargetType().getName().equals("JNIEnv"));
+ }
+ private JavaType typeToJavaTypeImpl(final Type cType, final MachineDescription curMachDesc) {
// Recognize JNIEnv* case up front
- PointerType opt = cType.asPointer();
- if ((opt != null) &&
- (opt.getTargetType().getName() != null) &&
- (opt.getTargetType().getName().equals("JNIEnv"))) {
- return JavaType.createForJNIEnv();
+ if( isJNIEnvPointer(cType) ) {
+ return JavaType.createForJNIEnv();
}
- Type t = cType;
-
// Opaque specifications override automatic conversions
// in case the identity is being used .. not if ptr-ptr
- TypeInfo info = cfg.typeInfo(t, typedefDictionary);
+ final TypeInfo info = cfg.typeInfo(cType, typedefDictionary);
if (info != null) {
boolean isPointerPointer = false;
- if (t.pointerDepth() > 0 || t.arrayDimension() > 0) {
+ if (cType.pointerDepth() > 0 || cType.arrayDimension() > 0) {
Type targetType; // target type
- if (t.isPointer()) {
+ if (cType.isPointer()) {
// t is <type>*, we need to get <type>
- targetType = t.asPointer().getTargetType();
+ targetType = cType.asPointer().getTargetType();
} else {
// t is <type>[], we need to get <type>
- targetType = t.asArray().getBaseElementType();
+ targetType = cType.asArray().getBaseElementType();
}
- if (t.pointerDepth() == 2 || t.arrayDimension() == 2) {
+ if (cType.pointerDepth() == 2 || cType.arrayDimension() == 2) {
// Get the target type of the target type (targetType was computer earlier
// as to be a pointer to the target type, so now we need to get its
// target type)
@@ -1369,7 +1953,9 @@ public class JavaEmitter implements GlueEmitter {
// t is<type>**, targetType is <type>*, we need to get <type>
Type bottomType = targetType.asPointer().getTargetType();
- LOG.log(INFO, "Opaque Type: {0}, targetType: {1}, bottomType: {2} is ptr-ptr", new Object[]{t, targetType, bottomType});
+ if( GlueGen.debug() ) {
+ LOG.log(INFO, "Opaque Type: {0}, targetType: {1}, bottomType: {2} is ptr-ptr", new Object[]{cType.getDebugString(), targetType, bottomType});
+ }
}
}
}
@@ -1378,35 +1964,35 @@ public class JavaEmitter implements GlueEmitter {
}
}
- if (t.isInt() || t.isEnum()) {
- switch ((int) t.getSize(curMachDesc)) {
+ if (cType.isInt() || cType.isEnum()) {
+ switch ((int) cType.getSize(curMachDesc)) {
case 1: return javaType(Byte.TYPE);
case 2: return javaType(Short.TYPE);
case 4: return javaType(Integer.TYPE);
case 8: return javaType(Long.TYPE);
default: throw new RuntimeException("Unknown integer type of size " +
- t.getSize(curMachDesc) + " and name " + t.getName());
+ cType.getSize(curMachDesc) + " and name " + cType.getName());
}
- } else if (t.isFloat()) {
+ } else if (cType.isFloat()) {
return javaType(Float.TYPE);
- } else if (t.isDouble()) {
+ } else if (cType.isDouble()) {
return javaType(Double.TYPE);
- } else if (t.isVoid()) {
+ } else if (cType.isVoid()) {
return javaType(Void.TYPE);
- } else if (t.pointerDepth() > 0 || t.arrayDimension() > 0) {
+ } else if (cType.pointerDepth() > 0 || cType.arrayDimension() > 0) {
Type targetType; // target type
- if (t.isPointer()) {
+ if (cType.isPointer()) {
// t is <type>*, we need to get <type>
- targetType = t.asPointer().getTargetType();
+ targetType = cType.asPointer().getTargetType();
} else {
// t is <type>[], we need to get <type>
- targetType = t.asArray().getBaseElementType();
+ targetType = cType.asArray().getBaseElementType();
}
// Handle Types of form pointer-to-type or array-of-type, like
// char* or int[]; these are expanded out into Java primitive
// arrays, NIO buffers, or both in expandMethodBinding
- if (t.pointerDepth() == 1 || t.arrayDimension() == 1) {
+ if (cType.pointerDepth() == 1 || cType.arrayDimension() == 1) {
if (targetType.isVoid()) {
return JavaType.createForCVoidPointer();
} else if (targetType.isInt()) {
@@ -1421,39 +2007,39 @@ public class JavaEmitter implements GlueEmitter {
case 4: return JavaType.createForCInt32Pointer();
case 8: return JavaType.createForCInt64Pointer();
default: throw new RuntimeException("Unknown integer array type of size " +
- t.getSize(curMachDesc) + " and name " + t.getName());
+ cType.getSize(curMachDesc) + " and name " + cType.getName()+", "+cType.getDebugString());
}
} else if (targetType.isFloat()) {
return JavaType.createForCFloatPointer();
} else if (targetType.isDouble()) {
return JavaType.createForCDoublePointer();
} else if (targetType.isCompound()) {
- if (t.isArray()) { // FIXME: Compound and Compound-Arrays
+ if (cType.isArray()) { // FIXME: Compound and Compound-Arrays
return JavaType.createForCArray(targetType);
}
// Special cases for known JNI types (in particular for converting jawt.h)
- if (t.getName() != null &&
- t.getName().equals("jobject")) {
+ if (cType.getName() != null &&
+ cType.getName().equals("jobject")) {
return javaType(java.lang.Object.class);
}
String name = targetType.getName();
if (name == null) {
// Try containing pointer type for any typedefs
- name = t.getName();
+ name = cType.getName();
if (name == null) {
- throw new RuntimeException("Couldn't find a proper type name for pointer type " + t);
+ throw new RuntimeException("Couldn't find a proper type name for pointer type " + cType.getDebugString());
}
}
return JavaType.createForCStruct(cfg.renameJavaType(name));
} else {
throw new RuntimeException("Don't know how to convert pointer/array type \"" +
- t + "\"");
+ cType.getDebugString() + "\"");
}
}
// Handle Types of form pointer-to-pointer-to-type or
// array-of-arrays-of-type, like char** or int[][]
- else if (t.pointerDepth() == 2 || t.arrayDimension() == 2) {
+ else if (cType.pointerDepth() == 2 || cType.arrayDimension() == 2) {
// Get the target type of the target type (targetType was computer earlier
// as to be a pointer to the target type, so now we need to get its
// target type)
@@ -1461,11 +2047,21 @@ public class JavaEmitter implements GlueEmitter {
if (targetType.isPointer()) {
// t is<type>**, targetType is <type>*, we need to get <type>
bottomType = targetType.asPointer().getTargetType();
+ if( GlueGen.debug() ) {
+ LOG.log(INFO, "typeToJavaType(ptr-ptr): {0}, targetType: {1}, bottomType: {2}", new Object[]{cType.getDebugString(), targetType, bottomType});
+ }
return JavaType.forNIOPointerBufferClass();
- } else {
+ } else if(targetType.isArray()) {
// t is<type>[][], targetType is <type>[], we need to get <type>
bottomType = targetType.asArray().getBaseElementType();
- LOG.log(WARNING, "typeToJavaType(ptr-ptr): {0}, targetType: {1}, bottomType: {2} -> Unhandled!", new Object[]{t, targetType, bottomType});
+ if( GlueGen.debug() ) {
+ LOG.log(INFO, "typeToJavaType(ptr-ptr.array): {0}, targetType: {1}, bottomType: {2}", new Object[]{cType.getDebugString(), targetType, bottomType});
+ }
+ } else {
+ bottomType = targetType;
+ if( GlueGen.debug() ) {
+ LOG.log(INFO, "typeToJavaType(ptr-ptr.primitive): {0}, targetType: {1}, bottomType: {2}", new Object[]{cType.getDebugString(), targetType, bottomType});
+ }
}
// Warning: The below code is not backed up by an implementation,
@@ -1479,14 +2075,14 @@ public class JavaEmitter implements GlueEmitter {
case 4: return javaType(ArrayTypes.intBufferArrayClass);
case 8: return javaType(ArrayTypes.longBufferArrayClass);
default: throw new RuntimeException("Unknown two-dimensional integer array type of element size " +
- bottomType.getSize(curMachDesc) + " and name " + bottomType.getName());
+ bottomType.getSize(curMachDesc) + " and name " + bottomType.getName()+", "+bottomType.getDebugString());
}
} else if (bottomType.isFloat()) {
return javaType(ArrayTypes.floatBufferArrayClass);
} else if (bottomType.isDouble()) {
return javaType(ArrayTypes.doubleBufferArrayClass);
} else {
- throw new RuntimeException("Unexpected primitive type " + bottomType.getName() +
+ throw new RuntimeException("Unexpected primitive type " + bottomType.getDebugString() +
" in two-dimensional array");
}
} else if (bottomType.isVoid()) {
@@ -1497,7 +2093,7 @@ public class JavaEmitter implements GlueEmitter {
return JavaType.createForCArray(bottomType);
} else {
throw new RuntimeException(
- "Could not convert C type \"" + t + "\" " +
+ "Could not convert C type \"" + cType.getDebugString() + "\" " +
"to appropriate Java type; need to add more support for " +
"depth=2 pointer/array types [debug info: targetType=\"" +
targetType + "\"]");
@@ -1505,23 +2101,23 @@ public class JavaEmitter implements GlueEmitter {
} else {
// can't handle this type of pointer/array argument
throw new RuntimeException(
- "Could not convert C pointer/array \"" + t + "\" to " +
+ "Could not convert C pointer/array \"" + cType.getDebugString() + "\" to " +
"appropriate Java type; types with pointer/array depth " +
"greater than 2 are not yet supported [debug info: " +
- "pointerDepth=" + t.pointerDepth() + " arrayDimension=" +
- t.arrayDimension() + " targetType=\"" + targetType + "\"]");
+ "pointerDepth=" + cType.pointerDepth() + " arrayDimension=" +
+ cType.arrayDimension() + " targetType=\"" + targetType + "\"]");
}
- } else if(t.isCompound() ) { // FIXME: Compound and Compound-Arrays
- final String name = t.getName();
+ } else if(cType.isCompound() ) { // FIXME: Compound and Compound-Arrays
+ final String name = cType.getName();
if (name == null) {
- throw new RuntimeException("Couldn't find a proper type name for pointer type " + t);
+ throw new RuntimeException("Couldn't find a proper type name for pointer type " + cType.getDebugString());
}
return JavaType.createForCStruct(cfg.renameJavaType(name));
} else {
throw new RuntimeException(
- "Could not convert C type \"" + t + "\" (class " +
- t.getClass().getName() + ") to appropriate Java type");
+ "Could not convert C type \"" + cType.getDebugString() + "\" (class " +
+ cType.getClass().getName() + ") to appropriate Java type");
}
}
@@ -1897,6 +2493,10 @@ public class JavaEmitter implements GlueEmitter {
cWriter.println(" return _initClazzAccess(env);");
cWriter.println("}");
cWriter.println();
+ cWriter.println("JNIEXPORT jint JNICALL "+JavaEmitter.getJNIMethodNamePrefix(packageName, className)+"_getCStringLengthImpl(JNIEnv *env, jclass _unused, jlong pString) {");
+ cWriter.println(" return 0 != pString ? strlen((const char*)(intptr_t)pString) : 0;");
+ cWriter.println("}");
+ cWriter.println();
}
}
@@ -1905,6 +2505,9 @@ public class JavaEmitter implements GlueEmitter {
jWriter.println();
jWriter.println(" private static native boolean initializeImpl();");
jWriter.println();
+ jWriter.println();
+ jWriter.println(" private static native int getCStringLengthImpl(final long pString);");
+ jWriter.println();
if( !cfg.manualStaticInitCall(className) ) {
jWriter.println(staticClassInitCallJavaCode);
}
@@ -1958,7 +2561,7 @@ public class JavaEmitter implements GlueEmitter {
}
binding.setJavaReturnType(javaType(java.lang.String.class));
} else {
- binding.setJavaReturnType(typeToJavaType(sym.getReturnType(), false, curMachDesc));
+ binding.setJavaReturnType(typeToJavaType(sym.getReturnType(), curMachDesc));
}
// System.out.println("bindFunction(1) "+binding.getJavaReturnType());
@@ -1969,7 +2572,7 @@ public class JavaEmitter implements GlueEmitter {
for (int i = 0; i < sym.getNumArguments(); i++) {
Type cArgType = sym.getArgumentType(i);
- JavaType mappedType = typeToJavaType(cArgType, true, curMachDesc);
+ JavaType mappedType = typeToJavaType(cArgType, curMachDesc);
// System.out.println("C arg type -> \"" + cArgType + "\"" );
// System.out.println(" Java -> \"" + mappedType + "\"" );
@@ -2147,5 +2750,4 @@ public class JavaEmitter implements GlueEmitter {
private final String capitalizeString(String string) {
return Character.toUpperCase(string.charAt(0)) + string.substring(1);
}
-
}
diff --git a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
index c651114..ea7910a 100644
--- a/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaMethodBindingEmitter.java
@@ -41,9 +41,7 @@ package com.jogamp.gluegen;
import com.jogamp.gluegen.cgram.HeaderParser;
import com.jogamp.gluegen.cgram.types.ArrayType;
-import com.jogamp.gluegen.cgram.types.CompoundType;
import com.jogamp.gluegen.cgram.types.EnumType;
-import com.jogamp.gluegen.cgram.types.PointerType;
import com.jogamp.gluegen.cgram.types.Type;
import java.io.PrintWriter;
@@ -93,6 +91,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
// incoming Java arguments as parameters and computing as an int the
// number of elements of the returned array.
private String returnedArrayLengthExpression;
+ private boolean returnedArrayLengthExpressionOnlyForComments = false;
// A suffix used to create a temporary outgoing array of Buffers to
// represent an array of compound type wrappers
@@ -154,6 +153,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
prologue = arg.prologue;
epilogue = arg.epilogue;
returnedArrayLengthExpression = arg.returnedArrayLengthExpression;
+ returnedArrayLengthExpressionOnlyForComments = arg.returnedArrayLengthExpressionOnlyForComments;
cfg = arg.cfg;
}
@@ -192,6 +192,17 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
arguments. */
public void setReturnedArrayLengthExpression(String expr) {
returnedArrayLengthExpression = expr;
+ returnedArrayLengthExpressionOnlyForComments = false;
+ }
+ protected void setReturnedArrayLengthExpression(String expr, boolean onlyForComments) {
+ returnedArrayLengthExpression = expr;
+ returnedArrayLengthExpressionOnlyForComments = onlyForComments;
+ }
+ protected String getReturnedArrayLengthExpression() {
+ return returnedArrayLengthExpressionOnlyForComments ? null : returnedArrayLengthExpression;
+ }
+ protected String getReturnedArrayLengthComment() {
+ return returnedArrayLengthExpression;
}
/** Sets the manually-generated prologue code for this emitter. */
@@ -278,6 +289,9 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
}
}
String name = type.getName();
+ if( null == name ) {
+ throw new IllegalArgumentException("null type name: "+type.getDebugString());
+ }
int index = name.lastIndexOf('.')+1; // always >= 0
name = name.substring(index);
@@ -389,7 +403,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
return byteOffsetArgName(getArgumentName(i));
}
- protected String byteOffsetArgName(String s) {
+ protected static String byteOffsetArgName(String s) {
return s + "_byte_offset";
}
@@ -715,38 +729,9 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
JavaType returnType = binding.getJavaReturnType();
if (returnType.isCompoundTypeWrapper()) {
- String fmt = getReturnedArrayLengthExpression();
+ // Details are handled in JavaEmitter's struct handling!
writer.println(" if (_res == null) return null;");
- if (fmt == null) {
- writer.print(" return " + returnType.getName() + ".create(Buffers.nativeOrder(_res))");
- } else {
- writer.println(" Buffers.nativeOrder(_res);");
- String expr = new MessageFormat(fmt).format(argumentNameArray());
- PointerType cReturnTypePointer = binding.getCReturnType().asPointer();
- CompoundType cReturnType = null;
- if (cReturnTypePointer != null) {
- cReturnType = cReturnTypePointer.getTargetType().asCompound();
- }
- if (cReturnType == null) {
- throw new RuntimeException("ReturnedArrayLength directive currently only supported for pointers to compound types " +
- "(error occurred while generating Java glue code for " + getName() + ")");
- }
- writer.println(" final " + getReturnTypeString(false) + " _retarray = new " + getReturnTypeString(true) + "[" + expr + "];");
- writer.println(" for (int _count = 0; _count < " + expr + "; _count++) {");
- // Create temporary ByteBuffer slice
- // FIXME: probably need Type.getAlignedSize() for arrays of
- // compound types (rounding up to machine-dependent alignment)
- writer.println(" _res.position(_count * " + getReturnTypeString(true) + ".size());");
- writer.println(" _res.limit ((1 + _count) * " + getReturnTypeString(true) + ".size());");
- writer.println(" final ByteBuffer _tmp = _res.slice();");
- writer.println(" Buffers.nativeOrder(_tmp);");
- writer.println(" _res.position(0);");
- writer.println(" _res.limit(_res.capacity());");
- writer.println(" _retarray[_count] = " + getReturnTypeString(true) + ".create(_tmp);");
- writer.println(" }");
- writer.print (" return _retarray");
- }
- writer.println(";");
+ writer.println(" return " + returnType.getName() + ".create(Buffers.nativeOrder(_res));");
} else if (returnType.isNIOBuffer()) {
writer.println(" if (_res == null) return null;");
writer.println(" Buffers.nativeOrder(_res);");
@@ -821,10 +806,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
@Override
protected String getBaseIndentString() { return " "; }
- protected String getReturnedArrayLengthExpression() {
- return returnedArrayLengthExpression;
- }
-
/**
* Class that emits a generic comment for JavaMethodBindingEmitters; the comment
* includes the C signature of the native method that is being bound by the
@@ -835,6 +816,10 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
public void emit(FunctionEmitter emitter, PrintWriter writer) {
emitBeginning(emitter, writer);
emitBindingCSignature(((JavaMethodBindingEmitter)emitter).getBinding(), writer);
+ final String arrayLengthExpr = getReturnedArrayLengthComment();
+ if( null != arrayLengthExpr ) {
+ writer.print(", covering an array of length <code>"+arrayLengthExpr+"</code>");
+ }
emitEnding(emitter, writer);
}
protected void emitBeginning(FunctionEmitter emitter, PrintWriter writer) {
@@ -889,8 +874,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter {
protected class InterfaceCommentEmitter extends JavaMethodBindingEmitter.DefaultCommentEmitter {
@Override
- protected void emitBeginning(FunctionEmitter emitter,
- PrintWriter writer) {
+ protected void emitBeginning(FunctionEmitter emitter, PrintWriter writer) {
writer.print("Interface to C language function: <br> ");
}
}
diff --git a/src/java/com/jogamp/gluegen/JavaType.java b/src/java/com/jogamp/gluegen/JavaType.java
index a1cbb01..9091588 100644
--- a/src/java/com/jogamp/gluegen/JavaType.java
+++ b/src/java/com/jogamp/gluegen/JavaType.java
@@ -60,7 +60,7 @@ public class JavaType {
}
private final Class<?> clazz; // Primitive types and other types representable as Class objects
- private final String name; // Types we're generating glue code for (i.e., C structs)
+ private final String structName; // Types we're generating glue code for (i.e., C structs)
private final Type elementType; // Element type if this JavaType represents a C array
private final C_PTR primitivePointerType;
@@ -82,8 +82,8 @@ public class JavaType {
JavaType t = (JavaType) arg;
return (this == t ||
(t.clazz == clazz &&
- ((name == null ? t.name == null : name.equals(t.name)) ||
- ((name != null) && (t.name != null) && (name.equals(t.name)))) &&
+ ((structName == null ? t.structName == null : structName.equals(t.structName)) ||
+ ((structName != null) && (t.structName != null) && (structName.equals(t.structName)))) &&
((elementType == t.elementType) ||
(elementType != null) && (t.elementType != null) && (elementType.equals(t.elementType))) &&
(primitivePointerType == t.primitivePointerType)));
@@ -92,10 +92,10 @@ public class JavaType {
@Override
public int hashCode() {
if (clazz == null) {
- if (name == null) {
+ if (structName == null) {
return 0;
}
- return name.hashCode();
+ return structName.hashCode();
}
return clazz.hashCode();
}
@@ -245,7 +245,7 @@ public class JavaType {
if (elementType != null) {
return elementType.getName();
}
- return name;
+ return structName;
}
/**
@@ -261,11 +261,14 @@ public class JavaType {
}
if (elementType != null) {
if(elementType.getName()==null) {
- throw new RuntimeException("elementType.name is null: "+getDumpString());
+ throw new RuntimeException("elementType.name is null: "+getDebugString());
}
return "[" + descriptor(elementType.getName());
}
- return descriptor(name);
+ if( null != structName ) {
+ return descriptor(structName);
+ }
+ return "ANON_NIO";
}
/** Returns the String corresponding to the JNI type for this type,
@@ -432,7 +435,7 @@ public class JavaType {
}
public boolean isCompoundTypeWrapper() {
- return (clazz == null && name != null && !isJNIEnv());
+ return (clazz == null && structName != null && !isJNIEnv());
}
public boolean isArrayOfCompoundTypeWrappers() {
@@ -473,12 +476,12 @@ public class JavaType {
}
public boolean isJNIEnv() {
- return clazz == null && "JNIEnv".equals(name);
+ return clazz == null && "JNIEnv".equals(structName);
}
@Override
public Object clone() {
- return new JavaType(primitivePointerType, clazz, name, elementType);
+ return new JavaType(primitivePointerType, clazz, structName, elementType);
}
@Override
@@ -497,16 +500,27 @@ public class JavaType {
sb.append(val);
}
// For debugging
- public String getDumpString() {
+ public String getDebugString() {
final StringBuilder sb = new StringBuilder();
- sb.append("JavaType[");
+ sb.append("JType[");
boolean prepComma = false;
+ {
+ final String javaTypeName = getName();
+ if( null != javaTypeName ) {
+ append(sb, javaTypeName, false);
+ } else {
+ append(sb, "ANON", false);
+ }
+ sb.append(" / ");
+ if( null != structName ) {
+ append(sb, "'"+structName+"'", prepComma); prepComma=true;
+ } else {
+ append(sb, "NIL", prepComma); prepComma=true;
+ }
+ }
if( null != clazz ) {
append(sb, "clazz = "+clazz.getName(), prepComma); prepComma=true;
}
- if( null != name ) {
- append(sb, "name = "+name, prepComma); prepComma=true;
- }
if( null != elementType ) {
append(sb, "elementType = "+elementType, prepComma); prepComma=true;
}
@@ -523,6 +537,15 @@ public class JavaType {
if( isCompoundTypeWrapper() ) {
append(sb, "compound", prepComma); prepComma=true;
}
+ if( isArray() ) {
+ append(sb, "array", prepComma); prepComma=true;
+ }
+ if( isPrimitive() ) {
+ append(sb, "primitive", prepComma); prepComma=true;
+ }
+ if( isPrimitiveArray() ) {
+ append(sb, "primitiveArray", prepComma); prepComma=true;
+ }
if( isNIOBuffer() ) {
append(sb, "nioBuffer", prepComma); prepComma=true;
}
@@ -532,7 +555,7 @@ public class JavaType {
if( isCPrimitivePointerType() ) {
append(sb, "C-Primitive-Pointer", prepComma); prepComma=true;
}
- sb.append("]]");
+ append(sb, "descriptor '"+getDescriptor()+"'", prepComma); prepComma=true;
return sb.toString();
}
@@ -543,15 +566,15 @@ public class JavaType {
private JavaType(Class<?> clazz) {
this.primitivePointerType = null;
this.clazz = clazz;
- this.name = null;
+ this.structName = null;
this.elementType = null;
}
/** Constructs a type representing a named C struct. */
- private JavaType(String name) {
+ private JavaType(String structName) {
this.primitivePointerType = null;
this.clazz = null;
- this.name = name;
+ this.structName = structName;
this.elementType = null;
}
@@ -560,7 +583,7 @@ public class JavaType {
private JavaType(C_PTR primitivePointerType) {
this.primitivePointerType = primitivePointerType;
this.clazz = null;
- this.name = null;
+ this.structName = null;
this.elementType = null;
}
@@ -568,14 +591,15 @@ public class JavaType {
private JavaType(Type elementType) {
this.primitivePointerType = null;
this.clazz = null;
- this.name = null;
+ this.structName = null;
this.elementType = elementType;
}
+ /** clone only */
private JavaType(C_PTR primitivePointerType, Class<?> clazz, String name, Type elementType) {
this.primitivePointerType = primitivePointerType;
this.clazz = clazz;
- this.name = name;
+ this.structName = name;
this.elementType = elementType;
}
diff --git a/src/java/com/jogamp/gluegen/MethodBinding.java b/src/java/com/jogamp/gluegen/MethodBinding.java
index 61732fb..53f6c7d 100644
--- a/src/java/com/jogamp/gluegen/MethodBinding.java
+++ b/src/java/com/jogamp/gluegen/MethodBinding.java
@@ -436,8 +436,16 @@ public class MethodBinding {
computedSignatureProperties = true;
}
- /** Indicates whether this MethodBinding is for a function pointer
- contained in a struct. */
+ /**
+ * Indicates whether this MethodBinding is for a function pointer
+ * contained in a struct, or to access array- or pointer-data from a struct.
+ * <p>
+ * The native calling convention, i.e. via a 'this' function pointer
+ * or by a static native function must be decided in the
+ * {@link JavaEmitter} handling structs and
+ * passed to the {@link CMethodBindingEmitter#setIsCStructFunctionPointer(boolean)}.
+ * </p>
+ */
public boolean hasContainingType() {
return (getContainingType() != null);
}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java b/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java
index 678fa10..401944b 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/ArrayType.java
@@ -72,8 +72,7 @@ public class ArrayType extends MemoryLayoutType implements Cloneable {
// names during parsing
// Note: don't think cvAttributes can be set for array types (unlike pointer types)
if (computedName == null) {
- computedName = elementType.getName() + " *";
- computedName = computedName.intern();
+ computedName = (elementType.getName() + " *").intern();
}
return computedName;
}
@@ -85,14 +84,14 @@ public class ArrayType extends MemoryLayoutType implements Cloneable {
public int getLength() { return length; }
public boolean hasLength() { return length >= 0; }
- /** Return the bottommost element type if this is a multidimensional
- array. */
+ @Override
public Type getBaseElementType() {
ArrayType t = this;
while (t.getElementType().isArray()) {
t = t.getElementType().asArray();
}
return t.getElementType();
+ // return elementType.getBaseElementType();
}
/** Recompute the size of this array if necessary. This needs to be
diff --git a/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java b/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java
index 70fbc64..7672744 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/FunctionType.java
@@ -126,19 +126,16 @@ public class FunctionType extends Type implements Cloneable {
return toString(null);
}
- public String toString(String functionName) {
+ public String toString(final String functionName) {
return toString(functionName, false);
}
- public String toString(String functionName, boolean emitNativeTag) {
+ public String toString(final String functionName, final boolean emitNativeTag) {
return toString(functionName, null, emitNativeTag, false);
}
- String toString(String functionName, String callingConvention, boolean emitNativeTag, boolean isPointer) {
- StringBuilder res = new StringBuilder();
- if(isConst()) {
- res.append("const ");
- }
+ String toString(final String functionName, final String callingConvention, final boolean emitNativeTag, final boolean isPointer) {
+ final StringBuilder res = new StringBuilder();
res.append(getReturnType());
res.append(" ");
if (isPointer) {
@@ -167,17 +164,11 @@ public class FunctionType extends Type implements Cloneable {
Type t = getArgumentType(i);
if (t.isFunctionPointer()) {
Type targetType = t.asPointer().getTargetType();
- if(targetType.isConst()) {
- res.append("const ");
- }
FunctionType ft = targetType.asFunction();
res.append(ft.toString(getArgumentName(i), callingConvention, false, true));
} else if (t.isArray()) {
res.append(t.asArray().toString(getArgumentName(i)));
} else {
- if(t.isConst()) {
- res.append("const ");
- }
res.append(t);
String argumentName = getArgumentName(i);
if (argumentName != null) {
@@ -190,9 +181,6 @@ public class FunctionType extends Type implements Cloneable {
}
}
res.append(")");
- if (!isPointer) {
- res.append(";");
- }
return res.toString();
}
diff --git a/src/java/com/jogamp/gluegen/cgram/types/PointerType.java b/src/java/com/jogamp/gluegen/cgram/types/PointerType.java
index 330d791..5f19202 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/PointerType.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/PointerType.java
@@ -97,8 +97,7 @@ public class PointerType extends Type implements Cloneable {
// Lazy computation of name due to lazy setting of compound type
// names during parsing
if (computedName == null) {
- computedName = targetType.getName(includeCVAttrs) + " *";
- computedName = computedName.intern();
+ computedName = (targetType.getName(includeCVAttrs) + " *").intern();
}
if (!includeCVAttrs) {
return computedName;
@@ -120,12 +119,15 @@ public class PointerType extends Type implements Cloneable {
return targetType;
}
- public Type getLastTargetType() {
+ @Override
+ public Type getBaseElementType() {
+ /**
if(targetType.isPointer()) {
- return ((PointerType)targetType).getLastTargetType();
+ return ((PointerType)targetType).getBaseElementType();
} else {
return targetType;
- }
+ } */
+ return targetType.getBaseElementType();
}
@Override
diff --git a/src/java/com/jogamp/gluegen/cgram/types/StructLayout.java b/src/java/com/jogamp/gluegen/cgram/types/StructLayout.java
index f105f1f..dfcb722 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/StructLayout.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/StructLayout.java
@@ -87,9 +87,6 @@ public class StructLayout {
} else {
curOffset = SizeThunk.add(curOffset, sz);
}
- if( GlueGen.debug() ) {
- System.err.printf("SL.%02d: o %03d, s %03d, t %s: %s%n", (i+1), f.getOffset(dbgMD), ft.getSize(dbgMD), ft, f);
- }
} else if (ft.isCompound()) {
final CompoundType ct = ft.asCompound();
if(!ct.isLayouted()) {
@@ -103,9 +100,6 @@ public class StructLayout {
} else {
curOffset = SizeThunk.add(curOffset, sz);
}
- if( GlueGen.debug() ) {
- System.err.printf("SL.%02d: o %03d, s %03d, t %s{%d}: %s%n", (i+1), f.getOffset(dbgMD), ft.getSize(dbgMD), ft, ct.getNumFields(), f);
- }
} else if (ft.isArray()) {
final ArrayType arrayType = ft.asArray();
if(!arrayType.isLayouted()) {
@@ -122,9 +116,6 @@ public class StructLayout {
curOffset = SizeThunk.align(curOffset, sz);
f.setOffset(curOffset);
curOffset = SizeThunk.add(curOffset, sz);
- if( GlueGen.debug() ) {
- System.err.printf("SL.%02d: o %03d, s %03d, t %s: %s%n", (i+1), f.getOffset(dbgMD), ft.getSize(dbgMD), ft, f);
- }
} else {
// FIXME
String name = t.getName();
@@ -136,6 +127,9 @@ public class StructLayout {
" in type " + name +
") not implemented yet");
}
+ if( GlueGen.debug() ) {
+ System.err.printf("SL.%02d: o %03d, s %03d: %s, %s%n", (i+1), f.getOffset(dbgMD), ft.getSize(dbgMD), f, ft.getDebugString());
+ }
}
if (t.isUnion()) {
t.setSize(maxSize);
diff --git a/src/java/com/jogamp/gluegen/cgram/types/Type.java b/src/java/com/jogamp/gluegen/cgram/types/Type.java
index a403de6..45d610d 100644
--- a/src/java/com/jogamp/gluegen/cgram/types/Type.java
+++ b/src/java/com/jogamp/gluegen/cgram/types/Type.java
@@ -52,8 +52,8 @@ public abstract class Type implements Cloneable {
private String name;
private SizeThunk size;
- private int cvAttributes;
- private int typedefedCVAttributes;
+ private final int cvAttributes;
+ private int typedefedCVAttributes;
private boolean hasTypedefName;
protected Type(String name, SizeThunk size, int cvAttributes) {
@@ -75,18 +75,96 @@ public abstract class Type implements Cloneable {
/** Returns the name of this type. The returned string is suitable
for use as a type specifier. Does not include any const/volatile
attributes. */
- public String getName() { return getName(false); }
+ public final String getName() { return getName(false); }
/** Returns the name of this type, optionally including
const/volatile attributes. The returned string is suitable for
use as a type specifier. */
- public String getName(boolean includeCVAttrs) {
+ public String getName(boolean includeCVAttrs) {
if (!includeCVAttrs) {
return name;
}
return getCVAttributesString() + name;
}
+ private void append(final StringBuilder sb, final String val, final boolean prepComma) {
+ if( prepComma ) {
+ sb.append(", ");
+ }
+ sb.append(val);
+ }
+ // For debugging
+ public String getDebugString() {
+ final StringBuilder sb = new StringBuilder();
+ boolean prepComma = false;
+ sb.append("CType[");
+ if( null != name ) {
+ append(sb, "'"+name+"'", prepComma); prepComma=true;
+ } else {
+ append(sb, "ANON", prepComma); prepComma=true;
+ }
+ if( hasTypedefName() ) {
+ sb.append(" (typedef)");
+ }
+ append(sb, "size ", prepComma); prepComma=true;
+ if( null != size ) {
+ final long mdSize;
+ {
+ long _mdSize = -1;
+ try {
+ _mdSize = size.computeSize(MachineDescription.StaticConfig.X86_64_UNIX.md);
+ } catch (Exception e) {}
+ mdSize = _mdSize;
+ }
+ sb.append("[fixed ").append(size.hasFixedNativeSize()).append(", lnx64 ").append(mdSize).append("]");
+ } else {
+ sb.append(" ZERO");
+ }
+ append(sb, "[", prepComma); prepComma=false;
+ if( isConst() ) {
+ append(sb, "const ", false);
+ }
+ if( isVolatile() ) {
+ append(sb, "volatile ", false);
+ }
+ if( isPointer() ) {
+ append(sb, "pointer*"+pointerDepth(), prepComma); prepComma=true;
+ }
+ if( isArray() ) {
+ append(sb, "array*"+arrayDimension(), prepComma); prepComma=true;
+ }
+ if( isBit() ) {
+ append(sb, "bit", prepComma); prepComma=true;
+ }
+ if( isCompound() ) {
+ sb.append("struct{").append(asCompound().getNumFields());
+ append(sb, "}", prepComma); prepComma=true;
+ }
+ if( isDouble() ) {
+ append(sb, "double", prepComma); prepComma=true;
+ }
+ if( isEnum() ) {
+ append(sb, "enum", prepComma); prepComma=true;
+ }
+ if( isFloat() ) {
+ append(sb, "float", prepComma); prepComma=true;
+ }
+ if( isFunction() ) {
+ append(sb, "function", prepComma); prepComma=true;
+ }
+ if( isFunctionPointer() ) {
+ append(sb, "funcPointer", prepComma); prepComma=true;
+ }
+ if( isInt() ) {
+ append(sb, "int", prepComma); prepComma=true;
+ }
+ if( isVoid() ) {
+ append(sb, "void", prepComma); prepComma=true;
+ }
+ sb.append("]]");
+ return sb.toString();
+ }
+
/** Set the name of this type; used for handling typedefs. */
public void setName(String name) {
if (name == null) {
@@ -269,6 +347,17 @@ public abstract class Type implements Cloneable {
return 1 + arrayType.getElementType().arrayDimension();
}
+ /**
+ * Helper method to returns the bottom-most element type of this type.
+ * <p>
+ * If this is a multidimensional array or pointer method returns the bottom-most element type,
+ * otherwise this.
+ * </p>
+ */
+ public Type getBaseElementType() {
+ return this;
+ }
+
/** Helper routine for list equality comparison */
static <C> boolean listsEqual(List<C> a, List<C> b) {
return ((a == null && b == null) || (a != null && b != null && a.equals(b)));
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java b/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java
index 3bfb5c4..fd64ba9 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java
@@ -36,6 +36,7 @@ import com.jogamp.junit.util.JunitTracer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.util.Arrays;
@@ -978,13 +979,28 @@ public class BaseClass extends JunitTracer {
Assert.assertEquals(2, surface.getClipSize());
+ TK_Dimension[] allclips = surface.getClips(0, new TK_Dimension[surface.getClipSize()]);
+
for(int i=0; i<surface.getClipSize(); i++) {
- TK_Dimension clip = surface.getClip(i);
- Assert.assertEquals(0x44444444 * (i+1) + 0x11111111, clip.getX());
- Assert.assertEquals(0x44444444 * (i+1) + 0x22222222, clip.getY());
- Assert.assertEquals(0x44444444 * (i+1) + 0x33333333, clip.getWidth());
- Assert.assertEquals(0x44444444 * (i+1) + 0x44444444, clip.getHeight());
+ TK_Dimension clip0 = surface.getClip(i);
+ Assert.assertEquals(0x44444444 * (i+1) + 0x11111111, clip0.getX());
+ Assert.assertEquals(0x44444444 * (i+1) + 0x22222222, clip0.getY());
+ Assert.assertEquals(0x44444444 * (i+1) + 0x33333333, clip0.getWidth());
+ Assert.assertEquals(0x44444444 * (i+1) + 0x44444444, clip0.getHeight());
+
+ TK_Dimension[] clip1 = new TK_Dimension[1];
+ surface.getClips(i, clip1);
+ Assert.assertEquals(0x44444444 * (i+1) + 0x11111111, clip1[0].getX());
+ Assert.assertEquals(0x44444444 * (i+1) + 0x22222222, clip1[0].getY());
+ Assert.assertEquals(0x44444444 * (i+1) + 0x33333333, clip1[0].getWidth());
+ Assert.assertEquals(0x44444444 * (i+1) + 0x44444444, clip1[0].getHeight());
+
+ Assert.assertEquals(0x44444444 * (i+1) + 0x11111111, allclips[i].getX());
+ Assert.assertEquals(0x44444444 * (i+1) + 0x22222222, allclips[i].getY());
+ Assert.assertEquals(0x44444444 * (i+1) + 0x33333333, allclips[i].getWidth());
+ Assert.assertEquals(0x44444444 * (i+1) + 0x44444444, allclips[i].getHeight());
}
+
binding.destroySurface(surface);
}
@@ -1028,10 +1044,10 @@ public class BaseClass extends JunitTracer {
}
final TK_DimensionPair dimPair = TK_DimensionPair.create();
- dimPair.setPair(sumands);
+ dimPair.setPair(0, sumands);
{
sub++;
- final TK_Dimension[] dimsGet = dimPair.getPair();
+ final TK_Dimension[] dimsGet = dimPair.getPair(0, new TK_Dimension[2]);
assertDim("ch11."+sub+": dimsGet[0] ", 11, 22, 33, 44, dimsGet[0]);
assertDim("ch11."+sub+": dimsGet[1] ", 1, 2, 3, 4, dimsGet[1]);
}
@@ -1098,4 +1114,441 @@ public class BaseClass extends JunitTracer {
Assert.assertEquals(3, result[0]);
}
}
+
+ public static final float EPSILON = 1.1920929E-7f; // Float.MIN_VALUE == 1.4e-45f ; double EPSILON 2.220446049250313E-16d
+
+ /** Test array and pointer bindings of structs */
+ public void chapter12TestStructArrayModelConst(Bindingtest1 binding) throws Exception {
+ final TK_ModelConst model = binding.createModelConst();
+
+ Assert.assertEquals(3, model.getIntxxPointerCustomLenVal());
+ Assert.assertEquals(3, model.getInt32PointerCustomLenVal());
+ Assert.assertEquals(3, model.getInt32ArrayFixedLenArrayLength());
+ Assert.assertEquals(3, model.getStructArrayFixedLenArrayLength());
+ Assert.assertEquals(3, model.getStructPointerCustomLenVal());
+
+ // field: int32ArrayFixedLen
+ // CType['int32_t *', size [fixed false, lnx64 12], [array*1]], with array length of 3
+ {
+ final int size = model.getInt32ArrayFixedLenArrayLength();
+ final int[] all = model.getInt32ArrayFixedLen(0, new int[size]);
+ final IntBuffer allB = model.getInt32ArrayFixedLen();
+ Assert.assertEquals(size, allB.limit());
+ for(int i=0; i<size; i++) {
+ Assert.assertEquals(21 + i, all[i]);
+ Assert.assertEquals(21 + i, allB.get(i));
+ final int[] s = model.getInt32ArrayFixedLen(i, new int[1]);
+ Assert.assertEquals(21 + i, s[0]);
+ }
+ }
+
+ // field: int32ArrayOneElem
+ // CType['int32_t *', size [fixed false, lnx64 4], [array*1]], with array length of 1
+ {
+ Assert.assertEquals(30, model.getInt32ArrayOneElem());
+ }
+
+ // field: int32PointerCustomLen
+ // field: CType['int32_t *', size [fixed false, lnx64 8], [pointer*1]], with array length of getInt32PointerCustomLenVal()
+ {
+ final int size = model.getInt32PointerCustomLenVal();
+ final IntBuffer all = model.getInt32PointerCustomLen();
+ Assert.assertEquals(size, all.limit());
+ for(int i=0; i<size; i++) {
+ Assert.assertEquals(31 + i, all.get(i));
+ }
+ }
+
+ // field: int32PointerOneElem
+ // CType['int32_t *', size [fixed false, lnx64 8], [pointer*1]], with array length of 1
+ {
+ final IntBuffer all = model.getInt32PointerOneElem();
+ Assert.assertEquals(1, all.limit());
+ Assert.assertEquals(41, all.get(0));
+ }
+
+ // field: mat4x4
+ // CType['float * *', size [fixed false, lnx64 64], [array*2]], with array length of <code>4*4</code> */
+ {
+ Assert.assertEquals(4*4, model.getMat4x4ArrayLength());
+ final FloatBuffer mat4x4 = model.getMat4x4();
+ Assert.assertEquals(4*4, mat4x4.limit());
+ for(int i=0; i<4; i++) {
+ final float[] vec4 = model.getMat4x4(i*4, new float[4]);
+ for(int j=0; j<4; j++) {
+ Assert.assertEquals(i*4+j, mat4x4.get(i*4+j), EPSILON);
+ Assert.assertEquals(i*4+j, vec4[j], EPSILON);
+ }
+ }
+ }
+
+ // field: structArrayFixedLen
+ // field: CType['TK_Dimension *', size [fixed false, lnx64 48], [array*1]], with array length of 3
+ {
+ final int size = model.getStructArrayFixedLenArrayLength();
+ final TK_Dimension[] all = model.getStructArrayFixedLen(0, new TK_Dimension[size]);
+ for(int i=0; i<size; i++) {
+ Assert.assertEquals(51 + i * 10, all[i].getX());
+ Assert.assertEquals(52 + i * 10, all[i].getY());
+ Assert.assertEquals(53 + i * 10, all[i].getWidth());
+ Assert.assertEquals(54 + i * 10, all[i].getHeight());
+ }
+ }
+
+ // field: structArrayOneElem
+ // CType['TK_Dimension *', size [fixed false, lnx64 16], [array*1]], with array length of 1
+ {
+ final TK_Dimension all = model.getStructArrayOneElem();
+ Assert.assertEquals(81, all.getX());
+ Assert.assertEquals(82, all.getY());
+ Assert.assertEquals(83, all.getWidth());
+ Assert.assertEquals(84, all.getHeight());
+ }
+
+ // field: structPointerCustomLen
+ // CType['TK_Dimension *', size [fixed false, lnx64 8], [pointer*1]], with array length of getStructPointerCustomLenVal()
+ {
+ final int size = model.getStructPointerCustomLenVal();
+ final TK_Dimension[] all = model.getStructPointerCustomLen(0, new TK_Dimension[size]);
+ for(int i=0; i<size; i++) {
+ Assert.assertEquals(91 + i * 10, all[i].getX());
+ Assert.assertEquals(92 + i * 10, all[i].getY());
+ Assert.assertEquals(93 + i * 10, all[i].getWidth());
+ Assert.assertEquals(94 + i * 10, all[i].getHeight());
+ }
+ }
+
+ // field: structPointerOneElem
+ // CType['TK_Dimension *', size [fixed false, lnx64 8], [pointer*1]], with array length of 1
+ {
+ final TK_Dimension all = model.getStructPointerOneElem();
+ Assert.assertEquals(121, all.getX());
+ Assert.assertEquals(122, all.getY());
+ Assert.assertEquals(123, all.getWidth());
+ Assert.assertEquals(124, all.getHeight());
+
+ }
+
+ final long surfaceContext = model.getCtx();
+ assertAPTR(0x123456789abcdef0L, surfaceContext);
+
+ model.setCtx(surfaceContext);
+ assertAPTR(surfaceContext, model.getCtx());
+
+ {
+ Assert.assertEquals(12, model.getModelNameArrayFixedLenArrayLength());
+
+ final ByteBuffer bb = model.getModelNameArrayFixedLen();
+ Assert.assertEquals(12, bb.limit());
+
+ final String exp = "Hello Array";
+ final String has = model.getModelNameArrayFixedLenAsString();
+ // System.err.println("exp '"+exp+"'");
+ System.err.println("has '"+has+"'");
+ // dumpStringChars("exp", exp);
+ dumpStringChars("has", has);
+ Assert.assertEquals(11, has.length()); // w/o EOS
+ Assert.assertEquals(exp, has);
+ }
+ {
+ Assert.assertEquals(14, model.getModelNamePointerCStringArrayLength());
+
+ final ByteBuffer bb = model.getModelNamePointerCString();
+ Assert.assertEquals(14, bb.limit());
+
+ final String exp = "Hello CString";
+ final String has = model.getModelNamePointerCStringAsString();
+ // System.err.println("exp '"+exp+"'");
+ System.err.println("has '"+has+"'");
+ // dumpStringChars("exp", exp);
+ dumpStringChars("has", has);
+ Assert.assertEquals(13, has.length()); // w/o EOS
+ Assert.assertEquals(exp, has);
+ }
+ {
+ Assert.assertEquals(14, model.getModelNamePointerCustomLenVal());
+
+ final ByteBuffer bb = model.getModelNamePointerCustomLen();
+ Assert.assertEquals(14, bb.limit());
+
+ final String exp = "Hello Pointer";
+ final String has = model.getModelNamePointerCustomLenAsString();
+ // System.err.println("exp '"+exp+"'");
+ System.err.println("has '"+has+"'");
+ // dumpStringChars("exp", exp);
+ dumpStringChars("has", has);
+ Assert.assertEquals(13, has.length()); // w/o EOS
+ Assert.assertEquals(exp, has);
+ }
+
+ binding.destroyModelConst(model);
+ }
+ private void dumpStringChars(String prefix, String s) {
+ final int len = s.length();
+ for(int i=0; i<len; i++) {
+ final char c = s.charAt(i);
+ System.err.printf("%s %3d: 0x%X %c%n", prefix, i, (int)c, c);
+ }
+ }
+
+ public void chapter13TestStructArrayModelMutable(Bindingtest1 binding) throws Exception {
+ final TK_ModelMutable model = binding.createModelMutable();
+
+ Assert.assertEquals(3, model.getIntxxPointerCustomLenVal());
+ Assert.assertEquals(3, model.getInt32PointerCustomLenVal());
+ Assert.assertEquals(3, model.getInt32ArrayFixedLenArrayLength());
+ Assert.assertEquals(3, model.getStructArrayFixedLenArrayLength());
+ Assert.assertEquals(3, model.getStructPointerCustomLenVal());
+
+ // field: int32ArrayFixedLen
+ // CType['int32_t *', size [fixed false, lnx64 12], [array*1]], with array length of 3
+ {
+ final int size = model.getInt32ArrayFixedLenArrayLength();
+ {
+ final int[] values = new int[] { 1, 2, 3 };
+ model.setInt32ArrayFixedLen(0, values);
+
+ final int[] all = model.getInt32ArrayFixedLen(0, new int[size]);
+ final IntBuffer allB = model.getInt32ArrayFixedLen();
+ Assert.assertEquals(size, allB.limit());
+ for(int i=0; i<size; i++) {
+ Assert.assertEquals(1 + i, all[i]);
+ Assert.assertEquals(1 + i, allB.get(i));
+ final int[] s = model.getInt32ArrayFixedLen(i, new int[1]);
+ Assert.assertEquals(1 + i, s[0]);
+ }
+ }
+ {
+ for(int i=0; i<size; i++) {
+ final int[] ia = new int[] { 4 + i };
+ model.setInt32ArrayFixedLen(i, ia);
+ }
+
+ final int[] all = model.getInt32ArrayFixedLen(0, new int[size]);
+ final IntBuffer allB = model.getInt32ArrayFixedLen();
+ Assert.assertEquals(size, allB.limit());
+ for(int i=0; i<size; i++) {
+ Assert.assertEquals(4 + i, all[i]);
+ Assert.assertEquals(4 + i, allB.get(i));
+ final int[] s = model.getInt32ArrayFixedLen(i, new int[1]);
+ Assert.assertEquals(4 + i, s[0]);
+ }
+ }
+ }
+
+ // field: int32ArrayOneElem
+ // CType['int32_t *', size [fixed false, lnx64 4], [array*1]], with array length of 1
+ {
+ model.setInt32ArrayOneElem(1);
+ Assert.assertEquals(1, model.getInt32ArrayOneElem());
+ }
+
+ // field: int32PointerCustomLen
+ // field: CType['int32_t *', size [fixed false, lnx64 8], [pointer*1]], with array length of getInt32PointerCustomLenVal()
+ {
+ final int size = model.getInt32PointerCustomLenVal();
+ {
+ final IntBuffer all0 = model.getInt32PointerCustomLen();
+ Assert.assertEquals(size, all0.limit());
+ for(int i=0; i<size; i++) {
+ all0.put(i, 1+i);
+ }
+
+ final IntBuffer all1 = model.getInt32PointerCustomLen();
+ Assert.assertEquals(size, all1.limit());
+ for(int i=0; i<size; i++) {
+ Assert.assertEquals(1 + i, all1.get(i));
+ }
+ }
+ }
+
+ // field: int32PointerOneElem
+ // CType['int32_t *', size [fixed false, lnx64 8], [pointer*1]], with array length of 1
+ {
+ {
+ final IntBuffer one0 = model.getInt32PointerOneElem();
+ Assert.assertEquals(1, one0.limit());
+ one0.put(0, 1);
+
+ final IntBuffer one1 = model.getInt32PointerOneElem();
+ Assert.assertEquals(1, one1.limit());
+ Assert.assertEquals(1, one1.get(0));
+ }
+ }
+
+
+ // field: mat4x4
+ // CType['float * *', size [fixed false, lnx64 64], [array*2]], with array length of <code>4*4</code> */
+ {
+ model.setMat4x4(0*4, new float[] { 11, 12, 13, 14 } );
+ model.setMat4x4(1*4, new float[] { 21, 22, 23, 24 } );
+ model.setMat4x4(2*4, new float[] { 31, 32, 33, 34 } );
+ model.setMat4x4(3*4, new float[] { 41, 42, 43, 44 } );
+
+ Assert.assertEquals(4*4, model.getMat4x4ArrayLength());
+ final FloatBuffer mat4x4 = model.getMat4x4();
+ Assert.assertEquals(4*4, mat4x4.limit());
+ for(int i=0; i<4; i++) {
+ final float[] vec4 = model.getMat4x4(i*4, new float[4]);
+ for(int j=0; j<4; j++) {
+ Assert.assertEquals((i+1)*10+(j+1), mat4x4.get(i*4+j), EPSILON);
+ Assert.assertEquals((i+1)*10+(j+1), vec4[j], EPSILON);
+ }
+ }
+ }
+
+ // field: structArrayFixedLen
+ // field: CType['TK_Dimension *', size [fixed false, lnx64 48], [array*1]], with array length of 3
+ {
+ final int size = model.getStructArrayFixedLenArrayLength();
+ {
+ for(int i=0; i<size; i++) {
+ final TK_Dimension d = TK_Dimension.create();
+ d.setX(1+i*10);
+ d.setY(2+i*10);
+ d.setWidth(3+i*10);
+ d.setHeight(4+i*10);
+ model.setStructArrayFixedLen(i, d);
+ }
+ final TK_Dimension[] all = model.getStructArrayFixedLen(0, new TK_Dimension[size]);
+ for(int i=0; i<size; i++) {
+ Assert.assertEquals(1 + i * 10, all[i].getX());
+ Assert.assertEquals(2 + i * 10, all[i].getY());
+ Assert.assertEquals(3 + i * 10, all[i].getWidth());
+ Assert.assertEquals(4 + i * 10, all[i].getHeight());
+ final TK_Dimension[] one = model.getStructArrayFixedLen(i, new TK_Dimension[1]);
+ Assert.assertEquals(1 + i * 10, one[0].getX());
+ Assert.assertEquals(2 + i * 10, one[0].getY());
+ Assert.assertEquals(3 + i * 10, one[0].getWidth());
+ Assert.assertEquals(4 + i * 10, one[0].getHeight());
+ }
+ }
+ {
+ final TK_Dimension[] da = new TK_Dimension[size];
+ for(int i=0; i<size; i++) {
+ final TK_Dimension d = TK_Dimension.create();
+ d.setX(5+i*10);
+ d.setY(6+i*10);
+ d.setWidth(7+i*10);
+ d.setHeight(8+i*10);
+ da[i] = d;
+ }
+ model.setStructArrayFixedLen(0, da);
+
+ final TK_Dimension[] all = model.getStructArrayFixedLen(0, new TK_Dimension[size]);
+ for(int i=0; i<size; i++) {
+ Assert.assertEquals(5 + i * 10, all[i].getX());
+ Assert.assertEquals(6 + i * 10, all[i].getY());
+ Assert.assertEquals(7 + i * 10, all[i].getWidth());
+ Assert.assertEquals(8 + i * 10, all[i].getHeight());
+ final TK_Dimension[] one = model.getStructArrayFixedLen(i, new TK_Dimension[1]);
+ Assert.assertEquals(5 + i * 10, one[0].getX());
+ Assert.assertEquals(6 + i * 10, one[0].getY());
+ Assert.assertEquals(7 + i * 10, one[0].getWidth());
+ Assert.assertEquals(8 + i * 10, one[0].getHeight());
+ }
+ }
+ {
+ for(int i=0; i<size; i++) {
+ final TK_Dimension d = TK_Dimension.create();
+ d.setX(1+i*10);
+ d.setY(3+i*10);
+ d.setWidth(5+i*10);
+ d.setHeight(7+i*10);
+ model.setStructArrayFixedLen(i, new TK_Dimension[] { d });
+ }
+
+ final TK_Dimension[] all = model.getStructArrayFixedLen(0, new TK_Dimension[size]);
+ for(int i=0; i<size; i++) {
+ Assert.assertEquals(1 + i * 10, all[i].getX());
+ Assert.assertEquals(3 + i * 10, all[i].getY());
+ Assert.assertEquals(5 + i * 10, all[i].getWidth());
+ Assert.assertEquals(7 + i * 10, all[i].getHeight());
+ final TK_Dimension[] one = model.getStructArrayFixedLen(i, new TK_Dimension[1]);
+ Assert.assertEquals(1 + i * 10, one[0].getX());
+ Assert.assertEquals(3 + i * 10, one[0].getY());
+ Assert.assertEquals(5 + i * 10, one[0].getWidth());
+ Assert.assertEquals(7 + i * 10, one[0].getHeight());
+ }
+ }
+ }
+
+ // field: structArrayOneElem
+ // CType['TK_Dimension *', size [fixed false, lnx64 16], [array*1]], with array length of 1
+ {
+ {
+ final TK_Dimension d = TK_Dimension.create();
+ d.setX(1);
+ d.setY(2);
+ d.setWidth(3);
+ d.setHeight(4);
+ model.setStructArrayOneElem(d);
+ }
+ {
+ final TK_Dimension one = model.getStructArrayOneElem();
+ Assert.assertEquals(1, one.getX());
+ Assert.assertEquals(2, one.getY());
+ Assert.assertEquals(3, one.getWidth());
+ Assert.assertEquals(4, one.getHeight());
+ }
+ }
+
+ // field: structPointerCustomLen
+ // CType['TK_Dimension *', size [fixed false, lnx64 8], [pointer*1]], with array length of getStructPointerCustomLenVal()
+ {
+ final int size = model.getStructPointerCustomLenVal();
+ {
+ final TK_Dimension[] all = model.getStructPointerCustomLen(0, new TK_Dimension[size]);
+ for(int i=0; i<size; i++) {
+ final TK_Dimension d = all[i];
+ d.setX(1+i*10);
+ d.setY(2+i*10);
+ d.setWidth(3+i*10);
+ d.setHeight(4+i*10);
+ }
+ }
+ {
+ final TK_Dimension[] all = model.getStructPointerCustomLen(0, new TK_Dimension[size]);
+ for(int i=0; i<size; i++) {
+ Assert.assertEquals(1 + i * 10, all[i].getX());
+ Assert.assertEquals(2 + i * 10, all[i].getY());
+ Assert.assertEquals(3 + i * 10, all[i].getWidth());
+ Assert.assertEquals(4 + i * 10, all[i].getHeight());
+ final TK_Dimension[] one = model.getStructPointerCustomLen(i, new TK_Dimension[1]);
+ Assert.assertEquals(1 + i * 10, one[0].getX());
+ Assert.assertEquals(2 + i * 10, one[0].getY());
+ Assert.assertEquals(3 + i * 10, one[0].getWidth());
+ Assert.assertEquals(4 + i * 10, one[0].getHeight());
+ }
+ }
+ }
+
+ // field: structPointerOneElem
+ // CType['TK_Dimension *', size [fixed false, lnx64 8], [pointer*1]], with array length of 1
+ {
+ {
+ final TK_Dimension d = model.getStructPointerOneElem();
+ d.setX(1);
+ d.setY(2);
+ d.setWidth(3);
+ d.setHeight(4);
+ }
+ {
+ final TK_Dimension one = model.getStructPointerOneElem();
+ Assert.assertEquals(1, one.getX());
+ Assert.assertEquals(2, one.getY());
+ Assert.assertEquals(3, one.getWidth());
+ Assert.assertEquals(4, one.getHeight());
+ }
+
+ }
+
+ final long surfaceContext = model.getCtx();
+ assertAPTR(0x123456789abcdef0L, surfaceContext);
+
+ model.setCtx(surfaceContext);
+ assertAPTR(surfaceContext, model.getCtx());
+
+ binding.destroyModelMutable(model);
+ }
}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java
index e63f255..e3e3ca9 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java
@@ -132,6 +132,22 @@ public class Test1p1JavaEmitter extends BaseClass {
chapter11TestCompoundCallByValue(new Bindingtest1p1Impl());
}
+ /**
+ * Test compound access read-only
+ */
+ @Test
+ public void chapter12TestStructArrayModelConst() throws Exception {
+ chapter12TestStructArrayModelConst(new Bindingtest1p1Impl());
+ }
+
+ /**
+ * Test compound access read-write
+ */
+ @Test
+ public void chapter13TestStructArrayModelMutable() throws Exception {
+ chapter13TestStructArrayModelMutable(new Bindingtest1p1Impl());
+ }
+
public static void main(String args[]) throws IOException {
String tstname = Test1p1JavaEmitter.class.getName();
org.junit.runner.JUnitCore.main(tstname);
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java
index 07201c0..39e3948 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java
@@ -30,7 +30,6 @@ package com.jogamp.gluegen.test.junit.generation;
import java.io.IOException;
-import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest1p1Impl;
import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest1p2Impl;
import com.jogamp.common.os.NativeLibrary;
@@ -142,6 +141,22 @@ public class Test1p2ProcAddressEmitter extends BaseClass {
}
/**
+ * Test compound access read-only
+ */
+ @Test
+ public void chapter12TestStructArrayModelConst() throws Exception {
+ chapter12TestStructArrayModelConst(new Bindingtest1p2Impl());
+ }
+
+ /**
+ * Test compound access read-write
+ */
+ @Test
+ public void chapter13TestStructArrayModelMutable() throws Exception {
+ chapter13TestStructArrayModelMutable(new Bindingtest1p2Impl());
+ }
+
+ /**
* Verifies unloading of the new library.
*/
@AfterClass
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1-common.cfg b/src/junit/com/jogamp/gluegen/test/junit/generation/test1-common.cfg
index d4e32cc..eca133e 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/test1-common.cfg
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1-common.cfg
@@ -41,8 +41,12 @@ EmitStruct TK_Dimension
StructPackage TK_DimensionPair com.jogamp.gluegen.test.junit.generation
EmitStruct TK_DimensionPair
+EmitStruct TK_Surface
StructPackage TK_Surface com.jogamp.gluegen.test.junit.generation
EmitStruct TK_Surface
+ReturnedArrayLength TK_Surface.clips getClipSize()
+IgnoreField TK_Surface GetComponent
+
# Implements TK_Surface TḴ_???
StructPackage TK_ComplicatedSuperSet com.jogamp.gluegen.test.junit.generation
@@ -50,10 +54,44 @@ EmitStruct TK_ComplicatedSuperSet
# Implements TK_ComplicatedSuperSet TḴ_???
ReturnValueCapacity createSurface sizeof(TK_Surface)
-ReturnValueCapacity getClip sizeof(TK_Dimension)
+ReturnValueCapacity TK_Surface.getClip sizeof(TK_Dimension)
ReturnValueCapacity createComplicatedSuperSet sizeof(TK_ComplicatedSuperSet)
+EmitStruct TK_ModelConst
+StructPackage TK_ModelConst com.jogamp.gluegen.test.junit.generation
+ReturnedArrayLength TK_ModelConst.intxxArrayCustomLen getIntxxArrayCustomLenVal()
+ReturnedArrayLength TK_ModelConst.intxxPointerCustomLen getIntxxPointerCustomLenVal()
+ReturnedArrayLength TK_ModelConst.int32ArrayCustomLen getInt32ArrayCustomLenVal()
+ReturnedArrayLength TK_ModelConst.int32PointerCustomLen getInt32PointerCustomLenVal()
+ReturnedArrayLength TK_ModelConst.structArrayCustomLen getStructArrayCustomLenVal()
+ReturnedArrayLength TK_ModelConst.structPointerCustomLen getStructPointerCustomLenVal()
+ReturnedArrayLength TK_ModelConst.int32PointerOneElem 1
+ReturnValueCapacity TK_ModelConst.int32PointerOneElem 1 * sizeof(int32_t) /* overridden by ReturnValueCapacity */
+ReturnedArrayLength TK_ModelConst.structPointerOneElem 1
+ReturnsString TK_ModelConst.modelNameArrayFixedLen
+ReturnsString TK_ModelConst.modelNamePointerCString
+ReturnsString TK_ModelConst.modelNamePointerCustomLen
+ReturnedArrayLength TK_ModelConst.modelNamePointerCustomLen getModelNamePointerCustomLenVal()
+
+EmitStruct TK_ModelMutable
+StructPackage TK_ModelMutable com.jogamp.gluegen.test.junit.generation
+ReturnedArrayLength TK_ModelMutable.intxxArrayCustomLen getIntxxArrayCustomLenVal()
+ReturnedArrayLength TK_ModelMutable.intxxPointerCustomLen getIntxxPointerCustomLenVal()
+ReturnedArrayLength TK_ModelMutable.int32ArrayCustomLen getInt32ArrayCustomLenVal()
+ReturnedArrayLength TK_ModelMutable.int32PointerCustomLen getInt32PointerCustomLenVal()
+ReturnedArrayLength TK_ModelMutable.structArrayCustomLen getStructArrayCustomLenVal()
+ReturnedArrayLength TK_ModelMutable.structPointerCustomLen getStructPointerCustomLenVal()
+ReturnedArrayLength TK_ModelMutable.int32PointerOneElem 1
+ReturnedArrayLength TK_ModelMutable.structPointerOneElem 1
+ReturnsString TK_ModelMutable.modelNameArrayFixedLen
+ReturnsString TK_ModelMutable.modelNamePointerCString
+ReturnsString TK_ModelMutable.modelNamePointerCustomLen
+ReturnedArrayLength TK_ModelMutable.modelNamePointerCustomLen getModelNamePointerCustomLenVal()
+
+ReturnValueCapacity createModelConst sizeof(TK_ModelConst)
+ReturnValueCapacity createModelMutable sizeof(TK_ModelMutable)
+
# Imports needed by all glue code
Import java.nio.*
Import java.util.*
@@ -65,6 +103,8 @@ Import com.jogamp.gluegen.test.junit.generation.TK_DimensionPair
Import com.jogamp.gluegen.test.junit.generation.TK_Engine
Import com.jogamp.gluegen.test.junit.generation.TK_ComplicatedSuperSet
Import com.jogamp.gluegen.test.junit.generation.TK_ComplicatedSubSet
+Import com.jogamp.gluegen.test.junit.generation.TK_ModelConst
+Import com.jogamp.gluegen.test.junit.generation.TK_ModelMutable
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c
index 3dc1ac5..9999274 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c
@@ -372,6 +372,7 @@ MYAPI TK_Surface * MYAPIENTRY createSurface() {
MYAPI void MYAPIENTRY destroySurface(TK_Surface * surface) {
assert(NULL!=surface);
+ assert(NULL!=surface->clips);
free(surface->clips);
// free(surface->engine);
free(surface);
@@ -578,3 +579,112 @@ MYAPI void MYAPIENTRY addByte(const char summands[2], char result[1]) {
result[0] = summands[0] + summands[1];
}
+MYAPI TK_ModelMutable * MYAPIENTRY createModelMutable() {
+ int i, j;
+ TK_ModelMutable * s = calloc(1, sizeof(TK_ModelMutable));
+
+ s->intxxArrayFixedLen[0]=1;
+ s->intxxArrayFixedLen[1]=2;
+ s->intxxArrayFixedLen[2]=3;
+
+ s->intxxPointerCustomLen = calloc(3, sizeof(int));
+ s->intxxPointerCustomLen[0] = 11;
+ s->intxxPointerCustomLen[1] = 12;
+ s->intxxPointerCustomLen[2] = 13;
+ s->intxxPointerCustomLenVal=3;
+
+ s->int32ArrayFixedLen[0] = 21;
+ s->int32ArrayFixedLen[1] = 22;
+ s->int32ArrayFixedLen[2] = 23;
+
+ s->int32ArrayOneElem[0] = 30;
+
+ s->int32PointerCustomLen = calloc(3, sizeof(int));
+ s->int32PointerCustomLen[0] = 31;
+ s->int32PointerCustomLen[1] = 32;
+ s->int32PointerCustomLen[2] = 33;
+ s->int32PointerCustomLenVal=3;
+
+ s->int32PointerOneElem = calloc(1, sizeof(int));
+ s->int32PointerOneElem[0] = 41;
+
+ for(i=0; i<4; i++) {
+ for(j=0; j<4; j++) {
+ s->mat4x4[i][j] = i*4 + j;
+ }
+ }
+
+ s->structArrayFixedLen[0].x = 51;
+ s->structArrayFixedLen[0].y = 52;
+ s->structArrayFixedLen[0].width = 53;
+ s->structArrayFixedLen[0].height = 54;
+ s->structArrayFixedLen[1].x = 61;
+ s->structArrayFixedLen[1].y = 62;
+ s->structArrayFixedLen[1].width = 63;
+ s->structArrayFixedLen[1].height = 64;
+ s->structArrayFixedLen[2].x = 71;
+ s->structArrayFixedLen[2].y = 72;
+ s->structArrayFixedLen[2].width = 73;
+ s->structArrayFixedLen[2].height = 74;
+
+ s->structArrayOneElem[0].x = 81;
+ s->structArrayOneElem[0].y = 82;
+ s->structArrayOneElem[0].width = 83;
+ s->structArrayOneElem[0].height = 84;
+
+ s->structPointerCustomLen = (TK_Dimension *) calloc(3, sizeof(TK_Dimension));
+ s->structPointerCustomLen[0].x = 91;
+ s->structPointerCustomLen[0].y = 92;
+ s->structPointerCustomLen[0].width = 93;
+ s->structPointerCustomLen[0].height = 94;
+ s->structPointerCustomLen[1].x = 101;
+ s->structPointerCustomLen[1].y = 102;
+ s->structPointerCustomLen[1].width = 103;
+ s->structPointerCustomLen[1].height = 104;
+ s->structPointerCustomLen[2].x = 111;
+ s->structPointerCustomLen[2].y = 112;
+ s->structPointerCustomLen[2].width = 113;
+ s->structPointerCustomLen[2].height = 114;
+ s->structPointerCustomLenVal = 3;
+
+ s->structPointerOneElem = (TK_Dimension *) calloc(1, sizeof(TK_Dimension));
+ s->structPointerOneElem[0].x = 121;
+ s->structPointerOneElem[0].y = 122;
+ s->structPointerOneElem[0].width = 123;
+ s->structPointerOneElem[0].height = 124;
+
+ s->ctx = (void *) 0x123456789abcdef0UL;
+
+ strncpy(s->modelNameArrayFixedLen, "Hello Array", sizeof(s->modelNameArrayFixedLen));
+
+ s->modelNamePointerCString = calloc(13+1, sizeof(char));
+ strncpy(s->modelNamePointerCString, "Hello CString", 13+1);
+
+ s->modelNamePointerCustomLen = calloc(13+1, sizeof(char));
+ strncpy(s->modelNamePointerCustomLen, "Hello Pointer", 13+1);
+ s->modelNamePointerCustomLenVal = 13+1;
+
+ return s;
+}
+
+MYAPI void MYAPIENTRY destroyModelMutable(TK_ModelMutable * s) {
+ assert(NULL!=s);
+ assert(NULL!=s->intxxPointerCustomLen);
+ assert(NULL!=s->int32PointerCustomLen);
+ assert(NULL!=s->int32PointerOneElem);
+ assert(NULL!=s->structPointerCustomLen);
+ free(s->intxxPointerCustomLen);
+ free(s->int32PointerCustomLen);
+ free(s->int32PointerOneElem);
+ free(s->structPointerCustomLen);
+ free(s->modelNamePointerCString);
+ free(s->modelNamePointerCustomLen);
+ free(s);
+}
+
+MYAPI TK_ModelConst * MYAPIENTRY createModelConst() {
+ return (TK_ModelConst *)createModelMutable();
+}
+MYAPI void MYAPIENTRY destroyModelConst(TK_ModelConst * s) {
+ destroyModelMutable((TK_ModelMutable *)s);
+}
diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h
index 7343172..ebb41d3 100644
--- a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h
+++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h
@@ -183,15 +183,23 @@ typedef struct {
TK_Context ctx;
} TK_ContextWrapper;
+struct _jobject;
+typedef struct _jobject *jobject;
+struct JNINativeInterface_;
+typedef const struct JNINativeInterface_ *JNIEnv;
+
+
typedef struct tk_Surface {
TK_Context ctx;
TK_ContextWrapper ctxWrapper;
- // const TK_Engine * engine;
TK_Engine engine;
TK_Dimension bounds;
int32_t clipSize;
TK_Dimension * clips;
TK_Dimension * (MYAPIENTRY *getClip) (struct tk_Surface * ds, int idx);
+
+ jobject (MYAPIENTRY *GetComponent)(JNIEnv* env, void* platformInfo);
+
} TK_Surface;
typedef struct {
@@ -274,3 +282,71 @@ MYAPI void MYAPIENTRY intToRgba(int irgba, char rgbaSink[4]);
MYAPI void MYAPIENTRY addInt(const int summands[2], int result[1]);
MYAPI void MYAPIENTRY addByte(const char summands[2], char result[1]);
+typedef struct {
+ const int intxxArrayFixedLen[3];
+
+ const int * intxxPointerCustomLen;
+ const int intxxPointerCustomLenVal;
+
+ const int32_t int32ArrayFixedLen[3];
+ const int32_t int32ArrayOneElem[1];
+
+ const int32_t * int32PointerCustomLen;
+ const int32_t int32PointerCustomLenVal;
+
+ const int32_t * int32PointerOneElem;
+
+ const float mat4x4[4][4];
+
+ const TK_Dimension structArrayFixedLen[3];
+ const TK_Dimension structArrayOneElem[1];
+
+ const TK_Dimension * structPointerCustomLen;
+ const int32_t structPointerCustomLenVal;
+ const TK_Dimension * structPointerOneElem;
+
+ const TK_Context ctx;
+
+ const char modelNameArrayFixedLen[12]; /* 'Hello Array' len=11+1 */
+ const char * modelNamePointerCString; /* 'Hello CString' len=13+1 */
+ const char * modelNamePointerCustomLen; /* 'Hello Pointer' len=13+1 */
+ const int modelNamePointerCustomLenVal; /* 13+1 */
+
+} TK_ModelConst;
+
+typedef struct {
+ int intxxArrayFixedLen[3];
+
+ int * intxxPointerCustomLen;
+ int intxxPointerCustomLenVal;
+
+ int32_t int32ArrayFixedLen[3];
+ int32_t int32ArrayOneElem[1];
+
+ int32_t * int32PointerCustomLen;
+ int32_t int32PointerCustomLenVal;
+
+ int32_t * int32PointerOneElem;
+
+ float mat4x4[4][4];
+
+ TK_Dimension structArrayFixedLen[3];
+ TK_Dimension structArrayOneElem[1];
+
+ TK_Dimension * structPointerCustomLen;
+ int32_t structPointerCustomLenVal;
+ TK_Dimension * structPointerOneElem;
+
+ TK_Context ctx;
+
+ char modelNameArrayFixedLen[12]; /* 'Hello Array' len=11+1 */
+ const char * modelNamePointerCString; /* 'Hello CString' len=13+1 */
+ char * modelNamePointerCustomLen; /* 'Hello Pointer' len=13+1 */
+ int modelNamePointerCustomLenVal; /* 13+1 */
+
+} TK_ModelMutable;
+
+MYAPI TK_ModelConst * MYAPIENTRY createModelConst();
+MYAPI void MYAPIENTRY destroyModelConst(TK_ModelConst * s);
+MYAPI TK_ModelMutable * MYAPIENTRY createModelMutable();
+MYAPI void MYAPIENTRY destroyModelMutable(TK_ModelMutable * s);