1 @(#)DIFFERENCES 1.1 95/09/13
3 Note -- this documentation was distributed with the original SunSoft
4 IIOP reference implementation and has very little relevance to what's
5 in TAO. We include it here only for "historical" reference, i.e., you
6 should disregard most of what's in this document.
10 ----------------------------------------
12 [ NOTE that the CORBA 2.0 specifications have now been published, but are
13 not yet sufficiently available that this document can usefully just list
14 any differences between that specification and this software. As a rule,
15 there are no differences between this software and CORBA 2.0 in areas
16 where CORBA 2.0 has specified an interface. ]
19 This document summarizes known differences between what is implemented in
20 this software and currently available OMG specifications. As a rule, these
21 establish compatibility with revised specifications that are currently being
22 prepared for publication. However, in some cases the differences resolve
23 problems that are currently being addressed by ORB taskforces. When those
24 revised CORBA specifications are published, this document will be updated to
25 reflect any remaining differences from them.
27 The reason for those changes is that different specifications were adopted
28 at the same time and there were in some cases subtle differences which need
29 to be resolved. Minor errata have also been fixed. None of these changes
30 are substantial, with the exception of the TypeCode interpreter API which
31 was added to the C++ mapping.
33 Also, note that the goal of this software is fidelity to the IIOP, so that
34 issues relating (in particular) to the C++ language mapping or other OMG
35 specifications were judged to be of less importance at this time.
38 DIFFERENCES from IIOP in UNO Spec (95-3-10)
39 -------------------------------------------
40 Some changes to the original specification (94-9-32) for the IIOP protocol
41 were found to be necessary; most related to the subsequently adopted Interface
42 Repository (IFR) specification (94-11-7). Others resulted from correction
43 of minor editorial errors, and experience gained as multiple teams implement
44 to that specification.
46 The bulk of those changes have been incorporated into the 95-3-10 document,
47 but these few have not.
50 CDR TYPECODE INDIRECTION
52 An additional constraint on the use of typecode indirection has been
53 identified. Specifically, the typecode to which an indirection points
54 be "self-sufficient", and may not point "outside of itself" for any
55 further indirections. For example, always indirections occur within
56 encapsulations, so it's OK for the indirection to point anywhere in
57 that encapsulation, or at the encoded TCKind enum value immediately
58 before the encapsulation's length. For typecode encapsulations nested
59 inside other typecode encapsulations, the indirection may point no
60 further than the outermost encapsulation.
62 Also, when an indirection points to another typecode, the byte order
63 of that other typecode must be deduced from the encoded value found
64 there. This is straightforward for encoded TCKind values, all of which
65 fit into a single byte: if the first byte of the word is zero, then
66 the encoding is big-endian, else it's little-endian.
68 Indirecting to another indirection is not allowed, since the byte order
69 of the encoded offset can't consistently be deduced.
74 The type GIOP::Version is assumed to be identical to IIOP::Version.
75 As part of the editorial separation of GIOP from its Internet version
76 IIOP, this typedef was accidentally omitted.
78 This implementation of IIOP supports the OMG-IDL Primitive Data Types as
79 defined in Appendix A of 94-9-32, but with TCKind numbers following the new
80 tk_exception and tk_alias codes. (That is, rather than using range 21-25,
81 these TCKind values are in the range 23-27.)
83 These data types are currently the topic of an RFP in process in the OMG,
84 and are not currently defined as part of a current OMG specification.
85 Clients and servers using these extended data types are relying on CORBA
86 extensions that are not yet standardized; and should be prepared to change.
89 CORBA 2.0/CORE Differences
90 --------------------------
91 As of this writing, the new CORBA 2.0/CORE document has not yet been made
92 available. This is a modification of the CORBA 1.2 document, with the
93 addition of (mandatory) extensions from the UNO (94-9-32) specification:
94 notably DSI and some new object reference operations. This summarizes
95 differences between the as-yet-unpublished CORBA 2.0/CORE document and
96 the original text in the UNO specification.
99 DYNAMIC SKELETON INTERFACE
101 Since the new "tk_except" typecodes now include the exception ID (this is
102 the repository ID describing the exception's type) the "exception" operation
103 used to report an exception through a ServerRequest no longer includes the
106 Since the OperationDef entries for attributes are no longer found in the
107 interface repositories, the ServerRequest convenience operation to return
108 this has been removed. Application programs (such as bridges) must compare
109 the operation name string with the prefixes "_get_" and "_set_" to see if
110 any given operation applies to an attribute. If an operation is one of the
111 two for which an OMG-IDL "attribute" declaration is shorthand, then the
112 application must search the interface repository for that attribute.
114 (There are in fact three categories of operations on which an object adapter
115 and implementation collaborate to handle: user defined operations, user
116 defined attributes, and operations defined by CORBA such as "is_a" and
117 "get_implementation". Some object adapters, like the BOA, handle this last
118 category directly, rather than exposing it to applications.)
120 The "non_existent" objref operation accidentally used attribute syntax; this
121 has been corrected. All operations on CORBA::Object references now use
122 normal operation syntax in their (pseudo) IDL definitions, and are uniformly
123 prefixed with underscores as part of their C++ mapping.
126 DIFFERENCES from IDL C++ Mapping (94-9-14)
127 ------------------------------------------
128 There are four basic ways in which the IIOP framework does not comply
129 with the OMG's IDL C++ mapping specification, beyond the use of the CORBA2
130 module/namespace rather than the CORBA module/namespace. (CORBA2 is used
131 so that this software can be linked with existing ORBs, which should be
132 using the CORBA module/namespace already.)
134 These ways are beyond the portability-derived use of the "class" construct
135 (instead of the C++ namespace construct), and the use of CORBA2::Environment
136 (rather than C++ exceptions), both of which are accomodated by the mapping:
138 (1) This framework does not attempt to be complete.
140 Completeness is not required to implement the Internet IOP,
141 so time was not spent in providing a complete mapping.
143 (2) In some cases the API provided is not the one in the mapping.
144 For example CORBA2::Environment is not always passed in all
145 operations. This was done to promote ease of implementation
148 (3) Implementation details are generally exposed.
150 This isn't so much a noncompliance issue (it's not specified
151 that such details must be hidden) as an issue of allowing
152 noncompliant applications. The effort required to actively
153 prevent use of implementation details by higher level code
154 would be nontrivial, and could slow down IIOP code, so no
155 time was applied to hiding such details.
157 (However, note that when the software was modified to use COM,
158 standard C++ techniques were used to hide most such details.)
160 (4) The C++ mapping needs completion in some areas.
162 Notably, 94-9-14 does not satisfy requirements to provide
163 support for for all data types in an "Any" or exception without
164 needing any precompiled data type support routines. The
165 TypeCode interpreter addresses this issue.
167 Some additional operations were not adopted at the time 94-9-14
168 was defined; both 94-9-32 and 94-11-7 added new ORB interfaces
169 which are not found in the initial C++ mapping document.
171 With respect to this fourth issue, descriptions of the API extensions
172 used is provided later in this file. The additional CORBA operations
173 are not described since their mapping is straightforward if it isn't given
177 ACCESS TO ALL DATA IN "ANY" AND EXCEPTIONS
179 The "void *" value in an "Any", and any "CORBA2::Exception *" value, may
180 always be passed to the TypeCode interpreter (see next). This allows access
181 to all data held within an "Any" and an Exception. The "void *" value in an
182 Any with an exception TypeCode is of type CORBA2::Exception *". Due to
183 the way CORBA is specified, it is not possible to tell whether an "Any"
184 holding an exception denotes a user or standard (system-defined) exception
185 except by exhaustive comparison against exception IDs.
187 Also, _all_ legal OMG-IDL data types may be held in an "Any", and may be
188 manipulated using the TypeCode interpreter. This satisfies a language
189 mapping requirement that DII (and DSI) be able to manipulate all OMG-IDL
190 data types without requiring compiler generated support for them.
195 In any given C/C++ execution environment there is a binary standard for how
196 data is represented. While that standard will differ between execution
197 environments, there are a very limited number of ways in which those
198 representations differ. Those differences are encapsulated only in the
199 TypeCode interpreter, so that portable applications using the dynamic
200 typing infrastructure in the ORB can completely ignore how it's done in
201 any particular environment.
203 The APIs in this software distribution have been suggested for adoption as
204 part of the OMG specification suite. The two APIs are nonstatic member
205 functions in the C++ mapping's TypeCode pseudo-object, and are augmented
206 by a single new enumeration type.
210 This returns the size of an instance of the type that is
211 described by the TypeCode.
213 For example, when invoked on the typecode constant CORBA::_tc_Short,
214 the value returned is sizeof(CORBA::Short); and when invoked on the
215 typecode for a structure, it is the size of that structure (including
216 any internal and tail padding needed). When invoked on a sequence
217 typecode, it returns a value that does not include the size for
220 enum traverse_status {TRAVERSE_STOP, TRAVERSE_CONTINUE };
222 This is a data type used in the traverse() member function.
223 It allows data type traversal to be terminated early for
224 non-exceptional conditions, and eliminates the confusion
225 that some similar APIs have created when they use a single
226 boolean value (does TRUE mean to stop, or to continue?).
228 traverse_status traverse (
231 traverse_status visit (
233 const void *visit_value1,
234 const void *visit_value2,
240 (In the current language mapping, CORBA2::Environment references
241 are passed as the final parameter to the 'traverse' and 'visit'
242 routines for use when reporting exceptions.)
244 The pointers "value1" and "value2" point to instances of the
245 data type described by the typecode (or are null pointers).
247 For each constituent of that data type (e.g. structure member)
248 the visit() routine is called once. The constituent's type
249 is described by "tc"; "visit_value1" points to the constituent
250 of that type in "value1" (assuming the traverse routine was
251 not passed a null pointer) and similarly for "visit_value2".
252 The "visit_context" parameter is the context parameter passed
253 to the traverse() routine, and can point to whatever data is
254 needed by the visit() routine.
256 Members are traversed in first-to-last order, as defined in the
257 IDL specification for the data type. So for example, the
258 visit routine for a structure could print out each element
259 on a IO stream passed through the context parameter, perhaps in
260 a neatly formatted form intended for human consumption.
262 The visit() function may choose to recursively traverse() each
263 element. So for example if "tc->kind()" in a visit routine
264 returned CORBA::tk_struct, the contents of that struct would
265 be ignored unless the visit routine invoked traverse() using
266 the typecode and values passed to it.
268 If the visit() routine returns TRAVERSE_CONTINUE, succeeding
269 constituents of the data type are visited in turn; if it
270 returns TRAVERSE_STOP, the traverse() routine returns that
271 value to its caller. Of course, if a visit() routine calls
272 traverse() itself, it may choose to ignore TRAVERSE_STOP.
274 The traverse() routine is a powerful tool. It is used in the IIOP code
275 itself in several ways; look at such use for tutorial details. You could
276 implement data value comparison and "debug" data dumping as simple exercises
277 in the use of these APIs.
279 The "marshaling interpreter" (marshal.cc) uses it to encode and decode
280 values according to the IIOP protocol specification. The "Any" code
281 (any.cc) uses traverse() both to free embedded pointers, and to make "deep"
282 copies of any data structure given its TypeCode.
284 Only that "deep copy" visit routine uses "value2" as anything other than a
285 null pointer; it allows efficient construction of "deep copies" without
286 needing extra space for temporary values or coroutine stacks. (A general
287 purpose two-value comparison could also use "value2".) Most uses of the API
288 only manipulate a single data value at a time; no realistic need has yet
289 been seen for manipulating more than two data values at once.
291 With respect to the OMG C and C++ mappings, it is clear that this style API
292 must be provided for the C mapping, but some people have noted that a
293 "purer" object oriented style API could also be provided in C++. That style
294 would use another internal visit routine, performing the requisite "switch"
295 over the fixed number of TCKind values, and then make a virtual function
296 call to an instance of a C++ class whose private state was the "context" and
297 whose member functions matched the arms of the switch.
302 In order to dynamically manipulate instances of arbitrary data types,
303 applications need to be able to allocate and free memory. The OMG C++
304 mapping only says how to do this for data types which have static C++
305 interfaces defined, which is clearly inadequate for using constructed
306 types with the DII/DSI/Any family of interfaces.
308 This infrastructure requires the standard "malloc" and "free" primitives to
309 be used, and cast to the appropriate type. Data allocated using malloc
310 will normally be sized according to TypeCode::size(), and then be stored
311 inside an Any. When the Any is deleted, if the ORB deallocates the memory
312 it always uses "free" (including for any nested pointers, and correctly
313 handling cases such as arrays and sequences).
315 Note that to support implementations where C and C++ language bindings
316 share the same ORB infrastructure, this solution is inadequate. This is
317 because the C binding's CORBA_free() interface would have no way to
318 determine the type of the data being freed. Instead, typed allocation
319 APIs will need to be used even when using the dynamically typed CORBA
320 subsystem ... a TypeCode::malloc() routine would suffice, if it returned
321 memory that was internally tagged with that TypeCode. In such a case,
322 the CORBA_free() routine could use that TypeCode to "deep free" data as
323 required, and C++ "new" and "delete" operators would need to know about
324 the internal tagging for all those data types. Such tagged allocation
325 would need to be used for all data that was to be freed by the ORB.
327 (Having the C mapping require use of "typed free" routines, instead of the
328 CORBA_free interface, is sufficient to eliminate this problem.)
331 PASSING EXCEPTIONS THROUGH THE DII
333 The C++ mapping's Dynamic Invocation Interface (DII) has key omissions
334 in that it doesn't say how to access to user-defined exception values,
335 and implicitly requires ORBs either to pass "excess" data on the wire
336 or else to consult an interface repository to deal with exceptions or
337 (deprecated) "context" strings.
339 This software changes the DII specification in two ways to support the
340 requirement for DII users to be able to see user-defined exceptions, yet
341 not to violate the OMG-IDL type model by reporting illegal exceptions:
343 * The Object::_create_request() member function, through which DII
344 users provide all the information included in an IDL operation's
345 signature, has an additional parameter.
347 That parameter is a sequence of exception typecodes, describing
348 the user-defined exceptions that the operation can return. (The
349 standard exceptions defined in CORBA may always be returned.)
350 When any other exception is returned, the client's ORB reports that
351 the object's type definition has been violated by the server's ORB.
353 * The TypeCode interpreter (see above) may be used to examine all
354 exception values reported through a CORBA::Environment. A new
355 Exception::id() operation may be used to determine which typecode
358 Note that a number of portability and specification problems have been
359 identified in the current C++ mapping for DII, e.g. for details of memory
360 management. Later versions of this code may attempt to closely comply
361 with an improved mapping for DII, to the extent that the interpretation
362 used here differs from that more unambiguous specification.
364 Since there is no efficient way to distinguish typecodes for user defined
365 exceptions from ones for system-defined ("standard") exceptions (comparing
366 the exception ID against all the system defined ones is inefficient :-)
367 a new enum type "ExceptionType" is defined. (An analogous type is already
368 defined for the C language mapping.) This is used to report exceptions