diff options
28 files changed, 2038 insertions, 982 deletions
diff --git a/doc/GlueGen_Mapping.html b/doc/GlueGen_Mapping.html index 537ce89..20e9265 100644 --- a/doc/GlueGen_Mapping.html +++ b/doc/GlueGen_Mapping.html @@ -1,407 +1,415 @@ -<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; +<!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> + 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; } - } - -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; - } + nav#TOC input { + display: none; + } -p {} + nav#TOC label { + color: var(--color-link); + cursor: pointer; + } -blockquote - { - font-style: italic; - } + nav#TOC > ul { + display: none; + } -li - { - } + nav#TOC > input:checked + ul { + display: block; + } -li > p - { - margin-top: 1em; - } + @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; -ul - { - } + page-break-after: avoid; -ul li - { - } + margin: 20px 0 10px; + padding: 0; + } -ol - { - } + h2 { + border-bottom: 1px solid #ccc; + } -ol li - { - } + div div + { -hr {} + } -sub - { - } + section section + { + margin-left: 2em; + } -sup - { - } + p {} -em - { - } + blockquote + { + font-style: italic; + } -em > em - { - font-style: normal; - } + li + { + } -strong - { - } + li > p + { + margin-top: 1em; + } -a - { + ul + { + } - text-decoration: none; - } + ul li + { + } -@media screen - { - a:hover - { + ol + { + } - text-decoration: underline; - } - } + ol li + { + } -@media print - { - a { + hr {} - color: black; - background: transparent; - } + sub + { + } - a[href^="http://"]:after, a[href^="https://"]:after - { + sup + { + } - content: " (" attr(href) ") "; - font-size: 90%; - } - } + em + { + } -img - { + em > em + { + font-style: normal; + } - vertical-align: middle; - } + strong + { + } -div.figure - { + a + { - margin-left: auto; - margin-right: auto; - text-align: center; - font-style: italic; - } + text-decoration: none; + } -p.caption - { + @media screen + { + a:hover + { - } + text-decoration: underline; + } + } -pre, code - { - background-color: #f8f8f8; + @media print + { + a { - white-space: pre-wrap; - white-space: -moz-pre-wrap !important; - white-space: -pre-wrap; - white-space: -o-pre-wrap; - word-wrap: break-word; + color: black; + background: transparent; + } - } + a[href^="http://"]:after, a[href^="https://"]:after + { -pre - { + content: " (" attr(href) ") "; + font-size: 90%; + } + } - padding: 0.5em; - border-radius: 5px; + img + { - background-color: #f8f8f8; - border: 1px solid #ccc; - font-size: 13px; - line-height: 19px; - overflow: auto; - padding: 6px 10px; + vertical-align: middle; + } - margin-left: 0.5em; - margin-right: 0.5em; - } + div.figure + { -@media screen - { - pre - { + margin-left: auto; + margin-right: auto; + text-align: center; + font-style: italic; + } - white-space: pre; - overflow: auto; + p.caption + { - 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 - { - } + pre, code + { + background-color: #f8f8f8; -@media print - { - a[href^="#fnref"], a.reversefootnote - { + white-space: pre-wrap; + white-space: -moz-pre-wrap !important; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; - display: none; - } - } + } -div.footnotes - { - } + pre + { -div.footnotes li[id^="fn"] - { - } + padding: 0.5em; + border-radius: 5px; -@media print - { - .noprint - { - display:none; + 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; } - } -</style> + 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> +</head> +<body> <nav id="TOC" role="doc-toc"> <strong>Contents</strong><label for="contents">⊕</label> <input type="checkbox" id="contents"> @@ -424,6 +432,8 @@ div.footnotes li[id^="fn"] <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-java-signature-examples">Struct Java Signature + Examples</a></li> <li><a href="#struct-setter-pseudo-code">Struct Setter Pseudo-Code</a></li> </ul></li> @@ -432,7 +442,6 @@ div.footnotes li[id^="fn"] </ul></li> </ul> </nav> - <style> table, th, td { border: 1px solid black; @@ -1021,13 +1030,18 @@ 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>Utilizing a <em>flexible</em> <em>elemCount</em> via +<strong>ReturnedArrayLength getValElements()</strong> renders us unable +to determine ownership of pointer referenced <em>native</em> memory +segment and hence renders ownership <em>mixed or ambiguous</em>, <a +href="#signature-const-int32_t--customsize-ambiguous-java-owned">see +[5]</a>. This is due to the fact, that native code may allocate memory +and writes its <em>elemCount</em> into the designated field +<em>valElements</em>. In such cases, the user being aware of the +underlying API shall utilize <code>setVal(..)</code> and +<code>releaseVal()</code> with care.</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 @@ -1127,7 +1141,7 @@ getBuffer()</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;">Parent</td> <td style="text-align: left;"></td> </tr> <tr class="odd"> @@ -1136,7 +1150,7 @@ getBuffer()</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;">Parent</td> <td style="text-align: left;">Read only</td> </tr> <tr class="even"> @@ -1145,13 +1159,16 @@ getBuffer()</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;">Parent</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;">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> @@ -1189,7 +1206,7 @@ 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;">Parent</td> <td style="text-align: left;"></td> </tr> <tr class="odd"> @@ -1199,7 +1216,7 @@ srcPos, int[] dest, 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;">Parent</td> <td style="text-align: left;">Read only</td> </tr> <tr class="even"> @@ -1218,7 +1235,8 @@ static int getValElemCount()</td> <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> +int len) [<a +href="#signature-int32_t--constelemcount-3-natively-owned">2</a>]</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> @@ -1228,10 +1246,12 @@ 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(int[] src, int srcPos, int destPos, -int len) <br> releaseVal()</td> +<td style="text-align: left;">setVal(boolean subset, int[] src, int +srcPos, int destPos, int len) [<a +href="#signature-int32_t--freesize-java-owned">3</a>] <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> @@ -1240,19 +1260,34 @@ int getValElemCount()</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) [<a href="#signature-const-int32_t--freesize-java-owned">4</a>] +<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="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> +int len) [<a +href="#signature-const-int32_t--customsize-ambiguous-java-owned">5</a>] +<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;"><strong>Ambiguous</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 +1298,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 +1311,177 @@ getName() <br> boolean isNameNull() <br> int getNameElemCount()</td> </tr> </tbody> </table> +<h3 id="struct-java-signature-examples">Struct Java Signature +Examples</h3> +<h4 id="signature-int32_t--maxoneelement-java-owned">Signature +<code>int32_t *</code> MaxOneElement, Java owned</h4> +<ul> +<li><p><code>void com.jogamp.gluegen.test.junit.generation.TK_Field.setVariaInt32PointerMaxOneElemElemCount(int src)</code></p> +<p>Setter for native field variaInt32PointerMaxOneElem, referencing a +Java owned array with variable element count of 0 initial elements.</p> +<p>Maximum element count is 1.</p> +<p>Native Signature:</p> +<ul> +<li>field-type (PointerType) 'int32_t <em>' -> (int32_t) * , size +[fixed false, lnx64 8], const[false], pointer</em>1</li> +<li>referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], +const[false], int</li> +</ul> +<p>Will reuse memory if existing, otherwise allocating memory.</p></li> +</ul> +<h4 id="signature-const-int32_t--maxoneelement-java-owned">Signature +<code>const int32_t *</code> MaxOneElement, Java owned</h4> +<ul> +<li><p><code>TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setConstInt32PointerMaxOneElem(int src)</code></p> +<p>Setter for native field variaInt32PointerMaxOneElem, referencing a +Java owned array with variable element count of 0 initial elements.</p> +<p>Maximum element count is 1.</p> +<p>Native Signature:</p> +<ul> +<li>field-type (PointerType) 'int32_t <em>' -> (const int32_t) * , +size [fixed false, lnx64 8], const[false], pointer</em>1</li> +<li>referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], +const[native, true], int</li> +</ul> +<p>Always replaces memory due to <code>const</code> value +modifier.</p></li> +</ul> +<h4 id="signature-int32_t--constelemcount-3-natively-owned">Signature +<code>int32_t *</code> ConstElemCount 3, Natively owned</h4> +<ul> +<li><p><code>TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setVariaInt32PointerConstLen(int[] src, int srcPos, int destPos, int length)</code></p> +<p>Setter for native field variaInt32PointerConstLen, referencing a +natively owned array with fixed element count of 3 elements.</p> +<p>Native Signature:</p> +<ul> +<li>field-type (PointerType) 'int32_t <em>' -> (int32_t) * , size +[fixed false, lnx64 8], const[false], pointer</em>1</li> +<li>referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], +const[false], int</li> +</ul> +<p>Copies the given source elements into the respective field's existing +memory.</p> +<p>Parameters:</p> +<ul> +<li>src the source array of elements</li> +<li>srcPos starting element position within the source array with +'srcPos >= 0<code>&&</code>srcPos + length <= src.length`, +otherwise an IndexOutOfBoundsException is thrown</li> +<li>destPos starting element position within the destination with +'destPos >= 0<code>&&</code>destPos + length <= +elemCount`, otherwise an exception is thrown</li> +<li>length the element count to be copied with 'length >= +0<code>&&</code>srcPos + length <= +src.length<code>&&</code>destPos + length <= elemCount`, +otherwise an IndexOutOfBoundsException is thrown</li> +</ul> +<p>Returns:</p> +<ul> +<li>this instance of chaining</li> +</ul></li> +</ul> +<h4 id="signature-int32_t--freesize-java-owned">Signature +<code>int32_t *</code> FreeSize, Java owned</h4> +<ul> +<li><p><code>TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setVariaInt32PointerVariaLen(boolean subset, int[] src, int srcPos, int destPos, int length)</code></p> +<p>Setter for native field variaInt32PointerVariaLen, referencing a Java +owned array with variable element count of 0 initial elements.</p> +<p>Native Signature:</p> +<ul> +<li>field-type (PointerType) 'int32_t <em>' -> (int32_t) * , size +[fixed false, lnx64 8], const[false], pointer</em>1</li> +<li>referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], +const[false], int</li> +</ul> +<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> +<p>Parameters:</p> +<ul> +<li>subset if <code>true</code> keeps the underlying memory and only +allows to set up to <code>elemCount</code> elements. Otherwise may +replace the underlying memory if +<code>destPos + length != elemCount</code>.</li> +<li>src the source array of elements</li> +<li>srcPos starting element position within the source array with +'srcPos >= 0<code>&&</code>srcPos + length <= src.length`, +otherwise an IndexOutOfBoundsException is thrown</li> +<li>destPos starting element position within the destination with +'destPos >= 0<code>. If </code>subset == true<code>, </code>destPos + +length <= elemCount<code>also must be be</code>true`. Otherwise an +exception is thrown</li> +<li>length the element count to be copied with 'length >= +0<code>&&</code>srcPos + length <= src.length`, otherwise an +IndexOutOfBoundsException is thrown</li> +</ul> +<p>Returns:</p> +<ul> +<li>this instance of chaining</li> +</ul></li> +</ul> +<h4 id="signature-const-int32_t--freesize-java-owned">Signature +<code>const int32_t *</code> FreeSize, Java owned</h4> +<ul> +<li><p><code>TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setConstInt32PointerVariaLen(int[] src, int srcPos, int length)</code></p> +<p>Setter for native field constInt32PointerVariaLen, referencing a Java +owned array with variable element count of 0 initial elements.</p> +<p>Native Signature:</p> +<ul> +<li>field-type (PointerType) 'int32_t <em>' -> (const int32_t) * , +size [fixed false, lnx64 8], const[false], pointer</em>1</li> +<li>referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], +const[native, true], int</li> +</ul> +<p>Replaces the respective field's memory with a new memory segment +containing given source elements and referencing it.</p> +<p>Parameters:</p> +<ul> +<li>src the source array of elements</li> +<li>srcPos starting element position within the source array with +'srcPos >= 0<code>&&</code>srcPos + length <= src.length`, +otherwise an IndexOutOfBoundsException is thrown</li> +<li>length the element count to be copied with 'length >= +0<code>&&</code>srcPos + length <= src.length`, otherwise an +IndexOutOfBoundsException is thrown</li> +</ul> +<p>Returns:</p> +<ul> +<li>this instance of chaining</li> +</ul></li> +</ul> +<h4 +id="signature-const-int32_t--customsize-ambiguous-java-owned">Signature +<code>const int32_t *</code> CustomSize, Ambiguous, Java owned</h4> +<ul> +<li><p><code>TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setConstInt32PointerCustomLen(int[] src, int srcPos, int length)</code></p> +<p>Setter for native field constIntxxPointerCustomLen, referencing a +mixed and ambigously owned (<strong>warning</strong>) array with +variable element count of getConstIntxxPointerCustomLenElemCount() +elements.</p> +<p>Native Signature:</p> +<ul> +<li>field-type (PointerType) 'int32_t <em>' -> (const int32_t) * , +size [fixed false, lnx64 8], const[false], pointer</em>1</li> +<li>referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], +const[native, true], int</li> +</ul> +<p>Replaces the respective field's memory with a new memory segment +containing given source elements and referencing it.</p> +<p>Parameters:</p> +<ul> +<li>src the source array of elements</li> +<li>srcPos starting element position within the source array with +'srcPos >= 0<code>&&</code>srcPos + length <= src.length`, +otherwise an IndexOutOfBoundsException is thrown</li> +<li>length the element count to be copied with 'length >= +0<code>&&</code>srcPos + length <= src.length`, otherwise an +IndexOutOfBoundsException is thrown</li> +</ul> +<p>Returns:</p> +<ul> +<li>this instance of chaining</li> +</ul></li> +</ul> <h3 id="struct-setter-pseudo-code">Struct Setter Pseudo-Code</h3> <ul> <li><em>ImmutableAccess</em>: Drops setter, immutable</li> @@ -1370,3 +1576,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..ad7ec27 100644 --- a/doc/GlueGen_Mapping.md +++ b/doc/GlueGen_Mapping.md @@ -296,11 +296,10 @@ A direct C code `char` array or indirect array via pointer can be interpreted as if the expression is constant. Otherwise the *native* memory has *java ownership*. See [ReturnedArrayLength Setting](#returnedarraylength-symbol-expression) above. +* Utilizing a *flexible* *elemCount* via **ReturnedArrayLength getValElements()** renders us unable to determine ownership + of pointer referenced *native* memory segment and hence renders ownership *mixed or ambiguous*, [see \[5\]](#signature-const-int32_t--customsize-ambiguous-java-owned). This is due to the fact, that native code may allocate memory and writes its *elemCount* into the designated field *valElements*. In such cases, the user being aware of the underlying API shall utilize `setVal(..)` and `releaseVal()` with care. + * 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 @@ -322,21 +321,132 @@ A similar mapping is produced for `struct` types, i.e. *compounds*. | | | | 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 | +| | int32_t val | setVal(int v) | int getVal() | | Parent | | +| const | int32_t val | *none* | int getVal() | | Parent | Read only | +| | int32_t val | *none* | int getVal() | **ImmutableAccess** | Parent | Read only | +| [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 | +| | 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) | | Parent | | +| const | int32_t val[3]| *none* | IntBuffer getVal() <br> int[] getVal(int srcPos, int[] dest, int destPos, int len) | | Parent | 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 | +| | int32_t* val | setVal(int[] src, int srcPos, int destPos, int len) \[[2](#signature-int32_t--constelemcount-3-natively-owned)\] | 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 | +| | int32_t* val | setVal(boolean subset, int[] src, int srcPos, int destPos, int len) \[[3](#signature-int32_t--freesize-java-owned)\] <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) \[[4](#signature-const-int32_t--freesize-java-owned)\] <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) \[[5](#signature-const-int32_t--customsize-ambiguous-java-owned)\] <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 Java Signature Examples + +#### Signature `int32_t *` MaxOneElement, Java owned + +* `void com.jogamp.gluegen.test.junit.generation.TK_Field.setVariaInt32PointerMaxOneElemElemCount(int src)` + + Setter for native field variaInt32PointerMaxOneElem, referencing a Java owned array with variable element count of 0 initial elements. + + Maximum element count is 1. + + Native Signature: + * field-type (PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1 + * referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[false], int + + Will reuse memory if existing, otherwise allocating memory. + +#### Signature `const int32_t *` MaxOneElement, Java owned + +* `TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setConstInt32PointerMaxOneElem(int src)` + + Setter for native field variaInt32PointerMaxOneElem, referencing a Java owned array with variable element count of 0 initial elements. + + Maximum element count is 1. + + Native Signature: + * field-type (PointerType) 'int32_t *' -> (const int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1 + * referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[native, true], int + + Always replaces memory due to `const` value modifier. + +#### Signature `int32_t *` ConstElemCount 3, Natively owned + +* `TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setVariaInt32PointerConstLen(int[] src, int srcPos, int destPos, int length)` + + Setter for native field variaInt32PointerConstLen, referencing a natively owned array with fixed element count of 3 elements. + + Native Signature: + * field-type (PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1 + * referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[false], int + + Copies the given source elements into the respective field's existing memory. + + Parameters: + * src the source array of elements + * srcPos starting element position within the source array with 'srcPos >= 0` && `srcPos + length <= src.length`, otherwise an IndexOutOfBoundsException is thrown + * destPos starting element position within the destination with 'destPos >= 0` && `destPos + length <= elemCount`, otherwise an exception is thrown + * length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length` && `destPos + length <= elemCount`, otherwise an IndexOutOfBoundsException is thrown + + Returns: + * this instance of chaining + +#### Signature `int32_t *` FreeSize, Java owned +* `TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setVariaInt32PointerVariaLen(boolean subset, int[] src, int srcPos, int destPos, int length)` + + Setter for native field variaInt32PointerVariaLen, referencing a Java owned array with variable element count of 0 initial elements. + + Native Signature: + * field-type (PointerType) 'int32_t *' -> (int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1 + * referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[false], int + + Copies the given source elements into the respective field, either writing into the existing memory or creating a new memory and referencing it. + + Parameters: + * 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`. + * src the source array of elements + * srcPos starting element position within the source array with 'srcPos >= 0` && `srcPos + length <= src.length`, otherwise an IndexOutOfBoundsException is thrown + * 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 + * length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length`, otherwise an IndexOutOfBoundsException is thrown + + Returns: + * this instance of chaining + +#### Signature `const int32_t *` FreeSize, Java owned +* `TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setConstInt32PointerVariaLen(int[] src, int srcPos, int length)` + + Setter for native field constInt32PointerVariaLen, referencing a Java owned array with variable element count of 0 initial elements. + + Native Signature: + * field-type (PointerType) 'int32_t *' -> (const int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1 + * referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[native, true], int + + Replaces the respective field's memory with a new memory segment containing given source elements and referencing it. + + Parameters: + * src the source array of elements + * srcPos starting element position within the source array with 'srcPos >= 0` && `srcPos + length <= src.length`, otherwise an IndexOutOfBoundsException is thrown + * length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length`, otherwise an IndexOutOfBoundsException is thrown + + Returns: + * this instance of chaining + +#### Signature `const int32_t *` CustomSize, Ambiguous, Java owned +* `TK_Field com.jogamp.gluegen.test.junit.generation.TK_Field.setConstInt32PointerCustomLen(int[] src, int srcPos, int length)` + + Setter for native field constIntxxPointerCustomLen, referencing a mixed and ambigously owned (**warning**) array with variable element count of getConstIntxxPointerCustomLenElemCount() elements. + + Native Signature: + * field-type (PointerType) 'int32_t *' -> (const int32_t) * , size [fixed false, lnx64 8], const[false], pointer*1 + * referenced (IntType) typedef 'int32_t', size [fixed true, lnx64 4], const[native, true], int + + Replaces the respective field's memory with a new memory segment containing given source elements and referencing it. + + Parameters: + * src the source array of elements + * srcPos starting element position within the source array with 'srcPos >= 0` && `srcPos + length <= src.length`, otherwise an IndexOutOfBoundsException is thrown + * length the element count to be copied with 'length >= 0` && `srcPos + length <= src.length`, otherwise an IndexOutOfBoundsException is thrown + + Returns: + * this instance of chaining + ### Struct Setter Pseudo-Code * *ImmutableAccess*: Drops setter, immutable diff --git a/doc/JogAmpMacOSVersions.html b/doc/JogAmpMacOSVersions.html index 22c2351..3b56244 100644 --- a/doc/JogAmpMacOSVersions.html +++ b/doc/JogAmpMacOSVersions.html @@ -1,407 +1,415 @@ -<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; +<!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>JogAmpMacOSVersions.md</title> + <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; } - } -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; -} + nav#TOC input { + display: none; + } -h2 { - border-bottom: 1px solid #ccc; -} + nav#TOC label { + color: var(--color-link); + cursor: pointer; + } -div div - { + nav#TOC > ul { + display: none; + } - } + nav#TOC > input:checked + ul { + display: block; + } -section section - { - margin-left: 2em; - } + @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; -p {} + page-break-after: avoid; -blockquote - { - font-style: italic; - } + margin: 20px 0 10px; + padding: 0; + } -li - { - } + h2 { + border-bottom: 1px solid #ccc; + } -li > p - { - margin-top: 1em; - } + div div + { -ul - { - } + } -ul li - { - } + section section + { + margin-left: 2em; + } -ol - { - } + p {} -ol li - { - } + blockquote + { + font-style: italic; + } -hr {} + li + { + } -sub - { - } + li > p + { + margin-top: 1em; + } -sup - { - } + ul + { + } -em - { - } + ul li + { + } -em > em - { - font-style: normal; - } + ol + { + } -strong - { - } + ol li + { + } -a - { + hr {} - text-decoration: none; - } + sub + { + } -@media screen - { - a:hover - { + sup + { + } - text-decoration: underline; - } - } + em + { + } -@media print - { - a { + em > em + { + font-style: normal; + } - color: black; - background: transparent; - } + strong + { + } - a[href^="http://"]:after, a[href^="https://"]:after - { + a + { - content: " (" attr(href) ") "; - font-size: 90%; - } - } + text-decoration: none; + } -img - { + @media screen + { + a:hover + { - vertical-align: middle; - } + text-decoration: underline; + } + } -div.figure - { + @media print + { + a { - margin-left: auto; - margin-right: auto; - text-align: center; - font-style: italic; - } + color: black; + background: transparent; + } -p.caption - { + a[href^="http://"]:after, a[href^="https://"]:after + { - } + content: " (" attr(href) ") "; + font-size: 90%; + } + } -pre, code - { - background-color: #f8f8f8; + img + { - white-space: pre-wrap; - white-space: -moz-pre-wrap !important; - white-space: -pre-wrap; - white-space: -o-pre-wrap; - word-wrap: break-word; + vertical-align: middle; + } - } + div.figure + { -pre - { + margin-left: auto; + margin-right: auto; + text-align: center; + font-style: italic; + } - padding: 0.5em; - border-radius: 5px; + p.caption + { - 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; - } + pre, code + { + background-color: #f8f8f8; -@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 - { - } + white-space: pre-wrap; + white-space: -moz-pre-wrap !important; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; -@media print - { - a[href^="#fnref"], a.reversefootnote - { - - display: none; - } - } + } -div.footnotes - { - } + pre + { -div.footnotes li[id^="fn"] - { - } + padding: 0.5em; + border-radius: 5px; -@media print - { - .noprint - { - display:none; + 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; } - } -</style> + 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> +</head> +<body> <nav id="TOC" role="doc-toc"> <strong>Contents</strong><label for="contents">⊕</label> <input type="checkbox" id="contents"> @@ -425,7 +433,6 @@ div.footnotes li[id^="fn"] </ul></li> </ul> </nav> - <style> table, th, td { border: 1px solid black; @@ -566,3 +573,5 @@ Sierra), Darwin 17, <code>x86_64</code></h3> </tr> </tbody> </table> +</body> +</html> diff --git a/jcpp b/jcpp -Subproject eddcad41a1dc2658747235b307bfd4ffd2c27bd +Subproject 00f97cc623469377c59985898b9b765ae66c0ae diff --git a/src/java/com/jogamp/common/nio/ElementBuffer.java b/src/java/com/jogamp/common/nio/ElementBuffer.java index f9909b8..e1e47bb 100644 --- a/src/java/com/jogamp/common/nio/ElementBuffer.java +++ b/src/java/com/jogamp/common/nio/ElementBuffer.java @@ -110,28 +110,37 @@ public class ElementBuffer extends AbstractBuffer<ElementBuffer> { if (0 > offset || offset + length > capacity) { throw new IndexOutOfBoundsException("idx "+offset+" + elementCount "+length+" not within [0.."+capacity+"), "+this); } - final ByteBuffer src = (ByteBuffer)buffer; + final ByteBuffer src = getByteBuffer(); final int oldPos = src.position(); final int oldLimit = src.limit(); - src.position(elementSize*offset); - src.limit(elementSize * (offset + length)); + src.position( elementSize * offset ).limit(elementSize * (offset + length)); final ByteBuffer ref = src.slice().order(src.order()); // slice and duplicate may change byte order - src.position(oldPos); - src.limit(oldLimit); + src.position( oldPos ).limit( oldLimit ); return ref; } - /** Absolute get method. Copy the element-bytes at the given index, storing them into `destElemBytes`. */ - public final ByteBuffer get(final int idx, final ByteBuffer destElemBytes) { - if (0 > idx || idx >= capacity) { - throw new IndexOutOfBoundsException("idx "+idx+" not within [0.."+capacity+"), "+this); - } - final ByteBuffer bBuffer = (ByteBuffer)buffer; - for(int i=0; i<elementSize; ++i) { - destElemBytes.put(i, bBuffer.get(elementSize*idx+i)); - } + /** Absolute get method. Get element-bytes for `elementCount` elements from this buffer at `srcElemPos` into `destElemBytes` at the given element-index `destElemPos` */ + public final ByteBuffer get(final int srcElemPos, final ByteBuffer destElemBytes, final int destElemPos, final int elementCount) { + if (0 > srcElemPos || srcElemPos + elementCount > capacity || 0 > elementCount || + 0 > destElemPos || elementSize * ( destElemPos + elementCount ) > destElemBytes.limit() ) + { + throw new IndexOutOfBoundsException("destElemPos "+destElemPos+", srcElemPos "+srcElemPos+", elementCount "+elementCount+ + ", srcCapacity "+capacity+", destLimit "+(destElemBytes.limit()/elementSize)+", "+this); + } + final ByteBuffer srcElemBytes = getByteBuffer(); + final int oldSrcLim = srcElemBytes.limit(); + srcElemBytes.position( srcElemPos * elementSize ).limit( ( srcElemPos + elementCount ) * elementSize ); // remaining = elementCount * elementSize + final int oldDestPos = destElemBytes.position(); + destElemBytes.position( destElemPos * elementSize ); + destElemBytes.put(srcElemBytes).position(oldDestPos); + srcElemBytes.limit(oldSrcLim).rewind(); return destElemBytes; } + + /** Absolute get method. Copy the element-bytes from this buffer at the given element-index `srcElemPos`, storing them into `destElemBytes`. */ + public final ByteBuffer get(final int srcElemPos, final ByteBuffer destElemBytes) { + return get(srcElemPos, destElemBytes, 0, 1); + } /** Relative get method. Copy the element-bytes at the current position and increment the position by one, storing the element-bytes into `destElemBytes`. */ public final ByteBuffer get(final ByteBuffer destElemBytes) { final ByteBuffer r = get(position, destElemBytes); @@ -156,17 +165,27 @@ public class ElementBuffer extends AbstractBuffer<ElementBuffer> { return this; } - /** Absolute put method. Put the element-bytes at the given element-index */ - public final ElementBuffer put(final int idx, final ByteBuffer srcElemBytes) { - if (0 > idx || idx >= capacity) { - throw new IndexOutOfBoundsException("idx "+idx+" not within [0.."+capacity+"), "+this); - } - final ByteBuffer bBuffer = (ByteBuffer)buffer; - for(int i=0; i<elementSize; ++i) { - bBuffer.put(elementSize*idx+i, srcElemBytes.get(i)); - } + /** Absolute put method. Put element-bytes for `elementCount` elements from `srcElemBytes` at `srcElemPos` into this buffer at the given element-index `destElemPos` */ + public final ElementBuffer put(final ByteBuffer srcElemBytes, final int srcElemPos, final int destElemPos, final int elementCount) { + if (0 > destElemPos || destElemPos + elementCount > capacity || 0 > elementCount || + 0 > srcElemPos || elementSize * ( srcElemPos + elementCount ) > srcElemBytes.limit() ) + { + throw new IndexOutOfBoundsException("srcElemPos "+srcElemPos+", destElemPos "+destElemPos+", elementCount "+elementCount+ + ", destCapacity "+capacity+", srcLimit "+(srcElemBytes.limit()/elementSize)+", "+this); + } + final ByteBuffer destElemBytes = getByteBuffer(); + final int oldSrcPos = srcElemBytes.position(); + final int oldSrcLim = srcElemBytes.limit(); + srcElemBytes.position( srcElemPos * elementSize ).limit( ( srcElemPos + elementCount ) * elementSize ); // remaining = elementCount * elementSize + destElemBytes.position( elementSize * destElemPos ); + destElemBytes.put(srcElemBytes).rewind(); + srcElemBytes.limit(oldSrcLim).position(oldSrcPos); return this; } + /** Absolute put method. Put element-bytes from `srcElemBytes` into the given element-index `destElemPos` */ + public final ElementBuffer put(final int destElemPos, final ByteBuffer srcElemBytes) { + return put(srcElemBytes, 0, destElemPos, 1); + } /** Relative put method. Put the element-bytes at the current position and increment the position by one. */ public final ElementBuffer put(final ByteBuffer srcElemBytes) { put(position, srcElemBytes); diff --git a/src/java/com/jogamp/gluegen/ConstantDefinition.java b/src/java/com/jogamp/gluegen/ConstantDefinition.java index 675c6d7..d579da1 100644 --- a/src/java/com/jogamp/gluegen/ConstantDefinition.java +++ b/src/java/com/jogamp/gluegen/ConstantDefinition.java @@ -760,7 +760,7 @@ public class ConstantDefinition extends AliasedSymbolImpl implements AliasedSema public final static Pattern patternIntegerNumber; /** - * One of: {@code +} {@code -} {@code *} {@code /} {@code |} {@code &} {@code (} {@code )} {@code <<} {@code >>} + * One of: {@code +} {@code -} {@code *} {@code /} {@code |} {@code &} {@code (} {@code )} {@code <<} {@code >>} {@code ~} * <p> * Expression excludes {@link #patternDecimalOrIntNumber}. * </p> @@ -949,6 +949,6 @@ public class ConstantDefinition extends AliasedSymbolImpl implements AliasedSema ")" + WhiteSpace // Optional trailing "whitespace" ; - patternCPPOperand = Pattern.compile("(?!"+fpOrIntRegex2+")[\\+\\-\\*\\/\\|\\&\\(\\)]|(\\<\\<)|(\\>\\>)"); + patternCPPOperand = Pattern.compile("(?!"+fpOrIntRegex2+")[\\+\\-\\*\\/\\|\\&\\(\\)]|(\\<\\<)|(\\>\\>)|(\\~)"); } } diff --git a/src/java/com/jogamp/gluegen/GlueGen.java b/src/java/com/jogamp/gluegen/GlueGen.java index 6dee6f0..e0c42c7 100644 --- a/src/java/com/jogamp/gluegen/GlueGen.java +++ b/src/java/com/jogamp/gluegen/GlueGen.java @@ -104,11 +104,16 @@ public class GlueGen implements GlueEmitterControls { public static final String __GLUEGEN__ = "__GLUEGEN__"; @SuppressWarnings("unchecked") - public void run(final Reader reader, final String filename, final Class<?> emitterClass, final List<String> includePaths, final List<String> cfgFiles, final String outputRootDir, final boolean copyCPPOutput2Stderr) { - + public void run(final Reader reader, final String filename, final Class<?> emitterClass, final List<String> includePaths, final List<String> cfgFiles, final String outputRootDir, + final boolean copyCPPOutput2Stderr, final boolean enablePragmaOnce) + { try { if(debug) { Logging.getLogger().setLevel(Level.ALL); + System.err.println("GlueGen.run: filename: "+filename+", emitter: "+emitterClass.getName()+", outputRootDir "+outputRootDir+ + ", copyCPPOutput2Stderr "+copyCPPOutput2Stderr+", enablePragmaOnce "+enablePragmaOnce); + System.err.println("GlueGen.run: includePaths "+includePaths); + System.err.println("GlueGen.run: cfgFiles "+cfgFiles); } else if( null != logLevel ) { Logging.getLogger().setLevel(logLevel); } @@ -131,8 +136,8 @@ public class GlueGen implements GlueEmitterControls { final File out = File.createTempFile("CPPTemp", ".cpp"); final FileOutputStream outStream = new FileOutputStream(out); - // preprocessor = new PCPP(includePaths, debug, copyCPPOutput2Stderr); - preprocessor = new JCPP(includePaths, debug, copyCPPOutput2Stderr); + // preprocessor = new PCPP(includePaths, debug, copyCPPOutput2Stderr, enablePragmaOnce); + preprocessor = new JCPP(includePaths, debug, copyCPPOutput2Stderr, enablePragmaOnce); final String cppName = preprocessor.getClass().getSimpleName(); if(debug) { System.err.println("CPP <"+cppName+"> output at (persistent): " + out.getAbsolutePath()); @@ -375,6 +380,7 @@ public class GlueGen implements GlueEmitterControls { String outputRootDir = null; final List<String> cfgFiles = new ArrayList<String>(); boolean copyCPPOutput2Stderr = false; + boolean enablePragmaOnce = true; final List<String> includePaths = new ArrayList<String>(); for (int i = 0; i < args.length; i++) { @@ -396,6 +402,10 @@ public class GlueGen implements GlueEmitterControls { debug=true; } else if (arg.equals("--dumpCPP")) { copyCPPOutput2Stderr=true; + } else if (arg.equals("--enablePragmaOnce")) { + enablePragmaOnce=true; + } else if (arg.equals("--disablePragmaOnce")) { + enablePragmaOnce=false; } else { usage(); } @@ -420,7 +430,7 @@ public class GlueGen implements GlueEmitterControls { try { final Class<?> emitterClass = emitterFQN == null ? null : Class.forName(emitterFQN); - new GlueGen().run(reader, filename, emitterClass, includePaths, cfgFiles, outputRootDir, copyCPPOutput2Stderr); + new GlueGen().run(reader, filename, emitterClass, includePaths, cfgFiles, outputRootDir, copyCPPOutput2Stderr, enablePragmaOnce); } catch (final ClassNotFoundException ex) { throw new RuntimeException("specified emitter class was not in the classpath", ex); } @@ -445,6 +455,8 @@ public class GlueGen implements GlueEmitterControls { out.println("-Cjava-emitter.cfg."); out.println(" --debug enables debug mode"); out.println(" --dumpCPP directs CPP to dump all output to stderr as well"); + out.println(" --enablePragmaOnce allow handle of #pragma once directive during parsing (default)"); + out.println(" --disablePragmaOnce disable handling of #pragma once directive during parsing"); exit(1); } } diff --git a/src/java/com/jogamp/gluegen/JavaConfiguration.java b/src/java/com/jogamp/gluegen/JavaConfiguration.java index f392525..3241d83 100644 --- a/src/java/com/jogamp/gluegen/JavaConfiguration.java +++ b/src/java/com/jogamp/gluegen/JavaConfiguration.java @@ -165,6 +165,7 @@ public class JavaConfiguration { private final Set<String> manuallyImplement = new HashSet<String>(); private final Map<String, String> delegatedImplementation = new HashMap<String, String>(); private final Map<String, List<String>> customJavaCode = new HashMap<String, List<String>>(); + private final Map<String, List<String>> customJNICode = new HashMap<String, List<String>>(); private final Map<String, List<String>> classJavadoc = new HashMap<String, List<String>>(); private final Map<String, List<String>> methodJavadoc = new HashMap<String, List<String>>(); private final Map<String, String> structPackages = new HashMap<String, String>(); @@ -601,6 +602,19 @@ public class JavaConfiguration { return res; } + /** Returns a list of Strings containing user-implemented JNI code for + the given Java type name (not fully-qualified, only the class + name); returns either null or an empty list if there is no + custom code for the class. */ + public List<String> customJNICodeForClass(final String className) { + List<String> res = customJNICode.get(className); + if (res == null) { + res = new ArrayList<String>(); + customJNICode.put(className, res); + } + return res; + } + public List<String> javadocForMethod(final String methodName) { List<String> res = methodJavadoc.get(methodName); if (res == null) { @@ -1330,6 +1344,10 @@ public class JavaConfiguration { } else if (cmd.equalsIgnoreCase("CustomCCode")) { readCustomCCode(tok, filename, lineNo); // Warning: make sure delimiters are reset at the top of this loop + // because readCustomJNICode changes them. + } else if (cmd.equalsIgnoreCase("CustomJNICode")) { + readCustomJNICode(tok, filename, lineNo); + // Warning: make sure delimiters are reset at the top of this loop // because readCustomCCode changes them. } else if (cmd.equalsIgnoreCase("MethodJavadoc")) { readMethodJavadoc(tok, filename, lineNo); @@ -1697,6 +1715,26 @@ public class JavaConfiguration { } } + protected void readCustomJNICode(final StringTokenizer tok, final String filename, final int lineNo) { + try { + final String tokenClassName = tok.nextToken(); + try { + final String restOfLine = tok.nextToken("\n\r\f"); + addCustomJNICode(tokenClassName, restOfLine); + } catch (final NoSuchElementException e) { + addCustomJNICode(tokenClassName, ""); + } + } catch (final NoSuchElementException e) { + throw new RuntimeException("Error parsing \"CustomJNICode\" command at line " + lineNo + + " in file \"" + filename + "\"", e); + } + } + + protected void addCustomJNICode(final String className, final String code) { + final List<String> codeList = customJNICodeForClass(className); + codeList.add(code); + } + protected void readMethodJavadoc(final StringTokenizer tok, final String filename, final int lineNo) { try { final String tokenClassName = tok.nextToken(); diff --git a/src/java/com/jogamp/gluegen/JavaEmitter.java b/src/java/com/jogamp/gluegen/JavaEmitter.java index ada1ce9..784976a 100644 --- a/src/java/com/jogamp/gluegen/JavaEmitter.java +++ b/src/java/com/jogamp/gluegen/JavaEmitter.java @@ -126,6 +126,20 @@ public class JavaEmitter implements GlueEmitter { private final String javaName; } + /** + * Resource ownership. + */ + public enum Ownership { + /** Parent ownership of resource, i.e. derived-from and shared-with compounding parent resource. */ + Parent, + /** Java ownership of resource. */ + Java, + /** Native ownership of resource. */ + Native, + /** Ambiguous mixed ownership of resource, i.e. {@Link #Java} or {@link #Native}. */ + Mixed; + } + 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; @@ -708,8 +722,12 @@ public class JavaEmitter implements GlueEmitter { if (cfg.allStatic() || cfg.emitInterface()) { emitCustomJavaCode(javaUnit(), cfg.className()); } + if( cfg.allStatic() && cfg.emitImpl()) { + emitCustomJNICode(cUnit(), cfg.className()); + } if (!cfg.allStatic() && cfg.emitImpl()) { emitCustomJavaCode(javaImplUnit(), cfg.implClassName()); + emitCustomJNICode(cUnit(), cfg.implClassName()); } } } @@ -830,7 +848,7 @@ public class JavaEmitter implements GlueEmitter { // Note that machDescJava MachineDataInfo is always 64bit unix, // which complies w/ Java types. - boolean needsNativeCode = false; + boolean needsNativeCode = !cfg.customJNICodeForClass(containingJTypeName).isEmpty(); // Native code for calls through function pointers gets emitted // into the abstract base class; Java code which accesses fields @@ -911,7 +929,7 @@ public class JavaEmitter implements GlueEmitter { for (final String doc : javadoc) { javaUnit.emitln(doc); } - javaUnit.emit("public final class " + containingJTypeName + " "); + javaUnit.emit("public class " + containingJTypeName + " "); boolean firstIteration = true; final List<String> userSpecifiedInterfaces = cfg.implementedInterfaces(containingJTypeName); for (final String userInterface : userSpecifiedInterfaces) { @@ -1089,7 +1107,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, false, false, fieldName, fieldType, Ownership.Parent, fieldType.getName(), 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 +1146,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, MethodAccess.PUBLIC, false, false, fieldName, fieldType, Ownership.Parent, containingJTypeName, 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 +1159,7 @@ public class JavaEmitter implements GlueEmitter { } // Getter - generateGetterSignature(javaUnit, fieldType, false, false, javaTypeName, fieldName, capFieldName, null, false, null); + generateGetterSignature(javaUnit, false, false, fieldName, fieldType, Ownership.Parent, javaTypeName, capFieldName, null, false, false, null, null); javaUnit.emitln(" {"); javaUnit.emit (" return "); if( fieldTypeNativeSizeFixed ) { @@ -1162,6 +1180,7 @@ public class JavaEmitter implements GlueEmitter { javaUnit.emitln("}"); javaUnit.close(); if (needsNativeCode) { + emitCustomJNICode(jniUnit, containingJTypeName); jniUnit.close(); } if( GlueGen.debug() ) { @@ -1200,60 +1219,143 @@ public class JavaEmitter implements GlueEmitter { //---------------------------------------------------------------------- // Internals only below this point // + private void generateArrayFieldNote(final CodeUnit unit, final String leadIn, final String leadOut, + final String fieldName, final Type fieldType, final Ownership ownership, + final boolean constElemCount, final boolean maxOneElem, final String elemCountExpr, + final boolean multiline, final boolean startNewPara) { + final boolean isPointer; + final Type referencedType; + { + final PointerType pointerType = fieldType.asPointer(); + if( null != pointerType ) { + isPointer = true; + referencedType = pointerType.getBaseElementType(); + } else { + isPointer = false; + referencedType = null; + } + } + // isPointer = true; + if( multiline ) { + if( startNewPara ) { + unit.emitln(" * <p>"); + } + unit.emit (" * "); + } + if( null != leadIn ) { + unit.emit(leadIn+" "); + } + final String ownershipTerm; + switch( ownership ) { + case Parent: ownershipTerm = "an"; break; + case Java: ownershipTerm = "a <i>Java</i> owned"; break; + case Native: ownershipTerm = "a <i>natively</i> owned"; break; + default: ownershipTerm = "a <i>mixed and ambigously</i> owned (<b>warning</b>)"; break; + } + final String relationship = isPointer ? "referencing" : "being"; - 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()); + unit.emit("native field <code>"+fieldName+"</code>, "+relationship+" "+ownershipTerm+" array with "+(constElemCount?"fixed":"variable")+" element count"); if( null != elemCountExpr ) { - unit.emit(", with "+(constElemCount?"fixed":"initial")+" array length of <code>"+elemCountExpr+"</code>"); + if( elemCountExpr.startsWith("get") && elemCountExpr.endsWith("()") ) { + unit.emit(" of {@link #"+elemCountExpr+"} "); + } else { + unit.emit(" of <code>"+elemCountExpr+"</code> "); + } + if( constElemCount || Ownership.Mixed == ownership ) { + unit.emit("elements."); + } else { + unit.emit("initial elements."); + } + } else { + unit.emit("."); } - 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>"); + if( multiline ) { + unit.emitln(); + if( startNewPara ) { + unit.emitln(" * </p>"); + } + } + if( maxOneElem ) { + if( multiline ) { + unit.emitln(" * <p>"); + unit.emitln(" * Maximum element count is <code>1</code>."); + unit.emitln(" * </p>"); + } else { + unit.emit(" Maximum element count is <code>1</code>."); + } + } + if( multiline ) { + unit.emitln(" * <p>"); + if( null == referencedType ) { + unit.emitln(" * Native Field Signature <code>"+fieldType.getSignature(null).toString()+"</code>"); + } else { + unit.emitln(" * Native Signature:"); + unit.emitln(" * <ul>"); + unit.emitln(" * <li>field-type <code>"+fieldType.getSignature(null).toString()+"</code></li>"); + unit.emitln(" * <li>referenced <code>"+referencedType.getSignature(null).toString()+"</code></li>"); + unit.emitln(" * </ul>"); + } + unit.emitln(" * </p>"); + } else { + unit.emit(" NativeSig <code>"+fieldType.getSignature(null).toString()+"</code>"); + } + if( null != leadOut ) { + unit.emit(" "+leadOut); + } + if( !multiline) { + unit.emitln(); } - 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 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>"); + private void generateIsNullSignature(final CodeUnit unit, final boolean abstractMethod, + final String fieldName, final Type fieldType, final Ownership ownership, + 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`."); + generateArrayFieldNote(unit, "Corresponds to", null, fieldName, fieldType, ownership, constElemCount, maxOneElem, elemCountExpr, true, true); + unit.emitln(" */"); + unit.emit(" public " + (abstractMethod ? "abstract " : "final ") + "boolean is" + capitalizedFieldName + "Null()"); + } + private void generateReleaseSignature(final CodeUnit unit, final boolean abstractMethod, + final String fieldName, final Type fieldType, final Ownership ownership, final String returnTypeName, + final String capitalizedFieldName, final boolean constElemCount, final boolean maxOneElement, final String elemCountExpr) { + unit.emitln(" /**"); + generateArrayFieldNote(unit, "Releases memory referenced by", null, fieldName, fieldType, ownership, constElemCount, maxOneElement, elemCountExpr, true, false); + unit.emitln(" */"); + unit.emit(" public " + (abstractMethod ? "abstract " : "final ") + returnTypeName + " release" + capitalizedFieldName + "()"); + } + private void generateGetterSignature(final CodeUnit unit, final boolean staticMethod, final boolean abstractMethod, + final String fieldName, final Type fieldType, final Ownership ownership, final String returnTypeName, + 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, fieldName, fieldType, ownership, constElemCount, maxOneElem, elemCountExpr, true, false); + if( null != apiDocTail ) { + unit.emitln(" * "+apiDocTail); } - unit.emitln(" */"); - unit.emit(" public final " + (staticMethod ? "static " : "") + (abstractMethod ? "abstract " : "") + returnTypeName + " get" + capitalizedFieldName + "("); + 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>"); + private void generateSetterSignature(final CodeUnit unit, final MethodAccess accessMod, final boolean staticMethod, final boolean abstractMethod, + final String fieldName, final Type fieldType, final Ownership ownership, final String returnTypeName, + final String capitalizedFieldName, 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, fieldName, fieldType, ownership, constElemCount, maxOneElem, elemCountExpr, true, false); + if( null != apiDocDetail ) { + unit.emitln(" * <p>"); + unit.emitln(" * "+apiDocDetail); + unit.emitln(" * </p>"); } - 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 != 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 +1529,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); }"; @@ -1448,7 +1582,10 @@ public class JavaEmitter implements GlueEmitter { returnSizeLookupName + "\", "+fieldType.getDebugString(), fieldType.getASTLocusTag(), e); } if( GlueGen.debug() ) { - System.err.printf("SE.ac.%02d: javaType %s%n", (i+1), javaType.getDebugString()); + System.err.printf("SE.ac.%02d: fieldName %s%n", (i+1), fieldName); + System.err.printf("SE.ac.%02d: structCType %s, %s%n", (i+1), structCType.toString(), structCType.getSignature(null).toString()); + System.err.printf("SE.ac.%02d: fieldType %s, %s%n", (i+1), fieldType.toString(), fieldType.getSignature(null).toString()); + System.err.printf("SE.ac.%02d: javaType %s, %s%n", (i+1), javaType.toString(), javaType.getSignature(null).toString()); } // @@ -1465,8 +1602,9 @@ public class JavaEmitter implements GlueEmitter { final boolean isPrimitive; 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 Ownership ownership; final String elemCountExpr; - final boolean constElemCount; // if true, implies native ownership of pointer referenced memory! + final boolean constElemCount; // if true, implies native ownership for pointer referenced memory! final boolean staticElemCount; final JavaType baseJElemType; final String baseJElemTypeName; @@ -1482,6 +1620,7 @@ public class JavaEmitter implements GlueEmitter { isConstValue = fieldType.isConst(); elemCountExpr = "1"; constElemCount = true; + ownership = Ownership.Parent; staticElemCount = true; baseJElemType = null; baseJElemTypeName = compatiblePrimitiveJavaTypeName(fieldType, javaType, machDescJava); @@ -1498,6 +1637,7 @@ public class JavaEmitter implements GlueEmitter { elemCountExpr = getArrayArrayLengthExpr(arrayType, returnSizeLookupName, _useFixedArrayLen, arrayLengthRes); // final int arrayLength = arrayLengthRes[0][0]; constElemCount = _useFixedArrayLen[0]; + ownership = Ownership.Parent; // a fixed linear array staticElemCount = constElemCount; baseCElemType = arrayType.getBaseElementType(); isPointer = false; @@ -1519,44 +1659,50 @@ public class JavaEmitter implements GlueEmitter { unit.addTailCode(optStringMaxStrnlenCode); elemCountExpr = "Buffers.strnlen(pString, _max_strnlen)+1"; constElemCount = false; + ownership = Ownership.Java; staticElemCount = constElemCount; } else if( null == _elemCountExpr ) { useGetCStringLength = false; elemCountExpr = "0"; constElemCount = false; + ownership = Ownership.Java; staticElemCount = constElemCount; } else { + // null != _elemCountExpr 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); + // 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; + if( constElemCount ) { + ownership = Ownership.Native; + } else { + ownership = Ownership.Mixed; + } staticElemCount = _staticElemCount; } } if( null == elemCountExpr ) { - final String msg = "SKIP unsized array in struct: "+returnSizeLookupName+": "+fieldType.getDebugString(); + final String msg = "SKIP unsized array in struct: "+returnSizeLookupName+": "+fieldType.getSignature(null).toString(); unit.emitln(" // "+msg); unit.emitln(); LOG.log(WARNING, structCType.getASTLocusTag(), msg); @@ -1570,7 +1716,15 @@ public class JavaEmitter implements GlueEmitter { } maxOneElement = _maxOneElement; if( GlueGen.debug() ) { - System.err.printf("SE.ac.%02d: baseCType %s%n", (i+1), baseCElemType.getDebugString()); + System.err.printf("SE.ac.%02d: baseCType ownership %s, %s%n", (i+1), ownership, baseCElemType.getSignature(null).toString()); + } + + if( !baseCElemType.hasSize() ) { // like 'void*' -> 'void' + final String msg = "SKIP unsized field in struct: "+returnSizeLookupName+": fieldType "+fieldType.getSignature(null).toString()+", baseType "+baseCElemType.getSignature(null).toString(); + unit.emitln(" // "+msg); + unit.emitln(); + LOG.log(WARNING, structCType.getASTLocusTag(), msg); + return; } isPrimitive = baseCElemType.isPrimitive(); @@ -1583,16 +1737,8 @@ public class JavaEmitter implements GlueEmitter { fieldType.getASTLocusTag(), e); } baseJElemTypeName = baseJElemType.getName(); - primCElemFixedSize = isPrimitive ? baseCElemType.getSize().hasFixedNativeSize() : true; + primCElemFixedSize = isPrimitive ? baseCElemType.getSize().hasFixedNativeSize() : false; 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; - } } if( GlueGen.debug() ) { System.err.printf("SE.ac.%02d: baseJElemType %s%n", (i+1), (null != baseJElemType ? baseJElemType.getDebugString() : null)); @@ -1615,16 +1761,17 @@ public class JavaEmitter implements GlueEmitter { primJElemTypeBufferName = primJElemTypeBufferClazz.getSimpleName(); primElemSize = Buffers.sizeOfBufferElem(primJElemTypeBufferClazz); isByteBuffer = null != primJElemTypeBufferClazz ? ByteBuffer.class.isAssignableFrom(primJElemTypeBufferClazz) : false; + if( primCElemFixedSize ) { + primElemSizeExpr = String.valueOf(primElemSize); + } else { + primElemSizeExpr = "md."+baseCElemSizeDenominator+"SizeInBytes()"; + } } else { primJElemTypeBufferClazz = null; primJElemTypeBufferName = null; primElemSize = 0; isByteBuffer = false; - } - if( primCElemFixedSize ) { - primElemSizeExpr = String.valueOf(primElemSize); - } else { - primElemSizeExpr = "md."+baseCElemSizeDenominator+"SizeInBytes()"; + primElemSizeExpr = null; } final String capitalFieldName = capitalizeString(fieldName); @@ -1651,10 +1798,10 @@ public class JavaEmitter implements GlueEmitter { } 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, "+ + System.err.printf("SE.ac.%02d: elemCountExpr: %s (const %b, ownership %s), ownArrayLenCpde %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, + (i+1), elemCountExpr, constElemCount, ownership, ownElemCountHandling, maxOneElement, primJElemTypeBufferName, primCElemFixedSize, primElemSize, baseCElemSizeDenominator, primElemSizeExpr, isByteBuffer, isString, isStringOnly, useGetCStringLength, isPointer, isPrimitive, isOpaque, isConstValue, immutableAccess); @@ -1665,20 +1812,21 @@ public class JavaEmitter implements GlueEmitter { // if( ownElemCountHandling ) { if( constElemCount ) { - generateGetterSignature(unit, fieldType, staticElemCount, false, "int", fieldName, capitalFieldName+"ElemCount", null, constElemCount, elemCountExpr); + generateGetterSignature(unit, staticElemCount, false, fieldName, fieldType, ownership, "int", 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, staticElemCount, false, fieldName, fieldType, ownership, "int", 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, staticElemCount, false, fieldName, fieldType, ownership, "int", 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, MethodAccess.PRIVATE, staticElemCount, false, fieldName, fieldType, ownership, "void", capitalFieldName+"ElemCount", null, "int", + null, constElemCount, maxOneElement, elemCountExpr, null, null); unit.emitln(" { _"+fieldName+"ArrayLen = src; }"); } } @@ -1687,13 +1835,13 @@ public class JavaEmitter implements GlueEmitter { // Null query for pointer if( isPointer ) { - generateIsNullSignature(unit, fieldType, false, false, fieldName, capitalFieldName, constElemCount, elemCountExpr); + generateIsNullSignature(unit, false, fieldName, fieldType, ownership, 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, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, constElemCount, maxOneElement, elemCountExpr); unit.emitln(" {"); unit.emitln(" accessor.setLongAt("+fieldName+"_offset[mdIdx], 0, md.pointerSizeInBytes()); // write nullptr"); unit.emitln(" _eb"+capitalFieldName+" = null;"); @@ -1708,22 +1856,26 @@ public class JavaEmitter implements GlueEmitter { // Setter if( immutableAccess ) { - generateSetterAPIDoc(unit, "SKIP setter for immutable", fieldType, fieldName, constElemCount, elemCountExpr); + generateArrayFieldNote(unit, " /** SKIP setter for immutable", " */", fieldName, fieldType, ownership, constElemCount, maxOneElement, elemCountExpr, false, false); unit.emitln(); - } else if( isPointer && isConstValue && constElemCount ) { - generateSetterAPIDoc(unit, "SKIP setter for constValue constElemCount Pointer w/ native ownership", fieldType, fieldName, constElemCount, elemCountExpr); + } else if( isPointer && isConstValue && ( Ownership.Native == ownership || constElemCount ) ) { + generateArrayFieldNote(unit, " /** SKIP setter for constValue constElemCount Pointer w/ native ownership", " */", fieldName, fieldType, ownership, constElemCount, maxOneElement, elemCountExpr, false, false); unit.emitln(); } else if( !isPointer && isConstValue ) { - generateSetterAPIDoc(unit, "SKIP setter for constValue Array", fieldType, fieldName, constElemCount, elemCountExpr); + generateArrayFieldNote(unit, " /** SKIP setter for constValue Array", " */", fieldName, fieldType, ownership, constElemCount, maxOneElement, elemCountExpr, false, false); 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, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, null, baseJElemTypeName, + null, constElemCount, maxOneElement, elemCountExpr, null, null); if( isConstValue ) { - // constElemCount excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership + // constElemCount/Ownership.Native excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership + if( Ownership.Native == ownership ) { + throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString()); + } unit.emitln(" {"); unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", 1);"); unit.emit (" eb.getByteBuffer()"); @@ -1747,8 +1899,9 @@ public class JavaEmitter implements GlueEmitter { } unit.emitln(".put(0, src);"); unit.emitln(" } else {"); - if( constElemCount ) { - unit.emitln(" throw new RuntimeException(\"Primitive '"+fieldName+"' of constElemCount and maxOneElement has elemCount \"+elemCount);"); + if( constElemCount || Ownership.Native == ownership ) { + unit.emitln(" throw new RuntimeException(\"Primitive '"+fieldName+"' of "+ownership+" ownership and maxOneElement has " + +(constElemCount?"const":"")+"elemCount \"+elemCount);"); unit.emitln(" }"); unit.emitln(" return this;"); unit.emitln(" }"); @@ -1768,7 +1921,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, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, null, baseJElemTypeName, + null, constElemCount, maxOneElement, elemCountExpr, null, null); unit.emitln(" {"); unit.emitln(" ElementBuffer.wrap("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])"); unit.emit (" .getByteBuffer()"); @@ -1785,13 +1939,15 @@ public class JavaEmitter implements GlueEmitter { 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); + // isConst && constElemCount/Ownership.Native excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership + generateSetterSignature(unit, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, null, "String", + null, constElemCount, maxOneElement, elemCountExpr, null, null); unit.emitln(" {"); unit.emitln(" final byte[] srcBytes = src.getBytes(_charset);"); - if( constElemCount ) { + if( constElemCount || Ownership.Native == ownership ) { 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(" if( srcBytes.length + 1 != elemCount ) { throw new IllegalArgumentException(\"strlen+1 \"+(srcBytes.length+1)+\" != " + +(constElemCount?"const":"")+" elemCount \"+elemCount+\" of "+ownership+" ownership\"); };"); unit.emitln(" final ElementBuffer eb = ElementBuffer.derefPointer("+primElemSizeExpr+", elemCount, getBuffer(), "+fieldName+"_offset[mdIdx]);"); } else { unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+primElemSizeExpr+", srcBytes.length + 1);"); @@ -1808,30 +1964,34 @@ 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)", " */", fieldName, fieldType, ownership, constElemCount, maxOneElement, elemCountExpr, false, false); } 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); + // constElemCount/Ownership.Native excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership + generateSetterSignature(unit, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, null, + baseJElemTypeName+"[]", SetReplaceArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetReplaceArrayApiDocDetail, SetReplaceArrayApiDocArgs); + if( Ownership.Native == ownership ) { + throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString()); + } 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, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, 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 +1999,48 @@ 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, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, SetArrayArgsPre, + baseJElemTypeName+"[]", SetArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetArrayApiDocDetail, SetArrayApiDocArgs); + if( Ownership.Native == ownership ) { + throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString()); + } 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,9 +2055,13 @@ 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, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, null, baseJElemTypeName, + null, constElemCount, maxOneElement, elemCountExpr, null, null); if( isConstValue ) { - // constElemCount excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership + // constElemCount/Ownership.Native excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership + if( Ownership.Native == ownership ) { + throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString()); + } unit.emitln(" {"); unit.emitln(" final ElementBuffer eb = ElementBuffer.allocateDirect("+baseJElemTypeName+".size(), 1);"); unit.emitln(" eb.put(0, src.getBuffer());"); @@ -1898,8 +2077,9 @@ public class JavaEmitter implements GlueEmitter { 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);"); + if( constElemCount || Ownership.Native == ownership ) { + unit.emitln(" throw new RuntimeException(\"Primitive '"+fieldName+"' of "+ownership+" ownership and maxOneElement has " + +(constElemCount?"const":"")+"elemCount \"+elemCount);"); unit.emitln(" }"); unit.emitln(" return this;"); unit.emitln(" }"); @@ -1915,7 +2095,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, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, 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());"); @@ -1927,25 +2108,29 @@ public class JavaEmitter implements GlueEmitter { // 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); + // constElemCount/Ownership.Native excluded: SKIP setter for constValue constElemCount Pointer w/ native ownership + generateSetterSignature(unit, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, null, + baseJElemTypeName+"[]", SetReplaceArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetReplaceArrayApiDocDetail, SetReplaceArrayApiDocArgs); + if( Ownership.Native == ownership ) { + throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString()); + } 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, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, 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 +2144,16 @@ 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, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, capitalFieldName, SetArrayArgsPre, + baseJElemTypeName+"[]", SetArrayArgsPost, constElemCount, maxOneElement, elemCountExpr, SetArrayApiDocDetail, SetArrayApiDocArgs); + if( Ownership.Native == ownership ) { + throw new InternalError("Native ownership but adding potential memory-replacement for '"+returnSizeLookupName+"': "+fieldType.getSignature(null).toString()); + } 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 +2161,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 +2178,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, accessMod, false, false, fieldName, fieldType, ownership, containingJTypeName, 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 +2200,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, false, false, fieldName, fieldType, ownership, baseJElemTypeName, capitalFieldName, + null, constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); if( isPointer ) { unit.emitln(" return ElementBuffer.derefPointer("+primElemSizeExpr+", 1, getBuffer(), "+fieldName+"_offset[mdIdx])"); @@ -2021,7 +2218,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, false, false, fieldName, fieldType, ownership, "String", capitalFieldName+(isStringOnly?"":"AsString"), + null, constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";"); if( isPointer ) { @@ -2041,10 +2239,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)", " */", fieldName, fieldType, ownership, constElemCount, maxOneElement, elemCountExpr, false, false); unit.emitln(); } else { - generateGetterSignature(unit, fieldType, false, false, primJElemTypeBufferName, fieldName, capitalFieldName, null, constElemCount, elemCountExpr); + generateGetterSignature(unit, false, false, fieldName, fieldType, ownership, primJElemTypeBufferName, capitalFieldName, + null, constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); if( isPointer ) { unit.emitln(" return ElementBuffer.derefPointer("+primElemSizeExpr+", "+getElemCountFuncExpr+", getBuffer(), "+fieldName+"_offset[mdIdx])"); @@ -2060,7 +2259,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, false, false, fieldName, fieldType, ownership, baseJElemTypeName+"[]", capitalFieldName, + "final int srcPos, "+baseJElemTypeName+" dest[], "+GetArrayArgs, constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); unit.emitln(GetArrayArgsCheck); unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";"); @@ -2084,7 +2284,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, false, false, fieldName, fieldType, ownership, baseJElemTypeName, capitalFieldName, + null, constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); unit.emitln(" return "+baseJElemTypeName+".create("); if( isPointer ) { @@ -2095,7 +2296,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, false, false, fieldName, fieldType, ownership, baseJElemTypeName+"[]", capitalFieldName, + "final int srcPos, "+baseJElemTypeName+" dest[], "+GetArrayArgs, constElemCount, maxOneElement, elemCountExpr, GetElemValueApiDocTail); unit.emitln(" {"); unit.emitln(GetArrayArgsCheck); unit.emitln(" final int elemCount = "+getElemCountFuncExpr+";"); @@ -2524,6 +2726,23 @@ public class JavaEmitter implements GlueEmitter { unit.emitln(" // ---- End CustomJavaCode .cfg declarations"); } + /** + * Emit all the strings specified in the "CustomJNICode" parameters of + * the configuration file. + */ + protected void emitCustomJNICode(final CodeUnit unit, final String className) throws Exception { + final List<String> code = cfg.customJNICodeForClass(className); + if (code.isEmpty()) + return; + + unit.emitln(); + unit.emitln(" // --- Begin CustomJNICode .cfg declarations"); + for (final String line : code) { + unit.emitln(line); + } + unit.emitln(" // ---- End CustomJNICode .cfg declarations"); + } + public String[] getClassAccessModifiers(final String classFQName) { String[] accessModifiers; final MethodAccess acc = cfg.accessControl(classFQName); diff --git a/src/java/com/jogamp/gluegen/JavaType.java b/src/java/com/jogamp/gluegen/JavaType.java index 9bcd663..2ea3b5f 100644 --- a/src/java/com/jogamp/gluegen/JavaType.java +++ b/src/java/com/jogamp/gluegen/JavaType.java @@ -510,10 +510,10 @@ public class JavaType { } sb.append(val); } - // For debugging - public String getDebugString() { - final StringBuilder sb = new StringBuilder(); - sb.append("JType["); + public final StringBuilder getSignature(StringBuilder sb) { + if( null == sb ) { + sb = new StringBuilder(); + } boolean prepComma = false; { final String javaTypeName = getName(); @@ -571,7 +571,16 @@ public class JavaType { append(sb, "C-Primitive-Pointer", prepComma); prepComma=true; } } - append(sb, "], descriptor '"+getDescriptor()+"']", prepComma); prepComma=true; + append(sb, "], descriptor '"+getDescriptor()+"'", prepComma); prepComma=true; + return sb; + } + + // For debugging + public String getDebugString() { + final StringBuilder sb = new StringBuilder(); + sb.append("JType["); + getSignature(sb); + sb.append("]"); return sb.toString(); } diff --git a/src/java/com/jogamp/gluegen/cgram/types/Type.java b/src/java/com/jogamp/gluegen/cgram/types/Type.java index 04c46af..7ff1fed 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,15 +211,14 @@ public abstract class Type implements SemanticEqualityOp, ASTLocusTagProvider { } else { sb.append(" ZERO"); } - append(sb, "[", prepComma); prepComma=false; { append(sb, "const[", prepComma); prepComma=false; { if( isConstTypedef() ) { - append(sb, "type ", prepComma); prepComma=true; + append(sb, "typedef", prepComma); prepComma=true; } if( isConstRaw() ) { - append(sb, "inst -> ", prepComma); prepComma=false; + append(sb, "native", prepComma); prepComma=true; } if( isConst() ) { append(sb, "true]", prepComma); @@ -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(); } @@ -337,6 +343,9 @@ public abstract class Type implements SemanticEqualityOp, ASTLocusTagProvider { return isTypedef; } + /** Returns true if {@link #getSize()} is not null, otherwise false. */ + public final boolean hasSize() { return null != size; } + /** SizeThunk which computes size of this type in bytes. */ public final SizeThunk getSize() { return size; } /** Size of this type in bytes according to the given MachineDataInfo. */ diff --git a/src/java/com/jogamp/gluegen/pcpp/PCPP.java b/src/java/com/jogamp/gluegen/pcpp/PCPP.java index c766634..c4af374 100644 --- a/src/java/com/jogamp/gluegen/pcpp/PCPP.java +++ b/src/java/com/jogamp/gluegen/pcpp/PCPP.java @@ -87,18 +87,21 @@ public class PCPP implements GenericCPP { /** List containing the #include paths as Strings */ private final List<String> includePaths; + private final List<String> alreadyIncludedFiles = new ArrayList<String>(); private ParseState state; private final boolean enableDebugPrint; private final boolean enableCopyOutput2Stderr; + private final boolean enablePragmaOnce; - public PCPP(final List<String> includePaths, final boolean debug, final boolean copyOutput2Stderr) { + public PCPP(final List<String> includePaths, final boolean debug, final boolean copyOutput2Stderr, final boolean pragmaOnce) { LOG = Logging.getLogger(PCPP.class.getPackage().getName(), PCPP.class.getSimpleName()); this.includePaths = includePaths; setOut(System.out); enableDebugPrint = debug; enableCopyOutput2Stderr = copyOutput2Stderr; + enablePragmaOnce = pragmaOnce; } @Override @@ -450,6 +453,9 @@ public class PCPP implements GenericCPP { } else if (w.equals("include")) { handleInclude(); shouldPrint = false; + } else if (w.equals("pragma")){ + handlePragma(); + shouldPrint = false; } else { int line = -1; try { @@ -1019,14 +1025,29 @@ public class PCPP implements GenericCPP { if (fullname == null) { throw new RuntimeException("Can't find #include file \"" + filename + "\" at file " + filename() + ", line " + lineNumber()); } - // Process this file in-line - final Reader reader = new BufferedReader(new FileReader(fullname)); - run(reader, fullname); + if ((!enablePragmaOnce || !alreadyIncludedFiles.contains(fullname))) { + // Process this file in-line + final Reader reader = new BufferedReader(new FileReader(fullname)); + run(reader, fullname); + } else { + //System.err.println("INACTIVE BLOCK, SKIPPING " + filename); + } } else { //System.err.println("INACTIVE BLOCK, SKIPPING " + filename); } } + ///////////////////////////////////// + // Handling of #pragma directives // + ///////////////////////////////////// + + private void handlePragma() throws IOException { + final String msg = nextWordOrString(); + if (enablePragmaOnce && msg.equals("once")) { + alreadyIncludedFiles.add(filename()); + } + } + //////////// // Output // //////////// @@ -1128,6 +1149,7 @@ public class PCPP implements GenericCPP { System.err.println("Output goes to standard output. Standard input can be used as input"); System.err.println("by passing '-' as the argument."); System.err.println(" --debug enables debug mode"); + System.err.println(" --enablePragmaOnce enables pragma once management"); System.exit(1); } @@ -1135,6 +1157,7 @@ public class PCPP implements GenericCPP { Reader reader = null; String filename = null; boolean debug = false; + boolean enablePragmaOnce = false; if (args.length == 0) { usage(); @@ -1151,6 +1174,8 @@ public class PCPP implements GenericCPP { } } else if (arg.equals("--debug")) { debug = true; + } else if (arg.equals("--enablePragmaOnce")) { + enablePragmaOnce = true; } else { usage(); } @@ -1169,7 +1194,7 @@ public class PCPP implements GenericCPP { } } - new PCPP(includePaths, debug, debug).run(reader, filename); + new PCPP(includePaths, debug, debug, enablePragmaOnce).run(reader, filename); } } diff --git a/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java b/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java index 13bf418..1072675 100644 --- a/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java +++ b/src/java/com/jogamp/gluegen/structgen/CStructAnnotationProcessor.java @@ -98,12 +98,15 @@ public class CStructAnnotationProcessor extends AbstractProcessor { } private static final String STRUCTGENOUTPUT_OPTION = "structgen.output"; + private static final String STRUCTGENPRAGMA_ONCE = "structgen.enable.pragma.once"; private static final String STRUCTGENOUTPUT = PropertyAccess.getProperty("jogamp.gluegen."+STRUCTGENOUTPUT_OPTION, true, "gensrc"); + private static final String STRUCTGENPRAGMAONCE = PropertyAccess.getProperty("jogamp.gluegen."+STRUCTGENPRAGMA_ONCE, true, "true"); private Filer filer; private Messager messager; private Elements eltUtils; private String outputPath; + private boolean enablePragmaOnce; private final static Set<String> generatedStructs = new HashSet<String>(); @@ -118,6 +121,9 @@ public class CStructAnnotationProcessor extends AbstractProcessor { outputPath = processingEnv.getOptions().get(STRUCTGENOUTPUT_OPTION); outputPath = outputPath == null ? STRUCTGENOUTPUT : outputPath; + + final String enablePragmaOnceOpt = processingEnv.getOptions().get(STRUCTGENPRAGMAONCE); + enablePragmaOnce = Boolean.parseBoolean(enablePragmaOnceOpt == null ? STRUCTGENPRAGMAONCE : enablePragmaOnceOpt); } private File locateSource(final String packageName, final String relativeName) { @@ -211,7 +217,7 @@ public class CStructAnnotationProcessor extends AbstractProcessor { headerParent = root0.substring(0, root0.length()-headerFile.getName().length()-1); rootOut = headerParent.substring(0, headerParent.length()-packageName.length()) + ".."; } - System.err.println("CStruct: "+headerFile+", abs: "+headerFile.isAbsolute()+", headerParent "+headerParent+", rootOut "+rootOut); + System.err.println("CStruct: "+headerFile+", abs: "+headerFile.isAbsolute()+", headerParent "+headerParent+", rootOut "+rootOut+", enablePragmaOnce "+enablePragmaOnce); generateStructBinding(element, struct, isPackageOrType, rootOut, packageName, headerFile, headerParent); } catch (final IOException ex) { @@ -276,7 +282,8 @@ public class CStructAnnotationProcessor extends AbstractProcessor { GlueGen.setDebug(true); } new GlueGen().run(reader, filename, AnnotationProcessorJavaStructEmitter.class, - includePaths, cfgFiles, outputPath1, false /* copyCPPOutput2Stderr */); + includePaths, cfgFiles, outputPath1, false /* copyCPPOutput2Stderr */, + enablePragmaOnce /* enablePragmaOnce */); configFile.delete(); generatedStructs.add(finalType); 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..ae47b43 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/BaseClass.java @@ -246,6 +246,15 @@ public class BaseClass extends SingletonJunitCase { Assert.assertEquals( 9, Bindingtest1.NUMBER_NINE); Assert.assertEquals( 10, Bindingtest1.NUMBER_TEN); + // Bitwise not Expression + Assert.assertEquals(~ Bindingtest1.NUMBER_ONE, Bindingtest1.BITWISE_NOT_OF_ONE); + Assert.assertEquals(~ Bindingtest1.NUMBER_TWO, Bindingtest1.BITWISE_NOT_OF_TWO); + Assert.assertEquals(~ Bindingtest1.NUMBER_FOUR, Bindingtest1.BITWISE_NOT_OF_FOUR); + Assert.assertEquals(~ Bindingtest1.NUMBER_FIVE, Bindingtest1.BITWISE_NOT_OF_FIVE); + Assert.assertEquals(~ Bindingtest1.NUMBER_EIGHT, Bindingtest1.BITWISE_NOT_OF_EIGHT); + Assert.assertEquals(~ Bindingtest1.NUMBER_NINE, Bindingtest1.BITWISE_NOT_OF_NINE); + Assert.assertEquals(~ Bindingtest1.NUMBER_TEN, Bindingtest1.BITWISE_NOT_OF_TEN); + // Enum Constant Expressions! Assert.assertEquals( 1, Bindingtest1.ENUM_NUM_ONE); Assert.assertEquals( 2, Bindingtest1.ENUM_NUM_TWO); @@ -1481,7 +1490,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 +1553,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 +1628,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 +1743,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 +1808,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 +1821,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 +1859,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 +1931,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 +1944,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 +2000,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 +2037,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 +2488,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); @@ -2256,4 +2557,8 @@ public class BaseClass extends SingletonJunitCase { model.setCtx(surfaceContext); assertAPTR(surfaceContext, model.getCtx()); } + + public void chapter14TestCustomJNICode(final Bindingtest1 binding) throws Exception { + Assert.assertEquals(Bindingtest1.FOO_VALUE, binding.getFoo()); + } } diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/PCPPTest.java b/src/junit/com/jogamp/gluegen/test/junit/generation/PCPPTest.java index 608a17f..5e06a37 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/PCPPTest.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/PCPPTest.java @@ -62,13 +62,23 @@ public class PCPPTest extends SingletonJunitCase { } @Test - public void pcppMacroDefinitionTest() throws FileNotFoundException, IOException { - final PCPP pp = new PCPP(Collections.<String>emptyList(), false, false); + public void pcppMacroDefinitionTestWithoutPragmaOnce() throws FileNotFoundException, IOException { + pcppMacroDefinitionTest(false); + } + + @Test + public void pcppMacroDefinitionTestWithPragmaOnce() throws FileNotFoundException, IOException { + pcppMacroDefinitionTest(true); + } + + public void pcppMacroDefinitionTest(final boolean pragmaOnce) throws FileNotFoundException, IOException { + final String folderpath = BuildEnvironment.gluegenRoot + "/src/junit/com/jogamp/gluegen/test/junit/generation"; + final PCPP pp = new PCPP(Collections.<String>singletonList(folderpath), false, false, pragmaOnce); final ByteArrayOutputStream output = new ByteArrayOutputStream(); pp.setOut(output); final String filename = "pcpptest.h"; - final String filepath = BuildEnvironment.gluegenRoot + "/src/junit/com/jogamp/gluegen/test/junit/generation/" + filename ; + final String filepath = folderpath + "/" + filename ; pp.run(new BufferedReader(new FileReader(filepath)), filename); final String expected = "# 1 \"pcpptest.h\""+ @@ -95,7 +105,20 @@ public class PCPPTest extends SingletonJunitCase { "#128\"pcpptest.h\""+ "#130\"pcpptest.h\""+ "#134\"pcpptest.h\""+ - "#136\"pcpptest.h\""; + "#1\""+folderpath+"/pcpptest-included.h\""+ + "# define EXAMPLE 42"+ + "#134\"pcpptest.h\""+ + (!pragmaOnce ? + ( + "#1\""+folderpath+"/pcpptest-included.h\""+ + "# define EXAMPLE 42"+ + "#135\"pcpptest.h\"" + ): + "" + )+ + "#137\"pcpptest.h\""+ + "#139\"pcpptest.h\"" + ; output.flush(); 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 3e19232..c7c5644 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p1JavaEmitter.java @@ -165,6 +165,14 @@ public class Test1p1JavaEmitter extends BaseClass { chapter15TestTKMixed(new Bindingtest1p1Impl()); } + /** + * Test Custom JNI Code invocation + */ + @Test + public void chapter14TestCustomJNICode() throws Exception { + chapter14TestCustomJNICode(new Bindingtest1p1Impl()); + } + public static void main(final String args[]) throws IOException { final String tstname = Test1p1JavaEmitter.class.getName(); org.junit.runner.JUnitCore.main(tstname); 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 def7655..e4adce1 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2DynamicLibraryBundle.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2DynamicLibraryBundle.java @@ -174,6 +174,14 @@ public class Test1p2DynamicLibraryBundle extends BaseClass { } /** + * Test Custom JNI Code invocation + */ + @Test + public void chapter14TestCustomJNICode() throws Exception { + chapter14TestCustomJNICode(new Bindingtest1p2Impl()); + } + + /** * Verifies unloading of the new library. */ @AfterClass 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 711f218..366d9eb 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/Test1p2ProcAddressEmitter.java @@ -175,6 +175,14 @@ public class Test1p2ProcAddressEmitter extends BaseClass { } /** + * Test Custom JNI Code invocation + */ + @Test + public void chapter14TestCustomJNICode() throws Exception { + chapter14TestCustomJNICode(new Bindingtest1p2Impl()); + } + + /** * Verifies unloading of the new library. */ @AfterClass diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/pcpptest-included.h b/src/junit/com/jogamp/gluegen/test/junit/generation/pcpptest-included.h new file mode 100644 index 0000000..8dbe022 --- /dev/null +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/pcpptest-included.h @@ -0,0 +1,2 @@ +#pragma once +#define EXAMPLE 42
\ No newline at end of file diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/pcpptest.h b/src/junit/com/jogamp/gluegen/test/junit/generation/pcpptest.h index e9ba181..31b80c3 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/pcpptest.h +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/pcpptest.h @@ -131,5 +131,8 @@ int TEST_G_VAL; } #endif +#include <pcpptest-included.h> +#include <pcpptest-included.h> + #endif /* __test_h_ */ diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1-CustomJavaCode.cfg b/src/junit/com/jogamp/gluegen/test/junit/generation/test1-CustomJavaCode.cfg deleted file mode 100644 index 8d8f650..0000000 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test1-CustomJavaCode.cfg +++ /dev/null @@ -1,7 +0,0 @@ - -@Override -public int testDelegate(int v) { - return testDelegateOrigImpl(v) + 1; -} - - diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1-CustomJavaCode.java.stub b/src/junit/com/jogamp/gluegen/test/junit/generation/test1-CustomJavaCode.java.stub new file mode 100644 index 0000000..c210ec9 --- /dev/null +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1-CustomJavaCode.java.stub @@ -0,0 +1,12 @@ + +@Override +public int testDelegate(int v) { + return testDelegateOrigImpl(v) + 1; +} + +private native int returnFooImpl(); + +public int getFoo() { + return returnFooImpl(); +}; + 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 7e9ba4a..05bed70 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 @@ -47,8 +47,11 @@ RenameJavaSymbol DEFINE_01_EXT DEFINE_01 RenameJavaSymbol testXID_EXT testXID DelegateImplementation testDelegate testDelegateOrigImpl -IncludeAs CustomJavaCode Bindingtest1p1Impl test1-CustomJavaCode.cfg -IncludeAs CustomJavaCode Bindingtest1p2Impl test1-CustomJavaCode.cfg +CustomJavaCode Bindingtest1 public int getFoo(); +IncludeAs CustomJavaCode Bindingtest1p1Impl test1-CustomJavaCode.java.stub +IncludeAs CustomJNICode Bindingtest1p1Impl test1p1-CustomJNICode.c.stub +IncludeAs CustomJavaCode Bindingtest1p2Impl test1-CustomJavaCode.java.stub +IncludeAs CustomJNICode Bindingtest1p2Impl test1p2-CustomJNICode.c.stub StructPackage TK_Dimension com.jogamp.gluegen.test.junit.generation EmitStruct TK_Dimension 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 89848d7..84045da 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1.h @@ -36,6 +36,8 @@ typedef void * XID; // Opaque typedef XID XID_2; // Opaque, due to XID typedef void * AnonBuffer; // Non Opaque +#define FOO_VALUE 42 + // typedef XID XID_2; // Duplicate w/ compatible type (ignored) - OpenSolaris: Native gcc error // typedef int XID_2; // Duplicate w/ incompatible type ERROR @@ -114,6 +116,14 @@ enum CL_INT { ENUM_I0=10, ENUM_I1, ENUM_I2=+12U, ENUM_I3=0x0d, ENUM_I4=-14, ENUM #define NUMBER_NINE ( 2 * 2 + ( 1 << 2 ) + 1 ) #define NUMBER_TEN ( NUMBER_EIGHT | NUMBER_TWO ) +#define BITWISE_NOT_OF_ONE ~ NUMBER_ONE +#define BITWISE_NOT_OF_TWO ~ NUMBER_TWO +#define BITWISE_NOT_OF_FOUR ~ NUMBER_FOUR +#define BITWISE_NOT_OF_FIVE ~ NUMBER_FIVE +#define BITWISE_NOT_OF_EIGHT ~ NUMBER_EIGHT +#define BITWISE_NOT_OF_NINE ~ NUMBER_NINE +#define BITWISE_NOT_OF_TEN ~ NUMBER_TEN + enum NumberOps { ENUM_NUM_ONE = CONSTANT_ONE, ENUM_NUM_TWO = 1+1, ENUM_NUM_THREE, diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1p1-CustomJNICode.c.stub b/src/junit/com/jogamp/gluegen/test/junit/generation/test1p1-CustomJNICode.c.stub new file mode 100644 index 0000000..f38c52d --- /dev/null +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1p1-CustomJNICode.c.stub @@ -0,0 +1,5 @@ + +JNIEXPORT jint JNICALL Java_com_jogamp_gluegen_test_junit_generation_impl_Bindingtest1p1Impl_returnFooImpl(JNIEnv *env, jobject _unused) { + return FOO_VALUE; +} + diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test1p2-CustomJNICode.c.stub b/src/junit/com/jogamp/gluegen/test/junit/generation/test1p2-CustomJNICode.c.stub new file mode 100644 index 0000000..bee94f2 --- /dev/null +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test1p2-CustomJNICode.c.stub @@ -0,0 +1,5 @@ + +JNIEXPORT jint JNICALL Java_com_jogamp_gluegen_test_junit_generation_impl_Bindingtest1p2Impl_returnFooImpl(JNIEnv *env, jobject _unused) { + return FOO_VALUE; +} + diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg index 3b68598..b55e1d6 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.cfg @@ -30,8 +30,10 @@ 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 + +Opaque long T2_InitializeOptions.Reserved2 +# ImmutableAccess long T2_InitializeOptions.Reserved + # ReturnedArrayLength T2_InitializeOptions.OverrideThreadAffinity 1 MaxOneElement T2_InitializeOptions.OverrideThreadAffinity diff --git a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h index e27e9aa..58b5c8f 100644 --- a/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h +++ b/src/junit/com/jogamp/gluegen/test/junit/generation/test2.h @@ -8,6 +8,8 @@ typedef void* ( * T2_ReallocateMemoryFunc)(void* Pointer, size_t SizeInBytes, si typedef void ( * T2_ReleaseMemoryFunc)(void* Pointer); +typedef void ( * T2_CustomFunc)(void* Pointer); + typedef struct { int32_t ApiVersion; uint64_t NetworkWork; @@ -28,7 +30,9 @@ typedef struct { const char* ProductVersion; - void* Reserved; + void* Reserved1; + void* Reserved2; + T2_CustomFunc CustomFunc2; T2_ThreadAffinity* OverrideThreadAffinity; } T2_InitializeOptions; |