diff options
author | Sven Gothel <[email protected]> | 2023-06-16 02:16:20 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-06-16 02:16:20 +0200 |
commit | 8b127c4c1dd26fcb1756805ddb83729203161f78 (patch) | |
tree | f8563a0e39d293bc070ef01e457cfe08ee44096d | |
parent | aeadfab9572e4b441b1bc1f0708cf4c72dfe181e (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.
18 files changed, 5375 insertions, 1407 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..e6a0a57 --- /dev/null +++ b/README.md @@ -0,0 +1,79 @@ +# GlueGen, Native Binding Generator for Java™ + +[Original document location](https://jogamp.org/cgit/gluegen.git/about/) + +## Git Repository +This project's canonical repositories is hosted on [JogAmp](https://jogamp.org/cgit/gluegen.git/). + +## Overview +[GlueGen](https://jogamp.org/gluegen/www/) is a compiler for function and data-structure declarations, +generating Java™ and JNI C code offline at compile time +and allows using native libraries within your Java™ application. + +It reads ANSI C header files +and separate configuration files which provide control over many +aspects of the glue code generation. GlueGen uses a complete ANSI C +parser and an internal representation (IR) capable of representing all +C types to represent the APIs for which it generates interfaces. It +has the ability to perform significant transformations on the IR +before glue code emission. + +GlueGen can produce native foreign function bindings to Java™ as well as +map native data structures to be fully accessible from Java™ including +potential calls to embedded function pointer. + +GlueGen is also capable to bind even low-level APIs such as the Java™ Native Interface (JNI) and +the AWT Native Interface (JAWT) back up to the Java™ programming language. + +GlueGen utilizes [JCPP](https://jogamp.org/cgit/jcpp.git/about/), migrated C preprocessor written in Java™. + +GlueGen is used for the [JogAmp](https://jogamp.org) projects +[JOAL](https://jogamp.org/cgit/joal.git/about/), +[JOGL](https://jogamp.org/cgit/jogl.git/about/) and +[JOCL](https://jogamp.org/cgit/jocl.git/). + +GlueGen is part of [the JogAmp project](https://jogamp.org). + +**The JogAmp project needs funding and we offer [commercial support](https://jogamp.org/wiki/index.php?title=Maintainer_and_Contacts#Commercial_Support)!**<br/> +Please contact [Göthel Software (Jausoft)](https://jausoft.com/). + +### License +See [LICENSE.txt](LICENSE.txt). + +## Documentation + +* [GlueGen Java™ API-Doc](https://jogamp.org/deployment/jogamp-next/javadoc/gluegen/javadoc/) +* [GlueGen Native Data & Function Mapping for Java™](doc/GlueGen_Mapping.md) +* [GlueGen Manual](doc/manual/) +* [JogAmp's MacOS Version Support](doc/JogAmpMacOSVersions.md) +* [How To Build](https://jogamp.org/gluegen/doc/HowToBuild.html) + +## Build Requirements +Check [GlueGen's HowToBuild](https://jogamp.org/gluegen/doc/HowToBuild.html). + +## Directory Organization: +``` +make/ Build-related files and the main build.xml +doc/ Documentation +jcpp/ JCPP (git sub-module), migrated C preprocessor written in Java +src/ The actual source for the JOAL APIs. +src/junit/ Unit tests +test/ Standalone manual tests +build/ (generated directory) Where the Jar and DLL files get built to +www/ JOAL project webpage files +``` + +## Contact Us +- JogAmp [http://jogamp.org/](https://jogamp.org/) +- JOAL Web [http://jogamp.org/](https://jogamp.org/joal/) +- Forum/Mailinglist [http://forum.jogamp.org/](https://forum.jogamp.org/) +- Repository [http://jogamp.org/git/](https://jogamp.org/git/) +- Wiki [https://jogamp.org/wiki/](https://jogamp.org/wiki/) +- Maintainer [https://jogamp.org/wiki/index.php/Maintainer_and_Contacts](https://jogamp.org/wiki/index.php/Maintainer_and_Contacts) +- Sven's Blog [https://jausoft.com/blog/tag/jogamp/](https://jausoft.com/blog/tag/jogamp/) +- Email sgothel _at_ jausoft _dot_ com + +## History +Since roughly 2010, GlueGen development has been continued +by individuals of the JogAmp community, see git log for details. + diff --git a/doc/GlueGen_Mapping.html b/doc/GlueGen_Mapping.html new file mode 100644 index 0000000..537ce89 --- /dev/null +++ b/doc/GlueGen_Mapping.html @@ -0,0 +1,1372 @@ +<style> +div#header, header + { + + border-bottom: 1px solid #aaa; + margin-bottom: 0.5em; + } + +.title + { + text-align: center; + } + +.author, .date + { + text-align: center; + } + +div#TOC, nav#TOC + { + + border-bottom: 1px solid #aaa; + margin-bottom: 0.5em; + } + +nav#TOC { + margin-bottom: var(--line-height); + + padding-bottom: 0.5rem; +} + +nav#TOC input { + display: none; +} + +nav#TOC label { + color: var(--color-link); + cursor: pointer; +} + +nav#TOC > ul { + display: none; +} + +nav#TOC > input:checked + ul { + display: block; +} + +@media print + { + div#TOC, nav#TOC + { + + display: none; + } + } + +div.content + { + color: #111111; + font-size: 14px; + line-height: 1.6; + } + +div#cgit a + { + color: #1212a0; + } + +div#cgit a.sourceLine + { + color: #111111; + } + +h1, h2, h3, h4, h5, h6 +{ + font-family: "Helvetica Neue", Helvetica, "Liberation Sans", Calibri, Arial, sans-serif; + + page-break-after: avoid; + + margin: 20px 0 10px; + padding: 0; +} + +h2 { + border-bottom: 1px solid #ccc; +} + +div div + { + + } + +section section + { + margin-left: 2em; + } + +p {} + +blockquote + { + font-style: italic; + } + +li + { + } + +li > p + { + margin-top: 1em; + } + +ul + { + } + +ul li + { + } + +ol + { + } + +ol li + { + } + +hr {} + +sub + { + } + +sup + { + } + +em + { + } + +em > em + { + font-style: normal; + } + +strong + { + } + +a + { + + text-decoration: none; + } + +@media screen + { + a:hover + { + + text-decoration: underline; + } + } + +@media print + { + a { + + color: black; + background: transparent; + } + + a[href^="http://"]:after, a[href^="https://"]:after + { + + content: " (" attr(href) ") "; + font-size: 90%; + } + } + +img + { + + vertical-align: middle; + } + +div.figure + { + + margin-left: auto; + margin-right: auto; + text-align: center; + font-style: italic; + } + +p.caption + { + + } + +pre, code + { + background-color: #f8f8f8; + + white-space: pre-wrap; + white-space: -moz-pre-wrap !important; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; + + } + +pre + { + + padding: 0.5em; + border-radius: 5px; + + background-color: #f8f8f8; + border: 1px solid #ccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + + margin-left: 0.5em; + margin-right: 0.5em; + } + +@media screen + { + pre + { + + white-space: pre; + overflow: auto; + + border: 1px dotted #777; + } + } + +code + { + } + +p > code, li > code + { + + padding-left: 2px; + padding-right: 2px; + } + +li > p code + { + + padding: 2px; + } + +span.math + { + + } + +div.math + { + } + +span.LaTeX + { + } + +eq + { + } + +table + { + border-collapse: collapse; + border-spacing: 0; + + margin-left: auto; + margin-right: auto; + } + +thead + { + border-bottom: 1pt solid #000; + background-color: #eee; + } + +tr.header + { + } + +tbody + { + } + +tr { + } +tr.odd:hover, tr.even:hover + { + background-color: #eee; + } + +tr.odd {} +tr.even {} + +td, th + { + vertical-align: top; + vertical-align: baseline; + padding-left: 0.5em; + padding-right: 0.5em; + padding-top: 0.2em; + padding-bottom: 0.2em; + } +th + { + font-weight: bold; + } + +tfoot + { + } + +caption + { + caption-side: top; + border: none; + font-size: 0.9em; + font-style: italic; + text-align: center; + margin-bottom: 0.3em; + padding-bottom: 0.2em; + } + +dl + { + border-top: 2pt solid black; + padding-top: 0.5em; + border-bottom: 2pt solid black; + } + +dt + { + font-weight: bold; + } + +dd+dt + { + border-top: 1pt solid black; + padding-top: 0.5em; + } + +dd + { + margin-bottom: 0.5em; + } + +dd+dd + { + border-top: 1px solid black; + } + +a.footnote, a.footnoteRef { + font-size: small; + vertical-align: text-top; +} + +a[href^="#fnref"], a.reversefootnote + { + } + +@media print + { + a[href^="#fnref"], a.reversefootnote + { + + display: none; + } + } + +div.footnotes + { + } + +div.footnotes li[id^="fn"] + { + } + +@media print + { + .noprint + { + display:none; + } + } +</style> + +<nav id="TOC" role="doc-toc"> + <strong>Contents</strong><label for="contents">⊕</label> + <input type="checkbox" id="contents"> + <ul> + <li><a href="#gluegen-native-data--function-mapping-for-java">GlueGen + Native Data & Function Mapping for Java™</a> + <ul> + <li><a href="#references">References</a></li> + <li><a href="#overview">Overview</a></li> + <li><a href="#primitive-mapping">Primitive Mapping</a> + <ul> + <li><a href="#string-mapping">String Mapping</a></li> + <li><a href="#alignment-for-compound-data">Alignment for Compound + Data</a></li> + </ul></li> + <li><a href="#struct-mapping">Struct Mapping</a> + <ul> + <li><a href="#gluegen-struct-settings">GlueGen Struct + Settings</a></li> + <li><a href="#struct-mapping-notes">Struct Mapping Notes</a></li> + <li><a href="#struct-java-signature-table">Struct Java Signature + Table</a></li> + <li><a href="#struct-setter-pseudo-code">Struct Setter + Pseudo-Code</a></li> + </ul></li> + <li><a href="#platform-header-files">Platform Header Files</a></li> + <li><a href="#pre-defined-macros">Pre-Defined Macros</a></li> + </ul></li> + </ul> +</nav> + +<style> +table, th, td { + border: 1px solid black; +} +</style> + +<h1 id="gluegen-native-data--function-mapping-for-java">GlueGen Native +Data & Function Mapping for Java™</h1> +<h2 id="references">References</h2> +<ul> +<li><a href="https://jogamp.org/cgit/gluegen.git/about/">GlueGen Git +Repo</a></li> +<li><a +href="https://jogamp.org/deployment/jogamp-next/javadoc/gluegen/javadoc/">GlueGen +Java™ API-Doc</a></li> +<li><a href="https://jogamp.org/gluegen/doc/manual/">GlueGen +Manual</a></li> +<li><a href="https://jogamp.org/gluegen/www/">GlueGen Project +Page</a></li> +<li><a href="https://jogamp.org/gluegen/doc/HowToBuild.html">How To +Build</a></li> +</ul> +<h2 id="overview">Overview</h2> +<p><a href="https://jogamp.org/gluegen/www/">GlueGen</a> is a compiler +for function and data-structure declarations, generating Java and JNI C +code offline at compile time and allows using native libraries within +your Java application.</p> +<p>It reads ANSI C header files and separate configuration files which +provide control over many aspects of the glue code generation. GlueGen +uses a complete ANSI C parser and an internal representation (IR) +capable of representing all C types to represent the APIs for which it +generates interfaces. It has the ability to perform significant +transformations on the IR before glue code emission.</p> +<p>GlueGen can produce native foreign function bindings to Java as well +as map native data structures to be fully accessible from Java including +potential calls to embedded function pointer.</p> +<p>GlueGen is also capable to bind even low-level APIs such as the Java +Native Interface (JNI) and the AWT Native Interface (JAWT) back up to +the Java programming language.</p> +<p>GlueGen utilizes <a +href="https://jogamp.org/cgit/jcpp.git/about/">JCPP</a>, migrated C +preprocessor written in Java.</p> +<p>GlueGen is used for the <a href="https://jogamp.org">JogAmp</a> +projects <a href="https://jogamp.org/cgit/joal.git/about/">JOAL</a>, <a +href="https://jogamp.org/cgit/jogl.git/about/">JOGL</a> and <a +href="https://jogamp.org/cgit/jocl.git/">JOCL</a>.</p> +<p>GlueGen is part of <a href="https://jogamp.org">the JogAmp +project</a>.</p> +<h2 id="primitive-mapping">Primitive Mapping</h2> +<p>Gluegen has build-in types (terminal symbols) for:</p> +<table> +<thead> +<tr class="header"> +<th style="text-align: left;">type</th> +<th style="text-align: left;">java-bits</th> +<th style="text-align: left;">native-bits <br> x32</th> +<th style="text-align: left;">native bits <br> x64</th> +<th style="text-align: left;">type</th> +<th style="text-align: left;">signed</th> +<th style="text-align: left;">origin</th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<td style="text-align: left;">void</td> +<td style="text-align: left;">0</td> +<td style="text-align: left;">0</td> +<td style="text-align: left;">0</td> +<td style="text-align: left;">void</td> +<td style="text-align: left;">void</td> +<td style="text-align: left;">ANSI-C</td> +</tr> +<tr class="even"> +<td style="text-align: left;">char</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">any</td> +<td style="text-align: left;">ANSI-C</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">short</td> +<td style="text-align: left;">16</td> +<td style="text-align: left;">16</td> +<td style="text-align: left;">16</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">any</td> +<td style="text-align: left;">ANSI-C</td> +</tr> +<tr class="even"> +<td style="text-align: left;">int</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">any</td> +<td style="text-align: left;">ANSI-C</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">long</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;"><strong>32</strong>†</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">any</td> +<td style="text-align: left;">ANSI-C - Windows</td> +</tr> +<tr class="even"> +<td style="text-align: left;">long</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;"><strong>64</strong></td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">any</td> +<td style="text-align: left;">ANSI-C - Unix</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">float</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">float</td> +<td style="text-align: left;">signed</td> +<td style="text-align: left;">ANSI-C</td> +</tr> +<tr class="even"> +<td style="text-align: left;">double</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">double</td> +<td style="text-align: left;">signed</td> +<td style="text-align: left;">ANSI-C</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">__int32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">any</td> +<td style="text-align: left;">windows</td> +</tr> +<tr class="even"> +<td style="text-align: left;">__int64</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">any</td> +<td style="text-align: left;">windows</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">int8_t</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">signed</td> +<td style="text-align: left;">stdint.h</td> +</tr> +<tr class="even"> +<td style="text-align: left;">uint8_t</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">unsigned</td> +<td style="text-align: left;">stdint.h</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">int16_t</td> +<td style="text-align: left;">16</td> +<td style="text-align: left;">16</td> +<td style="text-align: left;">16</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">signed</td> +<td style="text-align: left;">stdint.h</td> +</tr> +<tr class="even"> +<td style="text-align: left;">uint16_t</td> +<td style="text-align: left;">16</td> +<td style="text-align: left;">16</td> +<td style="text-align: left;">16</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">unsigned</td> +<td style="text-align: left;">stdint.h</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">int32_t</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">signed</td> +<td style="text-align: left;">stdint.h</td> +</tr> +<tr class="even"> +<td style="text-align: left;">uint32_t</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">unsigned</td> +<td style="text-align: left;">stdint.h</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">int64_t</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">signed</td> +<td style="text-align: left;">stdint.h</td> +</tr> +<tr class="even"> +<td style="text-align: left;">uint64_t</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">unsigned</td> +<td style="text-align: left;">stdint.h</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">intptr_t</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">signed</td> +<td style="text-align: left;">stdint.h</td> +</tr> +<tr class="even"> +<td style="text-align: left;">uintptr_t</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">unsigned</td> +<td style="text-align: left;">stdint.h</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">ptrdiff_t</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">signed</td> +<td style="text-align: left;">stddef.h</td> +</tr> +<tr class="even"> +<td style="text-align: left;">size_t</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">64</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">unsigned</td> +<td style="text-align: left;">stddef.h</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">wchar_t</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">32</td> +<td style="text-align: left;">integer</td> +<td style="text-align: left;">signed</td> +<td style="text-align: left;">stddef.h</td> +</tr> +</tbody> +</table> +<p><strong>Warning:</strong> Try to avoid unspecified bit sized types, +especially <strong>long</strong>, since it differs on Unix and +Windows!<br /> +<strong>Notes:</strong></p> +<ul> +<li>† Type <strong>long</strong> will result in broken code on Windows, +since we don't differentiate the OS and it's bit size is ambiguous.</li> +<li>Anonymous void-pointer <em>void*</em> are mapped to NIO +<em>Buffer</em>.</li> +<li>Pointers to pointer-size types like <em>intptr_t*</em>, +<em>uintptr_t*</em>, <em>ptrdiff_t*</em> and <em>size_t*</em> are mapped +to <em>PointerBuffer</em>, to reflect the architecture depending storage +size.</li> +</ul> +<h3 id="string-mapping">String Mapping</h3> +<h4 id="function-return-string-values">Function return String +values</h4> +<p>Function return values are currently mapped from <code>char*</code> +to Java String using <em>UTF-8</em> via JNI function</p> +<blockquote> +<p><code>jstring NewStringUTF(JNIEnv *env, const char *bytes)</code></p> +</blockquote> +<p><em>FIXME</em>: This might need more flexibility in case UTF-8 is not +suitable for 8-bit wide <code>char</code> mappings or wide characters, +e.g. for UTF-16 needs to be supported.</p> +<h4 id="function-argument-string-values">Function argument String +values</h4> +<p>Function argument values are either mapped from <code>char*</code> to +Java String using <em>UTF-8</em> via JNI function</p> +<blockquote> +<p><code>const char * GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)</code>.</p> +</blockquote> +<p>Alternatively, if a 16-bit wide <em>character</em> type has been +detected, i.e. <em>short</em>, the native <em>character</em> are mapped +to Java using <em>UTF-16</em> via JNI function</p> +<blockquote> +<p><code>void GetStringRegion(JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf)</code>.</p> +</blockquote> +<h4 id="struct-string-mapping">Struct String mapping</h4> +<p>String value mapping for <code>Struct</code> fields is performed +solely from the Java side using <em>Charset</em> and is hence most +flexible.</p> +<p>By default, <em>UTF-8</em> is being used for getter and setter of +String values.<br /> +The <em>Struct</em> class provides two methods to get and set the used +<em>Charset</em> for conversion</p> +<pre><code> /** Returns the Charset for this class's String mapping, default is StandardCharsets.UTF_8. */ + public static Charset getCharset() { return _charset; }; + + /** Sets the Charset for this class's String mapping, default is StandardCharsets.UTF_8. */ + public static void setCharset(Charset cs) { _charset = cs; } +</code></pre> +<p>In case the String length has not been configured via +<code>ReturnedArrayLength</code>, it will be dynamically calculated via +<code>strnlen(aptr, max_len)</code>.<br /> +The maximum length default for the <code>strnlen(..)</code> operation is +8192 bytes and can be get and set using:</p> +<pre><code> /** Returns the maximum number of bytes to read to determine native string length using `strnlen(..)`, default is 8192. */ + public static int getMaxStrnlen() { return _max_strnlen; }; + + /** Sets the maximum number of bytes to read to determine native string length using `strnlen(..)`, default is 8192. */ + public static void setMaxStrnlen(int v) { _max_strnlen = v; }</code></pre> +<p><em>FIXME</em>: This only works reliable using an 8-bit Charset +encoding, e.g. the default <em>UTF-8</em>.</p> +<h3 id="alignment-for-compound-data">Alignment for Compound Data</h3> +<p>In general, depending on CPU and it's configuration (OS), alignment +is set up for each type (char, short, int, long, ..).</p> +<p>Compounds (structures) are aligned naturally, i.e. their inner +components are aligned<br /> +and are itself aligned to it's largest element.</p> +<p>See:</p> +<ul> +<li><a +href="http://en.wikipedia.org/wiki/Data_structure_alignment">Wikipedia +Data Structure Alignment</a></li> +<li><a +href="http://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding">Wikipedia +Data Structure Alignment - Padding</a></li> +<li><a href="http://www.viva64.com/en/l/0021/">Viva64 Data +Alignment</a></li> +<li><a +href="http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/64bitPorting/transition/transition.html#//apple_ref/doc/uid/TP40001064-CH207-SW1">Apple: +Darwin 64bit Porting - Data Type Size & Alignment</a></li> +</ul> +<h4 id="simple-alignment-arithmetic">Simple alignment arithmetic</h4> +<p>Modulo operation, where the 2nd handles the case offset == +alignment:</p> +<blockquote> +<p>padding = ( alignment - ( offset % alignment ) ) % alignment ;<br /> +aligned_offset = offset + padding ;</p> +</blockquote> +<p>Optimization utilizing alignment as a multiple of 2 +<code>-> x % 2n == x & ( 2n - 1 )</code></p> +<blockquote> +<p>remainder = offset & ( alignment - 1 ) ;<br /> +padding = ( remainder > 0 ) ? alignment - remainder : 0 ;<br /> +aligned_offset = offset + padding ;</p> +</blockquote> +<p>Without branching, using the 2nd modulo operation for the case offset +== alignment:</p> +<blockquote> +<p>padding = ( alignment - ( offset & ( alignment - 1 ) ) ) & ( +alignment - 1 ) ;<br /> +aligned_offset = offset + padding ;</p> +</blockquote> +<p>See +<code>com.jogamp.gluegen.cgram.types.SizeThunk.align(..)</code>.</p> +<h4 +id="type-size--alignment-for-x86-x86_64-armv6l-32bit-eabi-and-windowmingwmingw64">Type +Size & Alignment for x86, x86_64, armv6l-32bit-eabi and +Window(mingw/mingw64)</h4> +<p>Runtime query is implemented as follows:</p> +<pre><code> typedef struct { + char fill; // nibble one byte + // padding to align s1: padding_0 + type_t s1; // + } test_struct_type_t; + + padding_0 = sizeof(test_struct_type_t) - sizeof(type_t) - sizeof(char) ; + alignmentOf(type_t) = sizeof(test_struct_type_t) - sizeof(type_t) ;</code></pre> +<table> +<thead> +<tr class="header"> +<th style="text-align: left;">type</th> +<th style="text-align: left;">size <br> <em>32 bit</em></th> +<th style="text-align: left;">alignment <br> <em>32 bit</em></th> +<th style="text-align: left;">size <br> <em>64 bit</em></th> +<th style="text-align: left;">alignment <br> <em>64 bit</em></th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<td style="text-align: left;">char</td> +<td style="text-align: left;">1</td> +<td style="text-align: left;">1</td> +<td style="text-align: left;">1</td> +<td style="text-align: left;">1</td> +</tr> +<tr class="even"> +<td style="text-align: left;">short</td> +<td style="text-align: left;">2</td> +<td style="text-align: left;">2</td> +<td style="text-align: left;">2</td> +<td style="text-align: left;">2</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">int</td> +<td style="text-align: left;">4</td> +<td style="text-align: left;">4</td> +<td style="text-align: left;">4</td> +<td style="text-align: left;">4</td> +</tr> +<tr class="even"> +<td style="text-align: left;">float</td> +<td style="text-align: left;">4</td> +<td style="text-align: left;">4</td> +<td style="text-align: left;">4</td> +<td style="text-align: left;">4</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">long</td> +<td style="text-align: left;">4</td> +<td style="text-align: left;">4</td> +<td style="text-align: left;">8†,4∗</td> +<td style="text-align: left;">8†,4∗</td> +</tr> +<tr class="even"> +<td style="text-align: left;">pointer</td> +<td style="text-align: left;">4</td> +<td style="text-align: left;">4</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">8</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">long long</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">4†,8∗+</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">8</td> +</tr> +<tr class="even"> +<td style="text-align: left;">double</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">4†,8∗+</td> +<td style="text-align: left;">8</td> +<td style="text-align: left;">8</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">long double</td> +<td style="text-align: left;">12†∗,8+,16-</td> +<td style="text-align: left;">4†∗,8+,16-</td> +<td style="text-align: left;">16</td> +<td style="text-align: left;">16</td> +</tr> +</tbody> +</table> +<p>† Linux, Darwin<br /> ++armv7l-eabi<br /> +- MacOsX-32bit-gcc4<br /> +∗ Windows</p> +<h2 id="struct-mapping">Struct Mapping</h2> +<p>A <em>Struct</em> is a C compound type declaration, which can be +mapped to a Java class.</p> +<p>A <em>Struct</em> may utilize the following data types for its +fields</p> +<ul> +<li><em>Primitive</em>, i.e. <em>char</em>, <em>int32_t</em>, ... +<ul> +<li>See <a href="#primitive-mapping"><em>Primitive Mapping</em></a> +above.</li> +<li>See <a href="#string-mapping"><em>String Mapping</em></a> +above.</li> +</ul></li> +<li><em>Struct</em>, i.e. another compound variable</li> +<li><em>Function Pointer</em>, a <em>typedef</em>'ed and set callable +function pointer</li> +</ul> +<p>A field may be a direct aggregation, i.e. instance, within the struct +including an array or a reference to a single element or array via a +pointer.</p> +<p>Both, <em>primitive</em> and <em>struct</em> field type mappings only +produce pure Java code, utilizing the <em>GlueGen Runtime</em>. Hence no +additional native code must be compiled nor a resulting additional +library loaded to use the mapping.</p> +<p>Only when mapping <em>function-pointer</em> within <em>structs</em>, +additional native glue-code is produced to call the underlying native +function which has to be compiled and its library loaded.</p> +<p>The generated method +<code>public static boolean usesNativeCode()</code> can be used to +validate whether the produced Java class requires a corresponding +library for additional native code.</p> +<h3 id="gluegen-struct-settings">GlueGen Struct Settings</h3> +<h4 id="immutableaccess-symbol"><strong>ImmutableAccess</strong> +<em>symbol</em></h4> +<p>Immutable access can be set for a whole struct or a single field of a +struct.</p> +<p>Immutable access will simply suppress generating setters in the Java +code and hence also reduces the footprint of the generated Java class +for such struct.</p> +<ul> +<li><p><code>ImmutableAccess TK_Struct</code></p> +<p>Immutable access for the whole struct `TK_Struct</p> +<p>Sets pseudo-code flag <em>ImmutableAccess</em>, see below.</p></li> +<li><p><code>ImmutableAccess TK_Struct.val</code></p> +<p>Immutable access for the single field <code>val</code> within struct +<code>TK_Struct</code></p> +<p>Sets pseudo-code flag <em>ImmutableAccess</em>, see below.</p></li> +</ul> +<h4 id="maxoneelement-symbol"><strong>MaxOneElement</strong> +<em>symbol</em></h4> +<ul> +<li><p><code>MaxOneElement TK_Struct.val</code></p> +<p>Sets field pointer <code>val</code> to point to a array with a +maximum of one element and unset initial value (zero elements).</p> +<p>Sets pseudo-code flag <em>MaxOneElement</em>, see below.</p></li> +</ul> +<h4 +id="returnedarraylength-symbol-expression"><strong>ReturnedArrayLength</strong> +<em>symbol</em> <em>expression</em></h4> +<ul> +<li><p><code>ReturnedArrayLength TK_Struct.val 3</code></p> +<p>Sets field pointer <code>val</code> to point to a array with three +elements.</p> +<p>Sets pseudo-code flag <em>ConstElemCount</em>, see below.</p> +<p>Having set <em>ConstElemCount</em> also implies <em>native +ownership</em> for a <em>Pointer</em> referenced <em>native</em> +memory.</p></li> +<li><p><code>ReturnedArrayLength TK_Struct.val 1</code></p> +<p>Sets field pointer <code>val</code> to point to a array with one +element.</p> +<p>Sets pseudo-code flags <em>ConstElemCount</em> and +<em>MaxOneElement</em>, see below.</p> +<p>Having set <em>ConstElemCount</em> also implies <em>native +ownership</em> for a <em>Pointer</em> referenced <em>native</em> +memory.</p></li> +<li><p><code>ReturnedArrayLength TK_Struct.val getValElements()</code></p> +<p>Sets field pointer <code>val</code> to point to a array with a +variable length as described by the field <code>valElements</code> +retrievable via its getter <code>getValElements()</code>.</p> +<p>Sets pseudo-code flag <em>VariaElemCount</em>, see below.</p></li> +</ul> +<h4 id="returnsstring-symbol"><strong>ReturnsString</strong> +<em>symbol</em></h4> +<p>A direct C code <code>char</code> array or indirect array via pointer +can be interpreted as a Java <code>String</code>.</p> +<ul> +<li><p><code>ReturnsString TK_Struct.name</code></p> +<p>Sets field char-array or char-pointer <code>name</code> to be +additionally interpreted as a Java <code>String</code>. Besides the +<code>byte[]</code> and <code>ByteBuffer</code> getter and setter +variants, a <code>String</code> variant will be added.</p> +<p>Sets pseudo-code flags <em>String</em>, see below.</p> +<p>See <a href="#string-mapping"><em>String Mapping</em></a> +above.</p></li> +</ul> +<h4 id="returnsstringonly-symbol"><strong>ReturnsStringOnly</strong> +<em>symbol</em></h4> +<ul> +<li><p><code>ReturnsStringOnly TK_Struct.name</code></p> +<p>Sets field char-array or char-pointer <code>name</code> to be +exclusively interpreted as a Java <code>String</code>. Instead of the +<code>byte[]</code> and <code>ByteBuffer</code> getter and setter +variants, a <code>String</code> variant will be produced.</p> +<p>Sets pseudo-code flags <em>StringOnly</em>, see below.</p> +<p>See <a href="#string-mapping"><em>String Mapping</em></a> +above.</p></li> +</ul> +<h3 id="struct-mapping-notes">Struct Mapping Notes</h3> +<ul> +<li><p><em>ConstElemCount</em> via <strong>ReturnedArrayLength +<int></strong> implies <em>native ownership</em> for a +<em>Pointer</em> referenced <em>native</em> memory if the expression is +constant. Otherwise the <em>native</em> memory has <em>java +ownership</em>. See <a +href="#returnedarraylength-symbol-expression">ReturnedArrayLength +Setting</a> above.</p></li> +<li><p>To release native memory with <em>java ownership</em>, i.e. a +native ByteBuffer, <code>releaseVal()</code> can be used.</p></li> +<li><p>To shrink a <em>Pointer</em> & <em>VariaElemCount</em> +pointer-array elemCount size with <em>java ownership</em> , the memory +must be cleared with <code>releaseVal()</code> first. This is due to +<code>setVal(src, srcPos, destPos, len)</code> reusing the existing +memory in case <code>destPos + len < elemCount</code>.</p></li> +</ul> +<h3 id="struct-java-signature-table">Struct Java Signature Table</h3> +<p>Please find below signature table as generated by the <em>C +Declaration</em> including its <em>C Modifier</em>, e.g. +<code>const</code> for constant, <code>[const]</code> for const and +non-const and <code>empty</code> for non-const (variable).</p> +<p>Further, the <em>GlueGen Setting</em> (see above) impacts the code +generation as well.</p> +<p>Below table demonstrates <em>primitive</em> types being mapped within +a <code>struct</code> named <code>TK_Struct</code>. A similar mapping is +produced for <code>struct</code> types, i.e. <em>compounds</em>.</p> +<table> +<thead> +<tr class="header"> +<th style="text-align: left;">C Mod</th> +<th style="text-align: left;">C Declaration</th> +<th style="text-align: left;">Java Setter</th> +<th style="text-align: left;">Java Getter</th> +<th style="text-align: left;">GlueGen Setting</th> +<th style="text-align: left;">Ownership</th> +<th style="text-align: left;">Remarks</th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">static boolean usesNativeCode()</td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Java, static, <br> <em>true</em> if using +native code</td> +</tr> +<tr class="even"> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">static int size()</td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Java, static, <br> native size in +bytes</td> +</tr> +<tr class="odd"> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">static TK_Struct create()</td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Java, static ctor</td> +</tr> +<tr class="even"> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">static TK_Struct create(ByteBuffer)</td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Java, static ctor <br> w/ existing +ByteBuffer</td> +</tr> +<tr class="odd"> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">static TK_Struct derefPointer(long +addr)</td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Java, static ctor <br> dereferencing +ByteBuffer <br> at native address of size()</td> +</tr> +<tr class="even"> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">ByteBuffer getBuffer()</td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Java, <br> underlying ByteBuffer</td> +</tr> +<tr class="odd"> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">long getDirectBufferAddress()</td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Java, native address <br> of underlying +getBuffer()</td> +</tr> +<tr class="even"> +<td style="text-align: left;"></td> +<td style="text-align: left;">int32_t val</td> +<td style="text-align: left;">setVal(int v)</td> +<td style="text-align: left;">int getVal()</td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Static</td> +<td style="text-align: left;"></td> +</tr> +<tr class="odd"> +<td style="text-align: left;">const</td> +<td style="text-align: left;">int32_t val</td> +<td style="text-align: left;"><em>none</em></td> +<td style="text-align: left;">int getVal()</td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Static</td> +<td style="text-align: left;">Read only</td> +</tr> +<tr class="even"> +<td style="text-align: left;"></td> +<td style="text-align: left;">int32_t val</td> +<td style="text-align: left;"><em>none</em></td> +<td style="text-align: left;">int getVal()</td> +<td style="text-align: left;"><strong>ImmutableAccess</strong></td> +<td style="text-align: left;">Static</td> +<td style="text-align: left;">Read only</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">[const]</td> +<td style="text-align: left;">int32_t* val</td> +<td style="text-align: left;">setVal(int v) <br> releaseVal()</td> +<td style="text-align: left;">int getVal() <br> boolean isValNull() <br> +int getValElemCount()</td> +<td style="text-align: left;"><strong>MaxOneElement</strong></td> +<td style="text-align: left;">Java</td> +<td style="text-align: left;">Starts w/ null elements,<br>max 1 +element</td> +</tr> +<tr class="even"> +<td style="text-align: left;">const</td> +<td style="text-align: left;">int32_t* val</td> +<td style="text-align: left;"><em>none</em></td> +<td style="text-align: left;">int getVal() <br> boolean isValNull() <br> +static int getValElemCount()</td> +<td style="text-align: left;"><strong>ReturnedArrayLength +1</strong></td> +<td style="text-align: left;">Native</td> +<td style="text-align: left;">Const element count 1</td> +</tr> +<tr class="odd"> +<td style="text-align: left;"></td> +<td style="text-align: left;">int32_t* val</td> +<td style="text-align: left;">setVal(int v)</td> +<td style="text-align: left;">int getVal() <br> boolean isValNull() <br> +static int getValElemCount()</td> +<td style="text-align: left;"><strong>ReturnedArrayLength +1</strong></td> +<td style="text-align: left;">Native</td> +<td style="text-align: left;">Const element count 1</td> +</tr> +<tr class="even"> +<td style="text-align: left;"></td> +<td style="text-align: left;">int32_t val[3]</td> +<td style="text-align: left;">setVal(int[] src, int srcPos, int destPos, +int len)</td> +<td style="text-align: left;">IntBuffer getVal() <br> int[] getVal(int +srcPos, int[] dest, int destPos, int len)</td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Static</td> +<td style="text-align: left;"></td> +</tr> +<tr class="odd"> +<td style="text-align: left;">const</td> +<td style="text-align: left;">int32_t val[3]</td> +<td style="text-align: left;"><em>none</em></td> +<td style="text-align: left;">IntBuffer getVal() <br> int[] getVal(int +srcPos, int[] dest, int destPos, int len)</td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Static</td> +<td style="text-align: left;">Read only</td> +</tr> +<tr class="even"> +<td style="text-align: left;">const</td> +<td style="text-align: left;">int32_t* val</td> +<td style="text-align: left;"><em>none</em></td> +<td style="text-align: left;">IntBuffer getVal() <br> int[] getVal(int +srcPos, int[] dest, int destPos, int len) <br> boolean isValNull() <br> +static int getValElemCount()</td> +<td style="text-align: left;"><strong>ReturnedArrayLength +3</strong></td> +<td style="text-align: left;">Native</td> +<td style="text-align: left;">Read only <br> Const element count 3</td> +</tr> +<tr class="odd"> +<td style="text-align: left;"></td> +<td style="text-align: left;">int32_t* val</td> +<td style="text-align: left;">setVal(int[] src, int srcPos, int destPos, +int len)</td> +<td style="text-align: left;">IntBuffer getVal() <br> int[] getVal(int +srcPos, int[] dest, int destPos, int len) <br> boolean isValNull() <br> +static int getValElemCount()</td> +<td style="text-align: left;"><strong>ReturnedArrayLength +3</strong></td> +<td style="text-align: left;">Native</td> +<td style="text-align: left;">Const element count 3</td> +</tr> +<tr class="even"> +<td style="text-align: left;">[const]</td> +<td style="text-align: left;">int32_t* val</td> +<td style="text-align: left;">setVal(int[] src, int srcPos, int destPos, +int len) <br> releaseVal()</td> +<td style="text-align: left;">IntBuffer getVal() <br> int[] getVal(int +srcPos, int[] dest, int destPos, int len) <br> boolean isValNull() <br> +int getValElemCount()</td> +<td style="text-align: left;"></td> +<td style="text-align: left;">Java</td> +<td style="text-align: left;">Starts w/ null elements</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">[const]</td> +<td style="text-align: left;">int32_t* val</td> +<td style="text-align: left;">setVal(int[] src, int srcPos, int destPos, +int len) <br> releaseVal()</td> +<td style="text-align: left;">IntBuffer getVal() <br> int[] getVal(int +srcPos, int[] dest, int destPos, int len) <br> boolean isValNull()</td> +<td style="text-align: left;"><strong>ReturnedArrayLength +getValCount()</strong></td> +<td style="text-align: left;"><em>Ambiguous</em></td> +<td style="text-align: left;">Variable element count<br>using field +<em>valCount</em>,<br>which has getter and setter</td> +</tr> +<tr class="even"> +<td style="text-align: left;">[const]</td> +<td style="text-align: left;">char* name</td> +<td style="text-align: left;">setName(String srcVal) <br> +releaseVal()</td> +<td style="text-align: left;">String getName() <br> boolean isNameNull() +<br> int getNameElemCount()</td> +<td style="text-align: left;"><strong>ReturnsStringOnly</strong></td> +<td style="text-align: left;">Java</td> +<td style="text-align: left;">String only, w/ EOS</td> +</tr> +<tr class="odd"> +<td style="text-align: left;">[const]</td> +<td style="text-align: left;">char* name</td> +<td style="text-align: left;">setName(String srcVal) <br> setName(byte[] +src, int srcPos, int destPos, int len) <br> releaseVal()</td> +<td style="text-align: left;">String getNameAsString() <br> ByteBuffer +getName() <br> boolean isNameNull() <br> int getNameElemCount()</td> +<td style="text-align: left;"><strong>ReturnsString</strong></td> +<td style="text-align: left;">Java</td> +<td style="text-align: left;">String and byte access, w/ EOS</td> +</tr> +</tbody> +</table> +<h3 id="struct-setter-pseudo-code">Struct Setter Pseudo-Code</h3> +<ul> +<li><em>ImmutableAccess</em>: Drops setter, immutable</li> +<li><em>Pointer</em> & <em>ConstValue</em> & +<em>ConstElemCount</em>: Drops setter, native ownership on +const-value</li> +<li><em>Array</em> & <em>ConstValue</em> : Drops setter, const-value +array</li> +<li><em>Primitive</em> +<ul> +<li>Single aggregated instance +<ul> +<li>Store value within <em>native</em> memory</li> +</ul></li> +<li><em>Array</em> | <em>Pointer</em> +<ul> +<li><em>MaxOneElement</em> +<ul> +<li><em>Pointer</em> +<ul> +<li><em>ConstValue</em>: Allocate new memory and store value</li> +<li><em>VariaValue</em>: +<ul> +<li><em>ConstElemCount</em>: Reuse <em>native</em> memory and store +value with matching <em>elemCount 1</em>, otherwise Exception</li> +<li><em>VariaElemCount</em>: Reuse <em>native</em> memory and store +value with matching <em>elemCount 1</em>, otherwise allocates new memory +(had <em>elemCount 0</em>)</li> +</ul></li> +</ul></li> +<li><em>Array</em> & <em>VariaValue</em>: Reuse <em>native</em> +memory and store value (has const <em>elemCount 1</em>)</li> +<li><em>else</em>: <em>SKIP</em> setter for const single-primitive +array</li> +</ul></li> +<li><em>AnyElementCount</em> +<ul> +<li><em>String</em> & <em>isByteBuffer</em> & <em>Pointer</em> +<ul> +<li><em>ConstElemCount</em>: Reuse <em>native</em> memory and store +UTF-8 bytes with EOS with matching <em>elemCount</em>, otherwise +Exception +<ul> +<li><em>StringOnly</em>: End, no more setter for this field, otherwise +continue</li> +</ul></li> +<li><em>VariaElemCount</em>: Allocate new <em>native</em> memory and +store UTF-8 bytes with EOS +<ul> +<li><em>StringOnly</em>: End, no more setter for this field, otherwise +continue</li> +</ul></li> +</ul></li> +<li><em>ConstValue</em> +<ul> +<li><em>Pointer</em> +<ul> +<li><em>VariaElemCount</em>: Allocates new <em>native</em> memory and +store value</li> +</ul></li> +<li><em>else</em>: <em>SKIP</em> setter for const primitive array</li> +</ul></li> +<li><em>Array</em> | <em>ConstElemCount</em>: Reuse <em>native</em> +memory and store value with <= <em>elemCount</em>, otherwise +Exception</li> +<li><em>Pointer</em> & <em>VariaElemCount</em>: Reuse +<em>native</em> memory and store value with <= <em>elemCount</em>, +otherwise allocate new <em>native</em> memory</li> +</ul></li> +</ul></li> +</ul></li> +<li><em>Struct</em> ...</li> +</ul> +<h2 id="platform-header-files">Platform Header Files</h2> +<p>GlueGen provides convenient platform headers,<br /> +which can be included in your C header files for native compilation and +GlueGen code generation.</p> +<p>Example:</p> +<pre><code> #include <gluegen_stdint.h> + #include <gluegen_stddef.h> + + uint64_t test64; + size_t size1; + ptrdiff_t ptr1;</code></pre> +<p>To compile this file you have to include the following folder to your +compilers system includes, ie <code>-I</code>:</p> +<pre><code> gluegen/make/stub_includes/platform</code></pre> +<p>To generate code for this file you have to include the following +folder to your GlueGen <code>includeRefid</code> element:</p> +<pre><code> gluegen/make/stub_includes/gluegen</code></pre> +<h2 id="pre-defined-macros">Pre-Defined Macros</h2> +<p>To identity a GlueGen code generation run, GlueGen defines the +following macros:</p> +<pre><code> #define __GLUEGEN__ 2</code></pre> diff --git a/doc/GlueGen_Mapping.md b/doc/GlueGen_Mapping.md new file mode 100644 index 0000000..dcdb51a --- /dev/null +++ b/doc/GlueGen_Mapping.md @@ -0,0 +1,402 @@ +<style> +table, th, td { + border: 1px solid black; +} +</style> + +# GlueGen Native Data & Function Mapping for Java™ + +## References + +- [GlueGen Git Repo](https://jogamp.org/cgit/gluegen.git/about/) +- [GlueGen Java™ API-Doc](https://jogamp.org/deployment/jogamp-next/javadoc/gluegen/javadoc/) +- [GlueGen Manual](https://jogamp.org/gluegen/doc/manual/) +- [GlueGen Project Page](https://jogamp.org/gluegen/www/) +- [How To Build](https://jogamp.org/gluegen/doc/HowToBuild.html) + +## Overview +[GlueGen](https://jogamp.org/gluegen/www/) is a compiler for function and data-structure declarations, +generating Java and JNI C code offline at compile time +and allows using native libraries within your Java application. + +It reads ANSI C header files +and separate configuration files which provide control over many +aspects of the glue code generation. GlueGen uses a complete ANSI C +parser and an internal representation (IR) capable of representing all +C types to represent the APIs for which it generates interfaces. It +has the ability to perform significant transformations on the IR +before glue code emission. + +GlueGen can produce native foreign function bindings to Java as well as +map native data structures to be fully accessible from Java including +potential calls to embedded function pointer. + +GlueGen is also capable to bind even low-level APIs such as the Java Native Interface (JNI) and +the AWT Native Interface (JAWT) back up to the Java programming language. + +GlueGen utilizes [JCPP](https://jogamp.org/cgit/jcpp.git/about/), migrated C preprocessor written in Java. + +GlueGen is used for the [JogAmp](https://jogamp.org) projects +[JOAL](https://jogamp.org/cgit/joal.git/about/), +[JOGL](https://jogamp.org/cgit/jogl.git/about/) and +[JOCL](https://jogamp.org/cgit/jocl.git/). + +GlueGen is part of [the JogAmp project](https://jogamp.org). + +## Primitive Mapping + +Gluegen has build-in types (terminal symbols) for: + +| type | java-bits | native-bits <br> x32 | native bits <br> x64 | type | signed | origin | +|:-----|:----------|:-----------------------|:---------------------|:--------|:-------|:-------| +| void | 0 | 0 | 0 | void | void | ANSI-C | +| char | 8 | 8 | 8 | integer | any | ANSI-C | +| short | 16 | 16 | 16 | integer | any | ANSI-C | +| int | 32 | 32 | 32 | integer | any | ANSI-C | +| long | 64 | 32 | **32**† | integer | any | ANSI-C - Windows | +| long | 64 | 32 | **64** | integer | any | ANSI-C - Unix | +| float | 32 | 32 | 32 | float | signed | ANSI-C | +| double | 64 | 64 | 64 | double | signed | ANSI-C | +| \_\_int32 | 32 | 32 | 32 | integer | any | windows | +| \_\_int64 | 64 | 64 | 64 | integer | any | windows | +| int8\_t | 8 | 8 | 8 | integer | signed | stdint.h | +| uint8\_t | 8 | 8 | 8 | integer | unsigned | stdint.h | +| int16\_t | 16 | 16 | 16 | integer | signed | stdint.h | +| uint16\_t | 16 | 16 | 16 | integer | unsigned | stdint.h | +| int32\_t | 32 | 32 | 32 | integer | signed | stdint.h | +| uint32\_t | 32 | 32 | 32 | integer | unsigned | stdint.h | +| int64\_t | 64 | 64 | 64 | integer | signed | stdint.h | +| uint64\_t | 64 | 64 | 64 | integer | unsigned | stdint.h | +| intptr\_t | 64 | 32 | 64 | integer | signed | stdint.h | +| uintptr\_t | 64 | 32 | 64 | integer | unsigned | stdint.h | +| ptrdiff\_t | 64 | 32 | 64 | integer | signed | stddef.h | +| size\_t | 64 | 32 | 64 | integer | unsigned | stddef.h | +| wchar\_t | 32 | 32 | 32 | integer | signed | stddef.h | + +**Warning:** Try to avoid unspecified bit sized types, especially **long**, since it differs on Unix and Windows! +**Notes:** + +* † Type **long** will result in broken code on Windows, since we don't differentiate the OS and it's bit size is ambiguous. +* Anonymous void-pointer _void\*_ are mapped to NIO _Buffer_. +* Pointers to pointer-size types like _intptr\_t\*_, _uintptr\_t\*_, _ptrdiff\_t\*_ and _size\_t\*_ are mapped to _PointerBuffer_, to reflect the architecture depending storage size. + +### String Mapping + +#### Function return String values +Function return values are currently mapped from `char*` to Java String using *UTF-8* +via JNI function +> `jstring NewStringUTF(JNIEnv *env, const char *bytes)` + +*FIXME*: This might need more flexibility in case UTF-8 is not suitable for 8-bit wide `char` mappings +or wide characters, e.g. for UTF-16 needs to be supported. + +#### Function argument String values +Function argument values are either mapped from `char*` to Java String using *UTF-8* +via JNI function +> `const char * GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)`. + +Alternatively, if a 16-bit wide *character* type has been detected, i.e. *short*, +the native *character* are mapped to Java using *UTF-16* +via JNI function +> `void GetStringRegion(JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf)`. + + +#### Struct String mapping + +String value mapping for `Struct` fields is performed solely from the Java side using *Charset* and is hence most flexible. + +By default, *UTF-8* is being used for getter and setter of String values. +The *Struct* class provides two methods to get and set the used *Charset* for conversion +``` + /** Returns the Charset for this class's String mapping, default is StandardCharsets.UTF_8. */ + public static Charset getCharset() { return _charset; }; + + /** Sets the Charset for this class's String mapping, default is StandardCharsets.UTF_8. */ + public static void setCharset(Charset cs) { _charset = cs; } + +``` + +In case the String length has not been configured via `ReturnedArrayLength`, +it will be dynamically calculated via `strnlen(aptr, max_len)`. +The maximum length default for the `strnlen(..)` operation is 8192 bytes and can be get and set using: +``` + /** Returns the maximum number of bytes to read to determine native string length using `strnlen(..)`, default is 8192. */ + public static int getMaxStrnlen() { return _max_strnlen; }; + + /** Sets the maximum number of bytes to read to determine native string length using `strnlen(..)`, default is 8192. */ + public static void setMaxStrnlen(int v) { _max_strnlen = v; } +``` +*FIXME*: This only works reliable using an 8-bit Charset encoding, e.g. the default *UTF-8*. + +### Alignment for Compound Data + +In general, depending on CPU and it's configuration (OS), alignment is set up for each type (char, short, int, long, ..). + +Compounds (structures) are aligned naturally, i.e. their inner components are aligned +and are itself aligned to it's largest element. + +See: + +* [Wikipedia Data Structure Alignment](http://en.wikipedia.org/wiki/Data_structure_alignment) +* [Wikipedia Data Structure Alignment - Padding](http://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding) +* [Viva64 Data Alignment](http://www.viva64.com/en/l/0021/) +* [Apple: Darwin 64bit Porting - Data Type Size & Alignment](http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/64bitPorting/transition/transition.html#//apple_ref/doc/uid/TP40001064-CH207-SW1) + +#### Simple alignment arithmetic + +Modulo operation, where the 2nd handles the case offset == alignment: + +> padding = ( alignment - ( offset % alignment ) ) % alignment ; +> aligned\_offset = offset + padding ; + +Optimization utilizing alignment as a multiple of 2 `-> x % 2n == x & ( 2n - 1 )` + +> remainder = offset & ( alignment - 1 ) ; +> padding = ( remainder > 0 ) ? alignment - remainder : 0 ; +> aligned\_offset = offset + padding ; + +Without branching, using the 2nd modulo operation for the case offset == alignment: + +> padding = ( alignment - ( offset & ( alignment - 1 ) ) ) & ( alignment - 1 ) ; +> aligned\_offset = offset + padding ; + +See `com.jogamp.gluegen.cgram.types.SizeThunk.align(..)`. + +#### Type Size & Alignment for x86, x86\_64, armv6l-32bit-eabi and Window(mingw/mingw64) + +Runtime query is implemented as follows: +``` + typedef struct { + char fill; // nibble one byte + // padding to align s1: padding_0 + type_t s1; // + } test_struct_type_t; + + padding_0 = sizeof(test_struct_type_t) - sizeof(type_t) - sizeof(char) ; + alignmentOf(type_t) = sizeof(test_struct_type_t) - sizeof(type_t) ; +``` + +| type | size <br> *32 bit* | alignment <br> *32 bit* | size <br> *64 bit* | alignment <br> *64 bit* | +|:------------|:-------------------|:------------------------|:-------------------|:------------------------| +| char | 1 | 1 | 1 | 1 | +| short | 2 | 2 | 2 | 2 | +| int | 4 | 4 | 4 | 4 | +| float | 4 | 4 | 4 | 4 | +| long | 4 | 4 | 8†,4∗ | 8†,4∗ | +| pointer | 4 | 4 | 8 | 8 | +| long long | 8 | 4†,8∗+ | 8 | 8 | +| double | 8 | 4†,8∗+ | 8 | 8 | +| long double | 12†∗,8+,16\- | 4†∗,8+,16\- | 16 | 16 | + +† Linux, Darwin ++armv7l-eabi +\- MacOsX-32bit-gcc4 +∗ Windows + +## Struct Mapping +A *Struct* is a C compound type declaration, which can be mapped to a Java class. + +A *Struct* may utilize the following data types for its fields +* *Primitive*, i.e. *char*, *int32_t*, ... + * See [*Primitive Mapping*](#primitive-mapping) above. + * See [*String Mapping*](#string-mapping) above. +* *Struct*, i.e. another compound variable +* *Function Pointer*, a *typedef*'ed and set callable function pointer + +A field may be a direct aggregation, i.e. instance, within the struct including an array +or a reference to a single element or array via a pointer. + +Both, *primitive* and *struct* field type mappings only produce pure Java code, utilizing the *GlueGen Runtime*. +Hence no additional native code must be compiled nor a resulting additional library loaded to use the mapping. + +Only when mapping *function-pointer* within *structs*, additional native glue-code is produced to +call the underlying native function which has to be compiled and its library loaded. + +The generated method `public static boolean usesNativeCode()` can be used to validate +whether the produced Java class requires a corresponding library for additional native code. + +### GlueGen Struct Settings + +#### **ImmutableAccess** *symbol* +Immutable access can be set for a whole struct or a single field of a struct. + +Immutable access will simply suppress generating setters in the Java code +and hence also reduces the footprint of the generated Java class for such struct. + +* `ImmutableAccess TK_Struct` + + Immutable access for the whole struct `TK_Struct + + Sets pseudo-code flag *ImmutableAccess*, see below. + +* `ImmutableAccess TK_Struct.val` + + Immutable access for the single field `val` within struct `TK_Struct` + + Sets pseudo-code flag *ImmutableAccess*, see below. + +#### **MaxOneElement** *symbol* +* `MaxOneElement TK_Struct.val` + + Sets field pointer `val` + to point to a array with a maximum of one element and unset initial value (zero elements). + + Sets pseudo-code flag *MaxOneElement*, see below. + +#### **ReturnedArrayLength** *symbol* *expression* +* `ReturnedArrayLength TK_Struct.val 3` + + Sets field pointer `val` to point to a array with three elements. + + Sets pseudo-code flag *ConstElemCount*, see below. + + Having set *ConstElemCount* also implies *native ownership* for a *Pointer* referenced *native* memory. + +* `ReturnedArrayLength TK_Struct.val 1` + + Sets field pointer `val` to point to a array with one element. + + Sets pseudo-code flags *ConstElemCount* and *MaxOneElement*, see below. + + Having set *ConstElemCount* also implies *native ownership* for a *Pointer* referenced *native* memory. + +* `ReturnedArrayLength TK_Struct.val getValElements()` + + Sets field pointer `val` to point to a array with a variable length as described by the + field `valElements` retrievable via its getter `getValElements()`. + + Sets pseudo-code flag *VariaElemCount*, see below. + +#### **ReturnsString** *symbol* +A direct C code `char` array or indirect array via pointer can be interpreted as a Java `String`. + +* `ReturnsString TK_Struct.name` + + Sets field char-array or char-pointer `name` to be additionally interpreted as a Java `String`. + Besides the `byte[]` and `ByteBuffer` getter and setter variants, a `String` variant will be added. + + Sets pseudo-code flags *String*, see below. + + See [*String Mapping*](#string-mapping) above. + +#### **ReturnsStringOnly** *symbol* + +* `ReturnsStringOnly TK_Struct.name` + + Sets field char-array or char-pointer `name` to be exclusively interpreted as a Java `String`. + Instead of the `byte[]` and `ByteBuffer` getter and setter variants, a `String` variant will be produced. + + Sets pseudo-code flags *StringOnly*, see below. + + See [*String Mapping*](#string-mapping) above. + +### Struct Mapping Notes + +* *ConstElemCount* via **ReturnedArrayLength \<int\>** implies *native ownership* for a *Pointer* referenced *native* memory + if the expression is constant. Otherwise the *native* memory has *java ownership*. + See [ReturnedArrayLength Setting](#returnedarraylength-symbol-expression) above. + +* To release native memory with *java ownership*, i.e. a native ByteBuffer, `releaseVal()` can be used. + +* To shrink a *Pointer* & *VariaElemCount* pointer-array elemCount size with *java ownership* , + the memory must be cleared with `releaseVal()` first. This is due to `setVal(src, srcPos, destPos, len)` + reusing the existing memory in case `destPos + len < elemCount`. + +### Struct Java Signature Table + +Please find below signature table as generated by the *C Declaration* including its *C Modifier*, +e.g. `const` for constant, `[const]` for const and non-const and `empty` for non-const (variable). + +Further, the *GlueGen Setting* (see above) impacts the code generation as well. + +Below table demonstrates *primitive* types being mapped within a `struct` named `TK_Struct`. +A similar mapping is produced for `struct` types, i.e. *compounds*. + + +| C Mod | C Declaration | Java Setter | Java Getter | GlueGen Setting | Ownership | Remarks | +|:--------|:--------------|:-----------------------------------------------------------------|:--------------------------------------|:-----------------------------------------------|:----------|:----------| +| | | | static boolean usesNativeCode() | | | Java, static, <br> *true* if using native code | +| | | | static int size() | | | Java, static, <br> native size in bytes | +| | | | static TK_Struct create() | | | Java, static ctor | +| | | | static TK_Struct create(ByteBuffer) | | | Java, static ctor <br> w/ existing ByteBuffer | +| | | | static TK_Struct derefPointer(long addr) | | | Java, static ctor <br> dereferencing ByteBuffer <br> at native address of size() | +| | | | ByteBuffer getBuffer() | | | Java, <br> underlying ByteBuffer | +| | | | long getDirectBufferAddress() | | | Java, native address <br> of underlying getBuffer() | +| | int32_t val | setVal(int v) | int getVal() | | Static | | +| const | int32_t val | *none* | int getVal() | | Static | Read only | +| | int32_t val | *none* | int getVal() | **ImmutableAccess** | Static | Read only | +| [const] | int32_t* val | setVal(int v) <br> releaseVal() | int getVal() <br> boolean isValNull() <br> int getValElemCount() | **MaxOneElement** | Java | Starts w/ null elements,<br>max 1 element | +| const | int32_t* val | *none* | int getVal() <br> boolean isValNull() <br> static int getValElemCount() | **ReturnedArrayLength 1** | Native | Const element count 1 | +| | int32_t* val | setVal(int v) | int getVal() <br> boolean isValNull() <br> static int getValElemCount() | **ReturnedArrayLength 1** | Native | Const element count 1 | | +| | int32_t val[3]| setVal(int[] src, int srcPos, int destPos, int len) | IntBuffer getVal() <br> int[] getVal(int srcPos, int[] dest, int destPos, int len) | | Static | | +| const | int32_t val[3]| *none* | IntBuffer getVal() <br> int[] getVal(int srcPos, int[] dest, int destPos, int len) | | Static | Read only | +| const | int32_t* val | *none* | IntBuffer getVal() <br> int[] getVal(int srcPos, int[] dest, int destPos, int len) <br> boolean isValNull() <br> static int getValElemCount() | **ReturnedArrayLength 3** | Native | Read only <br> Const element count 3 | +| | int32_t* val | setVal(int[] src, int srcPos, int destPos, int len) | IntBuffer getVal() <br> int[] getVal(int srcPos, int[] dest, int destPos, int len) <br> boolean isValNull() <br> static int getValElemCount() | **ReturnedArrayLength 3** | Native | Const element count 3 | +| [const] | int32_t* val | setVal(int[] src, int srcPos, int destPos, int len) <br> releaseVal() | IntBuffer getVal() <br> int[] getVal(int srcPos, int[] dest, int destPos, int len) <br> boolean isValNull() <br> int getValElemCount() | | Java | Starts w/ null elements | +| [const] | int32_t* val | setVal(int[] src, int srcPos, int destPos, int len) <br> releaseVal() | IntBuffer getVal() <br> int[] getVal(int srcPos, int[] dest, int destPos, int len) <br> boolean isValNull() | **ReturnedArrayLength getValCount()** | *Ambiguous* | Variable element count<br>using field *valCount*,<br>which has getter and setter | +| [const] | char* name | setName(String srcVal) <br> releaseVal() | String getName() <br> boolean isNameNull() <br> int getNameElemCount() | **ReturnsStringOnly** | Java | String only, w/ EOS | +| [const] | char* name | setName(String srcVal) <br> setName(byte[] src, int srcPos, int destPos, int len) <br> releaseVal() | String getNameAsString() <br> ByteBuffer getName() <br> boolean isNameNull() <br> int getNameElemCount() | **ReturnsString** | Java | String and byte access, w/ EOS| + +### Struct Setter Pseudo-Code + +* *ImmutableAccess*: Drops setter, immutable +* *Pointer* & *ConstValue* & *ConstElemCount*: Drops setter, native ownership on const-value +* *Array* & *ConstValue* : Drops setter, const-value array +* *Primitive* + * Single aggregated instance + * Store value within *native* memory + * *Array* | *Pointer* + * *MaxOneElement* + * *Pointer* + * *ConstValue*: Allocate new memory and store value + * *VariaValue*: + * *ConstElemCount*: Reuse *native* memory and store value with matching *elemCount 1*, otherwise Exception + * *VariaElemCount*: Reuse *native* memory and store value with matching *elemCount 1*, otherwise allocates new memory (had *elemCount 0*) + * *Array* & *VariaValue*: Reuse *native* memory and store value (has const *elemCount 1*) + * *else*: *SKIP* setter for const single-primitive array + * *AnyElementCount* + * *String* & *isByteBuffer* & *Pointer* + * *ConstElemCount*: Reuse *native* memory and store UTF-8 bytes with EOS with matching *elemCount*, otherwise Exception + * *StringOnly*: End, no more setter for this field, otherwise continue + * *VariaElemCount*: Allocate new *native* memory and store UTF-8 bytes with EOS + * *StringOnly*: End, no more setter for this field, otherwise continue + * *ConstValue* + * *Pointer* + * *VariaElemCount*: Allocates new *native* memory and store value + * *else*: *SKIP* setter for const primitive array + * *Array* | *ConstElemCount*: Reuse *native* memory and store value with <= *elemCount*, otherwise Exception + * *Pointer* & *VariaElemCount*: Reuse *native* memory and store value with <= *elemCount*, otherwise allocate new *native* memory +* *Struct* ... + + +## Platform Header Files + +GlueGen provides convenient platform headers, +which can be included in your C header files for native compilation and GlueGen code generation. + +Example: +``` + #include <gluegen_stdint.h> + #include <gluegen_stddef.h> + + uint64_t test64; + size_t size1; + ptrdiff_t ptr1; +``` + +To compile this file you have to include the following folder to your compilers system includes, ie `-I`: +``` + gluegen/make/stub_includes/platform +``` + +To generate code for this file you have to include the following folder to your GlueGen `includeRefid` element: +``` + gluegen/make/stub_includes/gluegen +``` + +## Pre-Defined Macros + +To identity a GlueGen code generation run, GlueGen defines the following macros: +``` + #define __GLUEGEN__ 2 +``` diff --git a/doc/JogAmpMacOSVersions.html b/doc/JogAmpMacOSVersions.html new file mode 100644 index 0000000..22c2351 --- /dev/null +++ b/doc/JogAmpMacOSVersions.html @@ -0,0 +1,568 @@ +<style> +div#header, header + { + + border-bottom: 1px solid #aaa; + margin-bottom: 0.5em; + } + +.title + { + text-align: center; + } + +.author, .date + { + text-align: center; + } + +div#TOC, nav#TOC + { + + border-bottom: 1px solid #aaa; + margin-bottom: 0.5em; + } + +nav#TOC { + margin-bottom: var(--line-height); + + padding-bottom: 0.5rem; +} + +nav#TOC input { + display: none; +} + +nav#TOC label { + color: var(--color-link); + cursor: pointer; +} + +nav#TOC > ul { + display: none; +} + +nav#TOC > input:checked + ul { + display: block; +} + +@media print + { + div#TOC, nav#TOC + { + + display: none; + } + } + +div.content + { + color: #111111; + font-size: 14px; + line-height: 1.6; + } + +div#cgit a + { + color: #1212a0; + } + +div#cgit a.sourceLine + { + color: #111111; + } + +h1, h2, h3, h4, h5, h6 +{ + font-family: "Helvetica Neue", Helvetica, "Liberation Sans", Calibri, Arial, sans-serif; + + page-break-after: avoid; + + margin: 20px 0 10px; + padding: 0; +} + +h2 { + border-bottom: 1px solid #ccc; +} + +div div + { + + } + +section section + { + margin-left: 2em; + } + +p {} + +blockquote + { + font-style: italic; + } + +li + { + } + +li > p + { + margin-top: 1em; + } + +ul + { + } + +ul li + { + } + +ol + { + } + +ol li + { + } + +hr {} + +sub + { + } + +sup + { + } + +em + { + } + +em > em + { + font-style: normal; + } + +strong + { + } + +a + { + + text-decoration: none; + } + +@media screen + { + a:hover + { + + text-decoration: underline; + } + } + +@media print + { + a { + + color: black; + background: transparent; + } + + a[href^="http://"]:after, a[href^="https://"]:after + { + + content: " (" attr(href) ") "; + font-size: 90%; + } + } + +img + { + + vertical-align: middle; + } + +div.figure + { + + margin-left: auto; + margin-right: auto; + text-align: center; + font-style: italic; + } + +p.caption + { + + } + +pre, code + { + background-color: #f8f8f8; + + white-space: pre-wrap; + white-space: -moz-pre-wrap !important; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; + + } + +pre + { + + padding: 0.5em; + border-radius: 5px; + + background-color: #f8f8f8; + border: 1px solid #ccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + + margin-left: 0.5em; + margin-right: 0.5em; + } + +@media screen + { + pre + { + + white-space: pre; + overflow: auto; + + border: 1px dotted #777; + } + } + +code + { + } + +p > code, li > code + { + + padding-left: 2px; + padding-right: 2px; + } + +li > p code + { + + padding: 2px; + } + +span.math + { + + } + +div.math + { + } + +span.LaTeX + { + } + +eq + { + } + +table + { + border-collapse: collapse; + border-spacing: 0; + + margin-left: auto; + margin-right: auto; + } + +thead + { + border-bottom: 1pt solid #000; + background-color: #eee; + } + +tr.header + { + } + +tbody + { + } + +tr { + } +tr.odd:hover, tr.even:hover + { + background-color: #eee; + } + +tr.odd {} +tr.even {} + +td, th + { + vertical-align: top; + vertical-align: baseline; + padding-left: 0.5em; + padding-right: 0.5em; + padding-top: 0.2em; + padding-bottom: 0.2em; + } +th + { + font-weight: bold; + } + +tfoot + { + } + +caption + { + caption-side: top; + border: none; + font-size: 0.9em; + font-style: italic; + text-align: center; + margin-bottom: 0.3em; + padding-bottom: 0.2em; + } + +dl + { + border-top: 2pt solid black; + padding-top: 0.5em; + border-bottom: 2pt solid black; + } + +dt + { + font-weight: bold; + } + +dd+dt + { + border-top: 1pt solid black; + padding-top: 0.5em; + } + +dd + { + margin-bottom: 0.5em; + } + +dd+dd + { + border-top: 1px solid black; + } + +a.footnote, a.footnoteRef { + font-size: small; + vertical-align: text-top; +} + +a[href^="#fnref"], a.reversefootnote + { + } + +@media print + { + a[href^="#fnref"], a.reversefootnote + { + + display: none; + } + } + +div.footnotes + { + } + +div.footnotes li[id^="fn"] + { + } + +@media print + { + .noprint + { + display:none; + } + } +</style> + +<nav id="TOC" role="doc-toc"> + <strong>Contents</strong><label for="contents">⊕</label> + <input type="checkbox" id="contents"> + <ul> + <li><a href="#jogamps-macos-version-support">JogAmp's MacOS Version + Support</a> + <ul> + <li><a href="#overview">Overview</a></li> + <li><a href="#openjdk">OpenJDK</a></li> + <li><a href="#jogamp-build-and-test-setup">JogAmp Build and Test + Setup</a> + <ul> + <li><a href="#macos-1265-monterey-darwin-21-x86_64">MacOS 12.6.5 + (Monterey), Darwin 21, <code>x86_64</code></a></li> + <li><a href="#macos-10136-high-sierra-darwin-17-x86_64">MacOS 10.13.6 + (High Sierra), Darwin 17, <code>x86_64</code></a></li> + <li><a href="#macos-131-ventura-darwin-22-arm64">MacOS 13.1 (Ventura), + Darwin 22, <code>arm64</code></a></li> + </ul></li> + <li><a href="#change-history">Change History</a></li> + </ul></li> + </ul> +</nav> + +<style> +table, th, td { + border: 1px solid black; +} +</style> + +<h1 id="jogamps-macos-version-support">JogAmp's MacOS Version +Support</h1> +<p>References</p> +<ul> +<li><a href="https://en.wikipedia.org/wiki/MacOS_version_history">Mac OS +Version History (wiki)</a>.</li> +<li><a +href="https://en.wikipedia.org/wiki/Xcode#Version_comparison_table">Xcode +Version Comparison Table (wiki)</a></li> +</ul> +<h2 id="overview">Overview</h2> +<table> +<thead> +<tr class="header"> +<th style="text-align: left;">MacOS Version</th> +<th style="text-align: left;">Release Name</th> +<th style="text-align: left;">Darwin Version</th> +<th style="text-align: left;">JogAmp Relation</th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<td style="text-align: left;">10.7</td> +<td style="text-align: left;">Lion</td> +<td style="text-align: left;">11</td> +<td style="text-align: left;">Min deployment target</td> +</tr> +<tr class="even"> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +</tr> +<tr class="odd"> +<td style="text-align: left;">10.13</td> +<td style="text-align: left;">High Sierra</td> +<td style="text-align: left;">17</td> +<td style="text-align: left;">Test node 10.13.6, +<code>x86_64</code></td> +</tr> +<tr class="even"> +<td style="text-align: left;">10.14</td> +<td style="text-align: left;">Mojave</td> +<td style="text-align: left;">18</td> +<td style="text-align: left;"></td> +</tr> +<tr class="odd"> +<td style="text-align: left;">10.15</td> +<td style="text-align: left;">Catalina</td> +<td style="text-align: left;">19</td> +<td style="text-align: left;"></td> +</tr> +<tr class="even"> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +<td style="text-align: left;"></td> +</tr> +<tr class="odd"> +<td style="text-align: left;">11</td> +<td style="text-align: left;">Big Sur</td> +<td style="text-align: left;">20</td> +<td style="text-align: left;"></td> +</tr> +<tr class="even"> +<td style="text-align: left;">12</td> +<td style="text-align: left;">Monterey</td> +<td style="text-align: left;">21</td> +<td style="text-align: left;">Build node 12.6.5, w/ Xcode 14.2, +<code>x86_64</code></td> +</tr> +<tr class="odd"> +<td style="text-align: left;">13</td> +<td style="text-align: left;">Ventura</td> +<td style="text-align: left;">22</td> +<td style="text-align: left;">Test node 13.1, <code>arm64</code></td> +</tr> +</tbody> +</table> +<h2 id="openjdk">OpenJDK</h2> +<p>Available Java(tm) VMs</p> +<ul> +<li><a href="http://openjdk.java.net/">OpenJDK</a> build @ <a +href="https://adoptium.net/temurin/releases/">Adoptium</a> +<ul> +<li><a href="https://adoptium.net/supported-platforms/">Adoptium +Supported MacOS Versions</a> +<ul> +<li>MacOS 10.15, 11, 12, 13 for <code>x86_64</code> and +<code>arm64</code></li> +</ul></li> +</ul></li> +</ul> +<h2 id="jogamp-build-and-test-setup">JogAmp Build and Test Setup</h2> +<h3 id="macos-1265-monterey-darwin-21-x86_64">MacOS 12.6.5 (Monterey), +Darwin 21, <code>x86_64</code></h3> +<ul> +<li>Build and main test machine</li> +<li>XCode 14.2 w/ SDK 11.3 +<ul> +<li><code>export SDKROOT=macosx11.3</code> (<em>MacOS SDK</em>)</li> +<li><code>-mmacosx-version-min=10.7</code> (<em>Miniumum deployment +target</em>)</li> +</ul></li> +<li>OpenJDK Temurin 17.0.5+8</li> +</ul> +<h3 id="macos-10136-high-sierra-darwin-17-x86_64">MacOS 10.13.6 (High +Sierra), Darwin 17, <code>x86_64</code></h3> +<ul> +<li>Test machine</li> +<li>OpenJDK Temurin 17.0.5+8</li> +</ul> +<h3 id="macos-131-ventura-darwin-22-arm64">MacOS 13.1 (Ventura), Darwin +22, <code>arm64</code></h3> +<ul> +<li>Test machine</li> +<li>OpenJDK Temurin 17.0.5+8</li> +</ul> +<h2 id="change-history">Change History</h2> +<table> +<thead> +<tr class="header"> +<th style="text-align: left;">Date</th> +<th style="text-align: left;">Note</th> +</tr> +</thead> +<tbody> +<tr class="odd"> +<td style="text-align: left;">2023-05-06</td> +<td style="text-align: left;">Initial Version for JogAmp Release +2.5.0</td> +</tr> +</tbody> +</table> diff --git a/doc/JogAmpMacOSVersions.md b/doc/JogAmpMacOSVersions.md index 924c53f..58eb199 100644 --- a/doc/JogAmpMacOSVersions.md +++ b/doc/JogAmpMacOSVersions.md @@ -1,4 +1,10 @@ -# MacOS Versions Related to JogAmp +<style> +table, th, td { + border: 1px solid black; +} +</style> + +# JogAmp's MacOS Version Support References diff --git a/make/build-test.xml b/make/build-test.xml index 85437f6..3a72ebd 100644 --- a/make/build-test.xml +++ b/make/build-test.xml @@ -165,6 +165,7 @@ <javac destdir="${build_t.java}" fork="yes" includeAntRuntime="false" + nativeheaderdir="${build_t.gen}/native/" memoryMaximumSize="${javac.memorymax}" encoding="UTF-8" source="${target.sourcelevel}" @@ -522,9 +523,9 @@ chmod 644 ${results}/* \${line.separator} --> - <target name="java.generate" depends="junit.test1.java.generate"/> + <target name="java.generate" depends="junit.test1.java.generate, junit.test2.java.generate"/> - <target name="native.build" depends="c.configure, junit.test1.c.build" unless="build.javaonly"> + <target name="native.build" depends="c.configure, junit.test1.c.build, junit.test2.c.build" unless="build.javaonly"> <antcall target="gluegen.cpptasks.striplibs" inheritRefs="true"> <param name="libdir" value="${build_t.lib}"/> </antcall> @@ -562,8 +563,8 @@ chmod 644 ${results}/* \${line.separator} includeRefid="stub.includes.fileset.test" emitter="com.jogamp.gluegen.JavaEmitter" dumpCPP="false" - debug="false" - logLevel="WARNING"> + debug="true" + logLevel="INFO"> <classpath refid="gluegen.classpath" /> </gluegen> <antcall target="java.generate.copy2temp" inheritRefs="true" /> @@ -588,7 +589,7 @@ chmod 644 ${results}/* \${line.separator} emitter="com.jogamp.gluegen.procaddress.ProcAddressEmitter" dumpCPP="false" debug="false" - logLevel="INFO"> + logLevel="WARNING"> <classpath refid="gluegen.classpath" /> </gluegen> </target> @@ -657,6 +658,64 @@ chmod 644 ${results}/* \${line.separator} --> + <target name="junit.test2.java.generate"> + <echo message=" - - - junit.test2.java.generate" /> + + <dirset id="stub.includes.fileset.test" dir="."> + <include name="${test.junit.generation.dir}/**"/> + <include name="${stub.includes.dir}/gluegen" /> + <include name="${stub.includes.dir}/macosx" /> + <include name="${stub.includes.dir}/unix" /> + <include name="${stub.includes.dir}/windows" /> + </dirset> + + <gluegen src="${test.junit.generation.dir}/test2.h" + outputRootDir="${build_t.gen}" + config="${test.junit.generation.dir}/test2.cfg" + literalInclude="${test.junit.generation.dir}" + includeRefid="stub.includes.fileset.test" + emitter="com.jogamp.gluegen.procaddress.ProcAddressEmitter" + dumpCPP="false" + debug="false" + logLevel="WARNING"> + <classpath refid="gluegen.classpath" /> + </gluegen> + <antcall target="java.generate.copy2temp" inheritRefs="true" /> + </target> + + <target name="junit.test2.c.build"> + <!-- this is the test2 implementation --> + <patternset id="junit.test2.implc.src.files"> + <include name="src/junit/${test.junit.generation.rel}/test2.c"/> + </patternset> + + <!-- Windows hacks ro make a proper DLL --> + <linker id="linker.test2.dll.cfg.id" extends="${linker.cfg.id}"> + </linker> + + <c.build c.compiler.src.files="junit.test2.implc.src.files" + output.lib.name="test2" + compiler.cfg.id="${compiler.cfg.id}" + linker.cfg.id="linker.test2.dll.cfg.id"/> + + <!-- this is a dynamic lookup binding to the test1 implementation --> + <linker id="linker.test2.runtime.cfg.id" extends="${linker.cfg.id}"> + </linker> + + <patternset id="junit.test2.jnic.src.files"> + <include name="${build_t.gen.rootrel}/native/BindingtestT2Impl_JNI.c"/> + <!-- include name="${build_t.gen.rootrel}/native/TK_Surface_JNI.c"/ --> + <!-- include name="${build_t.gen.rootrel}/native/TK_ModelConst_JNI.c"/ --> + <!-- include name="${build_t.gen.rootrel}/native/TK_ModelMutable_JNI.c"/ --> + </patternset> + + <c.build c.compiler.src.files="junit.test2.jnic.src.files" + output.lib.name="Bindingtest2" + compiler.cfg.id="${compiler.cfg.id}" + linker.cfg.id="linker.test1.runtime.cfg.id"/> + </target> + + <!-- updates / create the test results zip file --> <target name="test-zip-archive" depends="init"> <archive.7z destfile="${build}/${test.archive.name}.7z" 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"; } diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java b/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java index 34cd925..ed23f54 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java @@ -40,6 +40,7 @@ import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.LongBuffer; +import java.nio.charset.Charset; import java.util.Arrays; import jogamp.common.os.MachineDataInfoRuntime; @@ -1252,7 +1253,7 @@ public class BaseClass extends SingletonJunitCase { Assert.assertEquals(2, surface.getClipSize()); - final TK_Dimension[] allclips = surface.getClips(0, new TK_Dimension[surface.getClipSize()]); + final TK_Dimension[] allclips = surface.getClips(0, new TK_Dimension[surface.getClipSize()], 0, surface.getClipSize()); for(int i=0; i<surface.getClipSize(); i++) { final TK_Dimension clip0 = surface.getClip(i); @@ -1262,7 +1263,7 @@ public class BaseClass extends SingletonJunitCase { Assert.assertEquals(0x44444444 * (i+1) + 0x44444444, clip0.getHeight()); final TK_Dimension[] clip1 = new TK_Dimension[1]; - surface.getClips(i, clip1); + surface.getClips(i, clip1, 0, 1); Assert.assertEquals(0x44444444 * (i+1) + 0x11111111, clip1[0].getX()); Assert.assertEquals(0x44444444 * (i+1) + 0x22222222, clip1[0].getY()); Assert.assertEquals(0x44444444 * (i+1) + 0x33333333, clip1[0].getWidth()); @@ -1317,10 +1318,10 @@ public class BaseClass extends SingletonJunitCase { } final TK_DimensionPair dimPair = TK_DimensionPair.create(); - dimPair.setPair(0, sumands); + dimPair.setPair(sumands, 0, 0, sumands.length); { sub++; - final TK_Dimension[] dimsGet = dimPair.getPair(0, new TK_Dimension[2]); + final TK_Dimension[] dimsGet = dimPair.getPair(0, new TK_Dimension[2], 0, 2); assertDim("ch11."+sub+": dimsGet[0] ", 11, 22, 33, 44, dimsGet[0]); assertDim("ch11."+sub+": dimsGet[1] ", 1, 2, 3, 4, dimsGet[1]); } @@ -1388,430 +1389,865 @@ public class BaseClass extends SingletonJunitCase { } } - /** Test array and pointer bindings of structs */ - public void chapter12TestStructArrayModelConst(final Bindingtest1 binding) throws Exception { - final TK_ModelConst model = binding.createModelConst(); + /** Primitive.ConstValue.int32.Pointer - read access */ + private void chapter12_03aTestTKFieldConstValueInt32ReadAccess(final TK_Field model) { + // Primitive.ConstValue.int32.Array - read only + Assert.assertEquals(88, model.getConstInt32ArrayConstOneElem()); + Assert.assertEquals(3, TK_Field.getConstInt32ArrayConstLenElemCount()); + { + final int size = TK_Field.getConstInt32ArrayConstLenElemCount(); + Assert.assertEquals(3, size); + final int[] all = model.getConstInt32ArrayConstLen(0, new int[size], 0, size); + final IntBuffer allB = model.getConstInt32ArrayConstLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); + for(int i=0; i<size; i++) { + Assert.assertEquals(1 + i, all[i]); + Assert.assertEquals(1 + i, allB.get(i)); + final int[] s = model.getConstInt32ArrayConstLen(i /* srcPos */, new int[3] /* dest */, 1 /* destPos */, 1 /* length */); + Assert.assertEquals(1 + i, s[1]); + } + } + + // Primitive.ConstValue.int32.Pointer - read + Assert.assertEquals(1, TK_Field.getConstInt32PointerConstOneElemElemCount()); + Assert.assertEquals(false, model.isConstInt32PointerConstOneElemNull()); + Assert.assertEquals(10, model.getConstInt32PointerConstOneElem()); - Assert.assertEquals(3, model.getIntxxPointerCustomLenVal()); - Assert.assertEquals(3, model.getInt32PointerCustomLenVal()); - Assert.assertEquals(3, TK_ModelConst.getInt32ArrayFixedLenArrayLength()); - Assert.assertEquals(3, TK_ModelConst.getStructArrayFixedLenArrayLength()); - Assert.assertEquals(3, model.getStructPointerCustomLenVal()); + Assert.assertEquals(0, model.getConstInt32PointerMaxOneElemElemCount()); + Assert.assertEquals(true, model.isConstInt32PointerMaxOneElemNull()); + { + Exception e = null; + try { + @SuppressWarnings("unused") + final int i = model.getConstInt32PointerMaxOneElem(); // NULL -> exception + } catch(final Exception _e) { e = _e; } + Assert.assertNotNull(e); + System.err.println("Expected exception: "+e); + } - // field: int32ArrayFixedLen - // CType['int32_t *', size [fixed false, lnx64 12], [array*1]], with array length of 3 + Assert.assertEquals(3, TK_Field.getConstInt32PointerConstLenElemCount()); + Assert.assertEquals(false, model.isConstInt32PointerConstLenNull()); { - final int size = TK_ModelConst.getInt32ArrayFixedLenArrayLength(); - final int[] all = model.getInt32ArrayFixedLen(0, new int[size]); - final IntBuffer allB = model.getInt32ArrayFixedLen(); + final int size = TK_Field.getConstInt32PointerConstLenElemCount(); + Assert.assertEquals(3, size); + final int[] all = model.getConstInt32PointerConstLen(0, new int[size], 0, size); + final IntBuffer allB = model.getConstInt32PointerConstLen(); + Assert.assertEquals(size, all.length); Assert.assertEquals(size, allB.limit()); for(int i=0; i<size; i++) { Assert.assertEquals(21 + i, all[i]); Assert.assertEquals(21 + i, allB.get(i)); - final int[] s = model.getInt32ArrayFixedLen(i, new int[1]); - Assert.assertEquals(21 + i, s[0]); + final int[] s = model.getConstInt32PointerConstLen(i /* srcPos */, new int[3] /* dest */, 2 /* destPos */, 1 /* length */); + Assert.assertEquals(21 + i, s[2]); } } - // field: int32ArrayOneElem - // CType['int32_t *', size [fixed false, lnx64 4], [array*1]], with array length of 1 + Assert.assertEquals(0, model.getConstInt32PointerVariaLenElemCount()); + Assert.assertEquals(true, model.isConstInt32PointerVariaLenNull()); { - Assert.assertEquals(30, model.getInt32ArrayOneElem()); + Exception e1 = null; + try { + @SuppressWarnings("unused") + final IntBuffer ib = model.getConstInt32PointerVariaLen(); // NULL -> exception + } catch(final Exception _e) { e1 = _e; } + Assert.assertNotNull(e1); + System.err.println("Expected exception-1: "+e1); + + Exception e2 = null; + try { + @SuppressWarnings("unused") + final int[] ia = model.getConstInt32PointerVariaLen(0, new int[0], 0, 0); // NULL -> exception + } catch(final Exception _e) { e2 = _e; } + Assert.assertNotNull(e2); + System.err.println("Expected exception-2: "+e2); } - // field: int32PointerCustomLen - // field: CType['int32_t *', size [fixed false, lnx64 8], [pointer*1]], with array length of getInt32PointerCustomLenVal() { - final int size = model.getInt32PointerCustomLenVal(); - final IntBuffer all = model.getInt32PointerCustomLen(); - Assert.assertEquals(size, all.limit()); + final int size = model.getConstInt32PointerCustomLenElemCount(); + Assert.assertEquals(4, size); + Assert.assertEquals(false, model.isConstInt32PointerCustomLenNull()); + final int[] all = model.getConstInt32PointerCustomLen(0, new int[size], 0, size); + final IntBuffer allB = model.getConstInt32PointerCustomLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); for(int i=0; i<size; i++) { - Assert.assertEquals(31 + i, all.get(i)); + Assert.assertEquals(31 + i, all[i]); + Assert.assertEquals(31 + i, allB.get(i)); + final int[] s = model.getConstInt32PointerCustomLen(i /* srcPos */, new int[1] /* dest */, 0 /* destPos */, 1 /* length */); + Assert.assertEquals(31 + i, s[0]); } } + } - // field: int32PointerOneElem - // CType['int32_t *', size [fixed false, lnx64 8], [pointer*1]], with array length of 1 - { - final IntBuffer all = model.getInt32PointerOneElem(); - Assert.assertEquals(1, all.limit()); - Assert.assertEquals(41, all.get(0)); - } - - // field: mat4x4 - // CType['float * *', size [fixed false, lnx64 64], [array*2]], with array length of <code>4*4</code> */ + /** Primitive.ConstValue.int32.Pointer - write access */ + @SuppressWarnings("unused") + private void chapter12_03bTestTKFieldConstValueInt32WriteAccess(final TK_Field model) { + Assert.assertEquals(0, model.getConstInt32PointerMaxOneElemElemCount()); + Assert.assertEquals(true, model.isConstInt32PointerMaxOneElemNull()); + model.setConstInt32PointerMaxOneElem(110); + Assert.assertEquals(1, model.getConstInt32PointerMaxOneElemElemCount()); + Assert.assertEquals(false, model.isConstInt32PointerMaxOneElemNull()); + Assert.assertEquals(110, model.getConstInt32PointerMaxOneElem()); + model.releaseConstInt32PointerMaxOneElem(); + Assert.assertEquals(0, model.getConstInt32PointerMaxOneElemElemCount()); + Assert.assertEquals(true, model.isConstInt32PointerMaxOneElemNull()); + + Assert.assertEquals(3, TK_Field.getConstInt32PointerConstLenElemCount()); + Assert.assertEquals(false, model.isConstInt32PointerConstLenNull()); { - Assert.assertEquals(4*4, TK_ModelConst.getMat4x4ArrayLength()); - final FloatBuffer mat4x4 = model.getMat4x4(); - Assert.assertEquals(4*4, mat4x4.limit()); - for(int i=0; i<4; i++) { - final float[] vec4 = model.getMat4x4(i*4, new float[4]); - for(int j=0; j<4; j++) { - Assert.assertEquals(i*4+j, mat4x4.get(i*4+j), EPSILON); - Assert.assertEquals(i*4+j, vec4[j], EPSILON); + // write 1 via IntBuffer reference get + // FIXME: Sort of violates the contract + { + final IntBuffer ib = model.getConstInt32PointerConstLen(); + Assert.assertEquals(3, ib.limit()); + for(int i=0; i<3; ++i) { + ib.put(i, 120+i); + } + } + // verify 1 + { + final int size = TK_Field.getConstInt32PointerConstLenElemCount(); + Assert.assertEquals(3, size); + final int[] all = model.getConstInt32PointerConstLen(0, new int[size], 0, size); + final IntBuffer allB = model.getConstInt32PointerConstLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); + for(int i=0; i<size; i++) { + Assert.assertEquals(120 + i, all[i]); + Assert.assertEquals(120 + i, allB.get(i)); + final int[] s = model.getConstInt32PointerConstLen(i, new int[1], 0, 1); + Assert.assertEquals(120 + i, s[0]); } } } - // field: structArrayFixedLen - // field: CType['TK_Dimension *', size [fixed false, lnx64 48], [array*1]], with array length of 3 + Assert.assertEquals(0, model.getConstInt32PointerVariaLenElemCount()); + Assert.assertEquals(true, model.isConstInt32PointerVariaLenNull()); { - final int size = TK_ModelConst.getStructArrayFixedLenArrayLength(); - final TK_Dimension[] all = model.getStructArrayFixedLen(0, new TK_Dimension[size]); - for(int i=0; i<size; i++) { - Assert.assertEquals(51 + i * 10, all[i].getX()); - Assert.assertEquals(52 + i * 10, all[i].getY()); - Assert.assertEquals(53 + i * 10, all[i].getWidth()); - Assert.assertEquals(54 + i * 10, all[i].getHeight()); + Exception e1 = null; + try { + @SuppressWarnings("unused") + final IntBuffer ib = model.getConstInt32PointerVariaLen(); // NULL -> exception + } catch(final Exception _e) { e1 = _e; } + Assert.assertNotNull(e1); + System.err.println("Expected exception-1: "+e1); + + Exception e2 = null; + try { + @SuppressWarnings("unused") + final int[] ia = model.getConstInt32PointerVariaLen(0, new int[0], 0, 0); // NULL -> exception + } catch(final Exception _e) { e2 = _e; } + Assert.assertNotNull(e2); + System.err.println("Expected exception-2: "+e2); + } + { + // write 1 via int[] set, also actually allocating initial memory + { + final int[] ia = { 220, 221, 222, 223, 224 }; + model.setConstInt32PointerVariaLen(ia, 0, 0, ia.length); + } + // verify 1 + { + final int size = model.getConstInt32PointerVariaLenElemCount(); + Assert.assertEquals(5, size); + final int[] all = model.getConstInt32PointerVariaLen(0, new int[size], 0, size); + final IntBuffer allB = model.getConstInt32PointerVariaLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); + for(int i=0; i<size; i++) { + Assert.assertEquals(220 + i, all[i]); + Assert.assertEquals(220 + i, allB.get(i)); + final int[] s = model.getConstInt32PointerVariaLen(i, new int[1], 0, 1); + Assert.assertEquals(220 + i, s[0]); + } } + // write 2 via IntBuffer reference get + { + final IntBuffer ib = model.getConstInt32PointerVariaLen(); + Assert.assertEquals(5, ib.limit()); + for(int i=0; i<5; ++i) { + ib.put(i, 120+i); + } + } + // verify 2 + { + final int size = model.getConstInt32PointerVariaLenElemCount(); + Assert.assertEquals(5, size); + final int[] all = model.getConstInt32PointerVariaLen(0, new int[size], 0, size); + final IntBuffer allB = model.getConstInt32PointerVariaLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); + for(int i=0; i<size; i++) { + Assert.assertEquals(120 + i, all[i]); + Assert.assertEquals(120 + i, allB.get(i)); + final int[] s = model.getConstInt32PointerVariaLen(i, new int[1], 0, 1); + Assert.assertEquals(120 + i, s[0]); + } + } + model.releaseConstInt32PointerVariaLen(); + Assert.assertEquals(0, model.getConstInt32PointerVariaLenElemCount()); + Assert.assertEquals(true, model.isConstInt32PointerVariaLenNull()); } - // field: structArrayOneElem - // CType['TK_Dimension *', size [fixed false, lnx64 16], [array*1]], with array length of 1 { - final TK_Dimension all = model.getStructArrayOneElem(); - Assert.assertEquals(81, all.getX()); - Assert.assertEquals(82, all.getY()); - Assert.assertEquals(83, all.getWidth()); - Assert.assertEquals(84, all.getHeight()); + // write 1 via IntBuffer reference get + { + final int size = model.getConstInt32PointerCustomLenElemCount(); + Assert.assertEquals(4, size); + Assert.assertEquals(false, model.isConstInt32PointerCustomLenNull()); + final IntBuffer ib = model.getConstInt32PointerCustomLen(); + Assert.assertEquals(size, ib.limit()); + for(int i=0; i<size; ++i) { + ib.put(i, 120+i); + } + } + // verify 1 + { + final int size = model.getConstInt32PointerCustomLenElemCount(); + Assert.assertEquals(4, size); + final int[] all = model.getConstInt32PointerCustomLen(0, new int[size], 0, size); + final IntBuffer allB = model.getConstInt32PointerCustomLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); + for(int i=0; i<size; i++) { + Assert.assertEquals(120 + i, all[i]); + Assert.assertEquals(120 + i, allB.get(i)); + final int[] s = model.getConstInt32PointerCustomLen(i, new int[1], 0, 1); + Assert.assertEquals(120 + i, s[0]); + } + } + // write 2 via int[] set + { + final int[] ia = { 0, 220, 221, 222, 223, 224, 0 }; + model.setConstInt32PointerCustomLen(ia, 1 /* srcPos */, 0 /* destPos */, ia.length-2); + } + // verify 2 + { + final int size = model.getConstInt32PointerCustomLenElemCount(); + Assert.assertEquals(5, size); + final int[] all = model.getConstInt32PointerCustomLen(0, new int[size], 0, size); + final IntBuffer allB = model.getConstInt32PointerCustomLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); + for(int i=0; i<size; i++) { + Assert.assertEquals(220 + i, all[i]); + Assert.assertEquals(220 + i, allB.get(i)); + final int[] s = model.getConstInt32PointerCustomLen(i, new int[1], 0, 1); + Assert.assertEquals(220 + i, s[0]); + } + } + model.releaseConstInt32PointerCustomLen(); // FIXME: Ownership is ambiguous, may leak native allocated memory, not free'ed! + Assert.assertEquals(0, model.getConstInt32PointerCustomLenElemCount()); + Assert.assertEquals(true, model.isConstInt32PointerCustomLenNull()); } + } - // field: structPointerCustomLen - // CType['TK_Dimension *', size [fixed false, lnx64 8], [pointer*1]], with array length of getStructPointerCustomLenVal() + /** Primitive.VariaValue.int32.Pointer - read access */ + private void chapter12_04aTestTKFieldVariaValueInt32ReadAccess(final TK_Field model) { + // Primitive.ConstValue.int32.Array - read only + Assert.assertEquals(88, model.getVariaInt32ArrayConstOneElem()); + Assert.assertEquals(3, TK_Field.getVariaInt32ArrayConstLenElemCount()); { - final int size = model.getStructPointerCustomLenVal(); - final TK_Dimension[] all = model.getStructPointerCustomLen(0, new TK_Dimension[size]); + final int size = TK_Field.getVariaInt32ArrayConstLenElemCount(); + Assert.assertEquals(3, size); + final int[] all = model.getVariaInt32ArrayConstLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaInt32ArrayConstLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); for(int i=0; i<size; i++) { - Assert.assertEquals(91 + i * 10, all[i].getX()); - Assert.assertEquals(92 + i * 10, all[i].getY()); - Assert.assertEquals(93 + i * 10, all[i].getWidth()); - Assert.assertEquals(94 + i * 10, all[i].getHeight()); + Assert.assertEquals(1 + i, all[i]); + Assert.assertEquals(1 + i, allB.get(i)); + final int[] s = model.getVariaInt32ArrayConstLen(i /* srcPos */, new int[3] /* dest */, 1 /* destPos */, 1 /* length */); + Assert.assertEquals(1 + i, s[1]); } } - // field: structPointerOneElem - // CType['TK_Dimension *', size [fixed false, lnx64 8], [pointer*1]], with array length of 1 - { - final TK_Dimension all = model.getStructPointerOneElem(); - Assert.assertEquals(121, all.getX()); - Assert.assertEquals(122, all.getY()); - Assert.assertEquals(123, all.getWidth()); - Assert.assertEquals(124, all.getHeight()); + // Primitive.ConstValue.int32.Pointer - read + Assert.assertEquals(1, TK_Field.getVariaInt32PointerConstOneElemElemCount()); + Assert.assertEquals(false, model.isVariaInt32PointerConstOneElemNull()); + Assert.assertEquals(10, model.getVariaInt32PointerConstOneElem()); + Assert.assertEquals(0, model.getVariaInt32PointerMaxOneElemElemCount()); + Assert.assertEquals(true, model.isVariaInt32PointerMaxOneElemNull()); + { + Exception e = null; + try { + @SuppressWarnings("unused") + final int i = model.getVariaInt32PointerMaxOneElem(); // NULL -> exception + } catch(final Exception _e) { e = _e; } + Assert.assertNotNull(e); + System.err.println("Expected exception: "+e); } - final long surfaceContext = model.getCtx(); - assertAPTR(0x123456789abcdef0L, surfaceContext); - - model.setCtx(surfaceContext); - assertAPTR(surfaceContext, model.getCtx()); - + Assert.assertEquals(3, TK_Field.getVariaInt32PointerConstLenElemCount()); + Assert.assertEquals(false, model.isVariaInt32PointerConstLenNull()); { - Assert.assertEquals(12, TK_ModelConst.getModelNameArrayFixedLenArrayLength()); - - final ByteBuffer bb = model.getModelNameArrayFixedLen(); - Assert.assertEquals(12, bb.limit()); - - final String exp = "Hello Array"; - final String has = model.getModelNameArrayFixedLenAsString(); - // System.err.println("exp '"+exp+"'"); - System.err.println("has '"+has+"'"); - // dumpStringChars("exp", exp); - dumpStringChars("has", has); - Assert.assertEquals(11, has.length()); // w/o EOS - Assert.assertEquals(exp, has); + final int size = TK_Field.getVariaInt32PointerConstLenElemCount(); + Assert.assertEquals(3, size); + final int[] all = model.getVariaInt32PointerConstLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaInt32PointerConstLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); + for(int i=0; i<size; i++) { + Assert.assertEquals(21 + i, all[i]); + Assert.assertEquals(21 + i, allB.get(i)); + final int[] s = model.getVariaInt32PointerConstLen(i /* srcPos */, new int[3] /* dest */, 2 /* destPos */, 1 /* length */); + Assert.assertEquals(21 + i, s[2]); + } } - { - Assert.assertEquals(14, model.getModelNamePointerCStringArrayLength()); - final ByteBuffer bb = model.getModelNamePointerCString(); - Assert.assertEquals(14, bb.limit()); - - final String exp = "Hello CString"; - final String has = model.getModelNamePointerCStringAsString(); - // System.err.println("exp '"+exp+"'"); - System.err.println("has '"+has+"'"); - // dumpStringChars("exp", exp); - dumpStringChars("has", has); - Assert.assertEquals(13, has.length()); // w/o EOS - Assert.assertEquals(exp, has); - } + Assert.assertEquals(0, model.getVariaInt32PointerVariaLenElemCount()); + Assert.assertEquals(true, model.isVariaInt32PointerVariaLenNull()); { - Assert.assertEquals(14, model.getModelNamePointerCustomLenVal()); - - final ByteBuffer bb = model.getModelNamePointerCustomLen(); - Assert.assertEquals(14, bb.limit()); - - final String exp = "Hello Pointer"; - final String has = model.getModelNamePointerCustomLenAsString(); - // System.err.println("exp '"+exp+"'"); - System.err.println("has '"+has+"'"); - // dumpStringChars("exp", exp); - dumpStringChars("has", has); - Assert.assertEquals(13, has.length()); // w/o EOS - Assert.assertEquals(exp, has); + Exception e1 = null; + try { + @SuppressWarnings("unused") + final IntBuffer ib = model.getVariaInt32PointerVariaLen(); // NULL -> exception + } catch(final Exception _e) { e1 = _e; } + Assert.assertNotNull(e1); + System.err.println("Expected exception-1: "+e1); + + Exception e2 = null; + try { + @SuppressWarnings("unused") + final int[] ia = model.getVariaInt32PointerVariaLen(0, new int[0], 0, 0); // NULL -> exception + } catch(final Exception _e) { e2 = _e; } + Assert.assertNotNull(e2); + System.err.println("Expected exception-2: "+e2); } - binding.destroyModelConst(model); - } - private void dumpStringChars(final String prefix, final String s) { - final int len = s.length(); - for(int i=0; i<len; i++) { - final char c = s.charAt(i); - System.err.printf("%s %3d: 0x%X %c%n", prefix, i, (int)c, c); + { + final int size = model.getVariaInt32PointerCustomLenElemCount(); + Assert.assertEquals(4, size); + Assert.assertEquals(false, model.isVariaInt32PointerCustomLenNull()); + final int[] all = model.getVariaInt32PointerCustomLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaInt32PointerCustomLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); + for(int i=0; i<size; i++) { + Assert.assertEquals(31 + i, all[i]); + Assert.assertEquals(31 + i, allB.get(i)); + final int[] s = model.getVariaInt32PointerCustomLen(i /* srcPos */, new int[1] /* dest */, 0 /* destPos */, 1 /* length */); + Assert.assertEquals(31 + i, s[0]); + } } } - public void chapter13TestStructArrayModelMutable(final Bindingtest1 binding) throws Exception { - final TK_ModelMutable model = binding.createModelMutable(); - - Assert.assertEquals(3, model.getIntxxPointerCustomLenVal()); - Assert.assertEquals(3, model.getInt32PointerCustomLenVal()); - Assert.assertEquals(3, TK_ModelMutable.getInt32ArrayFixedLenArrayLength()); - Assert.assertEquals(3, TK_ModelMutable.getStructArrayFixedLenArrayLength()); - Assert.assertEquals(3, model.getStructPointerCustomLenVal()); - - // field: int32ArrayFixedLen - // CType['int32_t *', size [fixed false, lnx64 12], [array*1]], with array length of 3 + /** Primitive.VariaValue.int32.Pointer - write access */ + @SuppressWarnings("unused") + private void chapter12_04bTestTKFieldVariaValueInt32WriteAccess(final TK_Field model) { + Assert.assertEquals(1, TK_Field.getVariaInt32PointerConstOneElemElemCount()); + Assert.assertEquals(false, model.isVariaInt32PointerConstOneElemNull()); + model.setVariaInt32PointerConstOneElem(109); + Assert.assertEquals(109, model.getVariaInt32PointerConstOneElem()); + + Assert.assertEquals(0, model.getVariaInt32PointerMaxOneElemElemCount()); + Assert.assertEquals(true, model.isVariaInt32PointerMaxOneElemNull()); + model.setVariaInt32PointerMaxOneElem(110); + Assert.assertEquals(1, model.getVariaInt32PointerMaxOneElemElemCount()); + Assert.assertEquals(false, model.isVariaInt32PointerMaxOneElemNull()); + Assert.assertEquals(110, model.getVariaInt32PointerMaxOneElem()); + model.releaseVariaInt32PointerMaxOneElem(); + Assert.assertEquals(0, model.getVariaInt32PointerMaxOneElemElemCount()); + Assert.assertEquals(true, model.isVariaInt32PointerMaxOneElemNull()); + + Assert.assertEquals(3, TK_Field.getVariaInt32PointerConstLenElemCount()); + Assert.assertEquals(false, model.isVariaInt32PointerConstLenNull()); { - final int size = TK_ModelMutable.getInt32ArrayFixedLenArrayLength(); + // write 1 via IntBuffer reference get { - final int[] values = new int[] { 1, 2, 3 }; - model.setInt32ArrayFixedLen(0, values); - - final int[] all = model.getInt32ArrayFixedLen(0, new int[size]); - final IntBuffer allB = model.getInt32ArrayFixedLen(); + final IntBuffer ib = model.getVariaInt32PointerConstLen(); + Assert.assertEquals(3, ib.limit()); + for(int i=0; i<3; ++i) { + ib.put(i, 120+i); + } + } + // verify 1 + { + final int size = TK_Field.getVariaInt32PointerConstLenElemCount(); + Assert.assertEquals(3, size); + final int[] all = model.getVariaInt32PointerConstLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaInt32PointerConstLen(); + Assert.assertEquals(size, all.length); Assert.assertEquals(size, allB.limit()); for(int i=0; i<size; i++) { - Assert.assertEquals(1 + i, all[i]); - Assert.assertEquals(1 + i, allB.get(i)); - final int[] s = model.getInt32ArrayFixedLen(i, new int[1]); - Assert.assertEquals(1 + i, s[0]); + Assert.assertEquals(120 + i, all[i]); + Assert.assertEquals(120 + i, allB.get(i)); + final int[] s = model.getVariaInt32PointerConstLen(i, new int[1], 0, 1); + Assert.assertEquals(120 + i, s[0]); } } + // write 2 via int[] set + { + final int[] ia = { 220, 221, 222 }; + model.setVariaInt32PointerConstLen(ia, 0, 0, ia.length); + } + // verify 2 { + final int size = TK_Field.getVariaInt32PointerConstLenElemCount(); + Assert.assertEquals(3, size); + final int[] all = model.getVariaInt32PointerConstLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaInt32PointerConstLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); for(int i=0; i<size; i++) { - final int[] ia = new int[] { 4 + i }; - model.setInt32ArrayFixedLen(i, ia); + System.err.printf("%d/%d: A %d, B %d%n", i, size, all[i], allB.get(i)); } - - final int[] all = model.getInt32ArrayFixedLen(0, new int[size]); - final IntBuffer allB = model.getInt32ArrayFixedLen(); - Assert.assertEquals(size, allB.limit()); for(int i=0; i<size; i++) { - Assert.assertEquals(4 + i, all[i]); - Assert.assertEquals(4 + i, allB.get(i)); - final int[] s = model.getInt32ArrayFixedLen(i, new int[1]); - Assert.assertEquals(4 + i, s[0]); + Assert.assertEquals(220 + i, all[i]); + Assert.assertEquals(220 + i, allB.get(i)); + final int[] s = model.getVariaInt32PointerConstLen(i, new int[1], 0, 1); + Assert.assertEquals(220 + i, s[0]); } } - } - - // field: int32ArrayOneElem - // CType['int32_t *', size [fixed false, lnx64 4], [array*1]], with array length of 1 - { - model.setInt32ArrayOneElem(1); - Assert.assertEquals(1, model.getInt32ArrayOneElem()); - } - - // field: int32PointerCustomLen - // field: CType['int32_t *', size [fixed false, lnx64 8], [pointer*1]], with array length of getInt32PointerCustomLenVal() - { - final int size = model.getInt32PointerCustomLenVal(); { - final IntBuffer all0 = model.getInt32PointerCustomLen(); - Assert.assertEquals(size, all0.limit()); - for(int i=0; i<size; i++) { - all0.put(i, 1+i); + } + // write 3 via int[] single set @ offset + if( false ) { + { + final int[] ia = { 0, 320, 321, 322 }; + for(int i=0; i<3; i++) { + model.setVariaInt32PointerConstLen(ia, i+1, i, 3-i); } - - final IntBuffer all1 = model.getInt32PointerCustomLen(); - Assert.assertEquals(size, all1.limit()); + model.setVariaInt32PointerConstLen(new int[]{ 0, 320, 0, 0 }, 0+1 /* srcPos */, 0 /* destPos */, 3); + model.setVariaInt32PointerConstLen(new int[]{ 0, 0, 321, 0 }, 1+1 /* srcPos */, 1 /* destPos */, 2); + model.setVariaInt32PointerConstLen(new int[]{ 0, 0, 0, 322 }, 2+1 /* srcPos */, 2 /* destPos */, 1); + } + // verify 3 + { + final int size = TK_Field.getVariaInt32PointerConstLenElemCount(); + Assert.assertEquals(3, size); + final int[] all = model.getVariaInt32PointerConstLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaInt32PointerConstLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); for(int i=0; i<size; i++) { - Assert.assertEquals(1 + i, all1.get(i)); + Assert.assertEquals(320 + i, all[i]); + Assert.assertEquals(320 + i, allB.get(i)); + final int[] s = model.getVariaInt32PointerConstLen(i, new int[1], 0, 1); + Assert.assertEquals(320 + i, s[0]); } } - } - - // field: int32PointerOneElem - // CType['int32_t *', size [fixed false, lnx64 8], [pointer*1]], with array length of 1 - { - { - final IntBuffer one0 = model.getInt32PointerOneElem(); - Assert.assertEquals(1, one0.limit()); - one0.put(0, 1); - - final IntBuffer one1 = model.getInt32PointerOneElem(); - Assert.assertEquals(1, one1.limit()); - Assert.assertEquals(1, one1.get(0)); } } - - // field: mat4x4 - // CType['float * *', size [fixed false, lnx64 64], [array*2]], with array length of <code>4*4</code> */ + Assert.assertEquals(0, model.getVariaInt32PointerVariaLenElemCount()); + Assert.assertEquals(true, model.isVariaInt32PointerVariaLenNull()); { - model.setMat4x4(0*4, new float[] { 11, 12, 13, 14 } ); - model.setMat4x4(1*4, new float[] { 21, 22, 23, 24 } ); - model.setMat4x4(2*4, new float[] { 31, 32, 33, 34 } ); - model.setMat4x4(3*4, new float[] { 41, 42, 43, 44 } ); - - Assert.assertEquals(4*4, TK_ModelMutable.getMat4x4ArrayLength()); - final FloatBuffer mat4x4 = model.getMat4x4(); - Assert.assertEquals(4*4, mat4x4.limit()); - for(int i=0; i<4; i++) { - final float[] vec4 = model.getMat4x4(i*4, new float[4]); - for(int j=0; j<4; j++) { - Assert.assertEquals((i+1)*10+(j+1), mat4x4.get(i*4+j), EPSILON); - Assert.assertEquals((i+1)*10+(j+1), vec4[j], EPSILON); - } - } + Exception e1 = null; + try { + @SuppressWarnings("unused") + final IntBuffer ib = model.getVariaInt32PointerVariaLen(); // NULL -> exception + } catch(final Exception _e) { e1 = _e; } + Assert.assertNotNull(e1); + System.err.println("Expected exception-1: "+e1); + + Exception e2 = null; + try { + @SuppressWarnings("unused") + final int[] ia = model.getVariaInt32PointerVariaLen(0, new int[0], 0, 0); // NULL -> exception + } catch(final Exception _e) { e2 = _e; } + Assert.assertNotNull(e2); + System.err.println("Expected exception-2: "+e2); } - - // field: structArrayFixedLen - // field: CType['TK_Dimension *', size [fixed false, lnx64 48], [array*1]], with array length of 3 { - final int size = TK_ModelMutable.getStructArrayFixedLenArrayLength(); + // write 1 via int[] set, also actually allocating initial memory + { + final int[] ia = { 220, 221, 222, 223, 224 }; + model.setVariaInt32PointerVariaLen(ia, 0, 0, ia.length); + } + // verify 1 { + final int size = model.getVariaInt32PointerVariaLenElemCount(); + Assert.assertEquals(5, size); + final int[] all = model.getVariaInt32PointerVariaLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaInt32PointerVariaLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); for(int i=0; i<size; i++) { - final TK_Dimension d = TK_Dimension.create(); - d.setX(1+i*10); - d.setY(2+i*10); - d.setWidth(3+i*10); - d.setHeight(4+i*10); - model.setStructArrayFixedLen(i, d); + Assert.assertEquals(220 + i, all[i]); + Assert.assertEquals(220 + i, allB.get(i)); + final int[] s = model.getVariaInt32PointerVariaLen(i, new int[1], 0, 1); + Assert.assertEquals(220 + i, s[0]); } - final TK_Dimension[] all = model.getStructArrayFixedLen(0, new TK_Dimension[size]); - for(int i=0; i<size; i++) { - Assert.assertEquals(1 + i * 10, all[i].getX()); - Assert.assertEquals(2 + i * 10, all[i].getY()); - Assert.assertEquals(3 + i * 10, all[i].getWidth()); - Assert.assertEquals(4 + i * 10, all[i].getHeight()); - final TK_Dimension[] one = model.getStructArrayFixedLen(i, new TK_Dimension[1]); - Assert.assertEquals(1 + i * 10, one[0].getX()); - Assert.assertEquals(2 + i * 10, one[0].getY()); - Assert.assertEquals(3 + i * 10, one[0].getWidth()); - Assert.assertEquals(4 + i * 10, one[0].getHeight()); + } + // write 2 via IntBuffer reference get + { + final IntBuffer ib = model.getVariaInt32PointerVariaLen(); + Assert.assertEquals(5, ib.limit()); + for(int i=0; i<5; ++i) { + ib.put(i, 120+i); } } + // verify 2 { - final TK_Dimension[] da = new TK_Dimension[size]; + final int size = model.getVariaInt32PointerVariaLenElemCount(); + Assert.assertEquals(5, size); + final int[] all = model.getVariaInt32PointerVariaLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaInt32PointerVariaLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); for(int i=0; i<size; i++) { - final TK_Dimension d = TK_Dimension.create(); - d.setX(5+i*10); - d.setY(6+i*10); - d.setWidth(7+i*10); - d.setHeight(8+i*10); - da[i] = d; + Assert.assertEquals(120 + i, all[i]); + Assert.assertEquals(120 + i, allB.get(i)); + final int[] s = model.getVariaInt32PointerVariaLen(i, new int[1], 0, 1); + Assert.assertEquals(120 + i, s[0]); } - model.setStructArrayFixedLen(0, da); + } + model.releaseVariaInt32PointerVariaLen(); + Assert.assertEquals(0, model.getVariaInt32PointerVariaLenElemCount()); + Assert.assertEquals(true, model.isVariaInt32PointerVariaLenNull()); + } - final TK_Dimension[] all = model.getStructArrayFixedLen(0, new TK_Dimension[size]); - for(int i=0; i<size; i++) { - Assert.assertEquals(5 + i * 10, all[i].getX()); - Assert.assertEquals(6 + i * 10, all[i].getY()); - Assert.assertEquals(7 + i * 10, all[i].getWidth()); - Assert.assertEquals(8 + i * 10, all[i].getHeight()); - final TK_Dimension[] one = model.getStructArrayFixedLen(i, new TK_Dimension[1]); - Assert.assertEquals(5 + i * 10, one[0].getX()); - Assert.assertEquals(6 + i * 10, one[0].getY()); - Assert.assertEquals(7 + i * 10, one[0].getWidth()); - Assert.assertEquals(8 + i * 10, one[0].getHeight()); + { + // write 1 via IntBuffer reference get + { + final int size = model.getVariaInt32PointerCustomLenElemCount(); + Assert.assertEquals(4, size); + Assert.assertEquals(false, model.isVariaInt32PointerCustomLenNull()); + final IntBuffer ib = model.getVariaInt32PointerCustomLen(); + Assert.assertEquals(size, ib.limit()); + for(int i=0; i<size; ++i) { + ib.put(i, 120+i); } } + // verify 1 { + final int size = model.getVariaInt32PointerCustomLenElemCount(); + Assert.assertEquals(4, size); + final int[] all = model.getVariaInt32PointerCustomLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaInt32PointerCustomLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); for(int i=0; i<size; i++) { - final TK_Dimension d = TK_Dimension.create(); - d.setX(1+i*10); - d.setY(3+i*10); - d.setWidth(5+i*10); - d.setHeight(7+i*10); - model.setStructArrayFixedLen(i, new TK_Dimension[] { d }); + Assert.assertEquals(120 + i, all[i]); + Assert.assertEquals(120 + i, allB.get(i)); + final int[] s = model.getVariaInt32PointerCustomLen(i, new int[1], 0, 1); + Assert.assertEquals(120 + i, s[0]); } - - final TK_Dimension[] all = model.getStructArrayFixedLen(0, new TK_Dimension[size]); + } + // write 2 via int[] set + { + final int[] ia = { 0, 220, 221, 222, 223, 224, 0 }; + model.setVariaInt32PointerCustomLen(ia, 1 /* srcPos */, 0 /* destPos */, ia.length-2); + } + // verify 2 + { + final int size = model.getVariaInt32PointerCustomLenElemCount(); + Assert.assertEquals(5, size); + final int[] all = model.getVariaInt32PointerCustomLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaInt32PointerCustomLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); for(int i=0; i<size; i++) { - Assert.assertEquals(1 + i * 10, all[i].getX()); - Assert.assertEquals(3 + i * 10, all[i].getY()); - Assert.assertEquals(5 + i * 10, all[i].getWidth()); - Assert.assertEquals(7 + i * 10, all[i].getHeight()); - final TK_Dimension[] one = model.getStructArrayFixedLen(i, new TK_Dimension[1]); - Assert.assertEquals(1 + i * 10, one[0].getX()); - Assert.assertEquals(3 + i * 10, one[0].getY()); - Assert.assertEquals(5 + i * 10, one[0].getWidth()); - Assert.assertEquals(7 + i * 10, one[0].getHeight()); + Assert.assertEquals(220 + i, all[i]); + Assert.assertEquals(220 + i, allB.get(i)); + final int[] s = model.getVariaInt32PointerCustomLen(i, new int[1], 0, 1); + Assert.assertEquals(220 + i, s[0]); } } + model.releaseVariaInt32PointerCustomLen(); // FIXME: Ownership is ambiguous, may leak native allocated memory, not free'ed! + Assert.assertEquals(0, model.getVariaInt32PointerCustomLenElemCount()); + Assert.assertEquals(true, model.isVariaInt32PointerCustomLenNull()); } + } + + /** Struct */ + private void chapter12_05aTestTKFieldStruct(final TK_Field model) { // field: structArrayOneElem // CType['TK_Dimension *', size [fixed false, lnx64 16], [array*1]], with array length of 1 { - { - final TK_Dimension d = TK_Dimension.create(); - d.setX(1); - d.setY(2); - d.setWidth(3); - d.setHeight(4); - model.setStructArrayOneElem(d); - } - { - final TK_Dimension one = model.getStructArrayOneElem(); - Assert.assertEquals(1, one.getX()); - Assert.assertEquals(2, one.getY()); - Assert.assertEquals(3, one.getWidth()); - Assert.assertEquals(4, one.getHeight()); - } + final TK_Dimension all = model.getConstStructArrayConstOneElem(); + Assert.assertEquals(51, all.getX()); + Assert.assertEquals(52, all.getY()); + Assert.assertEquals(53, all.getWidth()); + Assert.assertEquals(54, all.getHeight()); } // field: structPointerCustomLen // CType['TK_Dimension *', size [fixed false, lnx64 8], [pointer*1]], with array length of getStructPointerCustomLenVal() { - final int size = model.getStructPointerCustomLenVal(); - { - final TK_Dimension[] all = model.getStructPointerCustomLen(0, new TK_Dimension[size]); - for(int i=0; i<size; i++) { - final TK_Dimension d = all[i]; - d.setX(1+i*10); - d.setY(2+i*10); - d.setWidth(3+i*10); - d.setHeight(4+i*10); - } - } - { - final TK_Dimension[] all = model.getStructPointerCustomLen(0, new TK_Dimension[size]); - for(int i=0; i<size; i++) { - Assert.assertEquals(1 + i * 10, all[i].getX()); - Assert.assertEquals(2 + i * 10, all[i].getY()); - Assert.assertEquals(3 + i * 10, all[i].getWidth()); - Assert.assertEquals(4 + i * 10, all[i].getHeight()); - final TK_Dimension[] one = model.getStructPointerCustomLen(i, new TK_Dimension[1]); - Assert.assertEquals(1 + i * 10, one[0].getX()); - Assert.assertEquals(2 + i * 10, one[0].getY()); - Assert.assertEquals(3 + i * 10, one[0].getWidth()); - Assert.assertEquals(4 + i * 10, one[0].getHeight()); - } + final int size = model.getConstStructPointerCustomLenElemCount(); + Assert.assertEquals(4, size); + final TK_Dimension[] all = model.getConstStructPointerCustomLen(0, new TK_Dimension[size], 0, size); + for(int i=0; i<size; i++) { + Assert.assertEquals(131 + i * 10, all[i].getX()); + Assert.assertEquals(132 + i * 10, all[i].getY()); + Assert.assertEquals(133 + i * 10, all[i].getWidth()); + Assert.assertEquals(134 + i * 10, all[i].getHeight()); } } // field: structPointerOneElem // CType['TK_Dimension *', size [fixed false, lnx64 8], [pointer*1]], with array length of 1 { + final TK_Dimension all = model.getConstStructPointerConstOneElem(); + Assert.assertEquals(91, all.getX()); + Assert.assertEquals(92, all.getY()); + Assert.assertEquals(93, all.getWidth()); + Assert.assertEquals(94, all.getHeight()); + + } + } + + private static ByteBuffer toEOSByteBuffer(final String val, final Charset cs) { + final byte[] ba = val.getBytes( cs ); + final ByteBuffer bb = Buffers.newDirectByteBuffer( ba.length + 1 ); + bb.put(ba); + bb.put((byte)0); + bb.rewind(); + return bb; + } + + /** String - Read Access */ + private void chapter12_10aTestTKFieldConstStringReadAccess(final TK_Field model) { + { + final int expStrLen = 12; // w/o EOS + final String exp = "Hello Array1"; + final ByteBuffer expBB = toEOSByteBuffer( exp, TK_Field.getCharset() ); + Assert.assertEquals(expStrLen, exp.length()); + Assert.assertEquals(expStrLen+1, expBB.limit()); + Assert.assertEquals(expStrLen+1, TK_Field.getConstCharArrayConstLenElemCount()); + + final ByteBuffer hasBB = model.getConstCharArrayConstLen(); + Assert.assertEquals(expStrLen+1, hasBB.limit()); + Assert.assertEquals(expBB, hasBB); + + final String has = model.getConstCharArrayConstLenAsString(); + System.err.println("has '"+has+"'"); + // dumpStringChars("has", has); + Assert.assertEquals(expStrLen, has.length()); // w/o EOS + Assert.assertEquals(exp, has); + } + { + final int expStrLen = 14; // w/o EOS + final String exp = "Hello CString1"; + final ByteBuffer expBB = toEOSByteBuffer( exp, TK_Field.getCharset() ); + Assert.assertEquals(expStrLen, exp.length()); + Assert.assertEquals(expStrLen+1, expBB.limit()); + Assert.assertEquals(expStrLen+1, TK_Field.getConstCharPointerConstLenElemCount()); + Assert.assertEquals(false, model.isConstCharPointerConstLenNull()); + + final ByteBuffer hasBB = model.getConstCharPointerConstLen(); + Assert.assertEquals(expStrLen+1, hasBB.limit()); + Assert.assertEquals(expBB, hasBB); + + final String has = model.getConstCharPointerConstLenAsString(); + System.err.println("has '"+has+"'"); + // dumpStringChars("has", has); + Assert.assertEquals(expStrLen, has.length()); // w/o EOS + Assert.assertEquals(exp, has); + } + { + Assert.assertEquals(0, model.getConstCharPointerVariaLenElemCount()); + Assert.assertEquals(true, model.isConstCharPointerVariaLenNull()); + } + { + final int expStrLen = 14; // w/o EOS + final String exp = "Hello CString3"; + final ByteBuffer expBB = toEOSByteBuffer( exp, TK_Field.getCharset() ); + Assert.assertEquals(expStrLen, exp.length()); + Assert.assertEquals(expStrLen+1, expBB.limit()); + Assert.assertEquals(expStrLen+1, model.getConstCharPointerCustomLenElemCount()); + Assert.assertEquals(false, model.isConstCharPointerCustomLenNull()); + + final ByteBuffer hasBB = model.getConstCharPointerCustomLen(); + Assert.assertEquals(expStrLen+1, hasBB.limit()); + Assert.assertEquals(expBB, hasBB); + + final String has = model.getConstCharPointerCustomLenAsString(); + System.err.println("has '"+has+"'"); + // dumpStringChars("has", has); + Assert.assertEquals(expStrLen, has.length()); // w/o EOS + Assert.assertEquals(exp, has); + } + } + + /** String - Read Access */ + private void chapter12_11aTestTKFieldConstStringOnlyReadAccess(final TK_Field model) { + { + final int expStrLen = 12; // w/o EOS + final String exp = "Hello Array1"; + Assert.assertEquals(expStrLen, exp.length()); + Assert.assertEquals(expStrLen+1, TK_Field.getConstStringOnlyArrayConstLenElemCount()); + + final String has = model.getConstStringOnlyArrayConstLen(); + System.err.println("has '"+has+"'"); + // dumpStringChars("has", has); + Assert.assertEquals(expStrLen, has.length()); // w/o EOS + Assert.assertEquals(exp, has); + } + { + final int expStrLen = 14; // w/o EOS + final String exp = "Hello CString1"; + Assert.assertEquals(expStrLen, exp.length()); + Assert.assertEquals(expStrLen+1, TK_Field.getConstStringOnlyPointerConstLenElemCount()); + Assert.assertEquals(false, model.isConstStringOnlyPointerConstLenNull()); + + final String has = model.getConstStringOnlyPointerConstLen(); + System.err.println("has '"+has+"'"); + // dumpStringChars("has", has); + Assert.assertEquals(expStrLen, has.length()); // w/o EOS + Assert.assertEquals(exp, has); + } + { + Assert.assertEquals(0, model.getConstStringOnlyPointerVariaLenElemCount()); + Assert.assertEquals(true, model.isConstStringOnlyPointerVariaLenNull()); + } + { + final int expStrLen = 14; // w/o EOS + final String exp = "Hello CString3"; + Assert.assertEquals(expStrLen, exp.length()); + Assert.assertEquals(expStrLen+1, model.getConstStringOnlyPointerCustomLenElemCount()); + Assert.assertEquals(false, model.isConstStringOnlyPointerCustomLenNull()); + + final String has = model.getConstStringOnlyPointerCustomLen(); + System.err.println("has '"+has+"'"); + // dumpStringChars("has", has); + Assert.assertEquals(expStrLen, has.length()); // w/o EOS + Assert.assertEquals(exp, has); + } + } + + /** String - Write Access */ + private void chapter12_11bTestTKFieldConstStringOnlyWriteAccess(final TK_Field model) { + { + Assert.assertEquals(0, model.getConstStringOnlyPointerVariaLenElemCount()); + Assert.assertEquals(true, model.isConstStringOnlyPointerVariaLenNull()); + + final int expStrLen = 15; // w/o EOS + final String exp = "Hello World2222"; + Assert.assertEquals(expStrLen, exp.length()); + + model.setConstStringOnlyPointerVariaLen(exp); + Assert.assertEquals(expStrLen+1, model.getConstStringOnlyPointerVariaLenElemCount()); + Assert.assertEquals(false, model.isConstStringOnlyPointerVariaLenNull()); + + final String has = model.getConstStringOnlyPointerVariaLen(); + System.err.println("has '"+has+"'"); + // dumpStringChars("has", has); + Assert.assertEquals(expStrLen, has.length()); // w/o EOS + Assert.assertEquals(exp, has); + + model.releaseConstStringOnlyPointerVariaLen(); + Assert.assertEquals(0, model.getConstStringOnlyPointerVariaLenElemCount()); + Assert.assertEquals(true, model.isConstStringOnlyPointerVariaLenNull()); + } + { + final int expStrLen = 15; // w/o EOS + final String exp = "Hello World4444"; + Assert.assertEquals(expStrLen, exp.length()); + Assert.assertEquals(false, model.isConstStringOnlyPointerCustomLenNull()); + + model.setConstStringOnlyPointerCustomLen(exp); + Assert.assertEquals(expStrLen+1, model.getConstStringOnlyPointerCustomLenElemCount()); + Assert.assertEquals(false, model.isConstStringOnlyPointerCustomLenNull()); + + final String has = model.getConstStringOnlyPointerCustomLen(); + System.err.println("has '"+has+"'"); + // dumpStringChars("has", has); + Assert.assertEquals(expStrLen, has.length()); // w/o EOS + Assert.assertEquals(exp, has); + + model.releaseConstStringOnlyPointerCustomLen(); // FIXME: Ownership is ambiguous, may leak native allocated memory, not free'ed! + Assert.assertEquals(0, model.getConstStringOnlyPointerCustomLenElemCount()); + Assert.assertEquals(true, model.isConstStringOnlyPointerCustomLenNull()); + } + } + + /** Test array and pointer bindings of structs */ + public void chapter12TestTKField(final Bindingtest1 binding) throws Exception { + Assert.assertEquals(false, TK_Field.usesNativeCode()); + Assert.assertNotEquals(0, TK_Field.size()); + + final TK_Field model0 = binding.createTKField(); + { + // Fetch native memory + final ByteBuffer bb0 = model0.getBuffer(); + Assert.assertNotNull(bb0); + Assert.assertEquals(TK_Field.size(), bb0.limit()); + + final long addr0 = model0.getDirectBufferAddress(); + Assert.assertNotEquals(0, addr0); + + // Compare a reference by memory address -> identical! { - final TK_Dimension d = model.getStructPointerOneElem(); - d.setX(1); - d.setY(2); - d.setWidth(3); - d.setHeight(4); + final TK_Field model1 = TK_Field.derefPointer(addr0); + final ByteBuffer bb1 = model1.getBuffer(); + Assert.assertNotNull(bb1); + Assert.assertEquals(TK_Field.size(), bb1.limit()); + + final long addr1 = model1.getDirectBufferAddress(); + Assert.assertNotEquals(0, addr1); } - { - final TK_Dimension one = model.getStructPointerOneElem(); - Assert.assertEquals(1, one.getX()); - Assert.assertEquals(2, one.getY()); - Assert.assertEquals(3, one.getWidth()); - Assert.assertEquals(4, one.getHeight()); + } + + chapter12_03aTestTKFieldConstValueInt32ReadAccess(model0); + chapter12_03bTestTKFieldConstValueInt32WriteAccess(model0); + chapter12_04aTestTKFieldVariaValueInt32ReadAccess(model0); + chapter12_04bTestTKFieldVariaValueInt32WriteAccess(model0); + chapter12_05aTestTKFieldStruct(model0); + chapter12_10aTestTKFieldConstStringReadAccess(model0); + chapter12_11aTestTKFieldConstStringOnlyReadAccess(model0); + chapter12_11bTestTKFieldConstStringOnlyWriteAccess(model0); + + binding.destroyTKField(model0); + } + @SuppressWarnings("unused") + private void dumpStringChars(final String prefix, final String s) { + final int len = s.length(); + for(int i=0; i<len; i++) { + final char c = s.charAt(i); + System.err.printf("%s %3d: 0x%X %c%n", prefix, i, (int)c, c); + } + } + + public void chapter13TestTKFieldImmutable(final Bindingtest1 binding) throws Exception { + Assert.assertEquals(false, TK_FieldImmutable.usesNativeCode()); + + final TK_FieldImmutable model = binding.createTKFieldImmutable(); + + binding.destroyTKFieldImmutable(model); + } + + public void chapter15TestTKMixed(final Bindingtest1 binding) throws Exception { + Assert.assertEquals(false, TK_ModelMixed.usesNativeCode()); + + final TK_ModelMixed model = binding.createTKModelMixed(); + + Assert.assertEquals(4*4, TK_ModelMixed.getMat4x4ElemCount()); + { + final FloatBuffer mat4x4 = model.getMat4x4(); + Assert.assertEquals(4*4, mat4x4.limit()); + for(int i=0; i<4; i++) { + final float[] vec4 = model.getMat4x4(i*4, new float[4], 0, 4); + for(int j=0; j<4; j++) { + Assert.assertEquals(i*4+j, mat4x4.get(i*4+j), EPSILON); + Assert.assertEquals(i*4+j, vec4[j], EPSILON); + } } + } + { + final float[] data = { 11, 12, 13, 14, + 21, 22, 23, 24, + 31, 32, 33, 34, + 41, 42, 43, 44 }; + model.setMat4x4(data, 0*4, 0*4, 4); + model.setMat4x4(data, 1*4, 1*4, 4); + model.setMat4x4(data, 2*4, 2*4, 4); + model.setMat4x4(data, 3*4, 3*4, 4); + final FloatBuffer mat4x4 = model.getMat4x4(); + Assert.assertEquals(4*4, mat4x4.limit()); + for(int i=0; i<4; i++) { + final float[] vec4 = model.getMat4x4(i*4, new float[4], 0, 4); + for(int j=0; j<4; j++) { + Assert.assertEquals((i+1)*10+(j+1), mat4x4.get(i*4+j), EPSILON); + Assert.assertEquals((i+1)*10+(j+1), vec4[j], EPSILON); + } + } } final long surfaceContext = model.getCtx(); @@ -1819,7 +2255,5 @@ public class BaseClass extends SingletonJunitCase { model.setCtx(surfaceContext); assertAPTR(surfaceContext, model.getCtx()); - - binding.destroyModelMutable(model); } } diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java index 5809acf..3e19232 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java @@ -145,19 +145,24 @@ public class Test1p1JavaEmitter extends BaseClass { } /** - * Test compound access read-only + * Test compound access read-write */ @Test - public void chapter12TestStructArrayModelConst() throws Exception { - chapter12TestStructArrayModelConst(new Bindingtest1p1Impl()); + public void chapter12TestTKField() throws Exception { + chapter12TestTKField(new Bindingtest1p1Impl()); } /** - * Test compound access read-write + * Test compound access read-only */ @Test - public void chapter13TestStructArrayModelMutable() throws Exception { - chapter13TestStructArrayModelMutable(new Bindingtest1p1Impl()); + public void chapter13TestTKFieldImmutable() throws Exception { + chapter13TestTKFieldImmutable(new Bindingtest1p1Impl()); + } + + @Test + public void chapter15TestTKMixed() throws Exception { + chapter15TestTKMixed(new Bindingtest1p1Impl()); } public static void main(final String args[]) throws IOException { diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2DynamicLibraryBundle.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2DynamicLibraryBundle.java index c063d15..def7655 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2DynamicLibraryBundle.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2DynamicLibraryBundle.java @@ -28,6 +28,7 @@ package com.jogamp.gluegen.test.junit.generation; +import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest1p1Impl; import com.jogamp.gluegen.test.junit.generation.impl.Bindingtest1p2Impl; import com.jogamp.common.os.DynamicLibraryBundle; import com.jogamp.common.os.DynamicLibraryBundleInfo; @@ -152,19 +153,24 @@ public class Test1p2DynamicLibraryBundle extends BaseClass { } /** - * Test compound access read-only + * Test compound access read-write */ @Test - public void chapter12TestStructArrayModelConst() throws Exception { - chapter12TestStructArrayModelConst(new Bindingtest1p2Impl()); + public void chapter12TestTKField() throws Exception { + chapter12TestTKField(new Bindingtest1p2Impl()); } /** - * Test compound access read-write + * Test compound access read-only */ @Test - public void chapter13TestStructArrayModelMutable() throws Exception { - chapter13TestStructArrayModelMutable(new Bindingtest1p2Impl()); + public void chapter13TestTKFieldImmutable() throws Exception { + chapter13TestTKFieldImmutable(new Bindingtest1p2Impl()); + } + + @Test + public void chapter15TestTKMixed() throws Exception { + chapter15TestTKMixed(new Bindingtest1p2Impl()); } /** diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java index fa99915..711f218 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java @@ -154,19 +154,24 @@ public class Test1p2ProcAddressEmitter extends BaseClass { } /** - * Test compound access read-only + * Test compound access read-write */ @Test - public void chapter12TestStructArrayModelConst() throws Exception { - chapter12TestStructArrayModelConst(new Bindingtest1p2Impl()); + public void chapter12TestTKField() throws Exception { + chapter12TestTKField(new Bindingtest1p2Impl()); } /** - * Test compound access read-write + * Test compound access read-only */ @Test - public void chapter13TestStructArrayModelMutable() throws Exception { - chapter13TestStructArrayModelMutable(new Bindingtest1p2Impl()); + public void chapter13TestTKFieldImmutable() throws Exception { + chapter13TestTKFieldImmutable(new Bindingtest1p2Impl()); + } + + @Test + public void chapter15TestTKMixed() throws Exception { + chapter15TestTKMixed(new Bindingtest1p2Impl()); } /** diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1-common.cfg b/src/junit/com/jogamp/gluegen/test/junit/generation/test1-common.cfg index 6c516c2..7e9ba4a 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test1-common.cfg +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1-common.cfg @@ -71,39 +71,300 @@ ReturnValueCapacity TK_Surface.getClip sizeof(TK_Dimension) ReturnValueCapacity createComplicatedSuperSet sizeof(TK_ComplicatedSuperSet) -EmitStruct TK_ModelConst -StructPackage TK_ModelConst com.jogamp.gluegen.test.junit.generation -ReturnedArrayLength TK_ModelConst.intxxArrayCustomLen getIntxxArrayCustomLenVal() -ReturnedArrayLength TK_ModelConst.intxxPointerCustomLen getIntxxPointerCustomLenVal() -ReturnedArrayLength TK_ModelConst.int32ArrayCustomLen getInt32ArrayCustomLenVal() -ReturnedArrayLength TK_ModelConst.int32PointerCustomLen getInt32PointerCustomLenVal() -ReturnedArrayLength TK_ModelConst.structArrayCustomLen getStructArrayCustomLenVal() -ReturnedArrayLength TK_ModelConst.structPointerCustomLen getStructPointerCustomLenVal() -ReturnedArrayLength TK_ModelConst.int32PointerOneElem 1 -ReturnValueCapacity TK_ModelConst.int32PointerOneElem 1 * sizeof(int32_t) /* overridden by ReturnValueCapacity */ -ReturnedArrayLength TK_ModelConst.structPointerOneElem 1 -ReturnsString TK_ModelConst.modelNameArrayFixedLen -ReturnsString TK_ModelConst.modelNamePointerCString -ReturnsString TK_ModelConst.modelNamePointerCustomLen -ReturnedArrayLength TK_ModelConst.modelNamePointerCustomLen getModelNamePointerCustomLenVal() - -EmitStruct TK_ModelMutable -StructPackage TK_ModelMutable com.jogamp.gluegen.test.junit.generation -ReturnedArrayLength TK_ModelMutable.intxxArrayCustomLen getIntxxArrayCustomLenVal() -ReturnedArrayLength TK_ModelMutable.intxxPointerCustomLen getIntxxPointerCustomLenVal() -ReturnedArrayLength TK_ModelMutable.int32ArrayCustomLen getInt32ArrayCustomLenVal() -ReturnedArrayLength TK_ModelMutable.int32PointerCustomLen getInt32PointerCustomLenVal() -ReturnedArrayLength TK_ModelMutable.structArrayCustomLen getStructArrayCustomLenVal() -ReturnedArrayLength TK_ModelMutable.structPointerCustomLen getStructPointerCustomLenVal() -ReturnedArrayLength TK_ModelMutable.int32PointerOneElem 1 -ReturnedArrayLength TK_ModelMutable.structPointerOneElem 1 -ReturnsString TK_ModelMutable.modelNameArrayFixedLen -ReturnsString TK_ModelMutable.modelNamePointerCString -ReturnsString TK_ModelMutable.modelNamePointerCustomLen -ReturnedArrayLength TK_ModelMutable.modelNamePointerCustomLen getModelNamePointerCustomLenVal() - -ReturnValueCapacity createModelConst sizeof(TK_ModelConst) -ReturnValueCapacity createModelMutable sizeof(TK_ModelMutable) +# +# TK_FieldImmutable +# + +EmitStruct TK_FieldImmutable +StructPackage TK_FieldImmutable com.jogamp.gluegen.test.junit.generation + +# TK_FieldImmutable Primitive.ConstValue.intxx +ImmutableAccess TK_FieldImmutable.constIntxxArrayConstOneElem +ImmutableAccess TK_FieldImmutable.constIntxxArrayConstLen +ImmutableAccess TK_FieldImmutable.constIntxxPointerConstOneElem +ReturnedArrayLength TK_FieldImmutable.constIntxxPointerConstOneElem 1 +ImmutableAccess TK_FieldImmutable.constIntxxPointerMaxOneElem +MaxOneElement TK_FieldImmutable.constIntxxPointerMaxOneElem +ImmutableAccess TK_FieldImmutable.constIntxxPointerConstLen +ReturnedArrayLength TK_FieldImmutable.constIntxxPointerConstLen 3 +ImmutableAccess TK_FieldImmutable.constIntxxPointerVariaLen +ImmutableAccess TK_FieldImmutable.constIntxxPointerCustomLen +ReturnedArrayLength TK_FieldImmutable.constIntxxPointerCustomLen getConstIntxxPointerCustomLenElemCount() + +# TK_FieldImmutable Primitive.VariaValue.intxx +ImmutableAccess TK_FieldImmutable.variaIntxxArrayConstOneElem +ImmutableAccess TK_FieldImmutable.variaIntxxArrayConstLen +ImmutableAccess TK_FieldImmutable.variaIntxxPointerConstOneElem +ReturnedArrayLength TK_FieldImmutable.variaIntxxPointerConstOneElem 1 +ImmutableAccess TK_FieldImmutable.variaIntxxPointerMaxOneElem +MaxOneElement TK_FieldImmutable.variaIntxxPointerMaxOneElem +ImmutableAccess TK_FieldImmutable.variaIntxxPointerConstLen +ReturnedArrayLength TK_FieldImmutable.variaIntxxPointerConstLen 3 +ImmutableAccess TK_FieldImmutable.variaIntxxPointerVariaLen +ImmutableAccess TK_FieldImmutable.variaIntxxPointerCustomLen +ReturnedArrayLength TK_FieldImmutable.variaIntxxPointerCustomLen getVariaIntxxPointerCustomLenElemCount() + +# TK_FieldImmutable Primitive.ConstValue.int32 +ImmutableAccess TK_FieldImmutable.constInt32ArrayConstOneElem +ImmutableAccess TK_FieldImmutable.constInt32ArrayConstLen +ImmutableAccess TK_FieldImmutable.constInt32PointerConstOneElem +ReturnedArrayLength TK_FieldImmutable.constInt32PointerConstOneElem 1 +ImmutableAccess TK_FieldImmutable.constInt32PointerMaxOneElem +MaxOneElement TK_FieldImmutable.constInt32PointerMaxOneElem +ImmutableAccess TK_FieldImmutable.constInt32PointerConstLen +ReturnedArrayLength TK_FieldImmutable.constInt32PointerConstLen 3 +ImmutableAccess TK_FieldImmutable.constInt32PointerVariaLen +ImmutableAccess TK_FieldImmutable.constInt32PointerCustomLen +ReturnedArrayLength TK_FieldImmutable.constInt32PointerCustomLen getConstInt32PointerCustomLenElemCount() + +# TK_FieldImmutable Primitive.VariaValue.int32 +ImmutableAccess TK_FieldImmutable.variaInt32ArrayConstOneElem +ImmutableAccess TK_FieldImmutable.variaInt32ArrayConstLen +ImmutableAccess TK_FieldImmutable.variaInt32PointerConstOneElem +ReturnedArrayLength TK_FieldImmutable.variaInt32PointerConstOneElem 1 +ImmutableAccess TK_FieldImmutable.variaInt32PointerMaxOneElem +MaxOneElement TK_FieldImmutable.variaInt32PointerMaxOneElem +ImmutableAccess TK_FieldImmutable.variaInt32PointerConstLen +ReturnedArrayLength TK_FieldImmutable.variaInt32PointerConstLen 3 +ImmutableAccess TK_FieldImmutable.variaInt32PointerVariaLen +ImmutableAccess TK_FieldImmutable.variaInt32PointerCustomLen +ReturnedArrayLength TK_FieldImmutable.variaInt32PointerCustomLen getVariaInt32PointerCustomLenElemCount() + +# TK_FieldImmutable Struct.ConstValue.TK_Dimension +ImmutableAccess TK_FieldImmutable.constStructArrayConstOneElem +ImmutableAccess TK_FieldImmutable.constStructArrayConstLen +ImmutableAccess TK_FieldImmutable.constStructPointerConstOneElem +ReturnedArrayLength TK_FieldImmutable.constStructPointerConstOneElem 1 +ImmutableAccess TK_FieldImmutable.constStructPointerMaxOneElem +MaxOneElement TK_FieldImmutable.constStructPointerMaxOneElem +ImmutableAccess TK_FieldImmutable.constStructPointerConstLen +ReturnedArrayLength TK_FieldImmutable.constStructPointerConstLen 3 +ImmutableAccess TK_FieldImmutable.constStructPointerVariaLen +ImmutableAccess TK_FieldImmutable.constStructPointerCustomLen +ReturnedArrayLength TK_FieldImmutable.constStructPointerCustomLen getConstStructPointerCustomLenElemCount() + +# TK_FieldImmutable Struct.VariaValue.TK_Dimension +ImmutableAccess TK_FieldImmutable.variaStructArrayConstOneElem +ImmutableAccess TK_FieldImmutable.variaStructArrayConstLen +ImmutableAccess TK_FieldImmutable.variaStructPointerConstOneElem +ReturnedArrayLength TK_FieldImmutable.variaStructPointerConstOneElem 1 +ImmutableAccess TK_FieldImmutable.variaStructPointerMaxOneElem +MaxOneElement TK_FieldImmutable.variaStructPointerMaxOneElem +ImmutableAccess TK_FieldImmutable.variaStructPointerConstLen +ReturnedArrayLength TK_FieldImmutable.variaStructPointerConstLen 3 +ImmutableAccess TK_FieldImmutable.variaStructPointerVariaLen +ImmutableAccess TK_FieldImmutable.variaStructPointerCustomLen +ReturnedArrayLength TK_FieldImmutable.variaStructPointerCustomLen getVariaStructPointerCustomLenElemCount() + +# TK_FieldImmutable String.ConstValue 1A + 3P = 4 +ImmutableAccess TK_FieldImmutable.constCharArrayConstLen +ReturnsString TK_FieldImmutable.constCharArrayConstLen +ImmutableAccess TK_FieldImmutable.constCharPointerConstLen +ReturnsString TK_FieldImmutable.constCharPointerConstLen +ReturnedArrayLength TK_FieldImmutable.constCharPointerConstLen 15 +ImmutableAccess TK_FieldImmutable.constCharPointerVariaLen +ReturnsString TK_FieldImmutable.constCharPointerVariaLen +ImmutableAccess TK_FieldImmutable.constCharPointerCustomLen +ReturnsString TK_FieldImmutable.constCharPointerCustomLen +ReturnedArrayLength TK_FieldImmutable.constCharPointerCustomLen getConstCharPointerCustomLenElemCount() + +# TK_FieldImmutable String.VariaValue 1A + 3P = 4 +ImmutableAccess TK_FieldImmutable.variaCharArrayConstLen +ReturnsString TK_FieldImmutable.variaCharArrayConstLen +ImmutableAccess TK_FieldImmutable.variaCharPointerConstLen +ReturnsString TK_FieldImmutable.variaCharPointerConstLen +ReturnedArrayLength TK_FieldImmutable.variaCharPointerConstLen 15 +ImmutableAccess TK_FieldImmutable.variaCharPointerVariaLen +ReturnsString TK_FieldImmutable.variaCharPointerVariaLen +ImmutableAccess TK_FieldImmutable.variaCharPointerCustomLen +ReturnsString TK_FieldImmutable.variaCharPointerCustomLen +ReturnedArrayLength TK_FieldImmutable.variaCharPointerCustomLen getVariaCharPointerCustomLenElemCount() + +# TK_FieldImmutable StringOnly.ConstValue 1A + 3P = 4 +ImmutableAccess TK_FieldImmutable.constStringOnlyArrayConstLen +ReturnsStringOnly TK_FieldImmutable.constStringOnlyArrayConstLen +ImmutableAccess TK_FieldImmutable.constStringOnlyPointerConstLen +ReturnsStringOnly TK_FieldImmutable.constStringOnlyPointerConstLen +ReturnedArrayLength TK_FieldImmutable.constStringOnlyPointerConstLen 15 +ImmutableAccess TK_FieldImmutable.constStringOnlyPointerVariaLen +ReturnsStringOnly TK_FieldImmutable.constStringOnlyPointerVariaLen +ImmutableAccess TK_FieldImmutable.constStringOnlyPointerCustomLen +ReturnsStringOnly TK_FieldImmutable.constStringOnlyPointerCustomLen +ReturnedArrayLength TK_FieldImmutable.constStringOnlyPointerCustomLen getConstStringOnlyPointerCustomLenElemCount() + +# TK_FieldImmutable StringOnly.VariaValue 1A + 3P = 4 +ImmutableAccess TK_FieldImmutable.variaStringOnlyArrayConstLen +ReturnsStringOnly TK_FieldImmutable.variaStringOnlyArrayConstLen +ImmutableAccess TK_FieldImmutable.variaStringOnlyPointerConstLen +ReturnsStringOnly TK_FieldImmutable.variaStringOnlyPointerConstLen +ReturnedArrayLength TK_FieldImmutable.variaStringOnlyPointerConstLen 15 +ImmutableAccess TK_FieldImmutable.variaStringOnlyPointerVariaLen +ReturnsStringOnly TK_FieldImmutable.variaStringOnlyPointerVariaLen +ImmutableAccess TK_FieldImmutable.variaStringOnlyPointerCustomLen +ReturnsStringOnly TK_FieldImmutable.variaStringOnlyPointerCustomLen +ReturnedArrayLength TK_FieldImmutable.variaStringOnlyPointerCustomLen getVariaStringOnlyPointerCustomLenElemCount() + + +# +# TK_StructImmutable +# + +EmitStruct TK_StructImmutable +StructPackage TK_StructImmutable com.jogamp.gluegen.test.junit.generation + +ImmutableAccess TK_StructImmutable + +# TK_StructImmutable Primitive.ConstValue.intxx +ReturnedArrayLength TK_StructImmutable.constIntxxPointerConstOneElem 1 +MaxOneElement TK_StructImmutable.constIntxxPointerMaxOneElem +ReturnedArrayLength TK_StructImmutable.constIntxxPointerConstLen 3 +ReturnedArrayLength TK_StructImmutable.constIntxxPointerCustomLen getConstIntxxPointerCustomLenElemCount() + +# TK_StructImmutable Primitive.VariaValue.intxx +ReturnedArrayLength TK_StructImmutable.variaIntxxPointerConstOneElem 1 +MaxOneElement TK_StructImmutable.variaIntxxPointerMaxOneElem +ReturnedArrayLength TK_StructImmutable.variaIntxxPointerConstLen 3 +ReturnedArrayLength TK_StructImmutable.variaIntxxPointerCustomLen getVariaIntxxPointerCustomLenElemCount() + +# TK_StructImmutable Primitive.ConstValue.int32 +ReturnedArrayLength TK_StructImmutable.constInt32PointerConstOneElem 1 +MaxOneElement TK_StructImmutable.constInt32PointerMaxOneElem +ReturnedArrayLength TK_StructImmutable.constInt32PointerConstLen 3 +ReturnedArrayLength TK_StructImmutable.constInt32PointerCustomLen getConstInt32PointerCustomLenElemCount() + +# TK_StructImmutable Primitive.VariaValue.int32 +ReturnedArrayLength TK_StructImmutable.variaInt32PointerConstOneElem 1 +MaxOneElement TK_StructImmutable.variaInt32PointerMaxOneElem +ReturnedArrayLength TK_StructImmutable.variaInt32PointerConstLen 3 +ReturnedArrayLength TK_StructImmutable.variaInt32PointerCustomLen getVariaInt32PointerCustomLenElemCount() + +# TK_StructImmutable Struct.ConstValue.TK_Dimension +ReturnedArrayLength TK_StructImmutable.constStructPointerConstOneElem 1 +MaxOneElement TK_StructImmutable.constStructPointerMaxOneElem +ReturnedArrayLength TK_StructImmutable.constStructPointerConstLen 3 +ReturnedArrayLength TK_StructImmutable.constStructPointerCustomLen getConstStructPointerCustomLenElemCount() + +# TK_StructImmutable Struct.VariaValue.TK_Dimension +ReturnedArrayLength TK_StructImmutable.variaStructPointerConstOneElem 1 +MaxOneElement TK_StructImmutable.variaStructPointerMaxOneElem +ReturnedArrayLength TK_StructImmutable.variaStructPointerConstLen 3 +ReturnedArrayLength TK_StructImmutable.variaStructPointerCustomLen getVariaStructPointerCustomLenElemCount() + +# TK_StructImmutable String.ConstValue 1A + 3P = 4 +ReturnsString TK_StructImmutable.constCharArrayConstLen +ReturnsString TK_StructImmutable.constCharPointerConstLen +ReturnedArrayLength TK_StructImmutable.constCharPointerConstLen 15 +ReturnsString TK_StructImmutable.constCharPointerVariaLen +ReturnsString TK_StructImmutable.constCharPointerCustomLen +ReturnedArrayLength TK_StructImmutable.constCharPointerCustomLen getConstCharPointerCustomLenElemCount() + +# TK_StructImmutable String.VariaValue 1A + 3P = 4 +ReturnsString TK_StructImmutable.variaCharArrayConstLen +ReturnsString TK_StructImmutable.variaCharPointerConstLen +ReturnedArrayLength TK_StructImmutable.variaCharPointerConstLen 15 +ReturnsString TK_StructImmutable.variaCharPointerVariaLen +ReturnsString TK_StructImmutable.variaCharPointerCustomLen +ReturnedArrayLength TK_StructImmutable.variaCharPointerCustomLen getVariaCharPointerCustomLenElemCount() + +# TK_StructImmutable StringOnly.ConstValue 1A + 3P = 4 +ReturnsStringOnly TK_StructImmutable.constStringOnlyArrayConstLen +ReturnsStringOnly TK_StructImmutable.constStringOnlyPointerConstLen +ReturnedArrayLength TK_StructImmutable.constStringOnlyPointerConstLen 15 +ReturnsStringOnly TK_StructImmutable.constStringOnlyPointerVariaLen +ReturnsStringOnly TK_StructImmutable.constStringOnlyPointerCustomLen +ReturnedArrayLength TK_StructImmutable.constStringOnlyPointerCustomLen getConstStringOnlyPointerCustomLenElemCount() + +# TK_StructImmutable StringOnly.VariaValue 1A + 3P = 4 +ReturnsStringOnly TK_StructImmutable.variaStringOnlyArrayConstLen +ReturnsStringOnly TK_StructImmutable.variaStringOnlyPointerConstLen +ReturnedArrayLength TK_StructImmutable.variaStringOnlyPointerConstLen 15 +ReturnsStringOnly TK_StructImmutable.variaStringOnlyPointerVariaLen +ReturnsStringOnly TK_StructImmutable.variaStringOnlyPointerCustomLen +ReturnedArrayLength TK_StructImmutable.variaStringOnlyPointerCustomLen getVariaStringOnlyPointerCustomLenElemCount() + +# +# TK_Field +# + +EmitStruct TK_Field +StructPackage TK_Field com.jogamp.gluegen.test.junit.generation + +# TK_Field Primitive.ConstValue.intxx +ReturnedArrayLength TK_Field.constIntxxPointerConstOneElem 1 +MaxOneElement TK_Field.constIntxxPointerMaxOneElem +ReturnedArrayLength TK_Field.constIntxxPointerConstLen 3 +ReturnedArrayLength TK_Field.constIntxxPointerCustomLen getConstIntxxPointerCustomLenElemCount() + +# TK_Field Primitive.VariaValue.intxx +ReturnedArrayLength TK_Field.variaIntxxPointerConstOneElem 1 +MaxOneElement TK_Field.variaIntxxPointerMaxOneElem +ReturnedArrayLength TK_Field.variaIntxxPointerConstLen 3 +ReturnedArrayLength TK_Field.variaIntxxPointerCustomLen getVariaIntxxPointerCustomLenElemCount() + +# TK_Field Primitive.ConstValue.int32 +ReturnedArrayLength TK_Field.constInt32PointerConstOneElem 1 +MaxOneElement TK_Field.constInt32PointerMaxOneElem +ReturnedArrayLength TK_Field.constInt32PointerConstLen 3 +ReturnedArrayLength TK_Field.constInt32PointerCustomLen getConstInt32PointerCustomLenElemCount() + +# TK_Field Primitive.VariaValue.int32 +ReturnedArrayLength TK_Field.variaInt32PointerConstOneElem 1 +MaxOneElement TK_Field.variaInt32PointerMaxOneElem +ReturnedArrayLength TK_Field.variaInt32PointerConstLen 3 +ReturnedArrayLength TK_Field.variaInt32PointerCustomLen getVariaInt32PointerCustomLenElemCount() + +# TK_Field Struct.ConstValue.TK_Dimension +ReturnedArrayLength TK_Field.constStructPointerConstOneElem 1 +MaxOneElement TK_Field.constStructPointerMaxOneElem +ReturnedArrayLength TK_Field.constStructPointerConstLen 3 +ReturnedArrayLength TK_Field.constStructPointerCustomLen getConstStructPointerCustomLenElemCount() + +# TK_Field Struct.VariaValue.TK_Dimension +ReturnedArrayLength TK_Field.variaStructPointerConstOneElem 1 +MaxOneElement TK_Field.variaStructPointerMaxOneElem +ReturnedArrayLength TK_Field.variaStructPointerConstLen 3 +ReturnedArrayLength TK_Field.variaStructPointerCustomLen getVariaStructPointerCustomLenElemCount() + +# TK_Field String.ConstValue 1A + 3P = 4 +ReturnsString TK_Field.constCharArrayConstLen +ReturnsString TK_Field.constCharPointerConstLen +ReturnedArrayLength TK_Field.constCharPointerConstLen 15 +ReturnsString TK_Field.constCharPointerVariaLen +ReturnsString TK_Field.constCharPointerCustomLen +ReturnedArrayLength TK_Field.constCharPointerCustomLen getConstCharPointerCustomLenElemCount() + +# TK_Field String.VariaValue 1A + 3P = 4 +ReturnsString TK_Field.variaCharArrayConstLen +ReturnsString TK_Field.variaCharPointerConstLen +ReturnedArrayLength TK_Field.variaCharPointerConstLen 15 +ReturnsString TK_Field.variaCharPointerVariaLen +ReturnsString TK_Field.variaCharPointerCustomLen +ReturnedArrayLength TK_Field.variaCharPointerCustomLen getVariaCharPointerCustomLenElemCount() + +# TK_Field StringOnly.ConstValue 1A + 3P = 4 +ReturnsStringOnly TK_Field.constStringOnlyArrayConstLen +ReturnsStringOnly TK_Field.constStringOnlyPointerConstLen +ReturnedArrayLength TK_Field.constStringOnlyPointerConstLen 15 +ReturnsStringOnly TK_Field.constStringOnlyPointerVariaLen +ReturnsStringOnly TK_Field.constStringOnlyPointerCustomLen +ReturnedArrayLength TK_Field.constStringOnlyPointerCustomLen getConstStringOnlyPointerCustomLenElemCount() + +# TK_Field StringOnly.VariaValue 1A + 3P = 4 +ReturnsStringOnly TK_Field.variaStringOnlyArrayConstLen +ReturnsStringOnly TK_Field.variaStringOnlyPointerConstLen +ReturnedArrayLength TK_Field.variaStringOnlyPointerConstLen 15 +ReturnsStringOnly TK_Field.variaStringOnlyPointerVariaLen +ReturnsStringOnly TK_Field.variaStringOnlyPointerCustomLen +ReturnedArrayLength TK_Field.variaStringOnlyPointerCustomLen getVariaStringOnlyPointerCustomLenElemCount() + +# +# +# + +ReturnValueCapacity createTKFieldImmutable sizeof(TK_FieldImmutable) +ReturnValueCapacity createTKStructImmutable sizeof(TK_StructImmutable) +ReturnValueCapacity createTKField sizeof(TK_Field) +ReturnValueCapacity createTKModelMixed sizeof(TK_ModelMixed) # Imports needed by all glue code Import java.nio.* @@ -119,8 +380,10 @@ Import com.jogamp.gluegen.test.junit.generation.TK_DimensionPair Import com.jogamp.gluegen.test.junit.generation.TK_Engine Import com.jogamp.gluegen.test.junit.generation.TK_ComplicatedSuperSet Import com.jogamp.gluegen.test.junit.generation.TK_ComplicatedSubSet -Import com.jogamp.gluegen.test.junit.generation.TK_ModelConst -Import com.jogamp.gluegen.test.junit.generation.TK_ModelMutable +Import com.jogamp.gluegen.test.junit.generation.TK_FieldImmutable +Import com.jogamp.gluegen.test.junit.generation.TK_StructImmutable +Import com.jogamp.gluegen.test.junit.generation.TK_Field +Import com.jogamp.gluegen.test.junit.generation.TK_ModelMixed diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c index 0683600..b74a171 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.c @@ -636,112 +636,418 @@ MYAPI void MYAPIENTRY addByte(const char summands[2], char result[1]) { result[0] = summands[0] + summands[1]; } -MYAPI TK_ModelMutable * MYAPIENTRY createModelMutable() { - int i, j; - TK_ModelMutable * s = calloc(1, sizeof(TK_ModelMutable)); +typedef struct { + // Primitive.ConstValue.intxx 2A + 5P = 7 + int constIntxxArrayConstOneElem[1]; + int constIntxxArrayConstLen[3]; // [3] + int* constIntxxPointerConstOneElem; // + int* constIntxxPointerMaxOneElem; // + int* constIntxxPointerConstLen; // [3] + int* constIntxxPointerVariaLen; + int* constIntxxPointerCustomLen; + int constIntxxPointerCustomLenElemCount; + + // Primitive.VariaValue.intxx 2A + 5P = 7 + int variaIntxxArrayConstOneElem[1]; + int variaIntxxArrayConstLen[3]; // [3] + int* variaIntxxPointerConstOneElem; // + int* variaIntxxPointerMaxOneElem; // + int* variaIntxxPointerConstLen; // [3] + int* variaIntxxPointerVariaLen; + int* variaIntxxPointerCustomLen; + int variaIntxxPointerCustomLenElemCount; + + int32_t constInt32Element; + int32_t variaInt32Element; + + // Primitive.ConstValue 2A + 5P = 7 + int32_t constInt32ArrayConstOneElem[1]; + int32_t constInt32ArrayConstLen[3]; + int32_t* constInt32PointerConstOneElem; + int32_t* constInt32PointerMaxOneElem; + int32_t* constInt32PointerConstLen; + int32_t* constInt32PointerVariaLen; + int32_t* constInt32PointerCustomLen; + int32_t constInt32PointerCustomLenElemCount; + + // Primitive.VariaValue 2A + 5P = 7 + int32_t variaInt32ArrayConstOneElem[1]; + int32_t variaInt32ArrayConstLen[3]; + int32_t* variaInt32PointerConstOneElem; + int32_t* variaInt32PointerMaxOneElem; + int32_t* variaInt32PointerConstLen; + int32_t* variaInt32PointerVariaLen; + int32_t* variaInt32PointerCustomLen; + int32_t variaInt32PointerCustomLenElemCount; + + // Struct.ConstValue 2A + 5P = 7 + TK_Dimension constStructArrayConstOneElem[1]; + TK_Dimension constStructArrayConstLen[3]; + TK_Dimension* constStructPointerConstOneElem; + TK_Dimension* constStructPointerMaxOneElem; + TK_Dimension* constStructPointerConstLen; + TK_Dimension* constStructPointerVariaLen; + TK_Dimension* constStructPointerCustomLen; + int32_t constStructPointerCustomLenElemCount; + + // Struct.VariaValue 2A + 5P = 7 + TK_Dimension variaStructArrayConstOneElem[1]; + TK_Dimension variaStructArrayConstLen[3]; + TK_Dimension* variaStructPointerConstOneElem; + TK_Dimension* variaStructPointerMaxOneElem; + TK_Dimension* variaStructPointerConstLen; + TK_Dimension* variaStructPointerVariaLen; + TK_Dimension* variaStructPointerCustomLen; + int32_t variaStructPointerCustomLenElemCount; + + // String.ConstValue 1A + 3P = 4 + char constCharArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + char* constCharPointerConstLen; /* 'Hello CString1' len=14+1 */ + char* constCharPointerVariaLen; /* 'Hello CString2' len=14+1 */ + char* constCharPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int constCharPointerCustomLenElemCount; + + // String.VariaValue 1A + 3P = 4 + char variaCharArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + char* variaCharPointerConstLen; /* 'Hello CString1' len=14+1 */ + char* variaCharPointerVariaLen; /* 'Hello CString2' len=14+1 */ + char* variaCharPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int variaCharPointerCustomLenElemCount; + + // StringOnly.ConstValue 1A + 3P = 4 + char constStringOnlyArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + char* constStringOnlyPointerConstLen; /* 'Hello CString1' len=14+1 */ + char* constStringOnlyPointerVariaLen; /* 'Hello CString2' len=14+1 */ + char* constStringOnlyPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int constStringOnlyPointerCustomLenElemCount; + + // StringOnly.VariaValue 1A + 3P = 4 + char variaStringOnlyArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + char* variaStringOnlyPointerConstLen; /* 'Hello CString1' len=14+1 */ + char* variaStringOnlyPointerVariaLen; /* 'Hello CString2' len=14+1 */ + char* variaStringOnlyPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int variaStringOnlyPointerCustomLenElemCount; + +} TK_FieldMutable; + + +static TK_FieldMutable * createTKFieldMutable() { + TK_FieldMutable * s = calloc(1, sizeof(TK_FieldMutable)); + + // Primitive.ConstValue.intxx 2A + 5P = 7 + s->constIntxxArrayConstOneElem[0] = 88; + s->constIntxxArrayConstLen[0] = 1; + s->constIntxxArrayConstLen[1] = 2; + s->constIntxxArrayConstLen[2] = 3; + s->constIntxxPointerConstOneElem = calloc(1, sizeof(int)); + s->constIntxxPointerConstOneElem[0] = 10; + s->constIntxxPointerMaxOneElem = NULL; + s->constIntxxPointerConstLen = calloc(3, sizeof(int)); + s->constIntxxPointerConstLen[0] = 21; + s->constIntxxPointerConstLen[1] = 22; + s->constIntxxPointerConstLen[2] = 23; + s->constIntxxPointerVariaLen = NULL; + s->constIntxxPointerCustomLen = calloc(4, sizeof(int)); + s->constIntxxPointerCustomLen[0] = 31; + s->constIntxxPointerCustomLen[1] = 32; + s->constIntxxPointerCustomLen[2] = 33; + s->constIntxxPointerCustomLen[3] = 34; + s->constIntxxPointerCustomLenElemCount = 4; + + // Primitive.VariaValue.intxx 2A + 5P = 7 + s->variaIntxxArrayConstOneElem[0] = 88; + s->variaIntxxArrayConstLen[0] = 1; + s->variaIntxxArrayConstLen[1] = 2; + s->variaIntxxArrayConstLen[2] = 3; + s->variaIntxxPointerConstOneElem = calloc(1, sizeof(int)); + s->variaIntxxPointerConstOneElem[0] = 10; + s->variaIntxxPointerMaxOneElem = NULL; + s->variaIntxxPointerConstLen = calloc(3, sizeof(int)); + s->variaIntxxPointerConstLen[0] = 21; + s->variaIntxxPointerConstLen[1] = 22; + s->variaIntxxPointerConstLen[2] = 23; + s->variaIntxxPointerVariaLen = NULL; + s->variaIntxxPointerCustomLen = calloc(4, sizeof(int)); + s->variaIntxxPointerCustomLen[0] = 31; + s->variaIntxxPointerCustomLen[1] = 32; + s->variaIntxxPointerCustomLen[2] = 33; + s->variaIntxxPointerCustomLen[3] = 34; + s->variaIntxxPointerCustomLenElemCount = 4; + + // Primitive.ConstValue.int32 2A + 5P = 7 + s->constInt32ArrayConstOneElem[0] = 88; + s->constInt32ArrayConstLen[0] = 1; + s->constInt32ArrayConstLen[1] = 2; + s->constInt32ArrayConstLen[2] = 3; + s->constInt32PointerConstOneElem = calloc(1, sizeof(int32_t)); + s->constInt32PointerConstOneElem[0] = 10; + s->constInt32PointerMaxOneElem = NULL; + s->constInt32PointerConstLen = calloc(3, sizeof(int32_t)); + s->constInt32PointerConstLen[0] = 21; + s->constInt32PointerConstLen[1] = 22; + s->constInt32PointerConstLen[2] = 23; + s->constInt32PointerVariaLen = NULL; + s->constInt32PointerCustomLen = calloc(4, sizeof(int32_t)); + s->constInt32PointerCustomLen[0] = 31; + s->constInt32PointerCustomLen[1] = 32; + s->constInt32PointerCustomLen[2] = 33; + s->constInt32PointerCustomLen[3] = 34; + s->constInt32PointerCustomLenElemCount = 4; + + // Primitive.VariaValue.int32 2A + 5P = 7 + s->variaInt32ArrayConstOneElem[0] = 88; + s->variaInt32ArrayConstLen[0] = 1; + s->variaInt32ArrayConstLen[1] = 2; + s->variaInt32ArrayConstLen[2] = 3; + s->variaInt32PointerConstOneElem = calloc(1, sizeof(int32_t)); + s->variaInt32PointerConstOneElem[0] = 10; + s->variaInt32PointerMaxOneElem = NULL; + s->variaInt32PointerConstLen = calloc(3, sizeof(int32_t)); + s->variaInt32PointerConstLen[0] = 21; + s->variaInt32PointerConstLen[1] = 22; + s->variaInt32PointerConstLen[2] = 23; + s->variaInt32PointerVariaLen = NULL; + s->variaInt32PointerCustomLen = calloc(4, sizeof(int32_t)); + s->variaInt32PointerCustomLen[0] = 31; + s->variaInt32PointerCustomLen[1] = 32; + s->variaInt32PointerCustomLen[2] = 33; + s->variaInt32PointerCustomLen[3] = 34; + s->variaInt32PointerCustomLenElemCount = 4; + + // Struct.ConstValue.TK_Dimension 2A + 5P = 7 + s->constStructArrayConstOneElem[0].x = 51; + s->constStructArrayConstOneElem[0].y = 52; + s->constStructArrayConstOneElem[0].width = 53; + s->constStructArrayConstOneElem[0].height = 54; + s->constStructArrayConstLen[0].x = 61; + s->constStructArrayConstLen[0].y = 62; + s->constStructArrayConstLen[0].width = 63; + s->constStructArrayConstLen[0].height = 64; + s->constStructArrayConstLen[1].x = 71; + s->constStructArrayConstLen[1].y = 72; + s->constStructArrayConstLen[1].width = 73; + s->constStructArrayConstLen[1].height = 74; + s->constStructArrayConstLen[2].x = 81; + s->constStructArrayConstLen[2].y = 82; + s->constStructArrayConstLen[2].width = 83; + s->constStructArrayConstLen[2].height = 84; + s->constStructPointerConstOneElem = calloc(1, sizeof(TK_Dimension)); + s->constStructPointerConstOneElem[0].x = 91; + s->constStructPointerConstOneElem[0].y = 92; + s->constStructPointerConstOneElem[0].width = 93; + s->constStructPointerConstOneElem[0].height = 94; + s->constStructPointerMaxOneElem = NULL; + s->constStructPointerConstLen = calloc(3, sizeof(TK_Dimension)); + s->constStructPointerConstLen[0].x = 101; + s->constStructPointerConstLen[0].y = 102; + s->constStructPointerConstLen[0].width = 103; + s->constStructPointerConstLen[0].height = 104; + s->constStructPointerConstLen[1].x = 111; + s->constStructPointerConstLen[1].y = 112; + s->constStructPointerConstLen[1].width = 113; + s->constStructPointerConstLen[1].height = 114; + s->constStructPointerConstLen[2].x = 121; + s->constStructPointerConstLen[2].y = 123; + s->constStructPointerConstLen[2].width = 124; + s->constStructPointerConstLen[2].height = 125; + s->constStructPointerVariaLen = NULL; + s->constStructPointerCustomLen = calloc(4, sizeof(TK_Dimension)); + s->constStructPointerCustomLen[0].x = 131; + s->constStructPointerCustomLen[0].y = 132; + s->constStructPointerCustomLen[0].width = 133; + s->constStructPointerCustomLen[0].height = 134; + s->constStructPointerCustomLen[1].x = 141; + s->constStructPointerCustomLen[1].y = 142; + s->constStructPointerCustomLen[1].width = 143; + s->constStructPointerCustomLen[1].height = 144; + s->constStructPointerCustomLen[2].x = 151; + s->constStructPointerCustomLen[2].y = 152; + s->constStructPointerCustomLen[2].width = 153; + s->constStructPointerCustomLen[2].height = 154; + s->constStructPointerCustomLen[3].x = 161; + s->constStructPointerCustomLen[3].y = 162; + s->constStructPointerCustomLen[3].width = 163; + s->constStructPointerCustomLen[3].height = 164; + s->constStructPointerCustomLenElemCount = 4; + + // Struct.VariaValue.TK_Dimension 2A + 5P = 7 + s->variaStructArrayConstOneElem[0].x = 51; + s->variaStructArrayConstOneElem[0].y = 52; + s->variaStructArrayConstOneElem[0].width = 53; + s->variaStructArrayConstOneElem[0].height = 54; + s->variaStructArrayConstLen[0].x = 61; + s->variaStructArrayConstLen[0].y = 62; + s->variaStructArrayConstLen[0].width = 63; + s->variaStructArrayConstLen[0].height = 64; + s->variaStructArrayConstLen[1].x = 71; + s->variaStructArrayConstLen[1].y = 72; + s->variaStructArrayConstLen[1].width = 73; + s->variaStructArrayConstLen[1].height = 74; + s->variaStructArrayConstLen[2].x = 81; + s->variaStructArrayConstLen[2].y = 82; + s->variaStructArrayConstLen[2].width = 83; + s->variaStructArrayConstLen[2].height = 84; + s->variaStructPointerConstOneElem = calloc(1, sizeof(TK_Dimension)); + s->variaStructPointerConstOneElem[0].x = 91; + s->variaStructPointerConstOneElem[0].y = 92; + s->variaStructPointerConstOneElem[0].width = 93; + s->variaStructPointerConstOneElem[0].height = 94; + s->variaStructPointerMaxOneElem = NULL; + s->variaStructPointerConstLen = calloc(3, sizeof(TK_Dimension)); + s->variaStructPointerConstLen[0].x = 101; + s->variaStructPointerConstLen[0].y = 102; + s->variaStructPointerConstLen[0].width = 103; + s->variaStructPointerConstLen[0].height = 104; + s->variaStructPointerConstLen[1].x = 111; + s->variaStructPointerConstLen[1].y = 112; + s->variaStructPointerConstLen[1].width = 113; + s->variaStructPointerConstLen[1].height = 114; + s->variaStructPointerConstLen[2].x = 121; + s->variaStructPointerConstLen[2].y = 123; + s->variaStructPointerConstLen[2].width = 124; + s->variaStructPointerConstLen[2].height = 125; + s->variaStructPointerVariaLen = NULL; + s->variaStructPointerCustomLen = calloc(4, sizeof(TK_Dimension)); + s->variaStructPointerCustomLen[0].x = 131; + s->variaStructPointerCustomLen[0].y = 132; + s->variaStructPointerCustomLen[0].width = 133; + s->variaStructPointerCustomLen[0].height = 134; + s->variaStructPointerCustomLen[1].x = 141; + s->variaStructPointerCustomLen[1].y = 142; + s->variaStructPointerCustomLen[1].width = 143; + s->variaStructPointerCustomLen[1].height = 144; + s->variaStructPointerCustomLen[2].x = 151; + s->variaStructPointerCustomLen[2].y = 152; + s->variaStructPointerCustomLen[2].width = 153; + s->variaStructPointerCustomLen[2].height = 154; + s->variaStructPointerCustomLen[3].x = 161; + s->variaStructPointerCustomLen[3].y = 162; + s->variaStructPointerCustomLen[3].width = 163; + s->variaStructPointerCustomLen[3].height = 164; + s->variaStructPointerCustomLenElemCount = 4; + + // String.ConstValue 1A + 3P = 4 + strncpy(s->constCharArrayConstLen, "Hello Array1", sizeof(s->constCharArrayConstLen)); + s->constCharPointerConstLen = calloc(14+1, sizeof(char)); + strncpy(s->constCharPointerConstLen, "Hello CString1", 14+1); + s->constCharPointerVariaLen = NULL; + s->constCharPointerCustomLen = calloc(14+1, sizeof(char)); + strncpy(s->constCharPointerCustomLen, "Hello CString3", 14+1); + s->constCharPointerCustomLenElemCount = 14+1; + + // String.VariaValue 1A + 3P = 4 + strncpy(s->variaCharArrayConstLen, "Hello Array1", sizeof(s->variaCharArrayConstLen)); + s->variaCharPointerConstLen = calloc(14+1, sizeof(char)); + strncpy(s->variaCharPointerConstLen, "Hello CString1", 14+1); + s->variaCharPointerVariaLen = NULL; + s->variaCharPointerCustomLen = calloc(14+1, sizeof(char)); + strncpy(s->variaCharPointerCustomLen, "Hello CString3", 14+1); + s->variaCharPointerCustomLenElemCount = 14+1; + + // StringOnly.ConstValue 1A + 3P = 4 + strncpy(s->constStringOnlyArrayConstLen, "Hello Array1", sizeof(s->constStringOnlyArrayConstLen)); + s->constStringOnlyPointerConstLen = calloc(14+1, sizeof(char)); + strncpy(s->constStringOnlyPointerConstLen, "Hello CString1", 14+1); + s->constStringOnlyPointerVariaLen = NULL; + s->constStringOnlyPointerCustomLen = calloc(14+1, sizeof(char)); + strncpy(s->constStringOnlyPointerCustomLen, "Hello CString3", 14+1); + s->constStringOnlyPointerCustomLenElemCount = 14+1; + + // StringOnly.VariaValue 1A + 3P = 4 + strncpy(s->variaStringOnlyArrayConstLen, "Hello Array1", sizeof(s->variaStringOnlyArrayConstLen)); + s->variaStringOnlyPointerConstLen = calloc(14+1, sizeof(char)); + strncpy(s->variaStringOnlyPointerConstLen, "Hello CString1", 14+1); + s->variaStringOnlyPointerVariaLen = NULL; + s->variaStringOnlyPointerCustomLen = calloc(14+1, sizeof(char)); + strncpy(s->variaStringOnlyPointerCustomLen, "Hello CString3", 14+1); + s->variaStringOnlyPointerCustomLenElemCount = 14+1; - s->intxxArrayFixedLen[0]=1; - s->intxxArrayFixedLen[1]=2; - s->intxxArrayFixedLen[2]=3; - - s->intxxPointerCustomLen = calloc(3, sizeof(int)); - s->intxxPointerCustomLen[0] = 11; - s->intxxPointerCustomLen[1] = 12; - s->intxxPointerCustomLen[2] = 13; - s->intxxPointerCustomLenVal=3; + return s; +} - s->int32ArrayFixedLen[0] = 21; - s->int32ArrayFixedLen[1] = 22; - s->int32ArrayFixedLen[2] = 23; +static void destroyTKFieldMutable(TK_FieldMutable * s) { + assert(NULL!=s); - s->int32ArrayOneElem[0] = 30; + assert(NULL!=s->constIntxxPointerConstOneElem); + free(s->constIntxxPointerConstOneElem); + assert(NULL!=s->constIntxxPointerConstLen); + free(s->constIntxxPointerConstLen); + if( 0 < s->constIntxxPointerCustomLenElemCount && NULL!=s->constIntxxPointerCustomLen ) { + // NOTE Ownership is ambiguous + free(s->constIntxxPointerCustomLen); + } - s->int32PointerCustomLen = calloc(3, sizeof(int)); - s->int32PointerCustomLen[0] = 31; - s->int32PointerCustomLen[1] = 32; - s->int32PointerCustomLen[2] = 33; - s->int32PointerCustomLenVal=3; - - s->int32PointerOneElem = calloc(1, sizeof(int)); - s->int32PointerOneElem[0] = 41; + assert(NULL!=s->constInt32PointerConstOneElem); + free(s->constInt32PointerConstOneElem); + assert(NULL!=s->constInt32PointerConstLen); + free(s->constInt32PointerConstLen); + if( 0 < s->constInt32PointerCustomLenElemCount && NULL!=s->constInt32PointerCustomLen ) { + // NOTE Ownership is ambiguous + free(s->constInt32PointerCustomLen); + } + + assert(NULL!=s->constStructPointerConstOneElem); + free(s->constStructPointerConstOneElem); + assert(NULL!=s->constStructPointerConstLen); + free(s->constStructPointerConstLen); + if( 0 < s->constStructPointerCustomLenElemCount && NULL!=s->constStructPointerCustomLen ) { + // NOTE Ownership is ambiguous + free(s->constStructPointerCustomLen); + } + + assert(NULL!=s->constCharPointerConstLen); + free(s->constCharPointerConstLen); + if( 0 < s->constCharPointerCustomLenElemCount && NULL!=s->constCharPointerCustomLen ) { + // NOTE Ownership is ambiguous + free(s->constCharPointerCustomLen); + } - for(i=0; i<4; i++) { - for(j=0; j<4; j++) { - s->mat4x4[i][j] = i*4 + j; - } + assert(NULL!=s->constStringOnlyPointerConstLen); + free(s->constStringOnlyPointerConstLen); + if( 0 < s->constStringOnlyPointerCustomLenElemCount && NULL!=s->constStringOnlyPointerCustomLen ) { + // NOTE Ownership is ambiguous + free(s->constStringOnlyPointerCustomLen); } - s->structArrayFixedLen[0].x = 51; - s->structArrayFixedLen[0].y = 52; - s->structArrayFixedLen[0].width = 53; - s->structArrayFixedLen[0].height = 54; - s->structArrayFixedLen[1].x = 61; - s->structArrayFixedLen[1].y = 62; - s->structArrayFixedLen[1].width = 63; - s->structArrayFixedLen[1].height = 64; - s->structArrayFixedLen[2].x = 71; - s->structArrayFixedLen[2].y = 72; - s->structArrayFixedLen[2].width = 73; - s->structArrayFixedLen[2].height = 74; - - s->structArrayOneElem[0].x = 81; - s->structArrayOneElem[0].y = 82; - s->structArrayOneElem[0].width = 83; - s->structArrayOneElem[0].height = 84; - - s->structPointerCustomLen = (TK_Dimension *) calloc(3, sizeof(TK_Dimension)); - s->structPointerCustomLen[0].x = 91; - s->structPointerCustomLen[0].y = 92; - s->structPointerCustomLen[0].width = 93; - s->structPointerCustomLen[0].height = 94; - s->structPointerCustomLen[1].x = 101; - s->structPointerCustomLen[1].y = 102; - s->structPointerCustomLen[1].width = 103; - s->structPointerCustomLen[1].height = 104; - s->structPointerCustomLen[2].x = 111; - s->structPointerCustomLen[2].y = 112; - s->structPointerCustomLen[2].width = 113; - s->structPointerCustomLen[2].height = 114; - s->structPointerCustomLenVal = 3; - - s->structPointerOneElem = (TK_Dimension *) calloc(1, sizeof(TK_Dimension)); - s->structPointerOneElem[0].x = 121; - s->structPointerOneElem[0].y = 122; - s->structPointerOneElem[0].width = 123; - s->structPointerOneElem[0].height = 124; + free(s); +} - s->ctx = (void *) 0x123456789abcdef0UL; +MYAPI TK_FieldImmutable * MYAPIENTRY createTKFieldImmutable() { + return (TK_FieldImmutable*) createTKFieldMutable(); +} +MYAPI void MYAPIENTRY destroyTKFieldImmutable(TK_FieldImmutable * s) { + destroyTKFieldMutable((TK_FieldMutable*) s); +} - strncpy(s->modelNameArrayFixedLen, "Hello Array", sizeof(s->modelNameArrayFixedLen)); +MYAPI TK_StructImmutable * MYAPIENTRY createTKStructImmutable() { + return (TK_StructImmutable*) createTKFieldMutable(); +} +MYAPI void MYAPIENTRY destroyTKStructImmutable(TK_StructImmutable * s) { + destroyTKFieldMutable((TK_FieldMutable*) s); +} - s->modelNamePointerCString = calloc(13+1, sizeof(char)); - strncpy(s->modelNamePointerCString, "Hello CString", 13+1); +MYAPI TK_Field * MYAPIENTRY createTKField() { + return (TK_Field*) createTKFieldMutable(); +} +MYAPI void MYAPIENTRY destroyTKField(TK_Field * s) { + destroyTKFieldMutable((TK_FieldMutable*) s); +} - s->modelNamePointerCustomLen = calloc(13+1, sizeof(char)); - strncpy(s->modelNamePointerCustomLen, "Hello Pointer", 13+1); - s->modelNamePointerCustomLenVal = 13+1; +MYAPI TK_ModelMixed* MYAPIENTRY createTKModelMixed() { + int i, j; + TK_ModelMixed * s = calloc(1, sizeof(TK_ModelMixed)); + for(i=0; i<4; i++) { + for(j=0; j<4; j++) { + s->mat4x4[i][j] = i*4 + j; + } + } + s->ctx = (void *) 0x123456789abcdef0UL; return s; } -MYAPI void MYAPIENTRY destroyModelMutable(TK_ModelMutable * s) { +MYAPI void MYAPIENTRY destroyTKModelMixed(TK_ModelMixed * s) { assert(NULL!=s); - assert(NULL!=s->intxxPointerCustomLen); - assert(NULL!=s->int32PointerCustomLen); - assert(NULL!=s->int32PointerOneElem); - assert(NULL!=s->structPointerCustomLen); - free(s->intxxPointerCustomLen); - free(s->int32PointerCustomLen); - free(s->int32PointerOneElem); - free(s->structPointerCustomLen); - free(s->modelNamePointerCString); - free(s->modelNamePointerCustomLen); free(s); } -MYAPI TK_ModelConst * MYAPIENTRY createModelConst() { - return (TK_ModelConst *)createModelMutable(); -} -MYAPI void MYAPIENTRY destroyModelConst(TK_ModelConst * s) { - destroyModelMutable((TK_ModelMutable *)s); -} diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h index 9465cd9..89848d7 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h @@ -437,71 +437,320 @@ MYAPI void MYAPIENTRY intToRgba(int irgba, char rgbaSink[4]); MYAPI void MYAPIENTRY addInt(const int summands[2], int result[1]); MYAPI void MYAPIENTRY addByte(const char summands[2], char result[1]); -typedef struct { - const int intxxArrayFixedLen[3]; - - const int * intxxPointerCustomLen; - const int intxxPointerCustomLenVal; - - const int32_t int32ArrayFixedLen[3]; - const int32_t int32ArrayOneElem[1]; - - const int32_t * int32PointerCustomLen; - const int32_t int32PointerCustomLenVal; - - const int32_t * int32PointerOneElem; - - const float mat4x4[4][4]; +// +// TK_FieldImmutable +// - const TK_Dimension structArrayFixedLen[3]; - const TK_Dimension structArrayOneElem[1]; - - const TK_Dimension * structPointerCustomLen; - const int32_t structPointerCustomLenVal; - const TK_Dimension * structPointerOneElem; +typedef struct { + // Primitive.ConstValue.intxx 2A + 5P = 7 + const int constIntxxArrayConstOneElem[1]; + const int constIntxxArrayConstLen[3]; // [3] + const int* constIntxxPointerConstOneElem; // [1] + const int* constIntxxPointerMaxOneElem; // null + const int* constIntxxPointerConstLen; // [3] + const int* constIntxxPointerVariaLen; // null + const int* constIntxxPointerCustomLen; // [4] + int constIntxxPointerCustomLenElemCount; + + // Primitive.VariaValue.intxx 2A + 5P = 7 + int variaIntxxArrayConstOneElem[1]; + int variaIntxxArrayConstLen[3]; // [3] + int* variaIntxxPointerConstOneElem; // [1] + int* variaIntxxPointerMaxOneElem; // null + int* variaIntxxPointerConstLen; // [3] + int* variaIntxxPointerVariaLen; // null + int* variaIntxxPointerCustomLen; // [4] + int variaIntxxPointerCustomLenElemCount; + + const int32_t constInt32Element; + int32_t variaInt32Element; + + // Primitive.ConstValue.int32 2A + 5P = 7 + const int32_t constInt32ArrayConstOneElem[1]; + const int32_t constInt32ArrayConstLen[3]; + const int32_t* constInt32PointerConstOneElem; + const int32_t* constInt32PointerMaxOneElem; + const int32_t* constInt32PointerConstLen; + const int32_t* constInt32PointerVariaLen; + const int32_t* constInt32PointerCustomLen; + int32_t constInt32PointerCustomLenElemCount; + + // Primitive.VariaValue.int32 2A + 5P = 7 + int32_t variaInt32ArrayConstOneElem[1]; + int32_t variaInt32ArrayConstLen[3]; + int32_t* variaInt32PointerConstOneElem; + int32_t* variaInt32PointerMaxOneElem; + int32_t* variaInt32PointerConstLen; + int32_t* variaInt32PointerVariaLen; + int32_t* variaInt32PointerCustomLen; + int32_t variaInt32PointerCustomLenElemCount; + + // Struct.ConstValue.TK_Dimension 2A + 5P = 7 + const TK_Dimension constStructArrayConstOneElem[1]; + const TK_Dimension constStructArrayConstLen[3]; + const TK_Dimension* constStructPointerConstOneElem; + const TK_Dimension* constStructPointerMaxOneElem; + const TK_Dimension* constStructPointerConstLen; + const TK_Dimension* constStructPointerVariaLen; + const TK_Dimension* constStructPointerCustomLen; + int32_t constStructPointerCustomLenElemCount; + + // Struct.VariaValue 2A + 5P = 7 + TK_Dimension variaStructArrayConstOneElem[1]; + TK_Dimension variaStructArrayConstLen[3]; + TK_Dimension* variaStructPointerConstOneElem; + TK_Dimension* variaStructPointerMaxOneElem; + TK_Dimension* variaStructPointerConstLen; + TK_Dimension* variaStructPointerVariaLen; + TK_Dimension* variaStructPointerCustomLen; + int32_t variaStructPointerCustomLenElemCount; + + // String.ConstValue 1A + 3P = 4 + const char constCharArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + const char* constCharPointerConstLen; /* 'Hello CString1' len=14+1 */ + const char* constCharPointerVariaLen; // null + const char* constCharPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int constCharPointerCustomLenElemCount; + + // String.VariaValue 1A + 3P = 4 + char variaCharArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + char* variaCharPointerConstLen; /* 'Hello CString1' len=14+1 */ + char* variaCharPointerVariaLen; /* 'Hello CString2' len=14+1 */ + char* variaCharPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int variaCharPointerCustomLenElemCount; + + // StringOnly.ConstValue 1A + 3P = 4 + const char constStringOnlyArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + const char* constStringOnlyPointerConstLen; /* 'Hello CString1' len=14+1 */ + const char* constStringOnlyPointerVariaLen; /* 'Hello CString2' len=14+1 */ + const char* constStringOnlyPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int constStringOnlyPointerCustomLenElemCount; + + // StringOnly.VariaValue 1A + 3P = 4 + char variaStringOnlyArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + char* variaStringOnlyPointerConstLen; /* 'Hello CString1' len=14+1 */ + char* variaStringOnlyPointerVariaLen; /* 'Hello CString2' len=14+1 */ + char* variaStringOnlyPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int variaStringOnlyPointerCustomLenElemCount; + +} TK_FieldImmutable; + +MYAPI TK_FieldImmutable * MYAPIENTRY createTKFieldImmutable(); +MYAPI void MYAPIENTRY destroyTKFieldImmutable(TK_FieldImmutable * s); - TK_Context ctx; +// +// TK_StructImmutable +// - char modelNameArrayFixedLen[12]; /* 'Hello Array' len=11+1 */ - char * modelNamePointerCString; /* 'Hello CString' len=13+1 */ - const char * modelNamePointerCustomLen; /* 'Hello Pointer' len=13+1 */ - const int modelNamePointerCustomLenVal; /* 13+1 */ +typedef struct { + // Primitive.ConstValue.intxx 2A + 5P = 7 + const int constIntxxArrayConstOneElem[1]; + const int constIntxxArrayConstLen[3]; // [3] + const int* constIntxxPointerConstOneElem; // + const int* constIntxxPointerMaxOneElem; // + const int* constIntxxPointerConstLen; // [3] + const int* constIntxxPointerVariaLen; + const int* constIntxxPointerCustomLen; + int constIntxxPointerCustomLenElemCount; + + // Primitive.VariaValue.intxx 2A + 5P = 7 + int variaIntxxArrayConstOneElem[1]; + int variaIntxxArrayConstLen[3]; // [3] + int* variaIntxxPointerConstOneElem; // + int* variaIntxxPointerMaxOneElem; // + int* variaIntxxPointerConstLen; // [3] + int* variaIntxxPointerVariaLen; + int* variaIntxxPointerCustomLen; + int variaIntxxPointerCustomLenElemCount; + + const int32_t constInt32Element; + int32_t variaInt32Element; + + // Primitive.ConstValue 2A + 5P = 7 + const int32_t constInt32ArrayConstOneElem[1]; + const int32_t constInt32ArrayConstLen[3]; + const int32_t* constInt32PointerConstOneElem; + const int32_t* constInt32PointerMaxOneElem; + const int32_t* constInt32PointerConstLen; + const int32_t* constInt32PointerVariaLen; + const int32_t* constInt32PointerCustomLen; + int32_t constInt32PointerCustomLenElemCount; + + // Primitive.VariaValue 2A + 5P = 7 + int32_t variaInt32ArrayConstOneElem[1]; + int32_t variaInt32ArrayConstLen[3]; + int32_t* variaInt32PointerConstOneElem; + int32_t* variaInt32PointerMaxOneElem; + int32_t* variaInt32PointerConstLen; + int32_t* variaInt32PointerVariaLen; + int32_t* variaInt32PointerCustomLen; + int32_t variaInt32PointerCustomLenElemCount; + + // Struct.ConstValue 2A + 5P = 7 + const TK_Dimension constStructArrayConstOneElem[1]; + const TK_Dimension constStructArrayConstLen[3]; + const TK_Dimension* constStructPointerConstOneElem; + const TK_Dimension* constStructPointerMaxOneElem; + const TK_Dimension* constStructPointerConstLen; + const TK_Dimension* constStructPointerVariaLen; + const TK_Dimension* constStructPointerCustomLen; + int32_t constStructPointerCustomLenElemCount; + + // Struct.VariaValue 2A + 5P = 7 + TK_Dimension variaStructArrayConstOneElem[1]; + TK_Dimension variaStructArrayConstLen[3]; + TK_Dimension* variaStructPointerConstOneElem; + TK_Dimension* variaStructPointerMaxOneElem; + TK_Dimension* variaStructPointerConstLen; + TK_Dimension* variaStructPointerVariaLen; + TK_Dimension* variaStructPointerCustomLen; + int32_t variaStructPointerCustomLenElemCount; + + // String.ConstValue 1A + 3P = 4 + const char constCharArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + const char* constCharPointerConstLen; /* 'Hello CString1' len=14+1 */ + const char* constCharPointerVariaLen; /* 'Hello CString2' len=14+1 */ + const char* constCharPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int constCharPointerCustomLenElemCount; + + // String.VariaValue 1A + 3P = 4 + char variaCharArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + char* variaCharPointerConstLen; /* 'Hello CString1' len=14+1 */ + char* variaCharPointerVariaLen; /* 'Hello CString2' len=14+1 */ + char* variaCharPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int variaCharPointerCustomLenElemCount; + + // StringOnly.ConstValue 1A + 3P = 4 + const char constStringOnlyArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + const char* constStringOnlyPointerConstLen; /* 'Hello CString1' len=14+1 */ + const char* constStringOnlyPointerVariaLen; /* 'Hello CString2' len=14+1 */ + const char* constStringOnlyPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int constStringOnlyPointerCustomLenElemCount; + + // StringOnly.VariaValue 1A + 3P = 4 + char variaStringOnlyArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + char* variaStringOnlyPointerConstLen; /* 'Hello CString1' len=14+1 */ + char* variaStringOnlyPointerVariaLen; /* 'Hello CString2' len=14+1 */ + char* variaStringOnlyPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int variaStringOnlyPointerCustomLenElemCount; + +} TK_StructImmutable; + +MYAPI TK_StructImmutable * MYAPIENTRY createTKStructImmutable(); +MYAPI void MYAPIENTRY destroyTKStructImmutable(TK_StructImmutable * s); -} TK_ModelConst; +// +// TK_Field +// typedef struct { - int intxxArrayFixedLen[3]; - - int * intxxPointerCustomLen; - int intxxPointerCustomLenVal; + // Primitive.ConstValue.intxx 2A + 5P = 7 + const int constIntxxArrayConstOneElem[1]; + const int constIntxxArrayConstLen[3]; // [3] + const int* constIntxxPointerConstOneElem; // + const int* constIntxxPointerMaxOneElem; // + const int* constIntxxPointerConstLen; // [3] + const int* constIntxxPointerVariaLen; + const int* constIntxxPointerCustomLen; + int constIntxxPointerCustomLenElemCount; + + // Primitive.VariaValue.intxx 2A + 5P = 7 + int variaIntxxArrayConstOneElem[1]; + int variaIntxxArrayConstLen[3]; // [3] + int* variaIntxxPointerConstOneElem; // + int* variaIntxxPointerMaxOneElem; // + int* variaIntxxPointerConstLen; // [3] + int* variaIntxxPointerVariaLen; + int* variaIntxxPointerCustomLen; + int variaIntxxPointerCustomLenElemCount; + + const int32_t constInt32Element; + int32_t variaInt32Element; + + // Primitive.ConstValue 2A + 5P = 7 + const int32_t constInt32ArrayConstOneElem[1]; + const int32_t constInt32ArrayConstLen[3]; + const int32_t* constInt32PointerConstOneElem; + const int32_t* constInt32PointerMaxOneElem; + const int32_t* constInt32PointerConstLen; + const int32_t* constInt32PointerVariaLen; + const int32_t* constInt32PointerCustomLen; + int32_t constInt32PointerCustomLenElemCount; + + // Primitive.VariaValue 2A + 5P = 7 + int32_t variaInt32ArrayConstOneElem[1]; + int32_t variaInt32ArrayConstLen[3]; + int32_t* variaInt32PointerConstOneElem; + int32_t* variaInt32PointerMaxOneElem; + int32_t* variaInt32PointerConstLen; + int32_t* variaInt32PointerVariaLen; + int32_t* variaInt32PointerCustomLen; + int32_t variaInt32PointerCustomLenElemCount; + + // Struct.ConstValue 2A + 5P = 7 + const TK_Dimension constStructArrayConstOneElem[1]; + const TK_Dimension constStructArrayConstLen[3]; + const TK_Dimension* constStructPointerConstOneElem; + const TK_Dimension* constStructPointerMaxOneElem; + const TK_Dimension* constStructPointerConstLen; + const TK_Dimension* constStructPointerVariaLen; + const TK_Dimension* constStructPointerCustomLen; + int32_t constStructPointerCustomLenElemCount; + + // Struct.VariaValue 2A + 5P = 7 + TK_Dimension variaStructArrayConstOneElem[1]; + TK_Dimension variaStructArrayConstLen[3]; + TK_Dimension* variaStructPointerConstOneElem; + TK_Dimension* variaStructPointerMaxOneElem; + TK_Dimension* variaStructPointerConstLen; + TK_Dimension* variaStructPointerVariaLen; + TK_Dimension* variaStructPointerCustomLen; + int32_t variaStructPointerCustomLenElemCount; + + // String.ConstValue 1A + 3P = 4 + const char constCharArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + const char* constCharPointerConstLen; /* 'Hello CString1' len=14+1 */ + const char* constCharPointerVariaLen; /* 'Hello CString2' len=14+1 */ + const char* constCharPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int constCharPointerCustomLenElemCount; + + // String.VariaValue 1A + 3P = 4 + char variaCharArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + char* variaCharPointerConstLen; /* 'Hello CString1' len=14+1 */ + char* variaCharPointerVariaLen; /* 'Hello CString2' len=14+1 */ + char* variaCharPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int variaCharPointerCustomLenElemCount; + + // StringOnly.ConstValue 1A + 3P = 4 + const char constStringOnlyArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + const char* constStringOnlyPointerConstLen; /* 'Hello CString1' len=14+1 */ + const char* constStringOnlyPointerVariaLen; /* 'Hello CString2' len=14+1 */ + const char* constStringOnlyPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int constStringOnlyPointerCustomLenElemCount; + + // StringOnly.VariaValue 1A + 3P = 4 + char variaStringOnlyArrayConstLen[13]; /* 'Hello Array1' len=12+1 */ + char* variaStringOnlyPointerConstLen; /* 'Hello CString1' len=14+1 */ + char* variaStringOnlyPointerVariaLen; /* 'Hello CString2' len=14+1 */ + char* variaStringOnlyPointerCustomLen; /* 'Hello CString3' len=14+1 */ + int variaStringOnlyPointerCustomLenElemCount; + +} TK_Field; + +MYAPI TK_Field * MYAPIENTRY createTKField(); +MYAPI void MYAPIENTRY destroyTKField(TK_Field * s); - int32_t int32ArrayFixedLen[3]; - int32_t int32ArrayOneElem[1]; - - int32_t * int32PointerCustomLen; - int32_t int32PointerCustomLenVal; - - int32_t * int32PointerOneElem; +// +// +// +typedef struct { float mat4x4[4][4]; - TK_Dimension structArrayFixedLen[3]; - TK_Dimension structArrayOneElem[1]; - - TK_Dimension * structPointerCustomLen; - int32_t structPointerCustomLenVal; - TK_Dimension * structPointerOneElem; - TK_Context ctx; - char modelNameArrayFixedLen[12]; /* 'Hello Array' len=11+1 */ - char * modelNamePointerCString; /* 'Hello CString' len=13+1 */ - char * modelNamePointerCustomLen; /* 'Hello Pointer' len=13+1 */ - int modelNamePointerCustomLenVal; /* 13+1 */ +} TK_ModelMixed; -} TK_ModelMutable; +MYAPI TK_ModelMixed* MYAPIENTRY createTKModelMixed(); +MYAPI void MYAPIENTRY destroyTKModelMixed(TK_ModelMixed* s); -MYAPI TK_ModelConst * MYAPIENTRY createModelConst(); -MYAPI void MYAPIENTRY destroyModelConst(TK_ModelConst * s); -MYAPI TK_ModelMutable * MYAPIENTRY createModelMutable(); -MYAPI void MYAPIENTRY destroyModelMutable(TK_ModelMutable * s); diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c new file mode 100644 index 0000000..3fff02c --- /dev/null +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.c @@ -0,0 +1,20 @@ +#include "test2.h" + +#include <stdio.h> + +int Initialize(const T2_InitializeOptions* Options) { + fprintf(stderr, "T2 Initialize API 0x%X, product %s, version %s\n", + Options->ApiVersion, + Options->ProductName, + Options->ProductVersion); + fprintf(stderr, "- MemFuncs: alloc %p, realloc %p, release %p\n", + Options->AllocateMemoryFunction, + Options->ReallocateMemoryFunction, + Options->ReleaseMemoryFunction); + return 0; +} + +int Shutdown() { + return 0; +} + diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg new file mode 100644 index 0000000..3b68598 --- /dev/null +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg @@ -0,0 +1,52 @@ +Package com.jogamp.gluegen.test.junit.generation +JavaClass BindingtestT2 +Style InterfaceAndImpl +JavaOutputDir classes +NativeOutputDir native + +# Use a ProcAddressTable so we dynamically look up the routines +EmitProcAddressTable true +ProcAddressTableClassName BindingtestT2ProcAddressTable +GetProcAddressTableExpr _table +ProcAddressNameExpr PFN $UPPERCASE({0}) PROC + +# Force all of the methods to be emitted using dynamic linking so we +# don't need to link against any emulation library on the desktop or +# depend on the presence of an import library for a particular device +ForceProcAddressGen __ALL__ + +# Also force the calling conventions of the locally generated function +# pointer typedefs for these routines to MYAPIENTRY +# LocalProcAddressCallingConvention __ALL__ MYAPIENTRY + +Opaque long T2_AllocateMemoryFunc +Opaque long T2_ReallocateMemoryFunc +Opaque long T2_ReleaseMemoryFunc + +EmitStruct T2_ThreadAffinity +StructPackage T2_ThreadAffinity com.jogamp.gluegen.test.junit.generation + +EmitStruct T2_InitializeOptions +StructPackage T2_InitializeOptions com.jogamp.gluegen.test.junit.generation +ReturnsStringOnly T2_InitializeOptions.ProductName +ReturnsStringOnly T2_InitializeOptions.ProductVersion +Opaque long T2_InitializeOptions.Reserved +ImmutableAccess long T2_InitializeOptions.Reserved +# ReturnedArrayLength T2_InitializeOptions.OverrideThreadAffinity 1 +MaxOneElement T2_InitializeOptions.OverrideThreadAffinity + +ReturnsOpaque long T2_InitializeOptions.AllocateMemoryFunction +ReturnsOpaque long T2_InitializeOptions.ReallocateMemoryFunc +ReturnsOpaque long T2_InitializeOptions.ReleaseMemoryFunc + +CustomCCode #include "test2.h" + +Import com.jogamp.gluegen.test.junit.generation.BindingtestT2 +Import com.jogamp.gluegen.test.junit.generation.T2_InitializeOptions +Import com.jogamp.gluegen.test.junit.generation.T2_ThreadAffinity + +CustomJavaCode BindingtestT2Impl private static BindingtestT2ProcAddressTable _table = new BindingtestT2ProcAddressTable(); +CustomJavaCode BindingtestT2Impl public static void resetProcAddressTable(DynamicLookupHelper lookup) { +CustomJavaCode BindingtestT2Impl _table.reset(lookup); +CustomJavaCode BindingtestT2Impl } + diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h new file mode 100644 index 0000000..e27e9aa --- /dev/null +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h @@ -0,0 +1,37 @@ + +#include <gluegen_stdint.h> +#include <gluegen_stddef.h> + +typedef void* ( * T2_AllocateMemoryFunc)(size_t SizeInBytes, size_t Alignment); + +typedef void* ( * T2_ReallocateMemoryFunc)(void* Pointer, size_t SizeInBytes, size_t Alignment); + +typedef void ( * T2_ReleaseMemoryFunc)(void* Pointer); + +typedef struct { + int32_t ApiVersion; + uint64_t NetworkWork; + uint64_t StorageIo; + uint64_t WebSocketIo; + uint64_t P2PIo; + uint64_t HttpRequestIo; + uint64_t RTCIo; +} T2_ThreadAffinity; + +typedef struct { + int32_t ApiVersion; + T2_AllocateMemoryFunc AllocateMemoryFunction; + T2_ReallocateMemoryFunc ReallocateMemoryFunction; + T2_ReleaseMemoryFunc ReleaseMemoryFunction; + + const char* ProductName; + + const char* ProductVersion; + + void* Reserved; + + T2_ThreadAffinity* OverrideThreadAffinity; +} T2_InitializeOptions; + +extern int Initialize(const T2_InitializeOptions* Options); +extern int Shutdown(); diff --git a/www/index.html b/www/index.html index 5729d74..7000629 100644 --- a/www/index.html +++ b/www/index.html @@ -10,7 +10,7 @@ <body> <div id="container"> <div id="header"> - <div id="slogan">JNI binding code generator</div> + <div id="slogan">Native Binding Generator for Java™</div> <div id="logo"><a href="http://jogamp.org/">Gluegen</a></div> </div> <div id="menu"> @@ -30,34 +30,48 @@ <div id="sidebar"> <h3>Useful Links</h3> <ul> + <li><a href="https://jogamp.org/cgit/gluegen.git/about/">GlueGen Git Repo</a></li> + <li><a href="../../deployment/jogamp-next/javadoc/gluegen/javadoc/">GlueGen API-Doc</a></li> + <li><a href="../doc/GlueGen_Mapping.html">GlueGen Native Data & Function Mapping</a></li> <li><a href="../doc/manual/">GlueGen Manual</a></li> - <li><a href="../../deployment/jogamp-next/javadoc/gluegen/javadoc/">GlueGen Runtime JavaDoc</a></li> + <li><a href="../doc/HowToBuild.html">How To Build</a></li> + <li><a href="../doc/JogAmpMacOSVersions.html">JogAmp's MacOS Version Support</a></li> </ul> </div> <div id="text" class="fill"> <p> - GlueGen is a tool which automatically generates the Java and JNI code - necessary to call C libraries. + GlueGen is a compiler for function and data-structure declarations, + generating Java™ and JNI C code offline at compile time + and allows using native libraries within your Java™ application. </p> <p> - It reads as input ANSI C header files + It reads ANSI C header files and separate configuration files which provide control over many aspects of the glue code generation. GlueGen uses a complete ANSI C parser and an internal representation (IR) capable of representing all C types to represent the APIs for which it generates interfaces. It has the ability to perform significant transformations on the IR - before glue code emission. GlueGen is currently powerful enough to - bind even low-level APIs such as the Java Native Interface (JNI) and - the AWT Native Interface (JAWT) back up to the Java programming - language. + before glue code emission. + </p> + <p> + GlueGen can produce native foreign function bindings to Java™ as well as + map native data structures to be fully accessible from Java™ including + potential calls to embedded function pointer. + </p> + <p> + GlueGen is also capable to bind even low-level APIs such as the Java™ Native Interface (JNI) and + the AWT Native Interface (JAWT) back up to the Java™ programming language. </p> <p> - GlueGen is currently used for the projects - <a href="../../jogl/www/">JOGL</a>, - <a href="../../jocl/www/">JOCL</a> and - <a href="../../joal/www/">JOAL</a>. + GlueGen utilizes <a href="https://jogamp.org/cgit/jcpp.git/about/">JCPP</a>, migrated C preprocessor written in Java™. + </p> + <p> + GlueGen is used for the JogAmp projects + <a href="../../joal/www/">JOAL</a>, + <a href="../../jogl/www/">JOGL</a> and + <a href="../../jocl/www/">JOCL</a>. </p> </div> |