SpecStruc-BeginC++.xml 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
  4. <sect1 id="BEGINCplus_Structure">
  5. <title>BEGINC++ Structure<indexterm>
  6. <primary>BEGINC++ Structure</primary>
  7. </indexterm></title>
  8. <para><emphasis>resulttype funcname </emphasis><emphasis
  9. role="bold">(</emphasis><emphasis> parameterlist </emphasis><emphasis
  10. role="bold">) := BEGINC++<indexterm>
  11. <primary>BEGINC++</primary>
  12. </indexterm></emphasis><emphasis role="bold">
  13. </emphasis><emphasis></emphasis></para>
  14. <para><emphasis> code</emphasis><emphasis role="bold"> </emphasis></para>
  15. <para><emphasis role="bold">ENDC++<indexterm>
  16. <primary>ENDC++</primary>
  17. </indexterm>;</emphasis></para>
  18. <informaltable colsep="0" frame="none" rowsep="0">
  19. <tgroup cols="2">
  20. <colspec align="left" colwidth="122.40pt" />
  21. <colspec />
  22. <tbody>
  23. <row>
  24. <entry><emphasis>resulttype</emphasis></entry>
  25. <entry>The ECL return value type of the C++ function.</entry>
  26. </row>
  27. <row>
  28. <entry><emphasis>funcname</emphasis></entry>
  29. <entry><para>The ECL attribute name of the function.</para></entry>
  30. </row>
  31. <row>
  32. <entry><emphasis>parameterlist</emphasis></entry>
  33. <entry>The parameters to pass to the C++ function.</entry>
  34. </row>
  35. <row>
  36. <entry><emphasis>code</emphasis></entry>
  37. <entry>The C++ function source code.</entry>
  38. </row>
  39. </tbody>
  40. </tgroup>
  41. </informaltable>
  42. <para>The <emphasis role="bold">BEGINC++ </emphasis>structure makes it
  43. possible to add in-line C++ code to your ECL. This is useful where string or
  44. bit processing would be complicated in ECL, and would be more easily done in
  45. C++, typically for a one-off use. For more commonly used C++ code, writing a
  46. plugin would be a better solution (see the <emphasis role="bold">External
  47. Service Implementation</emphasis> discussion).</para>
  48. <para><emphasis role="bold">WARNING: This feature could create memory
  49. corruption and/or security issues, so great care and forethought are
  50. advised—consult with Technical Support before using.</emphasis></para>
  51. <sect2 id="ECL_to_Cplus_Mapping">
  52. <title>ECL to C++ Mapping</title>
  53. <para>Types are passed as follows:</para>
  54. <programlisting>//The following typedefs are used below:
  55. typedef unsigned size32_t;
  56. typedef wchar_t UChar; [ unsigned short in linux ]</programlisting>
  57. <para>The following list describes the mappings from ECL to C++. For
  58. embedded C++ the parameters are always converted to lower case, and
  59. capitalized in conjunctions (see below).</para>
  60. <programlisting><emphasis role="bold">ECL C++ [Linux in brackets]</emphasis>
  61. BOOOLEAN xyz bool xyz
  62. INTEGER1 xyz signed char xyz
  63. INTEGER2 xyz signed short xyz
  64. INTEGER4 xyz signed int xyz
  65. INTEGER8 xyz signed __int64 xyz [ long long ]
  66. UNSIGNED1 xyz unsigned char xyz
  67. UNSIGNED2 xyz unsigned short xyz
  68. UNSIGNED4 xyz unsigned int xyz
  69. UNSIGNED8 xyz unsigned __int64 xyz [ unsigned long long xyz ]
  70. REAL4 xyz float xyz
  71. REAL/REAL8 xyz double xyz
  72. DATA xyz size32_t lenXyz, void * xyz
  73. STRING xyz size32_t lenXyz, char * xyz
  74. VARSTRING xyz char * xyz;
  75. QSTRING xyz size32_t lenXyz, char * xyz
  76. UNICODE xyz size32_t lenXyz, UChar * xyz
  77. VARUNICODE xyz UChar * xyz
  78. DATA&lt;nn&gt; xyz void * xyz
  79. STRING&lt;nn&gt; xyz char * xyz
  80. QSTRING&lt;nn&gt; xyz char * xyz
  81. UNICODE&lt;nn&gt; xyz UChar * xyz
  82. SET OF ... xyz bool isAllXyz, size32_t lenXyz, void * xyz</programlisting>
  83. <para>Note that strings of unknown length are passed differently from
  84. those with a known length. A variable length input string is passed as a
  85. number of characters, not the size (i.e. qstring/unicode), followed by a
  86. pointer to the data, like this (size32_t is an UNSIGNED4):</para>
  87. <programlisting>string ABC -&gt; size32_t lenAbc, const char * abc;
  88. unicode ABC -&gt; size32_t lenABC, const UChar * abc;</programlisting>
  89. <para>A dataset is passed as a size/pointer pair. The length gives the
  90. size of the following dataset in bytes. The same naming convention is
  91. used:</para>
  92. <programlisting>dataset(r) ABC -&gt; size32_t lenAbc, const void * abc</programlisting>
  93. <para>NOTE: variable length strings within a record are stored as a 4 byte
  94. number of characters, followed by the string data.</para>
  95. <para>Sets are passed as a set of parameters (all, size, pointer):</para>
  96. <programlisting>set of unsigned4 ABC -&gt; bool isAllAbc, size32_t lenAbc, const void * abc</programlisting>
  97. <para>Return types are handled as C++ functions returning the same types
  98. with some exceptions. The exceptions have some extra initial parameters to
  99. return the results in:</para>
  100. <programlisting><emphasis role="bold">ECL C++ [Linux in brackets]</emphasis>
  101. DATA xyz size32_t &amp; __lenResult, void * &amp; __result
  102. STRING xyz size32_t &amp; __lenResult, char * &amp; __result
  103. QSTRING xyz size32_t &amp; __lenResult, char * &amp; __result
  104. UNICODE xyz size32_t &amp; __lenResult, UChar * &amp; __result
  105. DATA&lt;nn&gt; xyz void * __result
  106. STRING&lt;nn&gt; xyz char * __result
  107. QSTRING&lt;nn&gt; xyz char * __result
  108. UNICODE&lt;nn&gt; xyz UChar * __result
  109. SET OF ... xyz bool __isAllResult, size32_t &amp; __lenResult,
  110. void * &amp; __result</programlisting>
  111. <para>For example,</para>
  112. <programlisting>STRING process(STRING value, INTEGER4 len)</programlisting>
  113. <para>has the prototype:</para>
  114. <programlisting>void process(size32_t &amp; __lenResult, char * &amp; __result,
  115. size32_t lenValue, char * value, int len);</programlisting>
  116. </sect2>
  117. <sect2 id="Available_Options">
  118. <title>Available Options</title>
  119. <para><emphasis role="bold">#option pure</emphasis>By default, embedded
  120. C++ functions are assumed to have side-effects, which means the generated
  121. code won't be as efficient as it might be since the calls can't be shared.
  122. Adding #option pure inside the embedded C++ <emphasis>code</emphasis>
  123. causes it to be treated as a pure function without side effects.</para>
  124. <para><emphasis role="bold">#option once</emphasis>Indicates the function
  125. has no side effects and is evaluated at query execution time, even if the
  126. parameters are constant, allowing the optimizer to make more efficient
  127. calls to the function in some cases.</para>
  128. <para><emphasis role="bold">#option action</emphasis>Indicates side
  129. effects, requiring the optimizer to keep all calls to the function.</para>
  130. <para><emphasis role="bold">#body</emphasis> Delimits the beginning of
  131. executable code. All <emphasis>code</emphasis> that precedes #body (such
  132. as #include) is generated outside the function definition; all code that
  133. follows it is generated inside the function definition.</para>
  134. <para>Example:</para>
  135. <programlisting>//static int add(int x,int y) {
  136. INTEGER4 add(INTEGER4 x, INTEGER4 y) := BEGINC++
  137. #option pure
  138. return x + y;
  139. ENDC++;
  140. OUTPUT(add(10,20));
  141. //static void reverseString(size32_t &amp; __lenResult,char * &amp; __result,
  142. // size32_t lenValue,char * value) {
  143. STRING reverseString(STRING value) := BEGINC++
  144. size32_t len = lenValue;
  145. char * out = (char *)rtlMalloc(len);
  146. for (unsigned i= 0; i &lt; len; i++)
  147. out[i] = value[len-1-i];
  148. __lenResult = len;
  149. __result = out;
  150. ENDC++;
  151. OUTPUT(reverseString('Kevin'));
  152. // This is a function returning an unknown length string via the
  153. // special reference parameters __lenResult and __result
  154. //this function demonstrates #body, allowing #include to be used
  155. BOOLEAN nocaseInList(STRING search,
  156. SET OF STRING values) := BEGINC++
  157. #include &lt;string.h&gt;
  158. #body
  159. if (isAllValues)
  160. return true;
  161. const byte * cur = (const byte *)values;
  162. const byte * end = cur + lenValues;
  163. while (cur != end)
  164. {
  165. unsigned len = *(unsigned *)cur;
  166. cur += sizeof(unsigned);
  167. if (lenSearch == len &amp;&amp; memicmp(search, cur, len) == 0)
  168. return true;
  169. cur += len;
  170. }
  171. return false;
  172. ENDC++;
  173. //and another example, generating a variable number of Xes
  174. STRING buildString(INTEGER4 value) := BEGINC++
  175. char * out = (char *)rtlMalloc(value);
  176. for (unsigned i= 0; i &lt; value; i++)
  177. out[i] = 'X';
  178. __lenResult = value;
  179. __result = out;
  180. ENDC++;</programlisting>
  181. <para>See Also: <link linkend="External_Service_Implementation">External Service Implementation</link></para>
  182. </sect2>
  183. </sect1>