diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/orber/doc/src/ch_idl_to_erlang_mapping.xml | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
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.xml | 1471 |
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 <long, 3> 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<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³². 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> + |