diff options
author | Sven Gothel <[email protected]> | 2023-07-05 10:21:48 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-07-05 10:21:48 +0200 |
commit | 5ceca8550b82591a6a2661a26d3e0d5e6e3e15ff (patch) | |
tree | 95768138afdb5ee4c6d3b705e803ad497241f756 /src/java/com/jogamp/gluegen/JavaConfiguration.java | |
parent | ae4c2c3e59ed92caa6f0e18360b7236e50899bf6 (diff) |
GlueGen: Add 'PascalString' string semantics (length + value-ptr), added prelim code for JavaCallback use-case emitBodyMapCToJNIType()
It is common in toolkit APIs that a string might not be passed as a 'nul' terminated (EOS) C string,
but as a Pascal string with a given length argument.
A C string is specied as
ArgumentIsString alEventCallbackInject 3
while allowing multiple indices ..
A Pascal string can be specified as
ArgumentIsPascalString ALEVENTPROCSOFT 3 4
while allowing multiple indice-tuples for length and value ..
The tuple consist of the length agrument-index first (usually an int)
followed by the value argument-index (usually a 'char*').
+++
CMethodBindingEmitter.emitBodyMapCToJNIType(), where PascalString is implemented,
is currently being used for
- JNI return statement (no PascalString impact possible)
- JavaCallback C type -> JNI type, PascalString impacting
Diffstat (limited to 'src/java/com/jogamp/gluegen/JavaConfiguration.java')
-rw-r--r-- | src/java/com/jogamp/gluegen/JavaConfiguration.java | 93 |
1 files changed, 86 insertions, 7 deletions
diff --git a/src/java/com/jogamp/gluegen/JavaConfiguration.java b/src/java/com/jogamp/gluegen/JavaConfiguration.java index 10f43a7..5cea4c3 100644 --- a/src/java/com/jogamp/gluegen/JavaConfiguration.java +++ b/src/java/com/jogamp/gluegen/JavaConfiguration.java @@ -144,12 +144,47 @@ public class JavaConfiguration { private final Map<String, String> returnedArrayLengths = new HashMap<String, String>(); private final Set<String> maxOneElement = new HashSet<String>(); + /** Pascal string argument index tuple for length and value. */ + public static class PascalStringIdx { + public final int lengthIndex; + public final int valueIndex; + + PascalStringIdx(final int lenIdx, final int valIdx) { + lengthIndex = lenIdx; + valueIndex = valIdx; + } + + public void pushValueIndex(final List<Integer> indices) { + indices.add(valueIndex); + } + public static final List<Integer> pushValueIndex(final List<PascalStringIdx> source, List<Integer> indices) { + if( null == indices ) { + indices = new ArrayList<Integer>(2); + } + for(final PascalStringIdx p : source) { + p.pushValueIndex(indices); + } + return indices; + } + + @Override + public String toString() { + return "PascalString[lenIdx "+lengthIndex+", valIdx "+valueIndex+"]"; + } + } + /** * Key is function that has some byte[] or short[] arguments that should be * converted to String args; value is List of Integer argument indices */ private final Map<String, List<Integer>> argumentsAreString = new HashMap<String, List<Integer>>(); + /** + * Key is function that has a pascal string, i.e. length and some byte[] or short[] arguments that should be + * converted to String args; value is a list of PascalStringArg + */ + private final Map<String, List<PascalStringIdx>> argumentsArePascalString = new HashMap<String, List<PascalStringIdx>>(); + /** JavaCallback configuration definition (static) */ public static class JavaCallbackDef { final String cbFuncTypeName; @@ -609,13 +644,6 @@ public class JavaConfiguration { /** Returns a list of <code>Integer</code>s which are the indices of <code>const char*</code> arguments that should be converted to <code>String</code>s. Returns null if there are no - such hints for the given function name. */ - public List<Integer> stringArguments(final String functionName) { - return argumentsAreString.get(functionName); - } - - /** Returns a list of <code>Integer</code>s which are the indices of <code>const char*</code> - arguments that should be converted to <code>String</code>s. Returns null if there are no such hints for the given function alias symbol. */ public List<Integer> stringArguments(final AliasedSymbol symbol) { final String name = symbol.getName(); @@ -632,6 +660,36 @@ public class JavaConfiguration { return res; } + /** Returns a list of PascalStringIdx which are tuples of indices of <code>int len, const char*</code> + arguments that should be converted to <code>String</code>s. Returns null if there are no + such hints for the given function alias symbol. */ + public List<PascalStringIdx> pascalStringArgument(final AliasedSymbol symbol) { + final String name = symbol.getName(); + final Set<String> aliases = symbol.getAliasedNames(); + + List<PascalStringIdx> res = argumentsArePascalString.get(name); + if( null == res ) { + res = oneInMap(argumentsArePascalString, aliases); + if( null == res ) { + return null; + } + } + LOG.log(INFO, getASTLocusTag(symbol), "ArgumentIsPascalString: {0} -> {1}", symbol, res); + return res; + } + + public int pascalStringLengthIndex(final AliasedSymbol symbol, final int valueIndex) { + final List<PascalStringIdx> pascals = pascalStringArgument(symbol); + if( null != pascals ) { + for(final PascalStringIdx p : pascals) { + if( valueIndex == p.valueIndex ) { + return p.lengthIndex; + } + } + } + return -1; + } + public boolean isForceUsingNIOOnly4All() { return forceUseNIOOnly4All; } public void addUseNIOOnly(final String fname ) { @@ -1380,6 +1438,8 @@ public class JavaConfiguration { readMaxOneElement(tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("ArgumentIsString")) { readArgumentIsString(tok, filename, lineNo); + } else if (cmd.equalsIgnoreCase("ArgumentIsPascalString")) { + readArgumentIsPascalString(tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("JavaCallbackDef")) { readJavaCallbackDef(tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("JavaCallbackKey")) { @@ -1948,6 +2008,25 @@ public class JavaConfiguration { } } + protected void readArgumentIsPascalString(final StringTokenizer tok, final String filename, final int lineNo) { + try { + final String methodName = tok.nextToken(); + final List<PascalStringIdx> pascalTuples = new ArrayList<PascalStringIdx>(2); + while (tok.countTokens() >= 2) { + final int lenIdx = Integer.valueOf(tok.nextToken()).intValue(); + final int valIdx = Integer.valueOf(tok.nextToken()).intValue(); + pascalTuples.add(new PascalStringIdx(lenIdx, valIdx)); + } + if( pascalTuples.size() > 0 ) { + argumentsArePascalString.put(methodName, pascalTuples); + } + } catch (final NoSuchElementException e) { + throw new RuntimeException( + "Error parsing \"ArgumentIsPascalString\" command at line " + lineNo + + " in file \"" + filename + "\"", e); + } + } + protected void readStructPackage(final StringTokenizer tok, final String filename, final int lineNo) { try { final String struct = tok.nextToken(); |