aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/com/jogamp/gluegen/JavaEmitter.java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-06-16 02:16:20 +0200
committerSven Gothel <[email protected]>2023-06-16 02:16:20 +0200
commit8b127c4c1dd26fcb1756805ddb83729203161f78 (patch)
treef8563a0e39d293bc070ef01e457cfe08ee44096d /src/java/com/jogamp/gluegen/JavaEmitter.java
parentaeadfab9572e4b441b1bc1f0708cf4c72dfe181e (diff)
GlueGen Struct [5]: Revised Struct Mapping + Documentation
GlueGen Revised Struct Mapping (esp pointer to array or single element), Struct String Charset, .. and Documentation - Documentation: - Added README.md Let's have a proper face for the git repo - Added doc/GlueGen_Mapping.md (and its html conversion doc/GlueGen_Mapping.html) Created a new document covering application and implementation details suitable for users/devs. - Added doc/JogAmpMacOSVersions.md conversion to doc/JogAmpMacOSVersions.html - Updated www/index.html - Use *CodeUnit instead of PrintWriter, representing a Java or C code unit covering a set of functions and structs. The CCodeUnit also handles common code shared by its unit across functions etc. - Dropping 'static initializer', as its no more required due to simplified `JVMUtil_NewDirectByteBufferCopy()` variant. - Revised Struct Mapping: - Pure Java implementation to map primitive and struct fields within a struct by utilizing ElementBuffer. Only 'Function Pointer' fields within a struct require native code. Exposes `static boolean usesNativeCode()` to query whether native code is used/required. - Transparent native memory address API Expose `long getDirectBufferAddress()` and `static TK_Struct derefPointer(long addr)`, allowing to - pass the native struct-pointer with native code - reconstruct the struct from a native struct-pointer - have a fully functional `TK_Struct.derefPointer(struct.getDirectBufferAddress())` cycle. - Add 'boolean is<Val>Null() to query whether a pointer (array) is NULL - *Changed* array get/set method for more flexibility alike `System.arraycopy(src, srcPos, dest, destPos, len)`, where 'src' is being dropped for the getter and 'dest' is being dropped for the setter as both objects are reflected by the struct instance. - *Changed* `get<Val>ArrayLength()` -> `get<Val>ElemCount()` for clarity - Considering all ConstElemCount values with config 'ReturnedArrayLength <int>' to be owned by native code -> NativeOwnership -> Not changing the underlying memory region! JavaOwnership is considered for all pointer-arrays not of NativeOwnership. Hence any setter on a NativeOwnership pointer-array will fail with non-matching elem-count. - Add 'release<Val>()' for JavaOwnership pointer-arrays, allowing to release the Java owned native memory incl. null-ing pointer and set<Val>ElemCount(0). - Support setter for 'const <type>*' w/ JavaOwnership, i.e. pointer to const value of a primitive or struct, setter and getter using pointer to array or single element in general. - Added Config `ImmutableAccess symbol` to disable all setter for whole struct or a field - Added Config `MaxOneElement symbol` to restrict a pointer to maximum one element and unset initial value (zero elements) - Added Config `ReturnsStringOnly symbol` to restrict mapping only to a Java String, dropping the ByteBuffer variant for 'char' - String mapping default is UTF-8 and can be read and set via [get|set]Charset(..) per class. - Dynamic string length retrieval in case no `ReturnedArrayLength` has been configured has changed from `strlen()` to `strnlen(aptr, max_len)` to be on the safe site. The maximum length default is 8192 bytes and can be read and set via [get|set]MaxStrnlen(..) per class. FIXME: strnlen(..) using EOS byte non-functional for non 8-bit codecs like UTF-8, US-ASCII. This is due to e.g. UTF-16 doesn't use an EOS byte, but interprets it as part of a code point. - TODO: Perhaps a few more unit tests - TODO: Allow plain 'int' to be mapped in structs IFF their size is same for all MachineDescriptions used. Currently this is the case -> 4 bytes like int32_t.
Diffstat (limited to 'src/java/com/jogamp/gluegen/JavaEmitter.java')
-rw-r--r--src/java/com/jogamp/gluegen/JavaEmitter.java1827
1 files changed, 959 insertions, 868 deletions
diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java
index 4e8a35f..e2be4ea 100644
--- a/src/java/com/jogamp/gluegen/JavaEmitter.java
+++ b/src/java/com/jogamp/gluegen/JavaEmitter.java
@@ -1,6 +1,6 @@
/*
+ * Copyright (c) 2010-2023 JogAmp Community. All rights reserved.
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -48,13 +48,13 @@ import static com.jogamp.gluegen.JavaEmitter.MethodAccess.PUBLIC_ABSTRACT;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
+import static java.util.logging.Level.SEVERE;
-import java.io.BufferedWriter;
import java.io.File;
-import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.Buffer;
+import java.nio.ByteBuffer;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -78,12 +78,9 @@ import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider;
import com.jogamp.gluegen.Logging.LoggerIf;
import com.jogamp.gluegen.cgram.types.AliasedSymbol;
import com.jogamp.gluegen.cgram.types.ArrayType;
-import com.jogamp.gluegen.cgram.types.CVAttributes;
import com.jogamp.gluegen.cgram.types.CompoundType;
import com.jogamp.gluegen.cgram.types.Field;
import com.jogamp.gluegen.cgram.types.FunctionSymbol;
-import com.jogamp.gluegen.cgram.types.FunctionType;
-import com.jogamp.gluegen.cgram.types.IntType;
import com.jogamp.gluegen.cgram.types.PointerType;
import com.jogamp.gluegen.cgram.types.SizeThunk;
import com.jogamp.gluegen.cgram.types.StructLayout;
@@ -106,7 +103,6 @@ public class JavaEmitter implements GlueEmitter {
private StructLayout layout;
private Map<Type, Type> canonMap;
protected JavaConfiguration cfg;
- private boolean requiresStaticInitialization = false;
/**
* Style of code emission. Can emit everything into one class
@@ -130,11 +126,9 @@ public class JavaEmitter implements GlueEmitter {
private final String javaName;
}
- private String javaFileName; // of javaWriter or javaImplWriter
- private PrintWriter javaWriter; // Emits either interface or, in AllStatic mode, everything
- private PrintWriter javaImplWriter; // Only used in non-AllStatic modes for impl class
- private String cFileName; // of cWriter
- private PrintWriter cWriter;
+ private JavaCodeUnit javaUnit; // Covers either interface or, in AllStatic mode, everything
+ private JavaCodeUnit javaImplUnit; // Only used in non-AllStatic modes for impl class
+ private CCodeUnit cUnit;
private final MachineDataInfo machDescJava = MachineDataInfo.StaticConfig.LP64_UNIX.md;
private final MachineDataInfo.StaticConfig[] machDescTargetConfigs = MachineDataInfo.StaticConfig.values();
@@ -262,7 +256,7 @@ public class JavaEmitter implements GlueEmitter {
if ( !cfg.structsOnly() ) {
try {
- openWriters();
+ openCodeUnits();
} catch (final Exception e) {
throw new RuntimeException("Unable to open files for writing", e);
}
@@ -286,7 +280,7 @@ public class JavaEmitter implements GlueEmitter {
@Override
public void beginDefines() throws Exception {
if ( ( cfg.allStatic() || cfg.emitInterface() ) && !cfg.structsOnly() ) {
- javaWriter().println();
+ javaUnit().emitln();
}
}
@@ -317,18 +311,18 @@ public class JavaEmitter implements GlueEmitter {
if ( !cfg.shouldIgnoreInInterface(def) ) {
final ConstantDefinition.JavaExpr constExpr = def.computeJavaExpr(constMap);
constMap.put(def.getName(), constExpr);
- javaWriter().print(" /** ");
+ javaUnit().emit(" /** ");
if (optionalComment != null && optionalComment.length() != 0) {
- javaWriter().print(optionalComment);
- javaWriter().print(" - ");
+ javaUnit().emit(optionalComment);
+ javaUnit().emit(" - ");
}
- javaWriter().print("CType: ");
+ javaUnit().emit("CType: ");
if( constExpr.resultType.isUnsigned ) {
- javaWriter().print("unsigned ");
+ javaUnit().emit("unsigned ");
}
- javaWriter().print(constExpr.resultJavaTypeName);
- javaWriter().println(" */");
- javaWriter().println(" public static final " + constExpr.resultJavaTypeName +
+ javaUnit().emit(constExpr.resultJavaTypeName);
+ javaUnit().emitln(" */");
+ javaUnit().emitln(" public static final " + constExpr.resultJavaTypeName +
" " + def.getName() + " = " + constExpr.javaExpression + ";");
}
}
@@ -345,10 +339,9 @@ public class JavaEmitter implements GlueEmitter {
// this.typedefDictionary = typedefDictionary;
this.canonMap = canonMap;
- this.requiresStaticInitialization = false; // reset
if ( ( cfg.allStatic() || cfg.emitInterface() ) && !cfg.structsOnly() ) {
- javaWriter().println();
+ javaUnit().emitln();
}
}
@@ -377,7 +370,7 @@ public class JavaEmitter implements GlueEmitter {
final FunctionSymbol cFunc = emitter.getCSymbol();
if ( !emitter.isInterface() || !cfg.shouldIgnoreInInterface(cFunc) ) {
emitter.emit();
- emitter.getDefaultOutput().println(); // put newline after method body
+ emitter.getUnit().emitln(); // put newline after method body
LOG.log(INFO, cFunc.getASTLocusTag(), "Non-Ignored Intf[{0}]: {1}", i++, cFunc);
}
} catch (final Exception e) {
@@ -453,11 +446,11 @@ public class JavaEmitter implements GlueEmitter {
final boolean emitBody = !signatureOnly && needsBody;
final boolean isNativeMethod = !isUnimplemented && !needsBody && !signatureOnly;
- final PrintWriter writer = ((signatureOnly || cfg.allStatic()) ? javaWriter() : javaImplWriter());
+ final CodeUnit unit = ((signatureOnly || cfg.allStatic()) ? javaUnit() : javaImplUnit());
final JavaMethodBindingEmitter emitter =
new JavaMethodBindingEmitter(binding,
- writer,
+ unit,
cfg.runtimeExceptionType(),
cfg.unsupportedExceptionType(),
emitBody, // emitBody
@@ -512,7 +505,6 @@ public class JavaEmitter implements GlueEmitter {
cfg.javaEpilogueForMethod(binding, false, false) != null ;
if ( !cfg.isUnimplemented( cSymbol ) ) {
-
// If we already generated a public native entry point for this
// method, don't emit another one
//
@@ -524,12 +516,12 @@ public class JavaEmitter implements GlueEmitter {
( binding.needsNIOWrappingOrUnwrapping() || hasPrologueOrEpilogue )
)
{
- final PrintWriter writer = (cfg.allStatic() ? javaWriter() : javaImplWriter());
+ final CodeUnit unit = (cfg.allStatic() ? javaUnit() : javaImplUnit());
// (Always) emit the entry point taking only direct buffers
final JavaMethodBindingEmitter emitter =
new JavaMethodBindingEmitter(binding,
- writer,
+ unit,
cfg.runtimeExceptionType(),
cfg.unsupportedExceptionType(),
false, // emitBody
@@ -563,7 +555,7 @@ public class JavaEmitter implements GlueEmitter {
// Generate a binding without mixed access (NIO-direct, -indirect, array)
final CMethodBindingEmitter cEmitter =
new CMethodBindingEmitter(binding,
- cWriter(),
+ cUnit(),
cfg.implPackageName(),
cfg.implClassName(),
true, // NOTE: we always disambiguate with a suffix now, so this is optional
@@ -714,18 +706,10 @@ public class JavaEmitter implements GlueEmitter {
public void endFunctions() throws Exception {
if ( !cfg.structsOnly() ) {
if (cfg.allStatic() || cfg.emitInterface()) {
- emitCustomJavaCode(javaWriter(), cfg.className());
+ emitCustomJavaCode(javaUnit(), cfg.className());
}
if (!cfg.allStatic() && cfg.emitImpl()) {
- emitCustomJavaCode(javaImplWriter(), cfg.implClassName());
- }
- if ( cfg.allStatic() ) {
- emitJavaInitCode(javaWriter(), cfg.className());
- } else if ( cfg.emitImpl() ) {
- emitJavaInitCode(javaImplWriter(), cfg.implClassName());
- }
- if ( cfg.emitImpl() ) {
- emitCInitCode(cWriter(), getImplPackageName(), cfg.implClassName());
+ emitCustomJavaCode(javaImplUnit(), cfg.implClassName());
}
}
}
@@ -750,6 +734,7 @@ public class JavaEmitter implements GlueEmitter {
@Override
public void emitStruct(final CompoundType structCType, final Type structCTypedefPtr) throws Exception {
final String structCTypeName, typedefedName;
+ final boolean immutableStruct;
{
final String _name = structCType.getName();
if ( null != structCTypedefPtr && null != structCTypedefPtr.getName() ) {
@@ -778,6 +763,7 @@ public class JavaEmitter implements GlueEmitter {
"skipping emission of ignored \"{0}\": {1}", aliases, structCType);
return;
}
+ immutableStruct = cfg.immutableAccess(aliases);
}
if( null != structCTypedefPtr && isOpaque(structCTypedefPtr) ) {
@@ -827,8 +813,6 @@ public class JavaEmitter implements GlueEmitter {
"emission of \"{0}\" with zero fields {1}", containingJTypeName, structCType);
}
- this.requiresStaticInitialization = false; // reset
-
// machDescJava global MachineDataInfo is the one used to determine
// the sizes of the primitive types seen in the public API in Java.
// For example, if a C long is an element of a struct, it is the size
@@ -854,16 +838,16 @@ public class JavaEmitter implements GlueEmitter {
for (int i = 0; i < structCType.getNumFields(); i++) {
final Field field = structCType.getField(i);
final Type fieldType = field.getType();
-
final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, 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(containingJTypeName, fieldName);
+ final TypeInfo opaqueField = cfg.canonicalNameOpaque(cfgFieldName1);
+ final boolean isOpaqueField = null != opaqueField;
- if ( fieldType.isFunctionPointer() || fieldType.isPointer() || requiresGetCStringLength(fieldType, cfgFieldName1) ) {
+ if ( fieldType.isFunctionPointer() && !isOpaqueField ) {
needsNativeCode = true;
break;
}
@@ -871,76 +855,84 @@ public class JavaEmitter implements GlueEmitter {
}
final String structClassPkgName = cfg.packageForStruct(structCTypeName);
- final PrintWriter javaWriter;
- final PrintWriter jniWriter;
+ final JavaCodeUnit javaUnit;
+ final CCodeUnit jniUnit;
try {
- javaWriter = openFile(cfg.javaOutputDir() + File.separator +
- CodeGenUtils.packageAsPath(structClassPkgName) +
- File.separator + containingJTypeName + ".java", containingJTypeName);
- if( null == javaWriter ) {
+ {
+ final String javaFileName = cfg.javaOutputDir() + File.separator +
+ CodeGenUtils.packageAsPath(structClassPkgName) +
+ File.separator + containingJTypeName + ".java";
+
+ javaUnit = openJavaUnit(javaFileName, structClassPkgName, containingJTypeName);
+ }
+
+ if( null == javaUnit ) {
// suppress output if openFile deliberately returns null.
return;
}
- CodeGenUtils.emitAutogeneratedWarning(javaWriter, this);
if (needsNativeCode) {
String nRoot = cfg.nativeOutputDir();
if (cfg.nativeOutputUsesJavaHierarchy()) {
nRoot += File.separator + CodeGenUtils.packageAsPath(cfg.packageName());
}
- jniWriter = openFile(nRoot + File.separator + containingJTypeName + "_JNI.c", containingJTypeName);
- CodeGenUtils.emitAutogeneratedWarning(jniWriter, this);
- emitCHeader(jniWriter, structClassPkgName, containingJTypeName);
+ final String cUnitName = containingJTypeName + "_JNI.c";
+ final String fname = nRoot + File.separator + cUnitName;
+ jniUnit = openCUnit(fname, cUnitName);
+ // jniUnit.emitHeader(structClassPkgName, containingJTypeName, Collections.emptyList());
+ jniUnit.emitHeader(structClassPkgName, containingJTypeName, cfg.customCCode());
} else {
- jniWriter = null;
+ jniUnit = null;
}
} catch(final Exception e) {
throw new RuntimeException("Unable to open files for emission of struct class", e);
}
- javaWriter.println();
- javaWriter.println("package " + structClassPkgName + ";");
- javaWriter.println();
- javaWriter.println("import java.nio.*;");
- javaWriter.println();
+ javaUnit.emitln();
+ javaUnit.emitln("package " + structClassPkgName + ";");
+ javaUnit.emitln();
+ javaUnit.emitln("import java.nio.*;");
+ javaUnit.emitln("import java.nio.charset.Charset;");
+ javaUnit.emitln("import java.nio.charset.StandardCharsets;");
+ javaUnit.emitln();
- javaWriter.println("import " + cfg.gluegenRuntimePackage() + ".*;");
- javaWriter.println("import " + DynamicLookupHelper.class.getPackage().getName() + ".*;");
- javaWriter.println("import " + Buffers.class.getPackage().getName() + ".*;");
- javaWriter.println("import " + MachineDataInfoRuntime.class.getName() + ";");
- javaWriter.println();
+ javaUnit.emitln("import " + cfg.gluegenRuntimePackage() + ".*;");
+ javaUnit.emitln("import " + DynamicLookupHelper.class.getPackage().getName() + ".*;");
+ javaUnit.emitln("import " + Buffers.class.getPackage().getName() + ".*;");
+ javaUnit.emitln("import " + MachineDataInfoRuntime.class.getName() + ";");
+ javaUnit.emitln();
final List<String> imports = cfg.imports();
for (final String str : imports) {
- javaWriter.print("import ");
- javaWriter.print(str);
- javaWriter.println(";");
+ javaUnit.emit("import ");
+ javaUnit.emit(str);
+ javaUnit.emitln(";");
}
- javaWriter.println();
+ javaUnit.emitln();
final List<String> javadoc = cfg.javadocForClass(containingJTypeName);
for (final String doc : javadoc) {
- javaWriter.println(doc);
+ javaUnit.emitln(doc);
}
- javaWriter.print("public class " + containingJTypeName + " ");
+ javaUnit.emit("public final class " + containingJTypeName + " ");
boolean firstIteration = true;
final List<String> userSpecifiedInterfaces = cfg.implementedInterfaces(containingJTypeName);
for (final String userInterface : userSpecifiedInterfaces) {
if (firstIteration) {
- javaWriter.print("implements ");
+ javaUnit.emit("implements ");
}
firstIteration = false;
- javaWriter.print(userInterface);
- javaWriter.print(" ");
+ javaUnit.emit(userInterface);
+ javaUnit.emit(" ");
}
- javaWriter.println("{");
- javaWriter.println();
- javaWriter.println(" StructAccessor accessor;");
- javaWriter.println();
+ javaUnit.emitln("{");
+ javaUnit.emitln();
+ javaUnit.emitln(" StructAccessor accessor;");
+ javaUnit.emitln();
final String cfgMachDescrIdxCode = cfg.returnStructMachineDataInfoIndex(containingJTypeName);
final String machDescrIdxCode = null != cfgMachDescrIdxCode ? cfgMachDescrIdxCode : "private static final int mdIdx = MachineDataInfoRuntime.getStatic().ordinal();";
- javaWriter.println(" "+machDescrIdxCode);
- javaWriter.println(" private final MachineDataInfo md;");
- javaWriter.println();
+ javaUnit.emitln(" "+machDescrIdxCode);
+ javaUnit.emitln(" private final MachineDataInfo md;");
+ javaUnit.emitln();
// generate all offset and size arrays
- generateOffsetAndSizeArrays(javaWriter, " ", containingJTypeName, structCType, null, null); /* w/o offset */
+ generateOffsetAndSizeArrays(javaUnit, " ", containingJTypeName, structCType, null, null); /* w/o offset */
if( GlueGen.debug() ) {
System.err.printf("SE.__: structCType %s%n", structCType.getDebugString());
System.err.printf("SE.__: contCTypeName %s%n", containingCType.getDebugString());
@@ -970,14 +962,15 @@ public class JavaEmitter implements GlueEmitter {
if( GlueGen.debug() ) {
System.err.printf("SE.os.%02d: %s / %s, %s (%s)%n", (i+1), field, cfgFieldName1, fieldType.getDebugString(), "compound");
}
- generateOffsetAndSizeArrays(javaWriter, " ", fieldName, fieldType, field, null);
+ generateOffsetAndSizeArrays(javaUnit, " ", fieldName, fieldType, field, null);
} else if (fieldType.isArray()) {
final Type baseElementType = field.getType().asArray().getBaseElementType();
if( GlueGen.debug() ) {
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);
+ generateOffsetAndSizeArrays(javaUnit, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaUnit, "//", fieldName, fieldType, null, null);
} else {
final JavaType externalJavaType;
try {
@@ -992,52 +985,74 @@ public class JavaEmitter implements GlueEmitter {
}
if (externalJavaType.isPrimitive()) {
// Primitive type
- generateOffsetAndSizeArrays(javaWriter, " ", fieldName, null, field, null); /* w/o size */
- generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, null, null);
+ generateOffsetAndSizeArrays(javaUnit, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaUnit, "//", fieldName, fieldType, null, null);
} else if (externalJavaType.isCPrimitivePointerType()) {
if( requiresGetCStringLength(fieldType, cfgFieldName1) ) {
- generateOffsetAndSizeArrays(javaWriter, " ", fieldName, null, field, null); /* w/o size */
- generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, null, "// "+externalJavaType.getDebugString());
+ generateOffsetAndSizeArrays(javaUnit, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaUnit, "//", fieldName, fieldType, null, "// "+externalJavaType.getDebugString());
} else {
- generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, field, "// "+externalJavaType.getDebugString());
+ generateOffsetAndSizeArrays(javaUnit, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaUnit, "//", fieldName, fieldType, field, "// "+externalJavaType.getDebugString());
}
} else {
- generateOffsetAndSizeArrays(javaWriter, " ", fieldName, null, field, null); /* w/o size */
- generateOffsetAndSizeArrays(javaWriter, "//", fieldName, fieldType, null, "// "+externalJavaType.getDebugString());
+ generateOffsetAndSizeArrays(javaUnit, " ", fieldName, null, field, null); /* w/o size */
+ generateOffsetAndSizeArrays(javaUnit, "//", fieldName, fieldType, null, "// "+externalJavaType.getDebugString());
}
}
} else if( GlueGen.debug() ) {
System.err.printf("SE.os.%02d: %s, %s (IGNORED)%n", (i+1), field, fieldType.getDebugString());
}
}
- javaWriter.println();
+ javaUnit.emitln();
+ javaUnit.emitln(" /** Returns true if this generated implementation uses native code, otherwise false. */");
+ javaUnit.emitln(" public static boolean usesNativeCode() {");
+ javaUnit.emitln(" return "+needsNativeCode+";");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
+
// getDelegatedImplementation
if( !cfg.manuallyImplement(JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, "size")) ) {
- javaWriter.println(" public static int size() {");
- javaWriter.println(" return "+containingJTypeName+"_size[mdIdx];");
- javaWriter.println(" }");
- javaWriter.println();
+ javaUnit.emitln(" /** Returns the aligned total size of a native instance. */");
+ javaUnit.emitln(" public static int size() {");
+ javaUnit.emitln(" return "+containingJTypeName+"_size[mdIdx];");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
}
if( !cfg.manuallyImplement(JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, "create")) ) {
- javaWriter.println(" public static " + containingJTypeName + " create() {");
- javaWriter.println(" return create(Buffers.newDirectByteBuffer(size()));");
- javaWriter.println(" }");
- javaWriter.println();
- javaWriter.println(" public static " + containingJTypeName + " create(java.nio.ByteBuffer buf) {");
- javaWriter.println(" return new " + containingJTypeName + "(buf);");
- javaWriter.println(" }");
- javaWriter.println();
- }
+ javaUnit.emitln(" /** Returns a new instance with all bytes set to zero. */");
+ javaUnit.emitln(" public static " + containingJTypeName + " create() {");
+ javaUnit.emitln(" return create(Buffers.newDirectByteBuffer(size()));");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
+ javaUnit.emitln(" /** Returns a new instance using the given ByteBuffer having at least {#link size()} bytes capacity. The ByteBuffer will be {@link ByteBuffer#rewind()} and native-order set. */");
+ javaUnit.emitln(" public static " + containingJTypeName + " create(java.nio.ByteBuffer buf) {");
+ javaUnit.emitln(" return new " + containingJTypeName + "(buf);");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
+ }
+ javaUnit.emitln(" /** Returns new instance dereferencing ByteBuffer at given native address `addr` with size {@link #size()}. */");
+ javaUnit.emitln(" public static " + containingJTypeName + " derefPointer(final long addr) {");
+ javaUnit.emitln(" return create( ElementBuffer.derefPointer(size(), 1, addr).getByteBuffer() );");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
if( !cfg.manuallyImplement(JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, containingJTypeName)) ) {
- javaWriter.println(" " + containingJTypeName + "(java.nio.ByteBuffer buf) {");
- javaWriter.println(" md = MachineDataInfo.StaticConfig.values()[mdIdx].md;");
- javaWriter.println(" accessor = new StructAccessor(buf);");
- javaWriter.println(" }");
- javaWriter.println();
- }
- javaWriter.println(" public java.nio.ByteBuffer getBuffer() {");
- javaWriter.println(" return accessor.getBuffer();");
- javaWriter.println(" }");
+ javaUnit.emitln(" " + containingJTypeName + "(java.nio.ByteBuffer buf) {");
+ javaUnit.emitln(" md = MachineDataInfo.StaticConfig.values()[mdIdx].md;");
+ javaUnit.emitln(" accessor = new StructAccessor(buf);");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
+ }
+ javaUnit.emitln(" /** Return the underlying native direct ByteBuffer */");
+ javaUnit.emitln(" public final java.nio.ByteBuffer getBuffer() {");
+ javaUnit.emitln(" return accessor.getBuffer();");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
+ javaUnit.emitln(" /** Returns the native address of the underlying native ByteBuffer {@link #getBuffer()} */");
+ javaUnit.emitln(" public final long getDirectBufferAddress() {");
+ javaUnit.emitln(" return accessor.getDirectBufferAddress();");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
final Set<MethodBinding> methodBindingSet = new HashSet<MethodBinding>();
@@ -1045,26 +1060,27 @@ public class JavaEmitter implements GlueEmitter {
final Field field = structCType.getField(i);
final Type fieldType = field.getType();
- final String cfgFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, field.getName());
- if (!cfg.shouldIgnoreInInterface(cfgFieldName0)) {
- final String renamed = cfg.getJavaSymbolRename(cfgFieldName0);
+ final String fqStructFieldName0 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, field.getName()); // containingJTypeName.field.getName()
+ if (!cfg.shouldIgnoreInInterface(fqStructFieldName0)) {
+ final String renamed = cfg.getJavaSymbolRename(fqStructFieldName0);
final String fieldName = renamed==null ? field.getName() : renamed;
- final String cfgFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, fieldName);
+ final String fqStructFieldName1 = JavaConfiguration.canonicalStructFieldSymbol(containingJTypeName, fieldName); // containingJTypeName.fieldName
final TypeInfo opaqueFieldType = cfg.typeInfo(fieldType);
final boolean isOpaqueFieldType = null != opaqueFieldType;
- final TypeInfo opaqueField = cfg.canonicalNameOpaque(cfgFieldName1);
+ final TypeInfo opaqueField = cfg.canonicalNameOpaque(fqStructFieldName1);
final boolean isOpaqueField = null != opaqueField;
+ final boolean immutableField = immutableStruct || cfg.immutableAccess(fqStructFieldName1);
if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: %s / %s (opaque %b), %s (opaque %b)%n", (i+1),
- (i+1), field, cfgFieldName1, isOpaqueField, fieldType.getDebugString(), isOpaqueFieldType);
+ System.err.printf("SE.ac.%02d: %s / %s (opaque %b), %s (opaque %b), immutable[struct %b, field %b]%n", (i+1),
+ (i+1), field, fqStructFieldName1, isOpaqueField, fieldType.getDebugString(), isOpaqueFieldType,
+ immutableStruct, immutableField);
}
if ( fieldType.isFunctionPointer() && !isOpaqueField ) {
final FunctionSymbol func = new FunctionSymbol(field.getName(), fieldType.asPointer().getTargetType().asFunction());
func.rename(renamed); // null is OK
- generateFunctionPointerCode(methodBindingSet, javaWriter, jniWriter, structCTypeName, structClassPkgName,
- containingCType, containingJType, i,
- func, cfgFieldName1);
+ generateFunctionPointerCode(methodBindingSet, javaUnit, jniUnit, structCTypeName,
+ containingCType, containingJType, i, func, fqStructFieldName1);
} else if ( fieldType.isCompound() && !isOpaqueField ) {
// FIXME: will need to support this at least in order to
// handle the union in jawt_Win32DrawingSurfaceInfo (fabricate a name?)
@@ -1073,17 +1089,15 @@ public class JavaEmitter implements GlueEmitter {
field + "\" in type \"" + structCTypeName + "\")",
fieldType.getASTLocusTag());
}
- javaWriter.println();
- generateGetterSignature(javaWriter, fieldType, false, false, fieldType.getName(), fieldName, capitalizeString(fieldName), null, null);
- javaWriter.println(" {");
- javaWriter.println(" return " + fieldType.getName() + ".create( accessor.slice( " +
+ generateGetterSignature(javaUnit, fieldType, false, false, fieldType.getName(), fieldName, capitalizeString(fieldName), null, false, null);
+ javaUnit.emitln(" {");
+ javaUnit.emitln(" return " + fieldType.getName() + ".create( accessor.slice( " +
fieldName+"_offset[mdIdx], "+fieldName+"_size[mdIdx] ) );");
- javaWriter.println(" }");
-
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
} else if ( ( fieldType.isArray() || fieldType.isPointer() ) && !isOpaqueField ) {
- generateArrayGetterSetterCode(methodBindingSet, javaWriter, jniWriter, structCType, structCTypeName,
- structClassPkgName, containingCType,
- containingJType, i, field, fieldName, cfgFieldName1);
+ generateArrayGetterSetterCode(javaUnit, structCType, containingJType,
+ i, field, fieldName, immutableField, fqStructFieldName1);
} else {
final JavaType javaType;
try {
@@ -1112,51 +1126,43 @@ public class JavaEmitter implements GlueEmitter {
"Java.StructEmitter.Primitive: "+field.getName()+", "+fieldType+", "+javaTypeName+", "+
", fixedSize "+fieldTypeNativeSizeFixed+", opaque[t "+isOpaqueFieldType+", f "+isOpaqueField+"], sizeDenominator "+sizeDenominator);
- if( !fieldType.isConst() ) {
+ if( !immutableField && !fieldType.isConst() ) {
// Setter
- javaWriter.println();
- generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, fieldName, capFieldName, null, javaTypeName, null, null);
- javaWriter.println(" {");
+ generateSetterSignature(javaUnit, fieldType, MethodAccess.PUBLIC, false, false, containingJTypeName, fieldName, capFieldName, null, javaTypeName, null, false, null);
+ javaUnit.emitln(" {");
if( fieldTypeNativeSizeFixed ) {
- javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val);");
+ javaUnit.emitln(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], src);");
} else {
- javaWriter.println(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], val, md."+sizeDenominator+"SizeInBytes());");
+ javaUnit.emitln(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], src, md."+sizeDenominator+"SizeInBytes());");
}
- javaWriter.println(" return this;");
- javaWriter.println(" }");
+ javaUnit.emitln(" return this;");
+ javaUnit.emitln(" }");
+ javaUnit.emitln();
}
// Getter
- javaWriter.println();
- generateGetterSignature(javaWriter, fieldType, false, false, javaTypeName, fieldName, capFieldName, null, null);
- javaWriter.println(" {");
- javaWriter.print (" return ");
+ generateGetterSignature(javaUnit, fieldType, false, false, javaTypeName, fieldName, capFieldName, null, false, null);
+ javaUnit.emitln(" {");
+ javaUnit.emit (" return ");
if( fieldTypeNativeSizeFixed ) {
- javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx]);");
+ javaUnit.emitln("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx]);");
} else {
- javaWriter.println("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], md."+sizeDenominator+"SizeInBytes());");
+ javaUnit.emitln("accessor.get" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], md."+sizeDenominator+"SizeInBytes());");
}
- javaWriter.println(" }");
+ javaUnit.emitln(" }");
} else {
- javaWriter.println();
- javaWriter.println(" /** UNKNOWN: "+cfgFieldName1 +": "+fieldType.getDebugString()+", "+javaType.getDebugString()+" */");
+ javaUnit.emitln(" /** UNKNOWN: "+fqStructFieldName1 +": "+fieldType.getDebugString()+", "+javaType.getDebugString()+" */");
}
+ javaUnit.emitln();
}
}
}
- emitCustomJavaCode(javaWriter, containingJTypeName);
- if (needsNativeCode) {
- javaWriter.println();
- emitJavaInitCode(javaWriter, containingJTypeName);
- javaWriter.println();
- }
- javaWriter.println("}");
- javaWriter.flush();
- javaWriter.close();
+ emitCustomJavaCode(javaUnit, containingJTypeName);
+ javaUnit.emitTailCode();
+ javaUnit.emitln("}");
+ javaUnit.close();
if (needsNativeCode) {
- emitCInitCode(jniWriter, structClassPkgName, containingJTypeName);
- jniWriter.flush();
- jniWriter.close();
+ jniUnit.close();
}
if( GlueGen.debug() ) {
System.err.printf("SE.XX: structCType %s%n", structCType.getDebugString());
@@ -1195,78 +1201,104 @@ public class JavaEmitter implements GlueEmitter {
// Internals only below this point
//
- private void generateGetterSignature(final PrintWriter writer, final Type origFieldType,
+ private void generateIsNullSignature(final CodeUnit unit, final Type origFieldType,
+ final boolean staticMethod, final boolean abstractMethod,
+ final String fieldName, final String capitalizedFieldName,
+ final boolean constElemCount, final String elemCountExpr) {
+ unit.emit(" /** Is 'null' for native field <code>"+fieldName+"</code>: "+origFieldType.getDebugString());
+ if( null != elemCountExpr ) {
+ unit.emit(", with "+(constElemCount?"fixed":"initial")+" array length of <code>"+elemCountExpr+"</code>");
+ }
+ unit.emitln(" */");
+ unit.emit(" public final " + (staticMethod ? "static " : "") + (abstractMethod ? "abstract " : "") + "boolean is" + capitalizedFieldName + "Null()");
+ }
+ private void generateReleaseSignature(final CodeUnit unit, final Type origFieldType,
+ final boolean abstractMethod,
+ final String returnTypeName, final String fieldName, final String capitalizedFieldName,
+ final boolean constElemCount, final String elemCountExpr) {
+ unit.emit(" /** Release for native field <code>"+fieldName+"</code>: "+origFieldType.getDebugString());
+ if( null != elemCountExpr ) {
+ unit.emit(", with "+(constElemCount?"fixed":"initial")+" array length of <code>"+elemCountExpr+"</code>");
+ }
+ unit.emitln(" */");
+ unit.emit(" public final " + (abstractMethod ? "abstract " : "") + returnTypeName + " release" + capitalizedFieldName + "()");
+ }
+ private void generateGetterSignature(final CodeUnit unit, final Type origFieldType,
final boolean staticMethod, final boolean abstractMethod,
- final String returnTypeName, final String fieldName,
- final String capitalizedFieldName, final String customArgs, final String arrayLengthExpr) {
- writer.print(" /** Getter for native field <code>"+fieldName+"</code>: "+origFieldType.getDebugString());
- if( null != arrayLengthExpr ) {
- writer.print(", with array length of <code>"+arrayLengthExpr+"</code>");
+ final String returnTypeName, final String fieldName, final String capitalizedFieldName,
+ final String customArgs, final boolean constElemCount, final String elemCountExpr) {
+ unit.emit(" /** Getter for native field <code>"+fieldName+"</code>: "+origFieldType.getDebugString());
+ if( null != elemCountExpr ) {
+ unit.emit(", with "+(constElemCount?"fixed":"initial")+" array length of <code>"+elemCountExpr+"</code>");
}
- writer.println(" */");
- writer.print(" public " + (staticMethod ? "static " : "") + (abstractMethod ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "(");
+ unit.emitln(" */");
+ unit.emit(" public final " + (staticMethod ? "static " : "") + (abstractMethod ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "(");
if( null != customArgs ) {
- writer.print(customArgs);
+ unit.emit(customArgs);
}
- writer.print(")");
+ unit.emit(")");
}
- private void generateSetterSignature(final PrintWriter writer, final Type origFieldType, final boolean abstractMethod,
- final String returnTypeName, final String fieldName,
- final String capitalizedFieldName, final String customArgsPre, final String paramTypeName,
- final String customArgsPost, final String arrayLengthExpr) {
- writer.print(" /** Setter for native field <code>"+fieldName+"</code>: "+origFieldType.getDebugString());
- if( null != arrayLengthExpr ) {
- writer.print(", with array length of <code>"+arrayLengthExpr+"</code>");
+ private void generateSetterAPIDoc(final CodeUnit unit, final String action,
+ final Type origFieldType, final String fieldName,
+ final boolean constElemCount, final String elemCountExpr) {
+ unit.emit(" /** "+action+" native field <code>"+fieldName+"</code>: "+origFieldType.getDebugString());
+ if( null != elemCountExpr ) {
+ unit.emit(", with "+(constElemCount?"fixed native-ownership":"initial")+" array length of <code>"+elemCountExpr+"</code>");
}
- writer.println(" */");
- writer.print(" public " + (abstractMethod ? "abstract " : "") + returnTypeName + " set" + capitalizedFieldName + "(");
+ unit.emitln(" */");
+ }
+ private void generateSetterSignature(final CodeUnit unit, final Type origFieldType, final MethodAccess accessMod,
+ final boolean staticMethod, final boolean abstractMethod,
+ final String returnTypeName, final String fieldName, final String capitalizedFieldName,
+ final String customArgsPre, final String paramTypeName, final String customArgsPost, final boolean constElemCount, final String elemCountExpr) {
+ generateSetterAPIDoc(unit, "Setter for", origFieldType, fieldName, constElemCount, elemCountExpr);
+ unit.emit(" "+accessMod.getJavaName()+" final " + (staticMethod ? "static " : "") + (abstractMethod ? "abstract " : "") + returnTypeName + " set" + capitalizedFieldName + "(");
if( null != customArgsPre ) {
- writer.print(customArgsPre+", ");
+ unit.emit(customArgsPre+", ");
}
- writer.print(paramTypeName + " val");
+ unit.emit(paramTypeName + " src");
if( null != customArgsPost ) {
- writer.print(", "+customArgsPost);
+ unit.emit(", "+customArgsPost);
}
- writer.print(")");
+ unit.emit(")");
}
- private void generateOffsetAndSizeArrays(final PrintWriter writer, final String prefix,
+ private void generateOffsetAndSizeArrays(final CodeUnit unit, final String prefix,
final String fieldName, final Type fieldType,
final Field field, final String postfix) {
if(null != field) {
- writer.print(prefix+"private static final int[] "+fieldName+"_offset = new int[] { ");
+ unit.emit(prefix+"private static final int[] "+fieldName+"_offset = new int[] { ");
for( int i=0; i < machDescTargetConfigs.length; i++ ) {
if(0<i) {
- writer.print(", ");
+ unit.emit(", ");
}
- writer.print(field.getOffset(machDescTargetConfigs[i].md) +
+ unit.emit(field.getOffset(machDescTargetConfigs[i].md) +
" /* " + machDescTargetConfigs[i].name() + " */");
}
- writer.println(" };");
+ unit.emitln(" };");
}
if(null!=fieldType) {
- writer.print(prefix+"private static final int[] "+fieldName+"_size = new int[] { ");
+ unit.emit(prefix+"private static final int[] "+fieldName+"_size = new int[] { ");
for( int i=0; i < machDescTargetConfigs.length; i++ ) {
if(0<i) {
- writer.print(", ");
+ unit.emit(", ");
}
- writer.print(fieldType.getSize(machDescTargetConfigs[i].md) +
+ unit.emit(fieldType.getSize(machDescTargetConfigs[i].md) +
" /* " + machDescTargetConfigs[i].name() + " */");
}
- writer.print(" };");
+ unit.emit(" };");
if( null != postfix ) {
- writer.println(postfix);
+ unit.emitln(postfix);
} else {
- writer.println();
+ unit.emitln();
}
}
}
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 JavaCodeUnit javaUnit, final CCodeUnit jniUnit,
+ final String structCTypeName, 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, true /* forInterface */, machDescJava, containingJType, containingCType);
@@ -1284,11 +1316,10 @@ public class JavaEmitter implements GlueEmitter {
// skip .. already exisiting binding ..
continue;
}
- javaWriter.println();
// Emit public Java entry point for calling this function pointer
JavaMethodBindingEmitter emitter =
new JavaMethodBindingEmitter(binding,
- javaWriter,
+ javaUnit,
cfg.runtimeExceptionType(),
cfg.unsupportedExceptionType(),
true, // emitBody
@@ -1305,11 +1336,12 @@ public class JavaEmitter implements GlueEmitter {
cfg);
emitter.addModifier(JavaMethodBindingEmitter.PUBLIC);
emitter.emit();
+ javaUnit.emitln();
// Emit private native Java entry point for calling this function pointer
emitter =
new JavaMethodBindingEmitter(binding,
- javaWriter,
+ javaUnit,
cfg.runtimeExceptionType(),
cfg.unsupportedExceptionType(),
false, // emitBody
@@ -1326,12 +1358,13 @@ public class JavaEmitter implements GlueEmitter {
emitter.addModifier(JavaMethodBindingEmitter.PRIVATE);
emitter.addModifier(JavaMethodBindingEmitter.NATIVE);
emitter.emit();
+ javaUnit.emitln();
// Emit (private) C entry point for calling this function pointer
final CMethodBindingEmitter cEmitter =
new CMethodBindingEmitter(binding,
- jniWriter,
- structClassPkgName,
+ jniUnit,
+ javaUnit.pkgName,
containingJType.getName(),
true, // FIXME: this is optional at this point
false,
@@ -1341,91 +1374,7 @@ public class JavaEmitter implements GlueEmitter {
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, true /* forInterface */, machDescJava, containingJType, containingCType);
- 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, // emitBody
- cfg.tagNativeBinding(), // tagNativeBinding
- true, // eraseBufferAndArrayTypes
- useNIOOnly,
- useNIODirectOnly,
- false, // forDirectBufferImplementation
- false, // forIndirectBufferAndArrayImplementation
- false, // isUnimplemented
- true, // isInterface
- true, // isNativeMethod
- true, // isPrivateNativeMethod
- 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
- final CMethodBindingEmitter cEmitter =
- new CMethodBindingEmitter(binding,
- jniWriter,
- structClassPkgName,
- containingJType.getName(),
- true, // FIXME: this is optional at this point
- false,
- true,
- false, // forIndirectBufferAndArrayImplementation
- machDescJava, getConfiguration());
- cEmitter.setIsCStructFunctionPointer(false);
- final String lenExprSet;
- if( null != nativeArrayLenExpr ) {
- final 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();
+ jniUnit.emitln();
}
}
@@ -1466,39 +1415,29 @@ public class JavaEmitter implements GlueEmitter {
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) ) {
+ if( !cfg.returnsString(returnSizeLookupName) && !cfg.returnsStringOnly(returnSizeLookupName) ) {
return false;
}
final PointerType pointerType = fieldType.asPointer();
if( null != pointerType ) {
- return null == getPointerArrayLengthExpr(pointerType, returnSizeLookupName);
+ return null == cfg.returnedArrayLength(returnSizeLookupName);
}
return false;
}
- private void generateArrayGetterSetterCode(final Set<MethodBinding> methodBindingSet,
- final PrintWriter javaWriter, final PrintWriter jniWriter,
+ private static final String SetArrayArgs = "final int srcPos, final int destPos, final int length";
+ private static final String SetArrayArgsCheck = " if( 0 > srcPos || 0 > destPos || 0 > length || srcPos + length > src.length ) { throw new IndexOutOfBoundsException(\"src[pos \"+srcPos+\", length \"+src.length+\"], destPos \"+destPos+\", length \"+length); }";
+ private static final String GetArrayArgs = "final int destPos, final int length";
+ private static final String GetArrayArgsCheck = " if( 0 > srcPos || 0 > destPos || 0 > length || destPos + length > dest.length ) { throw new IndexOutOfBoundsException(\"dest[pos \"+destPos+\", length \"+dest.length+\"], srcPos \"+srcPos+\", length \"+length); }";
+
+
+ private void generateArrayGetterSetterCode(final JavaCodeUnit unit,
final CompoundType structCType,
- final String structCTypeName, final String structClassPkgName,
- final Type containingCType, final JavaType containingJType,
+ final JavaType containingJType,
final int i, final Field field, final String fieldName,
+ final boolean immutableAccess,
final String returnSizeLookupName) throws Exception {
final Type fieldType = field.getType();
final JavaType javaType;
@@ -1517,423 +1456,699 @@ public class JavaEmitter implements GlueEmitter {
//
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 boolean arrayLengthExprIsConst;
- final int[] arrayLengths;
- final boolean useFixedTypeLen[] = { false };
+ final boolean isStringOnly = cfg.returnsStringOnly(returnSizeLookupName); // exclude alternative ByteBuffer representation to String
+ final boolean isString = isStringOnly || cfg.returnsString(returnSizeLookupName);
+ if( isString ) {
+ unit.addTailCode(optStringCharsetCode);
+ }
final boolean isPointer;
final boolean isPrimitive;
- final boolean isConst;
+ final boolean isConstValue; // Immutable 'const type value', immutable array 'const type value[]', or as mutable pointer 'const type * value'
+ final MethodAccess accessMod = MethodAccess.PUBLIC;
+ final String elemCountExpr;
+ final boolean constElemCount; // if true, implies native ownership of pointer referenced memory!
+ final boolean staticElemCount;
final JavaType baseJElemType;
final String baseJElemTypeName;
- final boolean hasSingleElement;
- final String capitalFieldName;
- final String baseJElemTypeNameC;
- final String baseJElemTypeNameU;
- final boolean isByteBuffer;
- final boolean baseCElemNativeSizeFixed;
+ final boolean primCElemFixedSize; // Is Primitive element size fixed? If not, use md.*_Size[]
final String baseCElemSizeDenominator;
- {
- final Type baseCElemType;
+ final boolean useGetCStringLength;
+ final boolean maxOneElement; // zero or one element
+ if( isOpaque || javaType.isPrimitive() ) {
+ // Overridden by JavaConfiguration.typeInfo(..), i.e. Opaque!
+ // Emulating array w/ 1 element
+ isPrimitive = true;
+ isPointer = false;
+ isConstValue = fieldType.isConst();
+ elemCountExpr = "1";
+ constElemCount = true;
+ staticElemCount = true;
+ baseJElemType = null;
+ baseJElemTypeName = compatiblePrimitiveJavaTypeName(fieldType, javaType, machDescJava);
+ primCElemFixedSize = false;
+ baseCElemSizeDenominator = fieldType.isPointer() ? "pointer" : baseJElemTypeName ;
+ useGetCStringLength = false;
+ maxOneElement = true;
+ } else {
final ArrayType arrayType = fieldType.asArray();
- String _arrayLengthExpr = null;
- boolean _arrayLengthExprIsConst = false;
- if( isOpaque || javaType.isPrimitive() ) {
- // Overridden by JavaConfiguration.typeInfo(..), i.e. Opaque!
- // Emulating array w/ 1 element
- isPrimitive = true;
- _arrayLengthExpr = nativeArrayLengthONE;
- _arrayLengthExprIsConst = true;
- arrayLengths = new int[] { 1 };
- baseCElemType = null;
+ final Type baseCElemType;
+ if( null != arrayType ) {
+ final int[][] arrayLengthRes = new int[1][];
+ final boolean[] _useFixedArrayLen = { false };
+ elemCountExpr = getArrayArrayLengthExpr(arrayType, returnSizeLookupName, _useFixedArrayLen, arrayLengthRes);
+ // final int arrayLength = arrayLengthRes[0][0];
+ constElemCount = _useFixedArrayLen[0];
+ staticElemCount = constElemCount;
+ baseCElemType = arrayType.getBaseElementType();
isPointer = false;
- isConst = fieldType.isConst();
- baseJElemType = null;
- baseJElemTypeName = compatiblePrimitiveJavaTypeName(fieldType, javaType, machDescJava);
- baseCElemNativeSizeFixed = false;
- baseCElemSizeDenominator = fieldType.isPointer() ? "pointer" : baseJElemTypeName ;
+ useGetCStringLength = false;
} else {
- if( null != arrayType ) {
- final int[][] lengthRes = new int[1][];
- _arrayLengthExpr = getArrayArrayLengthExpr(arrayType, returnSizeLookupName, useFixedTypeLen, lengthRes);
- _arrayLengthExprIsConst = true;
- arrayLengths = lengthRes[0];
- baseCElemType = arrayType.getBaseElementType();
- isPointer = false;
+ final PointerType pointerType = fieldType.asPointer();
+ final String _elemCountExpr = cfg.returnedArrayLength(returnSizeLookupName);
+ baseCElemType = pointerType.getBaseElementType();
+ isPointer = true;
+ if( 1 != pointerType.pointerDepth() ) {
+ final String msg = "SKIP ptr-ptr (depth "+pointerType.pointerDepth()+"): "+returnSizeLookupName +": "+fieldType;
+ unit.emitln(" // "+msg);
+ unit.emitln();
+ LOG.log(WARNING, structCType.getASTLocusTag(), msg);
+ return;
+ }
+ if( null == _elemCountExpr && isString ) {
+ useGetCStringLength = true;
+ unit.addTailCode(optStringMaxStrnlenCode);
+ elemCountExpr = "Buffers.strnlen(pString, _max_strnlen)+1";
+ constElemCount = false;
+ staticElemCount = constElemCount;
+ } else if( null == _elemCountExpr ) {
+ useGetCStringLength = false;
+ elemCountExpr = "0";
+ constElemCount = false;
+ staticElemCount = constElemCount;
} else {
- final PointerType pointerType = fieldType.asPointer();
- _arrayLengthExpr = getPointerArrayLengthExpr(pointerType, returnSizeLookupName);
- _arrayLengthExprIsConst = false;
- 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);
- LOG.log(WARNING, structCType.getASTLocusTag(), msg);
- return;
+ useGetCStringLength = false;
+ elemCountExpr = _elemCountExpr;
+ boolean _constElemCount = false;
+ boolean _staticElemCount = false;
+
+ if( null != elemCountExpr ) {
+ // try constant intenger 1st
+ try {
+ Integer.parseInt(elemCountExpr);
+ _constElemCount = true;
+ _staticElemCount = true;
+ } catch (final Exception e ) {}
+ if( !_constElemCount ) {
+ // check for const length field
+ if( elemCountExpr.startsWith("get") && elemCountExpr.endsWith("()") ) {
+ final String lenFieldName = decapitalizeString( elemCountExpr.substring(3, elemCountExpr.length()-2) );
+ final Field lenField = structCType.getField(lenFieldName);
+ if( null != lenField ) {
+ _constElemCount = lenField.getType().isConst();
+ }
+ LOG.log(INFO, structCType.getASTLocusTag(),
+ unit.className+": elemCountExpr "+elemCountExpr+", lenFieldName "+lenFieldName+" -> "+lenField.toString()+", isConst "+_constElemCount);
+ }
+ }
}
+ constElemCount = _constElemCount;
+ staticElemCount = _staticElemCount;
}
- if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: baseCType %s%n", (i+1), baseCElemType.getDebugString());
- }
- isPrimitive = baseCElemType.isPrimitive();
- isConst = baseCElemType.isConst();
+ }
+ if( null == elemCountExpr ) {
+ final String msg = "SKIP unsized array in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
+ unit.emitln(" // "+msg);
+ unit.emitln();
+ LOG.log(WARNING, structCType.getASTLocusTag(), msg);
+ return;
+ }
+ boolean _maxOneElement = cfg.maxOneElement(returnSizeLookupName);
+ if( !_maxOneElement ) {
try {
- baseJElemType = typeToJavaType(baseCElemType, machDescJava);
- } catch (final Exception e ) {
- throw new GlueGenException("Error occurred while creating array/pointer accessor for field \"" +
- returnSizeLookupName + "\", baseType "+baseCElemType.getDebugString()+", topType "+fieldType.getDebugString(),
- fieldType.getASTLocusTag(), e);
- }
- baseJElemTypeName = baseJElemType.getName();
- baseCElemNativeSizeFixed = baseCElemType.isPrimitive() ? baseCElemType.getSize().hasFixedNativeSize() : true;
- baseCElemSizeDenominator = baseCElemType.isPointer() ? "pointer" : baseJElemTypeName ;
-
- if( !baseCElemNativeSizeFixed ) {
- javaWriter.println();
- final String msg = "SKIP primitive w/ platform dependent sized type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
- javaWriter.println(" // "+msg);
- LOG.log(WARNING, structCType.getASTLocusTag(), msg);
- return;
- }
+ _maxOneElement = 1 == Integer.parseInt(elemCountExpr);
+ } catch (final Exception e ) {}
}
+ maxOneElement = _maxOneElement;
if( GlueGen.debug() ) {
- System.err.printf("SE.ac.%02d: baseJElemType %s%n", (i+1), (null != baseJElemType ? baseJElemType.getDebugString() : null));
+ System.err.printf("SE.ac.%02d: baseCType %s%n", (i+1), baseCElemType.getDebugString());
}
- capitalFieldName = capitalizeString(fieldName);
- baseJElemTypeNameC = capitalizeString(baseJElemTypeName);
- baseJElemTypeNameU = baseJElemTypeName.toUpperCase();
- isByteBuffer = "Byte".equals(baseJElemTypeNameC);
- if( null == _arrayLengthExpr && isString && isPointer ) {
- useGetCStringLength = true;
- _arrayLengthExpr = "getCStringLengthImpl(pString)+1";
- _arrayLengthExprIsConst = false;
- this.requiresStaticInitialization = true;
- LOG.log(INFO, structCType.getASTLocusTag(), "StaticInit Trigger.3 \"{0}\"", returnSizeLookupName);
- } else {
- useGetCStringLength = false;
+
+ isPrimitive = baseCElemType.isPrimitive();
+ isConstValue = baseCElemType.isConst();
+ try {
+ baseJElemType = typeToJavaType(baseCElemType, machDescJava);
+ } catch (final Exception e ) {
+ throw new GlueGenException("Error occurred while creating array/pointer accessor for field \"" +
+ returnSizeLookupName + "\", baseType "+baseCElemType.getDebugString()+", topType "+fieldType.getDebugString(),
+ fieldType.getASTLocusTag(), e);
}
- arrayLengthExpr = _arrayLengthExpr;
- arrayLengthExprIsConst = _arrayLengthExprIsConst;
- if( null == arrayLengthExpr ) {
- javaWriter.println();
- final String msg = "SKIP unsized array in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
- javaWriter.println(" // "+msg);
+ baseJElemTypeName = baseJElemType.getName();
+ primCElemFixedSize = isPrimitive ? baseCElemType.getSize().hasFixedNativeSize() : true;
+ baseCElemSizeDenominator = baseCElemType.isPointer() ? "pointer" : baseJElemTypeName ;
+
+ if( !primCElemFixedSize ) {
+ final String msg = "SKIP primitive w/ platform dependent sized type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
+ unit.emitln(" // "+msg);
+ unit.emitln();
LOG.log(WARNING, structCType.getASTLocusTag(), msg);
return;
}
- boolean _hasSingleElement=false;
- try {
- _hasSingleElement = 1 ==Integer.parseInt(_arrayLengthExpr);
- } catch (final 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 (const %b), hasSingleElement %b, isByteBuffer %b, isString %b, isPointer %b, isPrimitive %b, isOpaque %b, baseCElemNativeSizeFixed %b, baseCElemSizeDenominator %s, isConst %b, useGetCStringLength %b%n",
- (i+1), arrayLengthExpr, arrayLengthExprIsConst, hasSingleElement, isByteBuffer, isString, isPointer, isPrimitive, isOpaque,
- baseCElemNativeSizeFixed, baseCElemSizeDenominator,
- isConst, useGetCStringLength);
+ System.err.printf("SE.ac.%02d: baseJElemType %s%n", (i+1), (null != baseJElemType ? baseJElemType.getDebugString() : null));
+ }
+ // Collect fixed primitive-type mapping metrics
+ final Class<? extends Buffer> primJElemTypeBufferClazz;
+ final String primJElemTypeBufferName;
+ final int primElemSize;
+ final String primElemSizeExpr;
+ final boolean isByteBuffer;
+ if( isPrimitive ) {
+ primJElemTypeBufferClazz = Buffers.typeNameToBufferClass(baseJElemTypeName);
+ if( null == primJElemTypeBufferClazz ) {
+ final String msg = "Failed to map '"+baseJElemTypeName+"' to Buffer class, field "+field+", j-type "+baseJElemType;
+ unit.emitln(" // ERROR: "+msg);
+ unit.emitln();
+ LOG.log(SEVERE, structCType.getASTLocusTag(), msg);
+ throw new InternalError(msg);
+ }
+ primJElemTypeBufferName = primJElemTypeBufferClazz.getSimpleName();
+ primElemSize = Buffers.sizeOfBufferElem(primJElemTypeBufferClazz);
+ isByteBuffer = null != primJElemTypeBufferClazz ? ByteBuffer.class.isAssignableFrom(primJElemTypeBufferClazz) : false;
+ } else {
+ primJElemTypeBufferClazz = null;
+ primJElemTypeBufferName = null;
+ primElemSize = 0;
+ isByteBuffer = false;
+ }
+ if( primCElemFixedSize ) {
+ primElemSizeExpr = String.valueOf(primElemSize);
+ } else {
+ primElemSizeExpr = "md."+baseCElemSizeDenominator+"SizeInBytes()";
+ }
+
+ final String capitalFieldName = capitalizeString(fieldName);
+ final boolean ownElemCountHandling;
+ final String getElemCountFuncExpr, setElemCountLengthFunc;
+ if( constElemCount ) {
+ ownElemCountHandling = true;
+ getElemCountFuncExpr = "get"+capitalFieldName+"ElemCount()";
+ setElemCountLengthFunc = null;
+ } else {
+ if( useGetCStringLength ) {
+ ownElemCountHandling = true;
+ getElemCountFuncExpr = "get"+capitalFieldName+"ElemCount()";
+ setElemCountLengthFunc = null;
+ } else if( elemCountExpr.startsWith("get") && elemCountExpr.endsWith("()") ) {
+ ownElemCountHandling = false;
+ getElemCountFuncExpr = elemCountExpr;
+ setElemCountLengthFunc = "set" + elemCountExpr.substring(3, elemCountExpr.length()-2);
+ } else {
+ ownElemCountHandling = true;
+ getElemCountFuncExpr = "get"+capitalFieldName+"ElemCount()";
+ setElemCountLengthFunc = "set"+capitalFieldName+"ElemCount";
+ }
+ }
+ if( GlueGen.debug() ) {
+ System.err.printf("SE.ac.%02d: baseJElemTypeName %s%n", (i+1), baseJElemTypeName);
+ System.err.printf("SE.ac.%02d: elemCountExpr: %s (const %b), ownArrayLen %b, maxOneElement %b, "+
+ "Primitive[buffer %s, fixedSize %b, elemSize %d, sizeDenom %s, sizeExpr %s, isByteBuffer %b], "+
+ "isString[%b, only %b, strnlen %b], isPointer %b, isPrimitive %b, isOpaque %b, constVal %b, immutableAccess %b%n",
+ (i+1), elemCountExpr, constElemCount, ownElemCountHandling, maxOneElement,
+ primJElemTypeBufferName, primCElemFixedSize, primElemSize, baseCElemSizeDenominator, primElemSizeExpr, isByteBuffer,
+ isString, isStringOnly, useGetCStringLength,
+ isPointer, isPrimitive, isOpaque, isConstValue, immutableAccess);
}
//
// Emit ..
//
- if( !hasSingleElement && useFixedTypeLen[0] ) {
- javaWriter.println();
- generateGetterSignature(javaWriter, fieldType, arrayLengthExprIsConst, false, "final int", fieldName, capitalFieldName+"ArrayLength", null, arrayLengthExpr);
- javaWriter.println(" {");
- javaWriter.println(" return "+arrayLengthExpr+";");
- javaWriter.println(" }");
+ if( ownElemCountHandling ) {
+ if( constElemCount ) {
+ generateGetterSignature(unit, fieldType, staticElemCount, false, "int", fieldName, capitalFieldName+"ElemCount", null, constElemCount, elemCountExpr);
+ unit.emitln(" { return "+elemCountExpr+"; }");
+ } else if( useGetCStringLength ) {
+ generateGetterSignature(unit, fieldType, staticElemCount, false, "int", fieldName, capitalFieldName+"ElemCount", null, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(" final long pString = PointerBuffer.wrap( accessor.slice(" + fieldName+"_offset[mdIdx], PointerBuffer.POINTER_SIZE) ).get(0);");
+ unit.emitln(" return 0 != pString ? "+elemCountExpr+" : 0;");
+ unit.emitln(" }");
+ } else {
+ unit.emitln(" private int _"+fieldName+"ArrayLen = "+elemCountExpr+"; // "+(constElemCount ? "const" : "initial")+" array length");
+ generateGetterSignature(unit, fieldType, staticElemCount, false, "int", fieldName, capitalFieldName+"ElemCount", null, constElemCount, elemCountExpr);
+ unit.emitln(" { return _"+fieldName+"ArrayLen; }");
+ if( !immutableAccess ) {
+ generateSetterSignature(unit, fieldType, MethodAccess.PRIVATE, staticElemCount, false, "void", fieldName, capitalFieldName+"ElemCount", null, "int", null, constElemCount, elemCountExpr);
+ unit.emitln(" { _"+fieldName+"ArrayLen = src; }");
+ }
+ }
+ unit.emitln();
+ }
+
+ // Null query for pointer
+ if( isPointer ) {
+ generateIsNullSignature(unit, fieldType, false, false, fieldName, capitalFieldName, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(" return 0 == PointerBuffer.wrap(getBuffer(), "+fieldName+"_offset[mdIdx], 1).get(0);");
+ unit.emitln(" }");
+ unit.emitln();
+ if( !constElemCount && !immutableAccess ) {
+ generateReleaseSignature(unit, fieldType, false, containingJTypeName, fieldName, capitalFieldName, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(" accessor.setLongAt("+fieldName+"_offset[mdIdx], 0, md.pointerSizeInBytes()); // write nullptr");
+ unit.emitln(" _eb"+capitalFieldName+" = null;");
+ emitSetElemCount(unit, setElemCountLengthFunc, "0", !useGetCStringLength, capitalFieldName, structCType, " ");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ unit.emitln();
+ }
}
- if( !isConst ) {
- // Setter
- javaWriter.println();
- if( isPrimitive ) {
- // Setter Primitive
+
+ // Setter
+ if( immutableAccess ) {
+ generateSetterAPIDoc(unit, "SKIP setter for immutable", fieldType, fieldName, constElemCount, elemCountExpr);
+ unit.emitln();
+ } else if( isPointer && isConstValue && constElemCount ) {
+ generateSetterAPIDoc(unit, "SKIP setter for constValue constElemCount Pointer w/ native ownership", fieldType, fieldName, constElemCount, elemCountExpr);
+ unit.emitln();
+ } else if( !isPointer && isConstValue ) {
+ generateSetterAPIDoc(unit, "SKIP setter for constValue Array", fieldType, fieldName, constElemCount, elemCountExpr);
+ unit.emitln();
+ } else if( isPrimitive ) {
+ // Setter Primitive
+ if( maxOneElement ) {
+ // Setter Primitive Single Pointer + Array
if( isPointer ) {
- // Setter Primitive Pointer
- final String msg = "SKIP setter for primitive-pointer type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
- javaWriter.println(" // "+msg);
- LOG.log(INFO, structCType.getASTLocusTag(), msg);
- } else {
- // Setter Primitive Array
- if( hasSingleElement ) {
- generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, arrayLengthExpr);
- javaWriter.println(" {");
- if( baseCElemNativeSizeFixed ) {
- javaWriter.println(" accessor.set" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], val);");
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, constElemCount, elemCountExpr);
+ if( isConstValue ) {
+ // constElemCount excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership
+ unit.emitln(" {");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", 1);");
+ unit.emit (" eb.getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".put(0, src);");
+ unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" _eb"+capitalFieldName+" = eb;");
+ emitSetElemCount(unit, setElemCountLengthFunc, "1", !useGetCStringLength, capitalFieldName, structCType, " ");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ unit.emitln(" @SuppressWarnings(\"unused\")");
+ unit.emitln(" private ElementBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
+ } else {
+ unit.emitln(" {");
+ unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
+ unit.emitln(" if( 1 == elemCount ) {");
+ unit.emitln(" ElementBuffer.derefPointer("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
+ unit.emit (" .getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".put(0, src);");
+ unit.emitln(" } else {");
+ if( constElemCount ) {
+ unit.emitln(" throw new RuntimeException(\"Primitive '"+fieldName+"' of constElemCount and maxOneElement has elemCount \"+elemCount);");
+ unit.emitln(" }");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
} else {
- javaWriter.println(" accessor.set" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], val, md."+baseCElemSizeDenominator+"SizeInBytes());");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", 1);");
+ unit.emit (" eb.getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".put(0, src);");
+ unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" _eb"+capitalFieldName+" = eb;");
+ emitSetElemCount(unit, setElemCountLengthFunc, "1", !useGetCStringLength, capitalFieldName, structCType, " ");
+ unit.emitln(" }");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ unit.emitln(" @SuppressWarnings(\"unused\")");
+ unit.emitln(" private ElementBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
}
- javaWriter.println(" return this;");
- javaWriter.println(" }");
+ }
+ } else { // array && !isConstValue
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(" ElementBuffer.wrap("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
+ unit.emit (" .getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".put(0, src);");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ } // else SKIP setter for constValue Array
+ unit.emitln();
+ } else {
+ // Setter Primitive n Pointer + Array
+ boolean addedElementBufferCache = false;
+ boolean doneString = false;
+
+ if( isString && isByteBuffer && isPointer ) { // isConst is OK
+ // isConst && constElemCount excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, "String", null, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(" final byte[] srcBytes = src.getBytes(_charset);");
+ if( constElemCount ) {
+ unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
+ unit.emitln(" if( srcBytes.length + 1 != elemCount ) { throw new IllegalArgumentException(\"strlen+1 \"+(srcBytes.length+1)+\" != const elemCount \"+elemCount); };");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
} else {
- generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, fieldName, 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(" }");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", srcBytes.length + 1);");
+ }
+ unit.emitln(" eb.getByteBuffer().put(srcBytes, 0, srcBytes.length).put((byte)0).rewind(); // w/ EOS");
+ if( !constElemCount ) {
+ unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" _eb"+capitalFieldName+" = eb;");
+ emitSetElemCount(unit, setElemCountLengthFunc, "srcBytes.length + 1", !useGetCStringLength, capitalFieldName, structCType, " ");
}
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ if( !constElemCount ) {
+ unit.emitln(" @SuppressWarnings(\"unused\")");
+ unit.emitln(" private ElementBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
+ addedElementBufferCache = true;
+ doneString = true;
+ }
+ unit.emitln();
}
- } else {
- // Setter Struct
+ if( doneString && isStringOnly ) {
+ generateSetterAPIDoc(unit, "SKIP setter for String alternative (ByteBuffer)", fieldType, fieldName, constElemCount, elemCountExpr);
+ } else if( isConstValue ) {
+ if( isPointer ) {
+ // constElemCount excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", SetArrayArgs, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(SetArrayArgsCheck);
+ unit.emitln(" final int newElemCount = destPos + length;");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", newElemCount);");
+ unit.emit (" ( ( "+primJElemTypeBufferName+")(eb.getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".position(destPos) ) ).put(src, srcPos, length).rewind();");
+ unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" _eb"+capitalFieldName+" = eb;");
+ emitSetElemCount(unit, setElemCountLengthFunc, "newElemCount", !useGetCStringLength, capitalFieldName, structCType, " ");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ if( !addedElementBufferCache ) {
+ unit.emitln(" @SuppressWarnings(\"unused\")");
+ unit.emitln(" private ElementBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
+ }
+ } // else SKIP setter for constValue Array
+ } else if( constElemCount || !isPointer ) {
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", SetArrayArgs, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(SetArrayArgsCheck);
+ unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
+ unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
+ if( isPointer ) {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ } else {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.wrap("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ }
+ unit.emit (" ( ( "+primJElemTypeBufferName+")(eb.getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".position(destPos) ) ).put(src, srcPos, length).rewind();");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ } else /* if( !constElemCount && isPointer ) */ {
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", SetArrayArgs, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(SetArrayArgsCheck);
+ unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
+ unit.emitln(" if( destPos + length <= elemCount ) {");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emit (" ( ( "+primJElemTypeBufferName+")(eb.getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".position(destPos) ) ).put(src, srcPos, length).rewind();");
+ unit.emitln(" } else {");
+ unit.emitln(" final int newElemCount = destPos + length;");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", newElemCount);");
+ unit.emit (" ( ( "+primJElemTypeBufferName+")(eb.getByteBuffer()");
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".position(destPos) ) ).put(src, srcPos, length).rewind();");
+ unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" _eb"+capitalFieldName+" = eb;");
+ emitSetElemCount(unit, setElemCountLengthFunc, "newElemCount", !useGetCStringLength, capitalFieldName, structCType, " ");
+ unit.emitln(" }");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ if( !addedElementBufferCache ) {
+ unit.emitln(" @SuppressWarnings(\"unused\")");
+ unit.emitln(" private ElementBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
+ }
+ }
+ unit.emitln();
+ }
+ } else {
+ // Setter Struct
+ if( maxOneElement ) {
+ // Setter Struct Single Pointer + Array
if( isPointer ) {
- // Setter Struct Pointer
- final String msg = "SKIP setter for complex-pointer type in struct: "+returnSizeLookupName+": "+fieldType.getDebugString();
- javaWriter.println(" // "+msg);
- LOG.log(INFO, structCType.getASTLocusTag(), msg);
- } else {
- // Setter Struct Array
- if( hasSingleElement ) {
- generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, fieldName, 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(" }");
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, constElemCount, elemCountExpr);
+ if( isConstValue ) {
+ // constElemCount excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership
+ unit.emitln(" {");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+baseJElemTypeName+".size(), 1);");
+ unit.emitln(" eb.put(0, src.getBuffer());");
+ unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" _eb"+capitalFieldName+" = eb;");
+ emitSetElemCount(unit, setElemCountLengthFunc, "1", !useGetCStringLength, capitalFieldName, structCType, " ");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ unit.emitln(" @SuppressWarnings(\"unused\")");
+ unit.emitln(" private ElementBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
+ } else {
+ unit.emitln(" {");
+ unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
+ unit.emitln(" if( 1 == elemCount ) {");
+ unit.emitln(" ElementBuffer.derefPointer("+baseJElemTypeName+".size(), 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
+ unit.emitln(" .put(0, src.getBuffer());");
+ unit.emitln(" } else {");
+ if( constElemCount ) {
+ unit.emitln(" throw new RuntimeException(\"Primitive '"+fieldName+"' of constElemCount and maxOneElement has elemCount \"+elemCount);");
+ unit.emitln(" }");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ } else {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+baseJElemTypeName+".size(), 1);");
+ unit.emitln(" eb.put(0, src.getBuffer());");
+ unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" _eb"+capitalFieldName+" = eb;");
+ emitSetElemCount(unit, setElemCountLengthFunc, "1", !useGetCStringLength, capitalFieldName, structCType, " ");
+ unit.emitln(" }");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ unit.emitln(" @SuppressWarnings(\"unused\")");
+ unit.emitln(" private ElementBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
+ }
+ }
+ } else if( !isConstValue ) { // array && !isConstValue
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(" ElementBuffer.wrap("+baseJElemTypeName+".size(), 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
+ unit.emitln(" .put(0, src.getBuffer());");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ } // else SKIP setter for constValue Array
+ unit.emitln();
+ } else {
+ // Setter Struct n Pointer + Array
+ if( isConstValue ) {
+ if( isPointer ) {
+ // constElemCount excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", SetArrayArgs, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(SetArrayArgsCheck);
+ unit.emitln(" final int newElemCount = destPos + length;");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+baseJElemTypeName+".size(), newElemCount);");
+ unit.emitln(" for(int i=0; i<length; ++i) {");
+ unit.emitln(" eb.put(destPos+i, src[srcPos+i].getBuffer());");
+ unit.emitln(" }");
+ unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" _eb"+capitalFieldName+" = eb;");
+ emitSetElemCount(unit, setElemCountLengthFunc, "newElemCount", !useGetCStringLength, capitalFieldName, structCType, " ");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ unit.emitln(" @SuppressWarnings(\"unused\")");
+ unit.emitln(" private ElementBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
+ } // else SKIP setter for constValue Array
+ } else if( constElemCount || !isPointer ) {
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", SetArrayArgs, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(SetArrayArgsCheck);
+ unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
+ unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
+ if( isPointer ) {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ } else {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.wrap("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ }
+ unit.emitln(" for(int i=0; i<length; ++i) {");
+ unit.emitln(" eb.put(destPos+i, src[srcPos+i].getBuffer());");
+ unit.emitln(" }");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ } else /* if( !constElemCount && isPointer ) */ {
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", SetArrayArgs, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(SetArrayArgsCheck);
+ unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
+ unit.emitln(" if( destPos + length <= elemCount ) {");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" for(int i=0; i<length; ++i) {");
+ unit.emitln(" eb.put(destPos+i, src[srcPos+i].getBuffer());");
+ unit.emitln(" }");
+ unit.emitln(" } else {");
+ unit.emitln(" final int newElemCount = destPos + length;");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+baseJElemTypeName+".size(), newElemCount);");
+ unit.emitln(" for(int i=0; i<length; ++i) {");
+ unit.emitln(" eb.put(destPos+i, src[srcPos+i].getBuffer());");
+ unit.emitln(" }");
+ unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);");
+ unit.emitln(" _eb"+capitalFieldName+" = eb;");
+ emitSetElemCount(unit, setElemCountLengthFunc, "newElemCount", !useGetCStringLength, capitalFieldName, structCType, " ");
+ unit.emitln(" }");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ unit.emitln(" @SuppressWarnings(\"unused\")");
+ unit.emitln(" private ElementBuffer _eb"+capitalFieldName+"; // cache new memory buffer ensuring same lifecycle");
+ }
+ unit.emitln();
+ if( !isConstValue ) {
+ generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, "final int destPos", baseJElemTypeName, null, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
+ unit.emitln(" if( destPos + 1 > elemCount ) { throw new IndexOutOfBoundsException(\"destPos \"+destPos+\" + 1 > elemCount \"+elemCount); };");
+ if( isPointer ) {
+ unit.emitln(" ElementBuffer.derefPointer("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx])");
} else {
- generateSetterSignature(javaWriter, fieldType, false, containingJTypeName, fieldName, 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, fieldName, 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(" }");
+ unit.emitln(" ElementBuffer.wrap("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx])");
}
+ unit.emitln(" .put(destPos, src.getBuffer());");
+ unit.emitln(" return this;");
+ unit.emitln(" }");
+ unit.emitln();
}
}
}
+
// 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.newCVVariant(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(false));
- 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, false, baseJElemTypeNameC+"Buffer", fieldName, capitalFieldName, null, arrayLengthExpr);
- javaWriter.println(" {");
- if( useGetCStringLength ) {
- javaWriter.println(" final int arrayLength = get"+capitalFieldName+"ArrayLength();");
+ // Getter Primitive Pointer + Array
+ if( maxOneElement ) {
+ generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName, fieldName, capitalFieldName, null, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ if( isPointer ) {
+ unit.emitln(" return ElementBuffer.derefPointer("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
} else {
- javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ unit.emitln(" return ElementBuffer.wrap("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])");
}
- javaWriter.println(" final ByteBuffer _res = get"+capitalFieldName+"0(getBuffer(), arrayLength);");
- javaWriter.println(" if (_res == null) return null;");
- javaWriter.print(" return Buffers.nativeOrder(_res)");
+ unit.emit (" .getByteBuffer()");
if( !isByteBuffer ) {
- javaWriter.print(".as"+baseJElemTypeNameC+"Buffer()");
+ unit.emit(".as"+primJElemTypeBufferName+"()");
}
- javaWriter.println(";");
- javaWriter.println(" }");
+ unit.emitln(".get(0);");
+ unit.emitln(" }");
+ unit.emitln();
+ } else {
+ boolean doneString = false;
if( isString && isByteBuffer ) {
- javaWriter.println();
- generateGetterSignature(javaWriter, fieldType, false, false, "String", fieldName, capitalFieldName+"AsString", null, arrayLengthExpr);
- javaWriter.println(" {");
- if( useGetCStringLength ) {
- javaWriter.println(" final int arrayLength = get"+capitalFieldName+"ArrayLength();");
+ generateGetterSignature(unit, fieldType, false, false, "String", fieldName, capitalFieldName+(isStringOnly?"":"AsString"), null, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
+ if( isPointer ) {
+ unit.emitln(" final ByteBuffer bb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer();");
} else {
- javaWriter.println(" final int arrayLength = "+arrayLengthExpr+";");
+ unit.emitln(" final ByteBuffer bb = ElementBuffer.wrap("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer();");
}
- 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, false, "final int", fieldName, 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(" }");
+ unit.emitln(" final byte[] ba = new byte[elemCount];");
+ unit.emitln(" int i = -1;");
+ unit.emitln(" while( ++i < elemCount ) {");
+ unit.emitln(" ba[i] = bb.get(i);");
+ unit.emitln(" if( (byte)0 == ba[i] ) break;");
+ unit.emitln(" }");
+ unit.emitln(" return new String(ba, 0, i, _charset);");
+ unit.emitln(" }");
+ unit.emitln();
+ doneString = true;
}
- } else {
- // Getter Primitive Array
- if( hasSingleElement ) {
- generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeName, fieldName, capitalFieldName, null, arrayLengthExpr);
- javaWriter.println(" {");
- if( baseCElemNativeSizeFixed ) {
- javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx]);");
+ if( doneString && isStringOnly ) {
+ generateSetterAPIDoc(unit, "SKIP getter for String alternative (ByteBuffer)", fieldType, fieldName, constElemCount, elemCountExpr);
+ unit.emitln();
+ } else {
+ generateGetterSignature(unit, fieldType, false, false, primJElemTypeBufferName, fieldName, capitalFieldName, null, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ if( isPointer ) {
+ unit.emitln(" return ElementBuffer.derefPointer("+primElemSizeExpr+", "+getElemCountFuncExpr+", getBuffer(), "+fieldName+"_offset[mdIdx])");
} else {
- javaWriter.println(" return accessor.get" + baseJElemTypeNameC + "At(" + fieldName+"_offset[mdIdx], md."+baseCElemSizeDenominator+"SizeInBytes());");
+ unit.emitln(" return ElementBuffer.wrap("+primElemSizeExpr+", "+getElemCountFuncExpr+", getBuffer(), "+fieldName+"_offset[mdIdx])");
}
- javaWriter.println(" }");
- javaWriter.println();
- } else {
- generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeNameC+"Buffer", fieldName, capitalFieldName, null, arrayLengthExpr);
- javaWriter.println(" {");
- javaWriter.print(" return accessor.slice(" + fieldName+"_offset[mdIdx], Buffers.SIZEOF_"+baseJElemTypeNameU+" * "+arrayLengthExpr+")");
+ unit.emit (" .getByteBuffer()");
if( !isByteBuffer ) {
- javaWriter.print(".as"+baseJElemTypeNameC+"Buffer()");
+ unit.emit(".as"+primJElemTypeBufferName+"()");
}
- javaWriter.println(";");
- javaWriter.println(" }");
- javaWriter.println();
- if( isString && isByteBuffer ) {
- generateGetterSignature(javaWriter, fieldType, false, false, "String", fieldName, 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(" }");
+ unit.emitln(";");
+ unit.emitln(" }");
+ unit.emitln();
+ }
+ if( !doneString ) {
+ generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName+"[]", fieldName, capitalFieldName, "final int srcPos, "+baseJElemTypeName+" dest[], "+GetArrayArgs, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(GetArrayArgsCheck);
+ unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
+ unit.emitln(" if( srcPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"srcPos \"+srcPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
+ unit.emit (" ( ("+primJElemTypeBufferName+")( ");
+ if( isPointer ) {
+ unit.emit("ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer()");
} else {
- generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeName+"[]", fieldName, 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();
+ unit.emit("ElementBuffer.wrap("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer()");
}
+ if( !isByteBuffer ) {
+ unit.emit(".as"+primJElemTypeBufferName+"()");
+ }
+ unit.emitln(".position(srcPos) ) )");
+ unit.emitln(" .get(dest, destPos, length).rewind();");
+ unit.emitln(" return dest;");
+ unit.emitln(" }");
+ unit.emitln();
}
}
} else {
- // Getter Struct
- if( isPointer ) {
- // Getter Struct Pointer
- final FunctionType ft = new FunctionType(dummyFuncTypeName, SizeThunk.POINTER, fieldType, 0);
- ft.addArgument(containingCType.newCVVariant(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(false));
- 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, false, baseJElemTypeName, fieldName, 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(" }");
+ // Getter Struct Pointer + Array
+ if( maxOneElement ) {
+ generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName, fieldName, capitalFieldName, null, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(" return "+baseJElemTypeName+".create(");
+ if( isPointer ) {
+ unit.emitln(" ElementBuffer.derefPointer("+baseJElemTypeName+".size(), 1, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer() );");
} else {
- generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeName+"[]", fieldName, 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(" }");
+ unit.emitln(" ElementBuffer.wrap("+baseJElemTypeName+".size(), 1, getBuffer(), "+fieldName+"_offset[mdIdx]).getByteBuffer() );");
}
+ unit.emitln(" }");
+ unit.emitln();
} else {
- // Getter Struct Array
- if( hasSingleElement ) {
- generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeName, fieldName, capitalFieldName, null, arrayLengthExpr);
- javaWriter.println(" {");
- javaWriter.println(" return "+baseJElemTypeName+".create(accessor.slice("+fieldName+"_offset[mdIdx], "+baseJElemTypeName+".size()));");
- javaWriter.println(" }");
+ generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName+"[]", fieldName, capitalFieldName, "final int srcPos, "+baseJElemTypeName+" dest[], "+GetArrayArgs, constElemCount, elemCountExpr);
+ unit.emitln(" {");
+ unit.emitln(GetArrayArgsCheck);
+ unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";");
+ unit.emitln(" if( srcPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"srcPos \"+srcPos+\" + length \"+length+\" > elemCount \"+elemCount); };");
+ if( isPointer ) {
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
} else {
- generateGetterSignature(javaWriter, fieldType, false, false, baseJElemTypeName+"[]", fieldName, 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(" }");
+ unit.emitln(" final ElementBuffer eb = ElementBuffer.wrap("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);");
}
+ unit.emitln(" for(int i=0; i<length; ++i) {");
+ unit.emitln(" dest[destPos+i] = "+baseJElemTypeName+".create( eb.slice(srcPos+i, 1) );");
+ unit.emitln(" }");
+ unit.emitln(" return dest;");
+ unit.emitln(" }");
+ unit.emitln();
}
}
}
+ private void emitSetElemCount(final JavaCodeUnit unit, final String setElemCountFunc, final String newElemCountExpr, final boolean mandatory, final String capitalFieldName, final Type structCType, final String indentation) {
+ if( null != setElemCountFunc ) {
+ unit.emitln(indentation+setElemCountFunc+"( "+newElemCountExpr+" );");
+ } else if( mandatory ) {
+ final String msg = "Missing set"+capitalFieldName+"ElemCount( "+newElemCountExpr+" )";
+ unit.emitln(indentation+"// ERROR: "+msg);
+ unit.emitln();
+ LOG.log(SEVERE, structCType.getASTLocusTag(), msg);
+ throw new RuntimeException(msg);
+ }
+ }
private JavaType typeToJavaType(final Type cType, final MachineDataInfo curMachDesc) {
final JavaType jt = typeToJavaTypeImpl(cType, curMachDesc);
@@ -2180,18 +2395,23 @@ public class JavaEmitter implements GlueEmitter {
/**
* @param filename the class's full filename to open w/ write access
- * @param simpleClassName the simple class name, i.e. w/o package name
- * @return a {@link PrintWriter} instance to write the class source file or <code>null</code> to suppress output!
+ * @param cUnitName the base c-unit name, i.e. c-file basename with suffix
+ * @param generator informal optional object that is creating this unit, used to be mentioned in a warning message if not null.
* @throws IOException
*/
- protected PrintWriter openFile(final String filename, final String simpleClassName) throws IOException {
- //System.out.println("Trying to open: " + filename);
- final File file = new File(filename);
- final String parentDir = file.getParent();
- if (parentDir != null) {
- new File(parentDir).mkdirs();
- }
- return new PrintWriter(new BufferedWriter(new FileWriter(file)));
+ protected CCodeUnit openCUnit(final String filename, final String cUnitName) throws IOException {
+ return new CCodeUnit(filename, cUnitName, this);
+ }
+
+ /**
+ * @param filename the class's full filename to open w/ write access
+ * @param packageName the package name of the class
+ * @param simpleClassName the simple class name, i.e. w/o package name or c-file basename
+ * @param generator informal optional object that is creating this unit, used to be mentioned in a warning message if not null.
+ * @throws IOException
+ */
+ protected JavaCodeUnit openJavaUnit(final String filename, final String packageName, final String simpleClassName) throws IOException {
+ return new JavaCodeUnit(filename, packageName, simpleClassName, this);
}
private boolean isOpaque(final Type type) {
@@ -2217,7 +2437,7 @@ public class JavaEmitter implements GlueEmitter {
}
}
- private void openWriters() throws IOException {
+ private void openCodeUnits() throws IOException {
String jRoot = null;
if (cfg.allStatic() || cfg.emitInterface()) {
jRoot = cfg.javaOutputDir() + File.separator +
@@ -2237,74 +2457,54 @@ public class JavaEmitter implements GlueEmitter {
}
if (cfg.allStatic() || cfg.emitInterface()) {
- javaFileName = jRoot + File.separator + cfg.className() + ".java";
- javaWriter = openFile(javaFileName, cfg.className());
+ final String javaFileName = jRoot + File.separator + cfg.className() + ".java";
+ javaUnit = openJavaUnit(javaFileName, cfg.packageName(), cfg.className());
}
if (!cfg.allStatic() && cfg.emitImpl()) {
- javaFileName = jImplRoot + File.separator + cfg.implClassName() + ".java";
- javaImplWriter = openFile(javaFileName, cfg.implClassName());
+ final String javaFileName = jImplRoot + File.separator + cfg.implClassName() + ".java";
+ javaImplUnit = openJavaUnit(javaFileName, cfg.implPackageName(), cfg.implClassName());
}
if (cfg.emitImpl()) {
- cFileName = nRoot + File.separator + cfg.implClassName() + "_JNI.c";
- cWriter = openFile(cFileName, cfg.implClassName());
- }
-
- if (javaWriter != null) {
- CodeGenUtils.emitAutogeneratedWarning(javaWriter, this);
- }
- if (javaImplWriter != null) {
- CodeGenUtils.emitAutogeneratedWarning(javaImplWriter, this);
- }
- if (cWriter != null) {
- CodeGenUtils.emitAutogeneratedWarning(cWriter, this);
+ final String cUnitName = cfg.implClassName() + "_JNI.c";
+ final String cFileName = nRoot + File.separator + cUnitName;
+ cUnit = openCUnit(cFileName, cUnitName);
}
}
- /** For {@link #javaWriter} or {@link #javaImplWriter} */
- protected String javaFileName() { return javaFileName; }
-
- protected PrintWriter javaWriter() {
+ protected JavaCodeUnit javaUnit() {
if (!cfg.allStatic() && !cfg.emitInterface()) {
throw new InternalError("Should not call this");
}
- return javaWriter;
+ return javaUnit;
}
- protected PrintWriter javaImplWriter() {
+ protected JavaCodeUnit javaImplUnit() {
if (cfg.allStatic() || !cfg.emitImpl()) {
throw new InternalError("Should not call this");
}
- return javaImplWriter;
+ return javaImplUnit;
}
- /** For {@link #cImplWriter} */
- protected String cFileName() { return cFileName; }
-
- protected PrintWriter cWriter() {
+ protected CCodeUnit cUnit() {
if (!cfg.emitImpl()) {
throw new InternalError("Should not call this");
}
- return cWriter;
- }
-
- private void closeWriter(final PrintWriter writer) throws IOException {
- writer.flush();
- writer.close();
+ return cUnit;
}
private void closeWriters() throws IOException {
- if (javaWriter != null) {
- closeWriter(javaWriter);
+ if( javaUnit != null ) {
+ javaUnit.close();
+ javaUnit = null;
}
- if (javaImplWriter != null) {
- closeWriter(javaImplWriter);
+ if( javaImplUnit != null ) {
+ javaImplUnit.close();
+ javaImplUnit = null;
}
- if (cWriter != null) {
- closeWriter(cWriter);
+ if( cUnit != null ) {
+ cUnit.close();
+ cUnit = null;
}
- javaWriter = null;
- javaImplWriter = null;
- cWriter = null;
}
/**
@@ -2335,17 +2535,17 @@ public class JavaEmitter implements GlueEmitter {
* Emit all the strings specified in the "CustomJavaCode" parameters of
* the configuration file.
*/
- protected void emitCustomJavaCode(final PrintWriter writer, final String className) throws Exception {
+ protected void emitCustomJavaCode(final CodeUnit unit, final String className) throws Exception {
final List<String> code = cfg.customJavaCodeForClass(className);
if (code.isEmpty())
return;
- writer.println();
- writer.println(" // --- Begin CustomJavaCode .cfg declarations");
+ unit.emitln();
+ unit.emitln(" // --- Begin CustomJavaCode .cfg declarations");
for (final String line : code) {
- writer.println(line);
+ unit.emitln(line);
}
- writer.println(" // ---- End CustomJavaCode .cfg declarations");
+ unit.emitln(" // ---- End CustomJavaCode .cfg declarations");
}
public String[] getClassAccessModifiers(final String classFQName) {
@@ -2371,11 +2571,13 @@ public class JavaEmitter implements GlueEmitter {
*/
protected void emitAllFileHeaders() throws IOException {
try {
- final List<String> imports = new ArrayList<String>(cfg.imports());
- imports.add(cfg.gluegenRuntimePackage()+".*");
- imports.add(DynamicLookupHelper.class.getPackage().getName()+".*");
- imports.add(Buffers.class.getPackage().getName()+".*");
- imports.add(Buffer.class.getPackage().getName()+".*");
+ final List<String> imports = new ArrayList<String>(cfg.imports());
+ imports.add(cfg.gluegenRuntimePackage()+".*");
+ imports.add(DynamicLookupHelper.class.getPackage().getName()+".*");
+ imports.add(Buffers.class.getPackage().getName()+".*");
+ imports.add(Buffer.class.getPackage().getName()+".*");
+ imports.add("java.nio.charset.Charset");
+ imports.add("java.nio.charset.StandardCharsets");
if (cfg.allStatic() || cfg.emitInterface()) {
@@ -2402,7 +2604,7 @@ public class JavaEmitter implements GlueEmitter {
final String[] accessModifiers = getClassAccessModifiers(cfg.className());
CodeGenUtils.emitJavaHeaders(
- javaWriter,
+ javaUnit().output,
cfg.packageName(),
cfg.className(),
cfg.allStatic() ? true : false,
@@ -2440,7 +2642,7 @@ public class JavaEmitter implements GlueEmitter {
final String[] accessModifiers = getClassAccessModifiers(cfg.implClassName());
CodeGenUtils.emitJavaHeaders(
- javaImplWriter,
+ javaImplUnit().output,
cfg.implPackageName(),
cfg.implClassName(),
true,
@@ -2452,7 +2654,7 @@ public class JavaEmitter implements GlueEmitter {
}
if (cfg.emitImpl()) {
- emitCHeader(cWriter(), getImplPackageName(), cfg.implClassName());
+ cUnit().emitHeader(getImplPackageName(), cfg.implClassName(), cfg.customCCode());
}
} catch (final Exception e) {
throw new RuntimeException(
@@ -2463,153 +2665,18 @@ public class JavaEmitter implements GlueEmitter {
}
- protected void emitCHeader(final PrintWriter cWriter, final String packageName, final String className) {
- cWriter.println("#include <jni.h>");
- cWriter.println("#include <stdlib.h>");
- cWriter.println("#include <string.h>");
- cWriter.println();
-
- if (getConfig().emitImpl()) {
- cWriter.println("#include <assert.h>");
- cWriter.println("#include <stddef.h>");
- cWriter.println();
- cWriter.println("static jobject JVMUtil_NewDirectByteBufferCopy(JNIEnv *env, void * source_address, size_t capacity); /* forward decl. */");
- cWriter.println();
- }
- for (final String code : cfg.customCCode()) {
- cWriter.println(code);
- }
- cWriter.println();
- }
-
- private static final String staticClassInitCodeCCode = "\n"+
- "static const char * clazzNameBuffers = \"com/jogamp/common/nio/Buffers\";\n"+
- "static const char * clazzNameBuffersStaticNewCstrName = \"newDirectByteBuffer\";\n"+
- "static const char * clazzNameBuffersStaticNewCstrSignature = \"(I)Ljava/nio/ByteBuffer;\";\n"+
- "static const char * sFatalError = \"FatalError:\";\n"+
- "static jclass clazzBuffers = NULL;\n"+
- "static jmethodID cstrBuffersNew = NULL;\n"+
- "static jboolean _initClazzAccessDone = JNI_FALSE;\n"+
- "\n"+
- "static jboolean _initClazzAccess(JNIEnv *env) {\n"+
- " jclass c;\n"+
- "\n"+
- " if(NULL!=cstrBuffersNew) return JNI_TRUE;\n"+
- "\n"+
- " c = (*env)->FindClass(env, clazzNameBuffers);\n"+
- " if(NULL==c) {\n"+
- " fprintf(stderr, \"%s Can't find %s\\n\", sFatalError, clazzNameBuffers);\n"+
- " (*env)->FatalError(env, clazzNameBuffers);\n"+
- " return JNI_FALSE;\n"+
- " }\n"+
- " clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c);\n"+
- " if(NULL==clazzBuffers) {\n"+
- " fprintf(stderr, \"%s Can't use %s\\n\", sFatalError, clazzNameBuffers);\n"+
- " (*env)->FatalError(env, clazzNameBuffers);\n"+
- " return JNI_FALSE;\n"+
- " }\n"+
- "\n"+
- " cstrBuffersNew = (*env)->GetStaticMethodID(env, clazzBuffers,\n"+
- " clazzNameBuffersStaticNewCstrName, clazzNameBuffersStaticNewCstrSignature);\n"+
- " if(NULL==cstrBuffersNew) {\n"+
- " fprintf(stderr, \"%s can't create %s.%s %s\\n\", sFatalError,\n"+
- " clazzNameBuffers,\n"+
- " clazzNameBuffersStaticNewCstrName, clazzNameBuffersStaticNewCstrSignature);\n"+
- " (*env)->FatalError(env, clazzNameBuffersStaticNewCstrName);\n"+
- " return JNI_FALSE;\n"+
- " }\n"+
- " _initClazzAccessDone = JNI_TRUE;\n"+
- " return JNI_TRUE;\n"+
- "}\n"+
- "\n"+
- "#define JINT_MAX_VALUE ((size_t)0x7fffffffU)\n"+
- "static const char * sNewBufferImplNotCalled = \"initializeImpl() not called\";\n"+
- "static const char * sNewBufferMAX_INT = \"capacity > MAX_INT\";\n"+
- "static const char * sNewBufferEXCPT = \"New direct ByteBuffer threw Exception\";\n"+
- "static const char * sNewBufferNULL = \"New direct ByteBuffer is NULL\";\n"+
- "\n"+
- "static jobject JVMUtil_NewDirectByteBufferCopy(JNIEnv *env, void * source_address, size_t capacity) {\n"+
- " jobject jbyteBuffer;\n"+
- " void * byteBufferPtr;\n"+
- "\n"+
- " if( JNI_FALSE == _initClazzAccessDone ) {\n"+
- " fprintf(stderr, \"%s %s\\n\", sFatalError, sNewBufferImplNotCalled);\n"+
- " (*env)->FatalError(env, sNewBufferImplNotCalled);\n"+
- " return NULL;\n"+
- " }\n"+
- " if( JINT_MAX_VALUE < capacity ) {\n"+
- " fprintf(stderr, \"%s %s: %lu\\n\", sFatalError, sNewBufferMAX_INT, (unsigned long)capacity);\n"+
- " (*env)->FatalError(env, sNewBufferMAX_INT);\n"+
- " return NULL;\n"+
- " }\n"+
- " jbyteBuffer = (*env)->CallStaticObjectMethod(env, clazzBuffers, cstrBuffersNew, (jint)capacity);\n"+
- " if( (*env)->ExceptionCheck(env) ) {\n"+
- " (*env)->ExceptionDescribe(env);\n"+
- " (*env)->ExceptionClear(env);\n"+
- " (*env)->FatalError(env, sNewBufferEXCPT);\n"+
- " return NULL;\n"+
- " }\n"+
- " if( NULL == jbyteBuffer ) {\n"+
- " fprintf(stderr, \"%s %s: size %lu\\n\", sFatalError, sNewBufferNULL, (unsigned long)capacity);\n"+
- " (*env)->FatalError(env, sNewBufferNULL);\n"+
- " return NULL;\n"+
- " }\n"+
- " if( 0 < capacity ) {\n"+
- " byteBufferPtr = (*env)->GetDirectBufferAddress(env, jbyteBuffer);\n"+
- " memcpy(byteBufferPtr, source_address, capacity);\n"+
- " }\n"+
- " return jbyteBuffer;\n"+
- "}\n"+
- "\n";
-
- private static final String staticClassInitCallJavaCode = "\n"+
- " static {\n"+
- " if( !initializeImpl() ) {\n"+
- " throw new RuntimeException(\"Initialization failure\");\n"+
- " }\n"+
- " }\n"+
- "\n";
-
- protected void emitCInitCode(final PrintWriter cWriter, final String packageName, final String className) {
- if ( requiresStaticInitialization(className) ) {
- cWriter.println(staticClassInitCodeCCode);
- cWriter.println("JNIEXPORT jboolean JNICALL "+JavaEmitter.getJNIMethodNamePrefix(packageName, className)+"_initializeImpl(JNIEnv *env, jclass _unused) {");
- 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();
- }
- }
-
- protected void emitJavaInitCode(final PrintWriter jWriter, final String className) {
- if( null != jWriter && requiresStaticInitialization(className) ) {
- 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);
- }
- }
- }
-
/**
* Write out any footer information for the output files (closing brace of
* class definition, etc).
*/
protected void emitAllFileFooters() {
if (cfg.allStatic() || cfg.emitInterface()) {
- javaWriter().println();
- javaWriter().println("} // end of class " + cfg.className());
+ javaUnit.emitTailCode();
+ javaUnit().emitln("} // end of class " + cfg.className());
}
if (!cfg.allStatic() && cfg.emitImpl()) {
- javaImplWriter().println();
- javaImplWriter().println("} // end of class " + cfg.implClassName());
+ javaImplUnit.emitTailCode();
+ javaImplUnit().emitln("} // end of class " + cfg.implClassName());
}
}
@@ -2854,4 +2921,28 @@ public class JavaEmitter implements GlueEmitter {
private final String capitalizeString(final String string) {
return Character.toUpperCase(string.charAt(0)) + string.substring(1);
}
+ /**
+ * Converts first letter to lower case.
+ */
+ private final String decapitalizeString(final String string) {
+ return Character.toLowerCase(string.charAt(0)) + string.substring(1);
+ }
+
+ private static final String optStringCharsetCode =
+ " private static Charset _charset = StandardCharsets.UTF_8;\n" +
+ "\n"+
+ " /** Returns the Charset for this class's String mapping, default is StandardCharsets.UTF_8. */\n"+
+ " public static Charset getCharset() { return _charset; };\n"+
+ "\n"+
+ " /** Sets the Charset for this class's String mapping, default is StandardCharsets.UTF_8. */\n"+
+ " public static void setCharset(Charset cs) { _charset = cs; }\n";
+
+ private static final String optStringMaxStrnlenCode =
+ " private static int _max_strnlen = 8192;\n"+
+ "\n"+
+ " /** Returns the maximum number of bytes to read to determine native string length using `strnlen(..)`, default is 8192. */\n"+
+ " public static int getMaxStrnlen() { return _max_strnlen; };\n"+
+ "\n"+
+ " /** Sets the maximum number of bytes to read to determine native string length using `strnlen(..)`, default is 8192. */\n"+
+ " public static void setMaxStrnlen(int v) { _max_strnlen = v; }\n";
}