diff options
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 | 1504 |
1 files changed, 0 insertions, 1504 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 deleted file mode 100644 index eaa88f24f1..0000000000 --- a/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml +++ /dev/null @@ -1,1504 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<!DOCTYPE chapter SYSTEM "chapter.dtd"> - -<chapter> - <header> - <copyright> - <year>1997</year><year>2017</year> - <holder>Ericsson AB. All Rights Reserved.</holder> - </copyright> - <legalnotice> - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions 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. By using forward declaration we can define a recursive struct:</p> - <code type="none"><![CDATA[ -struct myStruct; // Forward declaration -typedef sequence<myStruct> myStructSeq; -struct myStruct { - myStructSeq chain; -}; - -// Deprecated definition (anonymous) not supported by IC -struct myStruct { - sequence<myStruct> chain; -}; - ]]></code> - </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> - <p>In the same way as structs, unions can be recursive if forward - declaration is used (anonymous types is deprecated and not supported):</p> - <code type="none"><![CDATA[ -// Forward declaration -union myUnion; -typedef sequence<myUnion>myUnionSeq; -union myUnion switch (long) { - case 1 : myUnionSeq chain; - default: boolean DefaultValue; -}; - ]]></code> - - <note> - <p>Recursive types (union and struct) require Light IFR. I.e. the - IC option {light_ifr, true} is used and that Orber is configured in such a way that - Light IFR is activated. Recursive TypeCode is currently not supported, which is - why these cannot be encapsulated in an any data type.</p> - </note> - - </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 { - ... - }; - - interface y { - - struct z { - ... - }; - }; -}; - </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="erl"> -%% 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 { - const 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 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="erl"> -'_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="erl"><![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) -> - %% Check if the ID/PW is valid and what - %% type of user it is (Common or Administrator). - OE_Reply - = case check_user(ID, PW) of - {ok, administrator} -> - 'DB_Administrator':oe_create(); - {ok, common} -> - 'DB_CommonUser':oe_create(); - error -> - %% Here we should throw an exception - corba:raise(....) - end, - {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) -> - {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) -> - ok. - - -%%---------------------------------------------------------------------- -%% 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) -> - {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) -> - {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="erl"> -%%====================================================================== -%% 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> - |