aboutsummaryrefslogtreecommitdiffstats
path: root/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/orber/doc/src/ch_idl_to_erlang_mapping.xml')
-rw-r--r--lib/orber/doc/src/ch_idl_to_erlang_mapping.xml1471
1 files changed, 1471 insertions, 0 deletions
diff --git a/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml b/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
new file mode 100644
index 0000000000..0e2b049ab9
--- /dev/null
+++ b/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
@@ -0,0 +1,1471 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>OMG IDL to Erlang Mapping</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date>1998-10-10</date>
+ <rev></rev>
+ <file>ch_idl_to_erlang_mapping.xml</file>
+ </header>
+
+ <section>
+ <title>OMG IDL to Erlang Mapping - Overview</title>
+ <p>The purpose of OMG IDL, <em>Interface Definition Language</em>, mapping
+ is to act as translator between platforms and languages. An IDL
+ specification is supposed to describe data types, object types etc.</p>
+ <p>CORBA is independent of the programming language used to construct
+ clients or implementations. In order to use the ORB, it is
+ necessary for programmers to know how to access ORB functionality
+ from their programming languages. It translates different IDL constructs
+ to a specific programming language. This chapter
+ describes the mapping of OMG IDL constructs to the Erlang programming
+ language.</p>
+ </section>
+
+ <section>
+ <title>OMG IDL Mapping Elements</title>
+ <p>A complete language mapping will allow the programmer to have
+ access to all ORB functionality in a way that is convenient for
+ a specified programming language.
+ </p>
+ <p>All mapping must define the following elements:
+ </p>
+ <list type="bulleted">
+ <item>All OMG IDL basic and constructed types</item>
+ <item>References to constants defined in OMG IDL</item>
+ <item>References to objects defined in OMG IDL</item>
+ <item>Invocations of operations, including passing of
+ parameters and receiving of results</item>
+ <item>Exceptions, including what happens when an operation
+ raises an exception and how the exception parameters are
+ accessed</item>
+ <item>Access to attributes</item>
+ <item>Signatures for operations defined by the ORB, such as
+ dynamic invocation interface, the object adapters etc.</item>
+ <item>Scopes;
+ OMG IDL has several levels of scopes, which are mapped to Erlang's
+ two scopes.</item>
+ </list>
+ </section>
+
+ <section>
+ <title>Getting Started</title>
+ <p>To begin with, we should decide which type of objects (i.e. servers) we
+ need and if two, or more, should export the same functionality. Let us
+ assume that we want to create a system for DB (database) access for different
+ kind of users. For example, anyone with a valid password may extract
+ data, but only a few may update the DB. Usually, an application
+ is defined within a <c>module</c>, and all global datatypes are defined
+ on the top-level. To begin with we create a module and the interfaces we
+ need:</p>
+ <code type="none">
+// DB IDL
+#ifndef _DB_IDL_
+#define _DB_IDL_
+// A module is simply a container
+module DB {
+
+ // An interface maps to a CORBA::Object.
+ interface CommonUser {
+
+ };
+
+ // Inherit the Consumer interface
+ interface Administrator : CommonUser {
+
+ };
+
+ interface Access {
+
+ };
+
+};
+#endif </code>
+ <p>Since the <c>Administrator</c> should be able to do the same things as the
+ <c>CommonUser</c>, the previous inherits from the latter. The <c>Access</c>
+ interface will grant access to the DB.
+ Now we are ready to define the functionality and data types we need. But, this
+ requires that we know a little bit more about the OMG IDL.</p>
+ <note>
+ <p>The OMG defines a set of reserved case insensitive key-words, which may
+ <em>NOT</em> be used as identifiers (e.g. module name). For more
+ information, see
+ <seealso marker="#key_words">Reserved Compiler Names and Keywords</seealso></p>
+ </note>
+ </section>
+
+ <section>
+ <title>Basic OMG IDL Types</title>
+ <p>The OMG IDL mapping is strongly typed and, even if you have a good knowledge
+ of CORBA types, it is essential to read carefully the following mapping to
+ Erlang types.</p>
+ <p>The mapping of basic types is straightforward. Note that the
+ OMG IDL double type is mapped to an Erlang float which does not
+ support the full double value range.</p>
+ <table>
+ <row>
+ <cell align="left" valign="middle">OMG IDL type</cell>
+ <cell align="left" valign="middle">Erlang type</cell>
+ <cell align="left" valign="middle">Note</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">float</cell>
+ <cell align="left" valign="middle">Erlang float</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">double</cell>
+ <cell align="left" valign="middle">Erlang float</cell>
+ <cell align="left" valign="middle">value range not supported</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">short</cell>
+ <cell align="left" valign="middle">Erlang integer</cell>
+ <cell align="left" valign="middle">-2^15 .. 2^15-1</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">unsigned short</cell>
+ <cell align="left" valign="middle">Erlang integer</cell>
+ <cell align="left" valign="middle">0 .. 2^16-1</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">long</cell>
+ <cell align="left" valign="middle">Erlang integer</cell>
+ <cell align="left" valign="middle">-2^31 .. 2^31-1</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">unsigned long</cell>
+ <cell align="left" valign="middle">Erlang integer</cell>
+ <cell align="left" valign="middle">0 .. 2^32-1</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">long long</cell>
+ <cell align="left" valign="middle">Erlang integer</cell>
+ <cell align="left" valign="middle">-2^63 .. 2^63-1</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">unsigned long long</cell>
+ <cell align="left" valign="middle">Erlang integer</cell>
+ <cell align="left" valign="middle">0 .. 2^64-1</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">char</cell>
+ <cell align="left" valign="middle">Erlang integer</cell>
+ <cell align="left" valign="middle">ISO-8859-1</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">wchar</cell>
+ <cell align="left" valign="middle">Erlang integer</cell>
+ <cell align="left" valign="middle">UTF-16 (ISO-10646-1:1993)</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">boolean</cell>
+ <cell align="left" valign="middle">Erlang atom</cell>
+ <cell align="left" valign="middle">true/false</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">octet</cell>
+ <cell align="left" valign="middle">Erlang integer</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">any</cell>
+ <cell align="left" valign="middle">Erlang record</cell>
+ <cell align="left" valign="middle">#any{typecode, value}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">long double</cell>
+ <cell align="left" valign="middle">Not supported</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Object</cell>
+ <cell align="left" valign="middle">Orber object reference</cell>
+ <cell align="left" valign="middle">Internal Representation</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">void</cell>
+ <cell align="left" valign="middle">Erlang atom</cell>
+ <cell align="left" valign="middle">ok</cell>
+ </row>
+ <tcaption>OMG IDL basic types</tcaption>
+ </table>
+ <p>The <c>any</c> value is written as a record with the field typecode which
+ contains the <term id="Type Code"><termdef>Type Code is a full definition of a type </termdef></term>representation,
+ <seealso marker="#tk_values">see also the Type Code table</seealso>,
+ and the value field itself.</p>
+ <p>Functions with return type <c>void</c> will return the atom <c>ok</c>.</p>
+ </section>
+
+ <section>
+ <title>Template OMG IDL Types and Complex Declarators</title>
+ <p>Constructed types all have native mappings as shown in the table
+ below.</p>
+ <table>
+ <row>
+ <cell align="left" valign="middle"><em>Type</em></cell>
+ <cell align="left" valign="middle"><em>IDL code</em></cell>
+ <cell align="left" valign="middle"><em>Maps to</em></cell>
+ <cell align="left" valign="middle"><em>Erlang code</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>string</em></cell>
+ <cell align="left" valign="middle">typedef string S; <br></br>
+void op(in S a);</cell>
+ <cell align="left" valign="middle">Erlang string</cell>
+ <cell align="left" valign="middle">ok = op(Obj, "Hello World"),</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>wstring</em></cell>
+ <cell align="left" valign="middle">typedef wstring S; <br></br>
+void op(in S a);</cell>
+ <cell align="left" valign="middle">Erlang list of Integers</cell>
+ <cell align="left" valign="middle">ok = op(Obj, "Hello World"),</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>sequence</em></cell>
+ <cell align="left" valign="middle">typedef sequence &lt;long, 3&gt; S; <br></br>
+void op(in S a);</cell>
+ <cell align="left" valign="middle">Erlang list</cell>
+ <cell align="left" valign="middle">ok = op(Obj, [1, 2, 3]),</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>array</em></cell>
+ <cell align="left" valign="middle">typedef string S[2]; <br></br>
+void op(in S a);</cell>
+ <cell align="left" valign="middle">Erlang tuple</cell>
+ <cell align="left" valign="middle">ok = op(Obj, {"one", "two"}),</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>fixed</em></cell>
+ <cell align="left" valign="middle">typedef fixed&lt;3,2> myFixed; <br></br>
+void op(in myFixed a);</cell>
+ <cell align="left" valign="middle">Erlang tuple</cell>
+ <cell align="left" valign="middle">MF = fixed:create(3, 2, 314), <br></br>
+ok = op(Obj, MF),</cell>
+ </row>
+ <tcaption>OMG IDL Template and Complex Declarators</tcaption>
+ </table>
+
+ <section>
+ <title>String/WString Data Types</title>
+ <p>A <c>string</c> consists of all possible 8-bit quantities except null.
+ Most ORB:s uses, including Orber, the character set Latin-1 (ISO-8859-1).
+ The <c>wstring</c> type is represented as a list of integers, where
+ each integer represents a wide character. In this case Orber uses, as
+ most other ORB:s, the UTF-16 (ISO-10646-1:1993) character set.</p>
+ <p>When defining a a string or wstring they can be of limited length or
+ null terminated:</p>
+ <code type="none"><![CDATA[
+// Null terminated
+typedef string myString;
+typedef wstring myWString;
+// Maximum length 10
+typedef string<10> myString10;
+typedef wstring<10> myWString10;
+ ]]></code>
+ <p>If we want to define a char/string or wchar/wstring constant, we can
+ use octal (\\OOO - one, two or three octal digits),
+ hexadecimal (\\xHH - one or two hexadecimal digits) and unicode (\\uHHHH -
+ one, two, three or four hexadecimal digits.) representation as well.
+ For example:</p>
+ <code type="none">
+const string SwedensBestSoccerTeam = "\\101" "\\x49" "\\u004B";
+const wstring SwedensBestHockeyTeam = L"\\101\\x49\\u004B";
+const char aChar = '\\u004B';
+const wchar aWchar = L'\\u004C';
+ </code>
+ <p>Naturally, we can use <c>"Erlang"</c>, <c>L"Rocks"</c>, <c>'A'</c>
+ and <c>L'A'</c> as well.</p>
+ </section>
+
+ <section>
+ <title>Sequence Data Type</title>
+ <p>A sequence can be defined to be of a maximum length or unbounded, and may
+ contain Basic and Template types and scoped names:</p>
+ <code type="none"><![CDATA[
+typedef sequence <short, 1> aShortSequence;
+typedef sequence <long> aLongSequence;
+typedef sequence <aLongSequence> anEvenLongerSequence;
+ ]]></code>
+ </section>
+
+ <section>
+ <title>Array Data Type</title>
+ <p>Arrays are multidimensional, fixed-size arrays. The indices is language
+ mapping specific, which is why one should not pass them as arguments
+ to another ORB.</p>
+ <code type="none">
+typedef long myMatrix[2][3];
+ </code>
+ </section>
+
+ <section>
+ <title>Fixed Data Type</title>
+ <p>A Fixed Point literal consists of an integer part (decimal digits),
+ decimal point and a fraction part (decimal digits),
+ followed by a <c>D</c> or <c>d</c>. Either the integer part or the
+ fraction part may be missing; the decimal point may be missing,
+ but not d/D. The integer part must be a positive integer less than 32.
+ The Fraction part must be a positive integer less than or equal to
+ the Integer part.</p>
+ <code type="none">
+const fixed myFixed1 = 3.14D;
+const fixed myFixed2 = .14D;
+const fixed myFixed3 = 0.14D;
+const fixed myFixed4 = 3.D;
+const fixed myFixed5 = 3D;
+ </code>
+ <p>It is also possible to use unary (+-) and binary (+-*/) operators:</p>
+ <code type="none">
+const fixed myFixed6 = 3D + 0.14D;
+const fixed myFixed7 = -3.14D;
+ </code>
+ <p>The Fixed Point examples above are, so called, <em>anonymous</em>
+ definitions. In later CORBA specifications these have been deprecated
+ as function parameters or return values. Hence, we strongly recommend that
+ you do not use them. Instead, you should use:</p>
+ <code type="none"><![CDATA[
+typedef fixed<5,3> myFixed53;
+const myFixed53 myFixed53constant = 03.140d;
+typedef fixed<3,2> myFixed32;
+const myFixed32 myFixed32constant = 3.14d;
+
+myFixed53 foo(in myFixed32 MF); // OK
+void bar(in fixed<5,3> MF); // Illegal
+ ]]></code>
+ </section>
+ <p>For more information, see <seealso marker="fixed">Fixed</seealso> in
+ Orber's Reference Manual.</p>
+ <p>Now we continue to work on our IDL specification. To begin with, we want
+ to limit the size of the logon parameters (Id and password). Since the
+ <c>UserID</c> and <c>Password</c> parameters, only will be used when
+ invoking operations on the <c>Access</c> interface, we may choose to define
+ them within the scope that interface. To keep it simple our DB will contain
+ employee information. Hence, as the DB key we choose an integer
+ (<c>EmployeeNo</c>).</p>
+ <code type="none"><![CDATA[
+// DB IDL
+#ifndef _DB_IDL_
+#define _DB_IDL_
+module DB {
+
+ typedef unsigned long EmployeeNo;
+
+ interface CommonUser {
+
+ any lookup(in EmployeeNo ENo);
+
+ };
+
+ interface Administrator : CommonUser {
+
+ void delete(in EmployeeNo ENo);
+
+ };
+
+ interface Access {
+
+ typedef string<10> UserID;
+ typedef string<10> Password;
+
+ CommonUser logon(in UserID ID, in Password PW);
+
+ };
+
+};
+#endif ]]></code>
+ <p>But what should, for example, the <c>lookup</c> operation return? One option
+ is to use the <c>any</c> data type. But, depending on what kind of data it
+ encapsulates, this datatype can be rather expensive to use. We might find a
+ solution to our problems among the <c>Constructed</c> IDL types.</p>
+ </section>
+
+ <section>
+ <title>Constructed OMG IDL Types</title>
+ <p>Constructed types all have native mappings as shown in the table
+ below.</p>
+ <table>
+ <row>
+ <cell align="left" valign="middle"><em>Type</em></cell>
+ <cell align="left" valign="middle"><em>IDL code</em></cell>
+ <cell align="left" valign="middle"><em>Maps to</em></cell>
+ <cell align="left" valign="middle"><em>Erlang code</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>struct</em></cell>
+ <cell align="left" valign="middle">struct myStruct { <br></br>
+long a; <br></br>
+short b; <br></br>
+}; <br></br>
+void op(in myStruct a);</cell>
+ <cell align="left" valign="middle">Erlang record</cell>
+ <cell align="left" valign="middle">ok = op(Obj, #'myStruct'{a=300, b=127}),</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>union</em></cell>
+ <cell align="left" valign="middle">union myUnion switch(long) { <br></br>
+case 1: long a; <br></br>
+}; <br></br>
+void op(in myUnion a);</cell>
+ <cell align="left" valign="middle">Erlang record</cell>
+ <cell align="left" valign="middle">ok = op(Obj, #'myUnion'{label=1, value=66}),</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>enum</em></cell>
+ <cell align="left" valign="middle">enum myEnum {one, two}; <br></br>
+void op(in myEnum a);</cell>
+ <cell align="left" valign="middle">Erlang atom</cell>
+ <cell align="left" valign="middle">ok = op(Obj, one),</cell>
+ </row>
+ <tcaption>OMG IDL constructed types</tcaption>
+ </table>
+
+ <section>
+ <title>Struct Data Type</title>
+ <p>A <c>struct</c> may have Basic, Template, Scoped Names and Constructed
+ types as members.</p>
+ </section>
+
+ <section>
+ <title>Enum Data Type</title>
+ <p>The maximum number of identifiers which may defined in an enumeration
+ is 2&sup3;&sup2;. The order in which the identifiers are named in the
+ specification of an enumeration defines the relative order of the
+ identifiers.</p>
+ </section>
+
+ <section>
+ <title>Union Data Type</title>
+ <p>A <c>union</c> may consist of:</p>
+ <list type="bulleted">
+ <item>Identifier</item>
+ <item>Switch - may be an integer, char, boolean, enum or scoped name.</item>
+ <item>Body - with or without a <c>default</c> case; may appear at
+ most once.</item>
+ </list>
+ <p>A case label must match the defined type of the discriminator, and may only
+ contain a default case if the values given in the non-default labels do
+ not cover the entire range of the union's discriminant type. For example:</p>
+ <code type="none">
+// Illegal default; all cases covered by
+// non-default cases.
+union BooleanUnion switch(boolean) {
+ case TRUE: long TrueValue;
+ case FALSE: long FalseValue;
+ default: long DefaultValue;
+};
+// OK
+union BooleanUnion2 switch(boolean) {
+ case TRUE: long TrueValue;
+ default: long DefaultValue;
+};
+ </code>
+ <p>It is not necessary to list all possible values of the union discriminator
+ in the body. Hence, the value of a union is the value of the discriminator
+ and, in given order, one of the following:</p>
+ <list type="ordered">
+ <item>If the discriminator match a label, explicitly listed in a
+ case statement, the value must be of the same type.</item>
+ <item>If the union contains a default label, the value must match the
+ type of the default label.</item>
+ <item>No value. Orber then inserts the Erlang atom <c>undefined</c>
+ in the value field when receiving a union from an external
+ ORB.</item>
+ </list>
+ <p>The above can be summed up to:</p>
+ <code type="none">
+// If the discriminator equals 1 or 2 the value
+// is a long. Otherwise, the atom undefined.
+union LongUnion switch(long) {
+ case 1:
+ case 2: long TrueValue;
+};
+// If the discriminator equals 1 or 2 the value
+// is a long. Otherwise, a boolean.
+union LongUnion2 switch(long) {
+ case 1:
+ case 2: long TrueValue;
+ default: boolean DefaultValue;
+};
+ </code>
+ </section>
+ <warning>
+ <p>Every field in, for example, a struct must be initiated. Otherwise
+ it will be set to the atom <c>undefined</c>, which Orber cannot
+ encode when communicating via IIOP. In the example above, invoking
+ the operation with #'myStruct'{a=300} will fail (equal to
+ #'myStruct'{a=300, b=undefined})</p>
+ </warning>
+ <p>Now we can continue to work on our IDL specification. To begin with, we should
+ determine the return value of the <c>lookup</c> operation. Since the <c>any</c>
+ type can be rather expensive we can use a <c>struct</c> or a <c>union</c> instead.
+ If we intend to return the same information about a employee every time we can
+ use a struct. Let us assume that the DB contains the name, address, employee
+ number and department.</p>
+ <code type="none"><![CDATA[
+// DB IDL
+#ifndef _DB_IDL_
+#define _DB_IDL_
+module DB {
+
+ typedef unsigned long EmployeeNo;
+
+ enum Department {Department1, Department2};
+
+ struct employee {
+ EmployeeNo No;
+ string Name;
+ string Address;
+ Department Dpt;
+ };
+
+ typedef employee EmployeeData;
+
+ interface CommonUser {
+
+ EmployeeData lookup(in EmployeeNo ENo);
+
+ };
+
+ interface Administrator : CommonUser {
+
+ void delete(in EmployeeNo ENo);
+
+ };
+
+ interface Access {
+
+ typedef string<10> UserID;
+ typedef string<10> Password;
+
+ // Since Administrator inherits from CommonUser
+ // the returned Object can be of either type.
+ CommonUser logon(in UserID ID, in Password PW);
+
+ };
+
+};
+#endif ]]></code>
+ <p>We can also define exceptions (i.e. not system exception) thrown by
+ each interface. Since exceptions are thoroughly described in the chapter
+ <seealso marker="ch_exceptions">System and User Defined Exceptions</seealso>,
+ we choose not to. Hence, we are now ready to compile our IDL-file by
+ invoking:</p>
+ <pre>
+$ <input>erlc DB.idl</input>
+ </pre>
+ <p>or:</p>
+ <pre>
+$ <input>erl</input>
+Erlang (BEAM) emulator version 5.1.1 [threads:0]
+
+Eshell V5.1.1 (abort with ^G)
+1> <input>ic:gen('DB').</input>
+ok
+2> <input>halt().</input>
+ </pre>
+ <p>The next step is to implement our servers. But, to be able to do that,
+ we need to know how we can access data type definitions. For example,
+ since a struct is mapped to an Erlang record we must include an hrl-file
+ in our callback module.</p>
+ </section>
+
+ <section>
+ <title>Scoped Names and Generated Files</title>
+
+ <section>
+ <title>Scoped Names</title>
+ <p>Within a scope all identifiers must be unique. The following kinds of
+ definitions form scopes in the OMG IDL:</p>
+ <list type="bulleted">
+ <item><em>module</em></item>
+ <item><em>interface</em></item>
+ <item><em>operation</em></item>
+ <item><em>valuetype</em></item>
+ <item><em>struct</em></item>
+ <item><em>union</em></item>
+ <item><em>exception</em></item>
+ </list>
+ <p>For example, since enumerants do not form a scope, the following IDL code
+ is not valid:</p>
+ <code type="none">
+module MyModule {
+ // 'two' is not unique
+ enum MyEnum {one, two};
+ enum MyOtherEnum {two, three};
+};
+ </code>
+ <p>But, since Erlang only has two levels of scope, <em>module</em> and
+ <em>function</em>, the OMG IDL scope is mapped as follows:</p>
+ <list type="bulleted">
+ <item><em>Function Scope</em> - used for constants, operations and attributes.</item>
+ <item><em>Erlang Module Scope</em> - the Erlang module scope
+ handles the remaining OMG IDL scopes.</item>
+ </list>
+ <p>An Erlang module, corresponding to an IDL global name, is derived by
+ converting occurrences of "::" to underscore, and eliminating
+ the leading "::". Hence, accessing <c>MyEnum</c> from another module, one
+ use <c>MyModule::MyEnum</c></p>
+ <p>For example, an operation <c>foo</c> defined in interface <c>I</c>, which
+ is defined in module <c>M</c>, would be written in IDL as <c>M::I::foo</c>
+ and as <c>'M_I':foo</c> in Erlang - <c>foo</c> is the function
+ name and <c>'M_I'</c> is the name of the Erlang module. Applying this
+ knowledge to a stripped version of the DB.idl gives:</p>
+ <code type="none"><![CDATA[
+// DB IDL
+#ifndef _DB_IDL_
+#define _DB_IDL_
+// ++ topmost scope ++
+// IC generates oe_XX.erl and oe_XX.hrl.
+// XX is equal to the name of the IDL-file.
+// Tips: create one IDL-file for each top module
+// and give the file the same name (DB.idl).
+// The oe_XX.erl module is used to register data
+// in the IFR.
+module DB {
+
+ // ++ Module scope ++
+ // To access 'EmployeeNo' from another scope, use:
+ // DB::EmployeeNo, DB::Access etc.
+ typedef unsigned long EmployeeNo;
+
+ enum Department {Department1, Department2};
+
+ // Definitions of this struct is contained in:
+ // DB.hrl
+ // Access functions exported by:
+ // DB_employee.erl
+ struct employee {
+ ... CUT ...
+ };
+
+ typedef employee EmployeeData;
+
+ ... CUT ...
+
+ // If this interface should inherit an interface
+ // in another module (e.g. OtherModule) use:
+ // interface Access : OtherModule::OtherInterface
+ interface Access {
+
+ // ++ interface scope ++
+ // Types within this scope is accessible via:
+ // DB::Access::UserID
+ // The Stub/Skeleton for this interface is
+ // placed in the module:
+ // DB_Access.erl
+ typedef string<10> UserID;
+ typedef string<10> Password;
+
+ // Since Administrator inherits from CommonUser
+ // the returned Object can be of either type.
+ // This operation is exported from:
+ // DB_Access.erl
+ CommonUser logon(in UserID ID, in Password PW);
+
+ };
+
+};
+#endif ]]></code>
+ <p>Using underscores in IDL names can lead to ambiguities
+ due to the name mapping described above. It is advisable to
+ avoid the use of underscores in identifiers. For example, the following
+ definition would generate two structures named <c>x_y_z</c>.</p>
+ <code type="none">
+module x {
+
+ struct y_z {
+\011...
+ };
+
+ interface y {
+
+\011struct z {
+\011 ...
+\011};
+ };
+};
+ </code>
+ </section>
+
+ <section>
+ <title>Generated Files</title>
+ <p>Several files can be generated for each scope.</p>
+ <list type="bulleted">
+ <item>An Erlang source code file (<c>.erl</c>) is generated
+ for top level scope as well as the Erlang header file.</item>
+ <item>An Erlang header file (<c>.hrl</c>) will be generated for
+ each scope. The header file will contain record definitions
+ for all <c>struct</c>, <c>union</c> and <c>exception</c>
+ types in that scope.</item>
+ <item>Modules that contain at least one constant definition,
+ will produce Erlang source code files (<c>.erl</c>).
+ That Erlang file will contain constant functions for
+ that scope.
+ Modules that contain no constant definitions are considered
+ empty and no code will be produced for them, but only for
+ their included modules/interfaces.</item>
+ <item>Interfaces will produce Erlang source code files (<c>.erl</c>),
+ this code will contain all operation stub code and implementation
+ functions.</item>
+ <item>In addition to the scope-related files, an Erlang source file will
+ be generated for each definition of the types <c>struct</c>,
+ <c>union</c> and <c>exception</c> (these are the types that
+ will be represented in Erlang as records).
+ This file will contain special access functions for that record.</item>
+ <item>The top level scope will produce two files, one header file
+ (<c>.hrl</c>) and one Erlang source file (<c>.erl</c>).
+ These files are named as the IDL file, prefixed with <c>oe_</c>.</item>
+ </list>
+ <p>After compiling DB.idl, the following files have been generated:</p>
+ <list type="bulleted">
+ <item><c>oe_DB.hrl</c> and <c>oe_DB.erl</c> for the top scope level.</item>
+ <item><c>DB.hrl</c> for the module <c>DB</c>.</item>
+ <item><c>DB_Access.hrl</c> and <c>DB_Access.erl</c> for the interface
+ <c>DB_Access</c>.</item>
+ <item><c>DB_CommonUser.hrl</c> and <c>DB_CommonUser.erl</c> for the interface
+ <c>DB_CommonUser</c>.</item>
+ <item><c>DB_Administrator.hrl</c> and <c>DB_Administrator.erl</c> for the interface
+ <c>DB_Administrator</c>.</item>
+ <item><c>DB_employee.erl</c> for the structure <c>employee</c> in module
+ <c>DB</c>.</item>
+ </list>
+ <p>Since the <c>employee</c> struct is defined in the top level scope,
+ the Erlang record definition is found in <c>DB.hrl</c>. IC also generates
+ stubs/skeletons (e.g. <c>DB_CommonUser.erl</c>) and access functions for
+ some datatypes (e.g. <c>DB_employee.erl</c>). How the stubs/skeletons are
+ used is thoroughly described in
+ <seealso marker="ch_stubs">Stubs/Skeletons</seealso> and
+ <seealso marker="Module_Interface">Module_Interface</seealso>.</p>
+ </section>
+ </section>
+
+ <section>
+ <title>Typecode, Identity and Name Access Functions</title>
+ <p>As mentioned in a previous section, <c>struct</c>, <c>union</c> and
+ <c>exception</c> types yield record definitions and access code
+ for that record.
+ For <c>struct</c>, <c>union</c>, <c>exception</c>, <c>array</c> and
+ <c>sequence</c> types, a special file is generated that holds access
+ functions for <c>TypeCode</c>, <c>Identity</c> and <c>Name</c>.
+ These functions are put in the file corresponding to the scope where
+ they are defined. For example, the module <c>DB_employee.erl</c>,
+ representing the <c>employee</c> struct, exports the following functions:</p>
+ <list type="bulleted">
+ <item>tc/0 - returns the type code for the struct.</item>
+ <item>id/0 - returns the IFR identity of the struct. In this case
+ the returned value is <c>"IDL:DB/employee:1.0"</c>, but
+ if the struct was defined in the scope of <c>CommonUser</c>,
+ the result would be <c>"IDL:DB/CommonUser/employee:1.0"</c>.
+ However, the user usually do not need to know the Id, just
+ which Erlang module contains the correct Id.</item>
+ <item>name/0 - returns the scoped name of the struct. The <c>employee</c>
+ struct name is <c>"DB_employee"</c>.</item>
+ </list>
+ <p><term id="Type Codes"><termdef>Type codes give a complete description of the type including all its components and structure.</termdef></term>are, for example, used in <seealso marker="any">Any</seealso> values.
+ Hence, we can encapsulate the <c>employee</c> struct in an <c>any</c>
+ type by:</p>
+ <code type="none">
+%% Erlang code
+....
+AnEmployee = #'DB_employee'{'No' = 1,
+ 'Name' = "Adam Ivan Kendall",
+ 'Address' = "Rasunda, Solna",
+ 'Dpt' = 'Department1'},
+EmployeeTC = 'DB_employee':tc(),
+EmployeeAny = any:create(EmployeeTC, AnEmployee),
+....
+ </code>
+ <p>For more information, see the
+ <seealso marker="#tk_values">Type Code listing</seealso>.</p>
+ </section>
+
+ <section>
+ <title>References to Constants</title>
+ <p>Constants are generated as Erlang functions, and are accessed by a
+ single function call. The functions are put in the file
+ corresponding to the scope where they are defined. There is no
+ need for an object to be started to access a constant.</p>
+ <p>Example:</p>
+ <code type="none">
+// m.idl
+module m {
+ const float pi = 3.14;
+
+ interface i {
+\011const float pi = 3.1415;
+ };
+};
+ </code>
+ <p>Since the two constants are defined in different scopes, the IDL code
+ above is valid, but not necessarily a good approach. After compiling
+ <c>m.idl</c>, the constant definitions can be extracted by invoking:</p>
+ <pre>
+$ <input>erlc m.idl</input>
+$ <input>erlc m.erl</input>
+$ <input>erl</input>
+Erlang (BEAM) emulator version 5.1.1 [threads:0]
+
+Eshell V5.1.1 (abort with ^G)
+1> <input>m:pi().</input>
+3.14
+2> <input>m_i:pi().</input>
+3.1415
+3> <input>halt().</input>
+ </pre>
+ </section>
+
+ <section>
+ <title>References to Objects Defined in OMG IDL</title>
+ <p>Objects are accessed by object references. An object reference
+ is an opaque Erlang term created and maintained by the ORB.</p>
+ <p>Objects are implemented by providing implementations for all
+ operations and attributes of the Object, <seealso marker="#op_impl">see operation implementation</seealso>.</p>
+ </section>
+
+ <section>
+ <title>Exceptions</title>
+ <p>Exceptions are handled as Erlang catch and throws. Exceptions
+ are translated to messages over an IIOP bridge but converted
+ back to a throw on the receiving side. Object implementations
+ that invoke operations on other objects must be aware of the
+ possibility of a non-local return. This includes invocation of
+ ORB and IFR services. See also the
+ <seealso marker="ch_exceptions">Exceptions</seealso> section.</p>
+ <p>Exception parameters are mapped as an Erlang record and accessed
+ as such.</p>
+ <p>An object implementation that raises an exception will use the
+ <c>corba:raise/1</c> function, passing the exception record as
+ parameter.</p>
+ </section>
+
+ <section>
+ <title>Access to Attributes</title>
+ <p>Attributes are accessed through their access functions. An
+ attribute implicitly defines the <c>_get</c> and <c>_set</c>
+ operations. These operations are handled in the same way as
+ normal operations. The <c>_get</c> operation is defined as a <c>readonly</c>
+ attribute.</p>
+ <code type="none">
+readonly attribute long RAttribute;
+attribute long RWAttribute;
+ </code>
+ <p>The <c>RAttribute</c> requires that you implement, in your call-back module,
+ <c>_get_RAttribute</c>. For the <c>RWAttribute</c> it is necessary to implement
+ <c>_get_RWAttribute</c> and <c>_set_RWAttribute</c>.</p>
+ </section>
+
+ <section>
+ <title>Invocations of Operations</title>
+ <marker id="op_impl"></marker>
+ <p>A standard Erlang <c>gen_server</c> behavior is used for
+ object implementation. The <c>gen_server</c> state is then
+ used as the object internal state. Implementation of the object
+ function is achieved by implementing its methods and attribute operations.
+ These functions will usually have the internal state as their first parameter,
+ followed by any <c>in</c> and <c>inout</c> parameters. </p>
+ <p>Do not confuse the
+ object internal state with its object reference. The object internal state is
+ an Erlang term which has a format defined by the user.</p>
+ <note>
+ <p>It is is not always the case that the internal state will be the first parameter, as stubs can use their own object reference as the first parameter (see the IC documentation).</p>
+ </note>
+ <p>A function call will invoke an operation. The first
+ parameter of the function should be the object reference and then
+ all <c>in</c> and <c>inout</c> parameters follow in the same
+ order as specified in the IDL specification. The result will be a return value
+ unless the function has <c>inout</c> or <c>out</c> parameters specified;
+ in which case, a tuple of the return value, followed by the parameters will
+ be returned.</p>
+ <p>Example:</p>
+ <code type="none">
+// IDL
+module m {
+ interface i {
+ readonly attribute long RAttribute;
+ attribute long RWAttribute;
+ long foo(in short a);
+ long bar(in char c, inout string s, out long count);
+ void baz(out long Id);
+ };
+};
+ </code>
+ <p>Is used in Erlang as :</p>
+ <code type="none">
+%% Erlang code
+....
+Obj = ... %% get object reference
+RAttr = m_i:'_get_RAttribute'(Obj),
+RWAttr = m_i:'_get_RWAttribute'(Obj),
+ok = m_i:'_set_RWAttribute'(Obj, Long),
+R1 = m_i:foo(Obj, 55),
+{R2, S, Count} = m_i:bar(Obj, $a, "hello"),
+....
+ </code>
+ <p>Note how the <c>inout</c> parameter is passed <em>and</em>
+ returned. There is no way to use a single occurrence of a
+ variable for this in Erlang. Also note, that <c>ok</c>, Orber's
+ representation of the IDL-type <c>void</c>, must be returned by
+ <c>baz</c> and <c>'_set_RWAttribute'</c>.
+ These operations can be implemented in the call-back module as:</p>
+ <code type="none">
+'_set_RWAttribute'(State, Long) ->
+ {reply, ok, State}.
+
+'_get_RWAttribute'(State) ->
+ {reply, Long, State}.
+
+'_get_RAttribute'(State) ->
+ {reply, Long, State}.
+
+foo(State, AShort) ->
+ {reply, ALong, State}.
+
+bar(State, AShort, AString) ->
+ {reply, {ALong, "MyString", ALong}, State}.
+
+baz(State) ->
+ {reply, {ok, AId}, State}.
+ </code>
+ <p>The operations may require more arguments (depends on IC options used). For
+ more information, see <seealso marker="ch_stubs">Stubs/Skeletons</seealso>
+ and <seealso marker="Module_Interface">Module_Interface</seealso>.</p>
+ <warning>
+ <p>A function can also be defined to be <c>oneway</c>, i.e.
+ asynchronous. But, since the behavior of a oneway operation is not
+ defined in the OMG specifications (i.e. the behavior can differ depending on
+ which other ORB Orber is communicating with), one should avoid using it.</p>
+ </warning>
+ </section>
+
+ <section>
+ <title>Implementing the DB Application</title>
+ <p>Now we are ready to implement the call-back modules. There are three modules
+ we must create:</p>
+ <list type="bulleted">
+ <item>DB_Access_impl.erl</item>
+ <item>DB_CommonUser_impl.erl</item>
+ <item>DB_Administrator_impl.erl</item>
+ </list>
+ <p>An easy way to accomplish that, is to use the IC backend <c>erl_template</c>,
+ which will generate a complete call-back module. One should also add
+ the same compile options, for example <c>this</c> or <c>from</c>,
+ used when generating the stub/skeleton modules:</p>
+ <code type="none">
+$> erlc +"{be,erl_template}" DB.idl
+ </code>
+ <p>We begin with implementing the <c>DB_Access_impl.erl</c> module, which,
+ if we used <c>erl_template</c>, will look like the following. All we need
+ to do is to add the logic to the <c>logon</c> operation.</p>
+ <code type="none"><![CDATA[
+%%----------------------------------------------------------------------
+%% <LICENSE>
+%%
+%% $Id$
+%%
+%%----------------------------------------------------------------------
+%% Module : DB_Access_impl.erl
+%%
+%% Source : /home/user/example/DB.idl
+%%
+%% Description :
+%%
+%% Creation date: 2005-05-20
+%%
+%%----------------------------------------------------------------------
+-module('DB_Access_impl').
+
+-export([logon/3]).
+
+%%----------------------------------------------------------------------
+%% Internal Exports
+%%----------------------------------------------------------------------
+-export([init/1,
+ terminate/2,
+ code_change/3,
+ handle_info/2]).
+
+%%----------------------------------------------------------------------
+%% Include Files
+%%----------------------------------------------------------------------
+
+
+%%----------------------------------------------------------------------
+%% Macros
+%%----------------------------------------------------------------------
+
+
+%%----------------------------------------------------------------------
+%% Records
+%%----------------------------------------------------------------------
+-record(state, {}).
+
+%%======================================================================
+%% API Functions
+%%======================================================================
+%%----------------------------------------------------------------------
+%% Function : logon/3
+%% Arguments : State - term()
+%% ID = String()
+%% PW = String()
+%% Returns : ReturnValue = OE_Reply
+%% OE_Reply = Object_Ref()
+%% Raises :
+%% Description:
+%%----------------------------------------------------------------------
+logon(State, ID, PW) ->
+\011%% Check if the ID/PW is valid and what
+\011%% type of user it is (Common or Administrator).
+\011OE_Reply
+ = case check_user(ID, PW) of
+\011 {ok, administrator} ->
+\011 'DB_Administrator':oe_create();
+\011 {ok, common} ->
+\011 'DB_CommonUser':oe_create();
+\011 error ->
+\011 %% Here we should throw an exception
+ \011 corba:raise(....)
+ end,
+\011{reply, OE_Reply, State}.
+
+%%======================================================================
+%% Internal Functions
+%%======================================================================
+%%----------------------------------------------------------------------
+%% Function : init/1
+%% Arguments : Env = term()
+%% Returns : {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%% Raises : -
+%% Description: Initiates the server
+%%----------------------------------------------------------------------
+init(_Env) ->
+\011{ok, #state{}}.
+
+
+%%----------------------------------------------------------------------
+%% Function : terminate/2
+%% Arguments : Reason = normal | shutdown | term()
+%% State = term()
+%% Returns : ok
+%% Raises : -
+%% Description: Invoked when the object is terminating.
+%%----------------------------------------------------------------------
+terminate(_Reason, _State) ->
+\011ok.
+
+
+%%----------------------------------------------------------------------
+%% Function : code_change/3
+%% Arguments : OldVsn = undefined | term()
+%% State = NewState = term()
+%% Extra = term()
+%% Returns : {ok, NewState}
+%% Raises : -
+%% Description: Invoked when the object should update its internal state
+%% due to code replacement.
+%%----------------------------------------------------------------------
+code_change(_OldVsn, State, _Extra) ->
+\011{ok, State}.
+
+
+%%----------------------------------------------------------------------
+%% Function : handle_info/2
+%% Arguments : Info = normal | shutdown | term()
+%% State = NewState = term()
+%% Returns : {noreply, NewState} |
+%% {noreply, NewState, Timeout} |
+%% {stop, Reason, NewState}
+%% Raises : -
+%% Description: Invoked when, for example, the server traps exits.
+%%----------------------------------------------------------------------
+handle_info(_Info, State) ->
+\011{noreply, State}.
+ ]]></code>
+ <p>Since <c>DB_Administrator</c> inherits from <c>DB_CommonUser</c>,
+ we must implement <c>delete</c> in the <c>DB_Administrator_impl.erl</c>
+ module, and <c>lookup</c> in <c>DB_Administrator_impl.erl</c><em>and</em><c>DB_CommonUser_impl.erl</c>. But wait, is that really necessary? Actually,
+ it is not. We simple use the IC compile option <em>impl</em>:</p>
+ <pre>
+$ <input>erlc +'{{impl, "DB::CommonUser"}, "DBUser_impl"}' +'{{impl, "DB::Administrator"}, "DBUser_impl"}' DB.idl</input>
+$ <input>erlc *.erl</input>
+ </pre>
+ <p>Instead of creating, and not the least, maintaining two call-back modules,
+ we only have to deal with <c>DBUser_impl.erl</c>. If we generated the
+ templates, we simply rename <c>DB_Administrator_impl.erl</c> to
+ <c>DBUser_impl.erl</c>. See also the
+ <seealso marker="ch_exceptions">Exceptions</seealso> chapter.
+ In the following example, only the implementation of the API functions
+ are shown:</p>
+ <code type="none">
+%%======================================================================
+%% API Functions
+%%======================================================================
+%%----------------------------------------------------------------------
+%% Function : delete/2
+%% Arguments : State - term()
+%% ENo = unsigned_Long()
+%% Returns : ReturnValue = ok
+%% Raises :
+%% Description:
+%%----------------------------------------------------------------------
+delete(State, ENo) ->
+ %% How we access the DB, for example mnesia, is not shown here.
+ case delete_employee(No) of
+ ok ->
+ {reply, ok, State};
+ error ->
+ %% Here we should throw an exception if
+ %% there is no match.
+ corba:raise(....)
+ end.
+
+%%----------------------------------------------------------------------
+%% Function : lookup/2
+%% Arguments : State - term()
+%% ENo = unsigned_Long()
+%% Returns : ReturnValue = OE_Reply
+%% OE_Reply = #'DB_employee'{No,Name,Address,Dpt}
+%% No = unsigned_Long()
+%% Name = String()
+%% Address = String()
+%% Dpt = Department
+%% Department = 'Department1' | 'Department2'
+%% Raises :
+%% Description:
+%%----------------------------------------------------------------------
+lookup(State, ENo) ->
+ %% How we access the DB, for example mnesia, is not shown here.
+ case lookup_employee(ENo) of
+ %% We assume that we receive a 'DB_employee' struct
+ {ok, Employee} ->
+ OE_Reply = Employee,
+ {reply, OE_Reply, State};
+ error ->
+ %% Here we should throw an exception if
+ %% there is no match.
+ corba:raise(....)
+ end.
+ </code>
+ <p>After you have compiled both call-back modules, and implemented the missing
+ functionality (e.g. lookup_employee/1), we can test our application:</p>
+ <code type="none">
+%% Erlang code
+....
+%% Create an Access object
+Acc = 'DB_Access':oe_create(),
+
+%% Login is Common user and Administrator
+Adm = 'DB_Access':logon(A, "admin", "pw"),
+Com = 'DB_Access':logon(A, "comm", "pw"),
+
+%% Lookup existing employee
+Employee = 'DB_Administrator':lookup(Adm, 1),
+Employee = 'DB_CommonUser':lookup(Adm, 1),
+
+%% If we try the same using the DB_CommonUser interface
+%% it result in an exit since that operation is not exported.
+{'EXIT', _} = (catch 'DB_CommonUser':delete(Adm, 1)),
+
+%% Try to delete the employee via the CommonUser Object
+{'EXCEPTION', _} = (catch 'DB_Administrator':delete(Com, 1)),
+
+%% Invoke delete operation on the Administrator object
+ok = 'DB_Administrator':delete(Adm, 1),
+....
+ </code>
+ </section>
+
+ <section>
+ <title>Reserved Compiler Names and Keywords</title>
+ <marker id="key_words"></marker>
+ <p>The use of some names is strongly discouraged due to
+ ambiguities. However, the use of some names is prohibited
+ when using the Erlang mapping , as they are strictly reserved for IC.</p>
+ <p>IC reserves all identifiers starting with <c>OE_</c> and <c>oe_</c>
+ for internal use.</p>
+ <p>Note also, that an identifier in IDL can contain alphabetic,
+ digits and underscore characters, but the first character
+ <em>must</em> be alphabetic.
+ </p>
+ <p>The OMG defines a set of reserved words, shown below, for use as keywords.
+ These may <em>not</em> be used as, for example, identifiers. The keywords
+ which are not in bold face was introduced in the OMG CORBA-3.0
+ specification.</p>
+ <table>
+ <row>
+ <cell align="left" valign="middle"><em>abstract</em></cell>
+ <cell align="left" valign="middle"><em>exception</em></cell>
+ <cell align="left" valign="middle"><em>inout</em></cell>
+ <cell align="left" valign="middle">provides</cell>
+ <cell align="left" valign="middle"><em>truncatable</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>any</em></cell>
+ <cell align="left" valign="middle">emits</cell>
+ <cell align="left" valign="middle"><em>interface</em></cell>
+ <cell align="left" valign="middle"><em>public</em></cell>
+ <cell align="left" valign="middle"><em>typedef</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>attribute</em></cell>
+ <cell align="left" valign="middle"><em>enum</em></cell>
+ <cell align="left" valign="middle"><em>local</em></cell>
+ <cell align="left" valign="middle">publishes</cell>
+ <cell align="left" valign="middle">typeid</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>boolean</em></cell>
+ <cell align="left" valign="middle">eventtype</cell>
+ <cell align="left" valign="middle"><em>long</em></cell>
+ <cell align="left" valign="middle"><em>raises</em></cell>
+ <cell align="left" valign="middle">typeprefix</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>case</em></cell>
+ <cell align="left" valign="middle"><em>factory</em></cell>
+ <cell align="left" valign="middle"><em>module</em></cell>
+ <cell align="left" valign="middle"><em>readonly</em></cell>
+ <cell align="left" valign="middle"><em>unsigned</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>char</em></cell>
+ <cell align="left" valign="middle"><em>FALSE</em></cell>
+ <cell align="left" valign="middle">multiple</cell>
+ <cell align="left" valign="middle">setraises</cell>
+ <cell align="left" valign="middle"><em>union</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">component</cell>
+ <cell align="left" valign="middle">finder</cell>
+ <cell align="left" valign="middle"><em>native</em></cell>
+ <cell align="left" valign="middle"><em>sequence</em></cell>
+ <cell align="left" valign="middle">uses</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>const</em></cell>
+ <cell align="left" valign="middle"><em>fixed</em></cell>
+ <cell align="left" valign="middle"><em>Object</em></cell>
+ <cell align="left" valign="middle"><em>short</em></cell>
+ <cell align="left" valign="middle"><em>ValueBase</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">consumes</cell>
+ <cell align="left" valign="middle"><em>float</em></cell>
+ <cell align="left" valign="middle"><em>octet</em></cell>
+ <cell align="left" valign="middle"><em>string</em></cell>
+ <cell align="left" valign="middle"><em>valuetype</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>context</em></cell>
+ <cell align="left" valign="middle">getraises</cell>
+ <cell align="left" valign="middle"><em>oneway</em></cell>
+ <cell align="left" valign="middle"><em>struct</em></cell>
+ <cell align="left" valign="middle"><em>void</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>custom</em></cell>
+ <cell align="left" valign="middle">home</cell>
+ <cell align="left" valign="middle"><em>out</em></cell>
+ <cell align="left" valign="middle"><em>supports</em></cell>
+ <cell align="left" valign="middle"><em>wchar</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>default</em></cell>
+ <cell align="left" valign="middle">import</cell>
+ <cell align="left" valign="middle">primarykey</cell>
+ <cell align="left" valign="middle"><em>switch</em></cell>
+ <cell align="left" valign="middle"><em>wstring</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle"><em>double</em></cell>
+ <cell align="left" valign="middle"><em>in</em></cell>
+ <cell align="left" valign="middle"><em>private</em></cell>
+ <cell align="left" valign="middle"><em>TRUE</em></cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <tcaption>OMG IDL keywords</tcaption>
+ </table>
+ <p>The keywords listed above must be written exactly as shown. Any usage
+ of identifiers that collide with a keyword is illegal. For example,
+ <em>long</em> is a valid keyword; <em>Long</em> and <em>LONG</em> are
+ illegal as keywords and identifiers. But, since the OMG must be able
+ to expand the IDL grammar, it is possible to use <em>Escaped Identifiers</em>. For example, it is not unlikely that <c>native</c>
+ have been used in IDL-specifications as identifiers. One option is to
+ change all occurrences to <c>myNative</c>. Usually, it is necessary
+ to change programming language code that depends upon that IDL as well.
+ Since Escaped Identifiers just disable type checking (i.e. if it is a reserved
+ word or not) and leaves everything else unchanged, it is only necessary to
+ update the IDL-specification. To escape an identifier, simply prefix it
+ with <em>_</em>. The following IDL-code is illegal:</p>
+ <code type="none">
+typedef string native;
+interface i {
+ void foo(in native Arg);
+ };
+};
+ </code>
+ <p>With Escaped Identifiers the code will look like:</p>
+ <code type="none">
+typedef string _native;
+interface i {
+ void foo(in _native Arg);
+ };
+};
+ </code>
+ </section>
+
+ <section>
+ <title>Type Code Representation</title>
+ <marker id="tk_values"></marker>
+ <p>Type Codes are used in <c>any</c> values. To avoid mistakes, you should
+ use access functions exported by the Data Types modules
+ (e.g. struct, union etc) or the <seealso marker="orber_tc">orber_tc</seealso>
+ module.</p>
+ <table>
+ <row>
+ <cell align="left" valign="middle"><em>Type Code</em></cell>
+ <cell align="left" valign="middle"><em>Example</em></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_null</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_void</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_short</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_long</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_longlong</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_ushort</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_ulong</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_ulonglong</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_float</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_double</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_boolean</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_char</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_wchar</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_octet</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_any</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_TypeCode</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">tk_Principal</cell>
+ <cell align="left" valign="middle"></cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{tk_objref, IFRId, Name}</cell>
+ <cell align="left" valign="middle">{tk_objref, "IDL:M1\\I1:1.0", "I1"}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{tk_struct, IFRId, Name, [{ElemName, ElemTC}]}</cell>
+ <cell align="left" valign="middle">{tk_struct, "IDL:M1\\S1:1.0", "S1", [{"a", tk_long}, {"b", tk_char}]}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{tk_union, IFRId, Name, DiscrTC, DefaultNr, [{Label, ElemName, ElemTC}]} <br></br>
+Note: DefaultNr tells which of tuples in the case list that is default, or -1 if no default</cell>
+ <cell align="left" valign="middle">{tk_union, "IDL:U1:1.0", "U1", tk_long, 1, [{1, "a", tk_long}, {default, "b", tk_char}]}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{tk_enum, IFRId, Name, [ElemName]}</cell>
+ <cell align="left" valign="middle">{tk_enum, "IDL:E1:1.0", "E1", ["a1", "a2"]}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{tk_string, Length}</cell>
+ <cell align="left" valign="middle">{tk_string, 5}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{tk_wstring, Length}</cell>
+ <cell align="left" valign="middle">{tk_wstring, 7}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{tk_fixed, Digits, Scale}</cell>
+ <cell align="left" valign="middle">{tk_fixed, 3, 2}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{tk_sequence, ElemTC, Length}</cell>
+ <cell align="left" valign="middle">{tk_sequence, tk_long, 4}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{tk_array, ElemTC, Length}</cell>
+ <cell align="left" valign="middle">{tk_array, tk_char, 9}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{tk_alias, IFRId, Name, TC}</cell>
+ <cell align="left" valign="middle">{tk_alias, "IDL:T1:1.0", "T1", tk_short}</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">{tk_except, IFRId, Name, [{ElemName, ElemTC}]}</cell>
+ <cell align="left" valign="middle">{tk_except, "IDL:Exc1:1.0", "Exc1", [{"a", tk_long}, {"b", {tk_string, 0}}]}</cell>
+ </row>
+ <tcaption>Type Code tuples</tcaption>
+ </table>
+ </section>
+</chapter>
+