diff options
-rw-r--r-- | doc/GlueGen_Mapping.html | 507 | ||||
-rw-r--r-- | doc/GlueGen_Mapping.md | 71 | ||||
-rw-r--r-- | src/java/com/jogamp/gluegen/JavaEmitter.java | 267 | ||||
-rw-r--r-- | src/java/com/jogamp/gluegen/cgram/types/Type.java | 18 | ||||
-rw-r--r-- | src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java | 336 |
5 files changed, 672 insertions, 527 deletions
diff --git a/doc/GlueGen_Mapping.html b/doc/GlueGen_Mapping.html index 537ce89..57d2089 100644 --- a/doc/GlueGen_Mapping.html +++ b/doc/GlueGen_Mapping.html @@ -1,407 +1,22 @@ -<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> - +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> +<head> + <meta charset="utf-8" /> + <meta name="generator" content="pandoc" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> + <title>GlueGen_Mapping.md</title> + <style> + code{white-space: pre-wrap;} + span.smallcaps{font-variant: small-caps;} + span.underline{text-decoration: underline;} + div.column{display: inline-block; vertical-align: top; width: 50%;} + div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} + ul.task-list{list-style: none;} + .display.math{display: block; text-align: center; margin: 0.5rem auto;} + </style> + <link rel="stylesheet" href="/usr/local/projects/Text_Processing/pandoc-buttondown-cgit/pandoc-data/css/cgit-buttondown.css" /> +</head> +<body> <nav id="TOC" role="doc-toc"> <strong>Contents</strong><label for="contents">⊕</label> <input type="checkbox" id="contents"> @@ -432,7 +47,6 @@ div.footnotes li[id^="fn"] </ul></li> </ul> </nav> - <style> table, th, td { border: 1px solid black; @@ -1151,7 +765,10 @@ getBuffer()</td> <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;">setVal(int v) [<a +href="#signature-int32_t--maxoneelement-java-owned">1</a>][<a +href="#signature-const-int32_t--maxoneelement-java-owned">2</a>] <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> @@ -1228,7 +845,19 @@ static int getValElemCount()</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;"></td> +<td style="text-align: left;">int32_t* val</td> +<td style="text-align: left;">setVal(boolean subset, 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> @@ -1239,7 +868,7 @@ int getValElemCount()</td> <td style="text-align: left;">Java</td> <td style="text-align: left;">Starts w/ null elements</td> </tr> -<tr class="odd"> +<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, @@ -1252,7 +881,7 @@ getValCount()</strong></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"> +<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> @@ -1263,7 +892,7 @@ releaseVal()</td> <td style="text-align: left;">Java</td> <td style="text-align: left;">String only, w/ EOS</td> </tr> -<tr class="odd"> +<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> setName(byte[] @@ -1276,6 +905,62 @@ getName() <br> boolean isNameNull() <br> int getNameElemCount()</td> </tr> </tbody> </table> +<h4 id="signature-int32_t--maxoneelement-java-owned">Signature +<code>int32_t *</code> MaxOneElement, Java owned</h4> +<pre><code> /** + * Setter for native field <code>variaInt32PointerMaxOneElem</code>, referencing an array with initial element count of <code>0</code>. Maximum element count is <code>1</code>. + * <p> + * NativeSig <code>(PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1</code> + * </p> + */ + public final TK_Field setVariaInt32PointerMaxOneElem(int src) { .. }</code></pre> +<p>Will reuse memory if existing, otherwise allocating memory.</p> +<h4 id="signature-const-int32_t--maxoneelement-java-owned">Signature +<code>const int32_t *</code> MaxOneElement, Java owned</h4> +<pre><code> /** + * Setter for native field <code>constInt32PointerMaxOneElem</code>, referencing an array with initial element count of <code>0</code>. Maximum element count is <code>1</code>. + * <p> + * NativeSig <code>(PointerType) 'int32_t *' -> (const int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1</code> + * </p> + */ + public final TK_Field setConstInt32PointerMaxOneElem(int src) { .. } + </code></pre> +<p>Always replaces memory due to <code>const</code> value modifier.</p> +<h4 id="signature-int32_t--constelemcount-3-natively-owned">Signature +<code>int32_t *</code> ConstElemCount 3, Natively owned</h4> +<pre><code> /** + * Setter for native field <code>variaInt32PointerConstLen</code>, referencing a natively owned array with fixed element count of <code>3</code>. + * <p> + * NativeSig <code>(PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1</code> + * </p> + * <p> + * Copies the given source elements into the respective field's existing memory. + * </p> + * @param src the source array of elements + * @param srcPos starting element position within the source array with 'srcPos >= 0` && `srcPos + length <= src.length`, otherwise an {@link IndexOutOfBoundsException} is thrown + * @param destPos starting element position within the destination with 'destPos >= 0` && `destPos + length <= elemCount`, otherwise an exception is thrown + * @param length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length` && `destPos + length <= elemCount`, otherwise an {@link IndexOutOfBoundsException} is thrown + * @return this instance of chaining + */ + public final TK_Field setVariaInt32PointerConstLen(int[] src, final int srcPos, final int destPos, final int length) { .. }</code></pre> +<h4 id="signature-int32_t--freesize-java-owned">Signature +<code>int32_t *</code> FreeSize, Java owned</h4> +<pre><code> /** + * Setter for native field <code>variaInt32PointerVariaLen</code>, referencing an array with initial element count of <code>0</code>. + * <p> + * NativeSig <code>(PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1</code> + * </p> + * <p> + * Copies the given source elements into the respective field, either writing into the existing memory or creating a new memory and referencing it. + * </p> + * @param subset if `true` keeps the underlying memory and only allows to set up to `elemCount` elements. Otherwise may replace the underlying memory if `destPos + length != elemCount`. + * @param src the source array of elements + * @param srcPos starting element position within the source array with 'srcPos >= 0` && `srcPos + length <= src.length`, otherwise an {@link IndexOutOfBoundsException} is thrown + * @param destPos starting element position within the destination with 'destPos >= 0`. If `subset == true`, `destPos + length <= elemCount` also must be be `true`. Otherwise an exception is thrown + * @param length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length`, otherwise an {@link IndexOutOfBoundsException} is thrown + * @return this instance of chaining + */ + public final TK_Field setVariaInt32PointerVariaLen(final boolean subset, int[] src, final int srcPos, final int destPos, final int length) { .. } </code></pre> <h3 id="struct-setter-pseudo-code">Struct Setter Pseudo-Code</h3> <ul> <li><em>ImmutableAccess</em>: Drops setter, immutable</li> @@ -1370,3 +1055,5 @@ folder to your GlueGen <code>includeRefid</code> element:</p> <p>To identity a GlueGen code generation run, GlueGen defines the following macros:</p> <pre><code> #define __GLUEGEN__ 2</code></pre> +</body> +</html> diff --git a/doc/GlueGen_Mapping.md b/doc/GlueGen_Mapping.md index dcdb51a..faa4ca3 100644 --- a/doc/GlueGen_Mapping.md +++ b/doc/GlueGen_Mapping.md @@ -325,18 +325,85 @@ A similar mapping is produced for `struct` types, i.e. *compounds*. | | 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 | setVal(int v) \[[1](#signature-int32_t--maxoneelement-java-owned)\]\[[2](#signature-const-int32_t--maxoneelement-java-owned)\] <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 | +| | int32_t* val | setVal(boolean subset, 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() <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| +#### Signature `int32_t *` MaxOneElement, Java owned +``` + /** + * Setter for native field <code>variaInt32PointerMaxOneElem</code>, referencing an array with initial element count of <code>0</code>. Maximum element count is <code>1</code>. + * <p> + * NativeSig <code>(PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1</code> + * </p> + */ + public final TK_Field setVariaInt32PointerMaxOneElem(int src) { .. } +``` + +Will reuse memory if existing, otherwise allocating memory. + +#### Signature `const int32_t *` MaxOneElement, Java owned +``` + /** + * Setter for native field <code>constInt32PointerMaxOneElem</code>, referencing an array with initial element count of <code>0</code>. Maximum element count is <code>1</code>. + * <p> + * NativeSig <code>(PointerType) 'int32_t *' -> (const int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1</code> + * </p> + */ + public final TK_Field setConstInt32PointerMaxOneElem(int src) { .. } + +``` + +Always replaces memory due to `const` value modifier. + +#### Signature `int32_t *` ConstElemCount 3, Natively owned +``` + /** + * Setter for native field <code>variaInt32PointerConstLen</code>, referencing a natively owned array with fixed element count of <code>3</code>. + * <p> + * NativeSig <code>(PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1</code> + * </p> + * <p> + * Copies the given source elements into the respective field's existing memory. + * </p> + * @param src the source array of elements + * @param srcPos starting element position within the source array with 'srcPos >= 0` && `srcPos + length <= src.length`, otherwise an {@link IndexOutOfBoundsException} is thrown + * @param destPos starting element position within the destination with 'destPos >= 0` && `destPos + length <= elemCount`, otherwise an exception is thrown + * @param length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length` && `destPos + length <= elemCount`, otherwise an {@link IndexOutOfBoundsException} is thrown + * @return this instance of chaining + */ + public final TK_Field setVariaInt32PointerConstLen(int[] src, final int srcPos, final int destPos, final int length) { .. } +``` + +#### Signature `int32_t *` FreeSize, Java owned +``` + /** + * Setter for native field <code>variaInt32PointerVariaLen</code>, referencing an array with initial element count of <code>0</code>. + * <p> + * NativeSig <code>(PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1</code> + * </p> + * <p> + * Copies the given source elements into the respective field, either writing into the existing memory or creating a new memory and referencing it. + * </p> + * @param subset if `true` keeps the underlying memory and only allows to set up to `elemCount` elements. Otherwise may replace the underlying memory if `destPos + length != elemCount`. + * @param src the source array of elements + * @param srcPos starting element position within the source array with 'srcPos >= 0` && `srcPos + length <= src.length`, otherwise an {@link IndexOutOfBoundsException} is thrown + * @param destPos starting element position within the destination with 'destPos >= 0`. If `subset == true`, `destPos + length <= elemCount` also must be be `true`. Otherwise an exception is thrown + * @param length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length`, otherwise an {@link IndexOutOfBoundsException} is thrown + * @return this instance of chaining + */ + public final TK_Field setVariaInt32PointerVariaLen(final boolean subset, int[] src, final int srcPos, final int destPos, final int length) { .. } +``` + ### Struct Setter Pseudo-Code * *ImmutableAccess*: Drops setter, immutable diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java index 63c7d73..f4edbee 100644 --- a/src/java/com/jogamp/gluegen/JavaEmitter.java +++ b/src/java/com/jogamp/gluegen/JavaEmitter.java @@ -1089,7 +1089,7 @@ public class JavaEmitter implements GlueEmitter { field + "\" in type \"" + structCTypeName + "\")", fieldType.getASTLocusTag()); } - generateGetterSignature(javaUnit, fieldType, false, false, fieldType.getName(), fieldName, capitalizeString(fieldName), null, false, null); + generateGetterSignature(javaUnit, fieldType, false, false, fieldType.getName(), fieldName, capitalizeString(fieldName), null, false, false, null, null); javaUnit.emitln(" {"); javaUnit.emitln(" return " + fieldType.getName() + ".create( accessor.slice( " + fieldName+"_offset[mdIdx], "+fieldName+"_size[mdIdx] ) );"); @@ -1128,7 +1128,7 @@ public class JavaEmitter implements GlueEmitter { if( !immutableField && !fieldType.isConst() ) { // Setter - generateSetterSignature(javaUnit, fieldType, MethodAccess.PUBLIC, false, false, containingJTypeName, fieldName, capFieldName, null, javaTypeName, null, false, null); + generateSetterSignature(javaUnit, fieldType, MethodAccess.PUBLIC, false, false, containingJTypeName, fieldName, capFieldName, null, javaTypeName, null, false, false, null, null, null); javaUnit.emitln(" {"); if( fieldTypeNativeSizeFixed ) { javaUnit.emitln(" accessor.set" + capJavaTypeName + "At(" + fieldName+"_offset[mdIdx], src);"); @@ -1141,7 +1141,7 @@ public class JavaEmitter implements GlueEmitter { } // Getter - generateGetterSignature(javaUnit, fieldType, false, false, javaTypeName, fieldName, capFieldName, null, false, null); + generateGetterSignature(javaUnit, fieldType, false, false, javaTypeName, fieldName, capFieldName, null, false, false, null, null); javaUnit.emitln(" {"); javaUnit.emit (" return "); if( fieldTypeNativeSizeFixed ) { @@ -1200,59 +1200,86 @@ public class JavaEmitter implements GlueEmitter { //---------------------------------------------------------------------- // Internals only below this point // - - private void generateIsNullSignature(final CodeUnit unit, final Type origFieldType, - 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()); + private void generateArrayFieldNote(final CodeUnit unit, final String leadIn, final String leadOut, + final Type origFieldType, final String fieldName, + final boolean constElemCount, final boolean maxOneElem, final String elemCountExpr) { + if( null != leadIn ) { + unit.emit(leadIn+" "); + } + unit.emit("native field <code>"+fieldName+"</code>, referencing "); if( null != elemCountExpr ) { - unit.emit(", with "+(constElemCount?"fixed":"initial")+" array length of <code>"+elemCountExpr+"</code>"); + unit.emit((constElemCount?"a natively owned array with fixed":"an array with initial")+" element count of <code>"+elemCountExpr+"</code>."); + } else { + unit.emit((constElemCount?"a natively owned":"an")+" array."); } - unit.emitln(" */"); + if( maxOneElem ) { + unit.emit(" Maximum element count is <code>1</code>."); + } + if( null == leadOut ) { + unit.emitln(); + unit.emitln(" * <p>"); + unit.emitln(" * NativeSig <code>"+origFieldType.getSignature(null).toString()+"</code>"); + unit.emitln(" * </p>"); + } else { + unit.emit(" NativeSig <code>"+origFieldType.getSignature(null).toString()+"</code>"); + unit.emit(" "+leadOut); + unit.emitln(); + } + } + private void generateIsNullSignature(final CodeUnit unit, final Type origFieldType, + final boolean abstractMethod, final String fieldName, + final String capitalizedFieldName, + final boolean constElemCount, final boolean maxOneElem, final String elemCountExpr) { + unit.emitln(" /**"); + unit.emitln(" * Returns `true` if native pointer <code>"+fieldName+"</code> is `null`, otherwise `false`."); + unit.emitln(" * <p>"); + generateArrayFieldNote(unit, " * Corresponds to", null, origFieldType, fieldName, constElemCount, maxOneElem, elemCountExpr); + unit.emitln(" * </p>"); + unit.emitln(" */"); unit.emit(" public " + (abstractMethod ? "abstract " : "final ") + "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(" */"); + final boolean constElemCount, final boolean maxOneElement, final String elemCountExpr) { + unit.emitln(" /**"); + generateArrayFieldNote(unit, " * Releases memory referenced by", null, origFieldType, fieldName, constElemCount, maxOneElement, elemCountExpr); + unit.emitln(" */"); unit.emit(" public " + (abstractMethod ? "abstract " : "final ") + 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 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>"); + final String returnTypeName, final String fieldName, final String capitalizedFieldName, final String customArgs, + final boolean constElemCount, final boolean maxOneElem, final String elemCountExpr, final String apiDocTail) { + unit.emitln(" /**"); + generateArrayFieldNote(unit, " * Getter for", null, origFieldType, fieldName, constElemCount, maxOneElem, elemCountExpr); + if( null != apiDocTail ) { + unit.emitln(" * "+apiDocTail); } - unit.emitln(" */"); + unit.emitln(" */"); unit.emit(" public " + (staticMethod ? "static " : "final ") + (abstractMethod ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "("); if( null != customArgs ) { unit.emit(customArgs); } unit.emit(")"); } - - 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>"); - } - 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); + final String customArgsPre, final String paramTypeName, final String customArgsPost, + final boolean constElemCount, final boolean maxOneElem, + final String elemCountExpr, final String apiDocDetail, final String apiDocArgs) { + unit.emitln(" /**"); + generateArrayFieldNote(unit, " * Setter for", null, origFieldType, fieldName, constElemCount, maxOneElem, elemCountExpr); + if( null != apiDocDetail ) { + unit.emitln(" * <p>"); + unit.emitln(" * "+apiDocDetail); + unit.emitln(" * </p>"); + } + if( null != apiDocArgs ) { + unit.emitln(apiDocArgs); + } + unit.emitln(" */"); unit.emit(" "+accessMod.getJavaName() + " " + (staticMethod ? "static " : "final ") + (abstractMethod ? "abstract " : "") + returnTypeName + " set" + capitalizedFieldName + "("); if( null != customArgsPre ) { unit.emit(customArgsPre+", "); @@ -1427,8 +1454,40 @@ public class JavaEmitter implements GlueEmitter { return false; } - 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 GetElemValueApiDocTail = "@return element value of the corresponding field-array"; + private static final String GetElemCountApiDocTail = "@return element count of the corresponding field-array"; + + private static final String SetSubArrayArgsPost = "final int srcPos, final int destPos, final int length"; + private static final String SetSubArrayArgsCheck = " 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 SetSubArrayApiDocDetail = "Copies the given source elements into the respective field's existing memory."; + private static final String SetSubArrayApiDocArgs = + " * @param src the source array of elements\n"+ + " * @param srcPos starting element position within the source array with 'srcPos >= 0` && `srcPos + length <= src.length`, otherwise an {@link IndexOutOfBoundsException} is thrown\n"+ + " * @param destPos starting element position within the destination with 'destPos >= 0` && `destPos + length <= elemCount`, otherwise an exception is thrown\n"+ + " * @param length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length` && `destPos + length <= elemCount`, otherwise an {@link IndexOutOfBoundsException} is thrown\n"+ + " * @return this instance of chaining"; + + private static final String SetArrayArgsPre = "final boolean subset"; + private static final String SetArrayArgsPost = "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(\"subset \"+subset+\", src[pos \"+srcPos+\", length \"+src.length+\"], destPos \"+destPos+\", length \"+length); }"; + private static final String SetArrayApiDocDetail = "Copies the given source elements into the respective field, either writing into the existing memory or creating a new memory and referencing it."; + private static final String SetArrayApiDocArgs = + " * @param subset if `true` keeps the underlying memory and only allows to set up to `elemCount` elements. Otherwise may replace the underlying memory if `destPos + length != elemCount`.\n"+ + " * @param src the source array of elements\n"+ + " * @param srcPos starting element position within the source array with 'srcPos >= 0` && `srcPos + length <= src.length`, otherwise an {@link IndexOutOfBoundsException} is thrown\n"+ + " * @param destPos starting element position within the destination with 'destPos >= 0`. If `subset == true`, `destPos + length <= elemCount` also must be be `true`. Otherwise an exception is thrown\n"+ + " * @param length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length`, otherwise an {@link IndexOutOfBoundsException} is thrown\n"+ + " * @return this instance of chaining"; + + private static final String SetReplaceArrayArgsPost = "final int srcPos, final int length"; + private static final String SetReplaceArrayArgsCheck = " if( 0 > srcPos || 0 > length || srcPos + length > src.length ) { throw new IndexOutOfBoundsException(\"src[pos \"+srcPos+\", length \"+src.length+\"], length \"+length); }"; + private static final String SetReplaceArrayApiDocDetail = "Replaces the respective field's memory with a new memory segment containing given source elements and referencing it."; + private static final String SetReplaceArrayApiDocArgs = + " * @param src the source array of elements\n"+ + " * @param srcPos starting element position within the source array with 'srcPos >= 0` && `srcPos + length <= src.length`, otherwise an {@link IndexOutOfBoundsException} is thrown\n"+ + " * @param length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length`, otherwise an {@link IndexOutOfBoundsException} is thrown\n"+ + " * @return this instance of chaining"; + 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); }"; @@ -1665,20 +1724,21 @@ public class JavaEmitter implements GlueEmitter { // if( ownElemCountHandling ) { if( constElemCount ) { - generateGetterSignature(unit, fieldType, staticElemCount, false, "int", fieldName, capitalFieldName+"ElemCount", null, constElemCount, elemCountExpr); + generateGetterSignature(unit, fieldType, staticElemCount, false, "int", fieldName, capitalFieldName+"ElemCount", null, constElemCount, maxOneElement, elemCountExpr, GetElemCountApiDocTail); unit.emitln(" { return "+elemCountExpr+"; }"); } else if( useGetCStringLength ) { - generateGetterSignature(unit, fieldType, staticElemCount, false, "int", fieldName, capitalFieldName+"ElemCount", null, constElemCount, elemCountExpr); + generateGetterSignature(unit, fieldType, staticElemCount, false, "int", fieldName, capitalFieldName+"ElemCount", null, constElemCount, maxOneElement, elemCountExpr, GetElemCountApiDocTail); 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); + generateGetterSignature(unit, fieldType, staticElemCount, false, "int", fieldName, capitalFieldName+"ElemCount", null, constElemCount, maxOneElement, elemCountExpr, GetElemCountApiDocTail); unit.emitln(" { return _"+fieldName+"ArrayLen; }"); if( !immutableAccess ) { - generateSetterSignature(unit, fieldType, MethodAccess.PRIVATE, staticElemCount, false, "void", fieldName, capitalFieldName+"ElemCount", null, "int", null, constElemCount, elemCountExpr); + generateSetterSignature(unit, fieldType, MethodAccess.PRIVATE, staticElemCount, false, "void", fieldName, capitalFieldName+"ElemCount", null, "int", null, + constElemCount, maxOneElement, elemCountExpr, null, null); unit.emitln(" { _"+fieldName+"ArrayLen = src; }"); } } @@ -1687,13 +1747,13 @@ public class JavaEmitter implements GlueEmitter { // Null query for pointer if( isPointer ) { - generateIsNullSignature(unit, fieldType, false, fieldName, capitalFieldName, constElemCount, elemCountExpr); + generateIsNullSignature(unit, fieldType, false, fieldName, capitalFieldName, constElemCount, maxOneElement, 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); + generateReleaseSignature(unit, fieldType, false, containingJTypeName, fieldName, capitalFieldName, constElemCount, maxOneElement, elemCountExpr); unit.emitln(" {"); unit.emitln(" accessor.setLongAt("+fieldName+"_offset[mdIdx], 0, md.pointerSizeInBytes()); // write nullptr"); unit.emitln(" _eb"+capitalFieldName+" = null;"); @@ -1708,20 +1768,21 @@ public class JavaEmitter implements GlueEmitter { // Setter if( immutableAccess ) { - generateSetterAPIDoc(unit, "SKIP setter for immutable", fieldType, fieldName, constElemCount, elemCountExpr); + generateArrayFieldNote(unit, " /** SKIP setter for immutable", " */", fieldType, fieldName, constElemCount, maxOneElement, elemCountExpr); unit.emitln(); } else if( isPointer && isConstValue && constElemCount ) { - generateSetterAPIDoc(unit, "SKIP setter for constValue constElemCount Pointer w/ native ownership", fieldType, fieldName, constElemCount, elemCountExpr); + generateArrayFieldNote(unit, " /** SKIP setter for constValue constElemCount Pointer w/ native ownership", " */", fieldType, fieldName, constElemCount, maxOneElement, elemCountExpr); unit.emitln(); } else if( !isPointer && isConstValue ) { - generateSetterAPIDoc(unit, "SKIP setter for constValue Array", fieldType, fieldName, constElemCount, elemCountExpr); + generateArrayFieldNote(unit, " /** SKIP setter for constValue Array", " */", fieldType, fieldName, constElemCount, maxOneElement, elemCountExpr); unit.emitln(); } else if( isPrimitive ) { // Setter Primitive if( maxOneElement ) { // Setter Primitive Single Pointer + Array if( isPointer ) { - generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, constElemCount, elemCountExpr); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, + constElemCount, maxOneElement, elemCountExpr, null, null); if( isConstValue ) { // constElemCount excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership unit.emitln(" {"); @@ -1768,7 +1829,8 @@ public class JavaEmitter implements GlueEmitter { } } } else { // array && !isConstValue - generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, constElemCount, elemCountExpr); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, + constElemCount, maxOneElement, elemCountExpr, null, null); unit.emitln(" {"); unit.emitln(" ElementBuffer.wrap("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])"); unit.emit (" .getByteBuffer()"); @@ -1786,7 +1848,8 @@ public class JavaEmitter implements GlueEmitter { 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); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, "String", null, + constElemCount, maxOneElement, elemCountExpr, null, null); unit.emitln(" {"); unit.emitln(" final byte[] srcBytes = src.getBytes(_charset);"); if( constElemCount ) { @@ -1808,30 +1871,31 @@ public class JavaEmitter implements GlueEmitter { doneString = true; } if( doneString && isStringOnly ) { - generateSetterAPIDoc(unit, "SKIP setter for String alternative (ByteBuffer)", fieldType, fieldName, constElemCount, elemCountExpr); + generateArrayFieldNote(unit, " /** SKIP setter for String alternative (ByteBuffer)", " */", fieldType, fieldName, constElemCount, maxOneElement, 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); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", + SetReplaceArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetReplaceArrayApiDocDetail, SetReplaceArrayApiDocArgs); 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()"); + unit.emitln(SetReplaceArrayArgsCheck); + unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", length);"); + unit.emit (" eb.getByteBuffer()"); if( !isByteBuffer ) { unit.emit(".as"+primJElemTypeBufferName+"()"); } - unit.emitln(".position(destPos) ) ).put(src, srcPos, length).rewind();"); + unit.emitln(".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, " "); + emitSetElemCount(unit, setElemCountLengthFunc, "length", !useGetCStringLength, capitalFieldName, structCType, " "); unit.emitln(" return this;"); unit.emitln(" }"); } // else SKIP setter for constValue Array } else if( constElemCount || !isPointer ) { - generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", SetArrayArgs, constElemCount, elemCountExpr); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", + SetSubArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetSubArrayApiDocDetail, SetSubArrayApiDocArgs); unit.emitln(" {"); - unit.emitln(SetArrayArgsCheck); + unit.emitln(SetSubArrayArgsCheck); unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";"); unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };"); if( isPointer ) { @@ -1839,33 +1903,45 @@ public class JavaEmitter implements GlueEmitter { } else { unit.emitln(" final ElementBuffer eb = ElementBuffer.wrap("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);"); } - unit.emit (" ( ( "+primJElemTypeBufferName+")(eb.getByteBuffer()"); + unit.emit (" ( ("+primJElemTypeBufferName+") eb.getByteBuffer()"); if( !isByteBuffer ) { unit.emit(".as"+primJElemTypeBufferName+"()"); } - unit.emitln(".position(destPos) ) ).put(src, srcPos, length).rewind();"); + 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); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, SetArrayArgsPre, baseJElemTypeName+"[]", + SetArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetArrayApiDocDetail, SetArrayApiDocArgs); unit.emitln(" {"); unit.emitln(SetArrayArgsCheck); unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";"); - unit.emitln(" if( destPos + length <= elemCount ) {"); + unit.emitln(" if( subset || destPos + length == elemCount ) {"); + unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"subset \"+subset+\", destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };"); unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);"); - unit.emit (" ( ( "+primJElemTypeBufferName+")(eb.getByteBuffer()"); + unit.emit (" ( ("+primJElemTypeBufferName+") eb.getByteBuffer()"); if( !isByteBuffer ) { unit.emit(".as"+primJElemTypeBufferName+"()"); } - unit.emitln(".position(destPos) ) ).put(src, srcPos, length).rewind();"); + 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()"); + unit.emit (" final "+primJElemTypeBufferName+" ebBB = eb.getByteBuffer()"); if( !isByteBuffer ) { unit.emit(".as"+primJElemTypeBufferName+"()"); } - unit.emitln(".position(destPos) ) ).put(src, srcPos, length).rewind();"); + unit.emitln(";"); + unit.emitln(" if( 0 < destPos ) {"); + unit.emitln(" final ElementBuffer pre_eb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);"); + unit.emit (" final "+primJElemTypeBufferName+" pre_ebBB = ("+primJElemTypeBufferName+") pre_eb.getByteBuffer()"); + if( !isByteBuffer ) { + unit.emit(".as"+primJElemTypeBufferName+"()"); + } + unit.emitln(".position(0).limit(destPos);"); + unit.emitln(" ebBB.put(pre_ebBB);"); + unit.emitln(" }"); + unit.emitln(" ebBB.put(src, srcPos, length).rewind();"); unit.emitln(" eb.storeDirectAddress(getBuffer(), "+fieldName+"_offset[mdIdx]);"); unit.emitln(" _eb"+capitalFieldName+" = eb;"); emitSetElemCount(unit, setElemCountLengthFunc, "newElemCount", !useGetCStringLength, capitalFieldName, structCType, " "); @@ -1880,7 +1956,8 @@ public class JavaEmitter implements GlueEmitter { if( maxOneElement ) { // Setter Struct Single Pointer + Array if( isPointer ) { - generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, constElemCount, elemCountExpr); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, + constElemCount, maxOneElement, elemCountExpr, null, null); if( isConstValue ) { // constElemCount excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership unit.emitln(" {"); @@ -1915,7 +1992,8 @@ public class JavaEmitter implements GlueEmitter { } } } else if( !isConstValue ) { // array && !isConstValue - generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, constElemCount, elemCountExpr); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName, null, + constElemCount, maxOneElement, elemCountExpr, null, null); unit.emitln(" {"); unit.emitln(" ElementBuffer.wrap("+baseJElemTypeName+".size(), 1, getBuffer(), "+fieldName+"_offset[mdIdx])"); unit.emitln(" .put(0, src.getBuffer());"); @@ -1928,24 +2006,25 @@ public class JavaEmitter implements GlueEmitter { 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); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", + SetReplaceArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetReplaceArrayApiDocDetail, SetReplaceArrayApiDocArgs); unit.emitln(" {"); - unit.emitln(SetArrayArgsCheck); - unit.emitln(" final int newElemCount = destPos + length;"); - unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+baseJElemTypeName+".size(), newElemCount);"); + unit.emitln(SetReplaceArrayArgsCheck); + unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+baseJElemTypeName+".size(), length);"); unit.emitln(" for(int i=0; i<length; ++i) {"); - unit.emitln(" eb.put(destPos+i, src[srcPos+i].getBuffer());"); + unit.emitln(" eb.put(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, " "); + emitSetElemCount(unit, setElemCountLengthFunc, "length", !useGetCStringLength, capitalFieldName, structCType, " "); unit.emitln(" return this;"); unit.emitln(" }"); } // else SKIP setter for constValue Array } else if( constElemCount || !isPointer ) { - generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", SetArrayArgs, constElemCount, elemCountExpr); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", + SetSubArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetSubArrayApiDocDetail, SetSubArrayApiDocArgs); unit.emitln(" {"); - unit.emitln(SetArrayArgsCheck); + unit.emitln(SetSubArrayArgsCheck); unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";"); unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };"); if( isPointer ) { @@ -1959,11 +2038,13 @@ public class JavaEmitter implements GlueEmitter { unit.emitln(" return this;"); unit.emitln(" }"); } else /* if( !constElemCount && isPointer ) */ { - generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, null, baseJElemTypeName+"[]", SetArrayArgs, constElemCount, elemCountExpr); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, SetArrayArgsPre, baseJElemTypeName+"[]", + SetArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetArrayApiDocDetail, SetArrayApiDocArgs); unit.emitln(" {"); unit.emitln(SetArrayArgsCheck); unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";"); - unit.emitln(" if( destPos + length <= elemCount ) {"); + unit.emitln(" if( subset || destPos + length == elemCount ) {"); + unit.emitln(" if( destPos + length > elemCount ) { throw new IndexOutOfBoundsException(\"subset \"+subset+\", destPos \"+destPos+\" + length \"+length+\" > elemCount \"+elemCount); };"); unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);"); unit.emitln(" for(int i=0; i<length; ++i) {"); unit.emitln(" eb.put(destPos+i, src[srcPos+i].getBuffer());"); @@ -1971,6 +2052,11 @@ public class JavaEmitter implements GlueEmitter { unit.emitln(" } else {"); unit.emitln(" final int newElemCount = destPos + length;"); unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+baseJElemTypeName+".size(), newElemCount);"); + + unit.emitln(" if( 0 < destPos ) {"); + unit.emitln(" final ElementBuffer pre_eb = ElementBuffer.derefPointer("+baseJElemTypeName+".size(), elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);"); + unit.emitln(" eb.put(pre_eb.getByteBuffer(), 0, 0, destPos);"); + unit.emitln(" }"); unit.emitln(" for(int i=0; i<length; ++i) {"); unit.emitln(" eb.put(destPos+i, src[srcPos+i].getBuffer());"); unit.emitln(" }"); @@ -1983,7 +2069,8 @@ public class JavaEmitter implements GlueEmitter { } unit.emitln(); if( !isConstValue ) { - generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, "final int destPos", baseJElemTypeName, null, constElemCount, elemCountExpr); + generateSetterSignature(unit, fieldType, accessMod, false, false, containingJTypeName, fieldName, capitalFieldName, "final int destPos", baseJElemTypeName, null, + constElemCount, maxOneElement, elemCountExpr, null, null); unit.emitln(" {"); unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";"); unit.emitln(" if( destPos + 1 > elemCount ) { throw new IndexOutOfBoundsException(\"destPos \"+destPos+\" + 1 > elemCount \"+elemCount); };"); @@ -2004,7 +2091,8 @@ public class JavaEmitter implements GlueEmitter { if( isPrimitive ) { // Getter Primitive Pointer + Array if( maxOneElement ) { - generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName, fieldName, capitalFieldName, null, constElemCount, elemCountExpr); + generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName, fieldName, capitalFieldName, null, + constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); if( isPointer ) { unit.emitln(" return ElementBuffer.derefPointer("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])"); @@ -2021,7 +2109,8 @@ public class JavaEmitter implements GlueEmitter { } else { boolean doneString = false; if( isString && isByteBuffer ) { - generateGetterSignature(unit, fieldType, false, false, "String", fieldName, capitalFieldName+(isStringOnly?"":"AsString"), null, constElemCount, elemCountExpr); + generateGetterSignature(unit, fieldType, false, false, "String", fieldName, capitalFieldName+(isStringOnly?"":"AsString"), null, + constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";"); if( isPointer ) { @@ -2041,10 +2130,11 @@ public class JavaEmitter implements GlueEmitter { doneString = true; } if( doneString && isStringOnly ) { - generateSetterAPIDoc(unit, "SKIP getter for String alternative (ByteBuffer)", fieldType, fieldName, constElemCount, elemCountExpr); + generateArrayFieldNote(unit, " /** SKIP getter for String alternative (ByteBuffer)", " */", fieldType, fieldName, constElemCount, maxOneElement, elemCountExpr); unit.emitln(); } else { - generateGetterSignature(unit, fieldType, false, false, primJElemTypeBufferName, fieldName, capitalFieldName, null, constElemCount, elemCountExpr); + generateGetterSignature(unit, fieldType, false, false, primJElemTypeBufferName, fieldName, capitalFieldName, null, + constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); if( isPointer ) { unit.emitln(" return ElementBuffer.derefPointer("+primElemSizeExpr+", "+getElemCountFuncExpr+", getBuffer(), "+fieldName+"_offset[mdIdx])"); @@ -2060,7 +2150,8 @@ public class JavaEmitter implements GlueEmitter { unit.emitln(); } if( !doneString ) { - generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName+"[]", fieldName, capitalFieldName, "final int srcPos, "+baseJElemTypeName+" dest[], "+GetArrayArgs, constElemCount, elemCountExpr); + generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName+"[]", fieldName, capitalFieldName, "final int srcPos, "+baseJElemTypeName+" dest[], "+GetArrayArgs, + constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); unit.emitln(GetArrayArgsCheck); unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";"); @@ -2084,7 +2175,8 @@ public class JavaEmitter implements GlueEmitter { } else { // Getter Struct Pointer + Array if( maxOneElement ) { - generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName, fieldName, capitalFieldName, null, constElemCount, elemCountExpr); + generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName, fieldName, capitalFieldName, null, + constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); unit.emitln(" return "+baseJElemTypeName+".create("); if( isPointer ) { @@ -2095,7 +2187,8 @@ public class JavaEmitter implements GlueEmitter { unit.emitln(" }"); unit.emitln(); } else { - generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName+"[]", fieldName, capitalFieldName, "final int srcPos, "+baseJElemTypeName+" dest[], "+GetArrayArgs, constElemCount, elemCountExpr); + generateGetterSignature(unit, fieldType, false, false, baseJElemTypeName+"[]", fieldName, capitalFieldName, "final int srcPos, "+baseJElemTypeName+" dest[], "+GetArrayArgs, + constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); unit.emitln(GetArrayArgsCheck); unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";"); diff --git a/src/java/com/jogamp/gluegen/cgram/types/Type.java b/src/java/com/jogamp/gluegen/cgram/types/Type.java index 04c46af..2c32235 100644 --- a/src/java/com/jogamp/gluegen/cgram/types/Type.java +++ b/src/java/com/jogamp/gluegen/cgram/types/Type.java @@ -170,11 +170,11 @@ public abstract class Type implements SemanticEqualityOp, ASTLocusTagProvider { sb.append(val); return sb; } - // For debugging - public final String getDebugString() { - final StringBuilder sb = new StringBuilder(); + public final StringBuilder getSignature(StringBuilder sb) { + if( null == sb ) { + sb = new StringBuilder(); + } boolean prepComma = false; - sb.append("CType["); sb.append("(").append(getClass().getSimpleName()).append(") "); if( isTypedef() ) { sb.append("typedef "); @@ -211,7 +211,6 @@ public abstract class Type implements SemanticEqualityOp, ASTLocusTagProvider { } else { sb.append(" ZERO"); } - append(sb, "[", prepComma); prepComma=false; { append(sb, "const[", prepComma); prepComma=false; { @@ -268,8 +267,15 @@ public abstract class Type implements SemanticEqualityOp, ASTLocusTagProvider { if( isVoid() ) { append(sb, "void", prepComma); prepComma=true; } - sb.append("]"); } + return sb; + } + + // For debugging + public final String getDebugString() { + final StringBuilder sb = new StringBuilder(); + sb.append("CType["); + getSignature(sb); sb.append("]"); return sb.toString(); } 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 ed23f54..071d2d7 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java @@ -1481,7 +1481,6 @@ public class BaseClass extends SingletonJunitCase { } /** 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()); @@ -1545,7 +1544,7 @@ public class BaseClass extends SingletonJunitCase { // 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); + model.setConstInt32PointerVariaLen(ia, 0, ia.length); } // verify 1 { @@ -1620,7 +1619,7 @@ public class BaseClass extends SingletonJunitCase { // 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); + model.setConstInt32PointerCustomLen(ia, 1 /* srcPos */, ia.length-2); } // verify 2 { @@ -1735,7 +1734,6 @@ public class BaseClass extends SingletonJunitCase { } /** 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()); @@ -1801,18 +1799,10 @@ public class BaseClass extends SingletonJunitCase { Assert.assertEquals(220 + i, s[0]); } } - { - } // 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); - } - 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); + final int[] ia = { 0, 321, 322 }; + model.setVariaInt32PointerConstLen(ia, 1, 1, 2); } // verify 3 { @@ -1822,14 +1812,19 @@ public class BaseClass extends SingletonJunitCase { final IntBuffer allB = model.getVariaInt32PointerConstLen(); Assert.assertEquals(size, all.length); Assert.assertEquals(size, allB.limit()); - for(int i=0; i<size; i++) { + for(int i=0; i<1; i++) { + 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]); + } + for(int i=1; i<size; 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]); } } - } } Assert.assertEquals(0, model.getVariaInt32PointerVariaLenElemCount()); @@ -1855,7 +1850,7 @@ public class BaseClass extends SingletonJunitCase { // 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); + model.setVariaInt32PointerVariaLen(false /* subset */, ia, 0, 0, ia.length); } // verify 1 { @@ -1927,10 +1922,10 @@ public class BaseClass extends SingletonJunitCase { Assert.assertEquals(120 + i, s[0]); } } - // write 2 via int[] set + // write 2 via int[] set all, keep 1st element by writing to destPos 1, 5 elements total, 4 written { final int[] ia = { 0, 220, 221, 222, 223, 224, 0 }; - model.setVariaInt32PointerCustomLen(ia, 1 /* srcPos */, 0 /* destPos */, ia.length-2); + model.setVariaInt32PointerCustomLen(false /* subset */, ia, 2 /* srcPos */, 1 /* destPos */, ia.length-1-2); } // verify 2 { @@ -1940,13 +1935,54 @@ public class BaseClass extends SingletonJunitCase { final IntBuffer allB = model.getVariaInt32PointerCustomLen(); Assert.assertEquals(size, all.length); Assert.assertEquals(size, allB.limit()); - for(int i=0; i<size; i++) { + for(int i=0; i<1; i++) { + 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]); + } + for(int i=1; i<size; i++) { 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]); } } + // write 3 via int[] set a subset only + { + final int[] ia = { 0, 0, 322, 323, 324, 0, 0 }; + model.setVariaInt32PointerCustomLen(true /* subset */, ia, 2 /* srcPos */, 2 /* destPos */, 3); + } + // 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++) { + System.err.printf("%d/%d: A %d, B %d%n", i, size, all[i], allB.get(i)); + } + for(int i=0; i<1; i++) { + 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]); + } + for(int i=1; i<2; i++) { + Assert.assertEquals(220 + i, all[i]); + Assert.assertEquals(220 + i, allB.get(i)); + final int[] s = model.getVariaInt32PointerCustomLen(i, new int[3], 1, 1); + Assert.assertEquals(220 + i, s[1]); + } + for(int i=2; i<size; i++) { + Assert.assertEquals(320 + i, all[i]); + Assert.assertEquals(320 + i, allB.get(i)); + final int[] s = model.getVariaInt32PointerCustomLen(i, new int[3], 2, 1); + Assert.assertEquals(320 + i, s[2]); + } + } model.releaseVariaInt32PointerCustomLen(); // FIXME: Ownership is ambiguous, may leak native allocated memory, not free'ed! Assert.assertEquals(0, model.getVariaInt32PointerCustomLenElemCount()); Assert.assertEquals(true, model.isVariaInt32PointerCustomLenNull()); @@ -1955,7 +1991,7 @@ public class BaseClass extends SingletonJunitCase { /** Struct */ - private void chapter12_05aTestTKFieldStruct(final TK_Field model) { + private void chapter12_05aTestTKFieldConstValueStructReadAccess(final TK_Field model) { // field: structArrayOneElem // CType['TK_Dimension *', size [fixed false, lnx64 16], [array*1]], with array length of 1 { @@ -1992,6 +2028,261 @@ public class BaseClass extends SingletonJunitCase { } } + private static TK_Dimension createTKDim(final int x, final int y, final int w, final int h) { + return TK_Dimension.create().setX(x).setY(y).setWidth(w).setHeight(h); + } + private static boolean equals(final TK_Dimension a, final TK_Dimension b) { + if( a == b ) { + return true; + } + return a.getX() == b.getX() && + a.getY() == b.getY() && + a.getWidth() == b.getWidth() && + a.getHeight() == b.getHeight(); + } + + /** Primitive.VariaValue.Struct.Pointer - write access */ + private void chapter12_06bTestTKFieldVariaValueStructWriteAccess(final TK_Field model) { + Assert.assertEquals(1, TK_Field.getVariaStructPointerConstOneElemElemCount()); + Assert.assertEquals(false, model.isVariaStructPointerConstOneElemNull()); + { + final TK_Dimension val = createTKDim(10, 11, 100, 111); + model.setVariaStructPointerConstOneElem(val); + Assert.assertTrue( equals(val, model.getVariaStructPointerConstOneElem()) ); + } + + Assert.assertEquals(0, model.getVariaStructPointerMaxOneElemElemCount()); + Assert.assertEquals(true, model.isVariaStructPointerMaxOneElemNull()); + { + final TK_Dimension val = createTKDim(20, 21, 200, 211); + model.setVariaStructPointerMaxOneElem(val); + Assert.assertEquals(1, model.getVariaStructPointerMaxOneElemElemCount()); + Assert.assertEquals(false, model.isVariaStructPointerMaxOneElemNull()); + Assert.assertTrue( equals(val, model.getVariaStructPointerMaxOneElem()) ); + model.releaseVariaStructPointerMaxOneElem(); + Assert.assertEquals(0, model.getVariaStructPointerMaxOneElemElemCount()); + Assert.assertEquals(true, model.isVariaStructPointerMaxOneElemNull()); + } + + Assert.assertEquals(3, TK_Field.getVariaStructPointerConstLenElemCount()); + Assert.assertEquals(false, model.isVariaStructPointerConstLenNull()); + { + // No write/verify 1 via ByteBuffer reference + + // write 2 via TK_Dimension[] set + { + final TK_Dimension[] all = new TK_Dimension[3]; + for(int i=0; i<3; ++i) { + all[i] = createTKDim(i*10, i*10+1, 100+i*10, 100+i*10+1); + } + model.setVariaStructPointerConstLen(all, 0, 0, 3); + } + // verify 2 + { + final int size = TK_Field.getVariaStructPointerConstLenElemCount(); + Assert.assertEquals(3, size); + final TK_Dimension[] all = model.getVariaStructPointerConstLen(0, new TK_Dimension[3], 0, 3); + Assert.assertEquals(size, all.length); + for(int i=0; i<size; i++) { + final TK_Dimension val = createTKDim(i*10, i*10+1, 100+i*10, 100+i*10+1); + Assert.assertTrue( equals(val, all[i]) ); + final TK_Dimension[] s = model.getVariaStructPointerConstLen(i, new TK_Dimension[1], 0, 1); + Assert.assertTrue( equals(val, s[0]) ); + } + } + // write 3 via int[] single set @ offset + { + final TK_Dimension[] all = new TK_Dimension[3]; + for(int i=1; i<3; ++i) { + all[i] = createTKDim(i*20, i*20+1, 100+i*20, 100+i*20+1); + } + model.setVariaStructPointerConstLen(all, 1, 1, 2); + } + // verify 3 + { + final int size = TK_Field.getVariaStructPointerConstLenElemCount(); + Assert.assertEquals(3, size); + final TK_Dimension[] all = model.getVariaStructPointerConstLen(0, new TK_Dimension[3], 0, 3); + Assert.assertEquals(size, all.length); + for(int i=0; i<1; i++) { + final TK_Dimension val = createTKDim(i*10, i*10+1, 100+i*10, 100+i*10+1); + Assert.assertTrue( equals(val, all[i]) ); + final TK_Dimension[] s = model.getVariaStructPointerConstLen(i, new TK_Dimension[1], 0, 1); + Assert.assertTrue( equals(val, s[0]) ); + } + for(int i=1; i<size; i++) { + final TK_Dimension val = createTKDim(i*20, i*20+1, 100+i*20, 100+i*20+1); + Assert.assertTrue( equals(val, all[i]) ); + final TK_Dimension[] s = model.getVariaStructPointerConstLen(i, new TK_Dimension[1], 0, 1); + Assert.assertTrue( equals(val, s[0]) ); + } + } + } + + Assert.assertEquals(0, model.getVariaStructPointerVariaLenElemCount()); + Assert.assertEquals(true, model.isVariaStructPointerVariaLenNull()); + /** + { + Exception e1 = null; + try { + @SuppressWarnings("unused") + final IntBuffer ib = model.getVariaStructPointerVariaLen(); // 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.getVariaStructPointerVariaLen(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.setVariaStructPointerVariaLen(false, ia, 0, 0, ia.length); + } + // verify 1 + { + final int size = model.getVariaStructPointerVariaLenElemCount(); + Assert.assertEquals(5, size); + final int[] all = model.getVariaStructPointerVariaLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaStructPointerVariaLen(); + 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.getVariaStructPointerVariaLen(i, new int[1], 0, 1); + Assert.assertEquals(220 + i, s[0]); + } + } + // write 2 via IntBuffer reference get + { + final IntBuffer ib = model.getVariaStructPointerVariaLen(); + Assert.assertEquals(5, ib.limit()); + for(int i=0; i<5; ++i) { + ib.put(i, 120+i); + } + } + // verify 2 + { + final int size = model.getVariaStructPointerVariaLenElemCount(); + Assert.assertEquals(5, size); + final int[] all = model.getVariaStructPointerVariaLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaStructPointerVariaLen(); + 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.getVariaStructPointerVariaLen(i, new int[1], 0, 1); + Assert.assertEquals(120 + i, s[0]); + } + } + model.releaseVariaStructPointerVariaLen(); + Assert.assertEquals(0, model.getVariaStructPointerVariaLenElemCount()); + Assert.assertEquals(true, model.isVariaStructPointerVariaLenNull()); + } + + { + // write 1 via IntBuffer reference get + { + final int size = model.getVariaStructPointerCustomLenElemCount(); + Assert.assertEquals(4, size); + Assert.assertEquals(false, model.isVariaStructPointerCustomLenNull()); + final IntBuffer ib = model.getVariaStructPointerCustomLen(); + Assert.assertEquals(size, ib.limit()); + for(int i=0; i<size; ++i) { + ib.put(i, 120+i); + } + } + // verify 1 + { + final int size = model.getVariaStructPointerCustomLenElemCount(); + Assert.assertEquals(4, size); + final int[] all = model.getVariaStructPointerCustomLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaStructPointerCustomLen(); + 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.getVariaStructPointerCustomLen(i, new int[1], 0, 1); + Assert.assertEquals(120 + i, s[0]); + } + } + // write 2 via int[] set all, keep 1st element by writing to destPos 1, 5 elements total, 4 written + { + final int[] ia = { 0, 220, 221, 222, 223, 224, 0 }; + model.setVariaStructPointerCustomLen(false, ia, 2, 1, ia.length-1-2); + } + // verify 2 + { + final int size = model.getVariaStructPointerCustomLenElemCount(); + Assert.assertEquals(5, size); + final int[] all = model.getVariaStructPointerCustomLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaStructPointerCustomLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); + for(int i=0; i<1; i++) { + Assert.assertEquals(120 + i, all[i]); + Assert.assertEquals(120 + i, allB.get(i)); + final int[] s = model.getVariaStructPointerCustomLen(i, new int[1], 0, 1); + Assert.assertEquals(120 + i, s[0]); + } + for(int i=1; i<size; i++) { + Assert.assertEquals(220 + i, all[i]); + Assert.assertEquals(220 + i, allB.get(i)); + final int[] s = model.getVariaStructPointerCustomLen(i, new int[1], 0, 1); + Assert.assertEquals(220 + i, s[0]); + } + } + // write 3 via int[] set a subset only + { + final int[] ia = { 0, 0, 322, 323, 324, 0, 0 }; + model.setVariaStructPointerCustomLen(true, ia, 2, 2, 3); + } + // verify 2 + { + final int size = model.getVariaStructPointerCustomLenElemCount(); + Assert.assertEquals(5, size); + final int[] all = model.getVariaStructPointerCustomLen(0, new int[size], 0, size); + final IntBuffer allB = model.getVariaStructPointerCustomLen(); + Assert.assertEquals(size, all.length); + Assert.assertEquals(size, allB.limit()); + for(int i=0; i<size; i++) { + System.err.printf("%d/%d: A %d, B %d%n", i, size, all[i], allB.get(i)); + } + for(int i=0; i<1; i++) { + Assert.assertEquals(120 + i, all[i]); + Assert.assertEquals(120 + i, allB.get(i)); + final int[] s = model.getVariaStructPointerCustomLen(i, new int[1], 0, 1); + Assert.assertEquals(120 + i, s[0]); + } + for(int i=1; i<2; i++) { + Assert.assertEquals(220 + i, all[i]); + Assert.assertEquals(220 + i, allB.get(i)); + final int[] s = model.getVariaStructPointerCustomLen(i, new int[3], 1, 1); + Assert.assertEquals(220 + i, s[1]); + } + for(int i=2; i<size; i++) { + Assert.assertEquals(320 + i, all[i]); + Assert.assertEquals(320 + i, allB.get(i)); + final int[] s = model.getVariaStructPointerCustomLen(i, new int[3], 2, 1); + Assert.assertEquals(320 + i, s[2]); + } + } + model.releaseVariaStructPointerCustomLen(); // FIXME: Ownership is ambiguous, may leak native allocated memory, not free'ed! + Assert.assertEquals(0, model.getVariaStructPointerCustomLenElemCount()); + Assert.assertEquals(true, model.isVariaStructPointerCustomLenNull()); + } + */ + } + private static ByteBuffer toEOSByteBuffer(final String val, final Charset cs) { final byte[] ba = val.getBytes( cs ); final ByteBuffer bb = Buffers.newDirectByteBuffer( ba.length + 1 ); @@ -2188,7 +2479,8 @@ public class BaseClass extends SingletonJunitCase { chapter12_03bTestTKFieldConstValueInt32WriteAccess(model0); chapter12_04aTestTKFieldVariaValueInt32ReadAccess(model0); chapter12_04bTestTKFieldVariaValueInt32WriteAccess(model0); - chapter12_05aTestTKFieldStruct(model0); + chapter12_05aTestTKFieldConstValueStructReadAccess(model0); + chapter12_06bTestTKFieldVariaValueStructWriteAccess(model0); chapter12_10aTestTKFieldConstStringReadAccess(model0); chapter12_11aTestTKFieldConstStringOnlyReadAccess(model0); chapter12_11bTestTKFieldConstStringOnlyWriteAccess(model0); |