diff options
author | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-05-16 02:28:59 +0000 |
---|---|---|
committer | schmidt <douglascraigschmidt@users.noreply.github.com> | 1997-05-16 02:28:59 +0000 |
commit | 2976108a293f7e72bd0913830376556a27e58991 (patch) | |
tree | 67ed7e614e2106962eaf395329805b38063d37f1 | |
parent | 203e6ff5c00e605757acc0ea4f5f0b1c6d3e6908 (diff) | |
download | ATCD-2976108a293f7e72bd0913830376556a27e58991.tar.gz |
*** empty log message ***
42 files changed, 6546 insertions, 7073 deletions
diff --git a/ChangeLog-97a b/ChangeLog-97a index e006ccd0340..1d37552176b 100644 --- a/ChangeLog-97a +++ b/ChangeLog-97a @@ -6,9 +6,9 @@ Thu May 15 17:40:06 1997 <irfan@TWOSTEP> Thu May 15 13:10:12 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> - * include/makeinclude/platform_osf1_4.0.GNU (CXX): Added - "-expect_unresolved '*'." Thanks to Steve Huston for verifying - this. + * include/makeinclude/platform_osf1_4.0.GNU: Added support for + templates. Thanks to Steve Huston and James Johnson for + verifying this. * include/makeinclude/platform_osf1_3.2.GNU: Got rid of all unresolved symbol warnings using cxx 5.5 on DEC/OSF v3.2 by diff --git a/TAO/ChangeLog-98c b/TAO/ChangeLog-98c index fb0b1dbecd4..664698faeee 100644 --- a/TAO/ChangeLog-98c +++ b/TAO/ChangeLog-98c @@ -1,3 +1,7 @@ +Thu May 15 19:08:16 1997 Douglas C. Schmidt <schmidt@flamenco.cs.wustl.edu> + + * Finished updating all the reformatting. + Thu May 15 15:54:49 1997 Chris Cleeland <cleeland@cs.wustl.edu> * IIOP/lib/principa.h: Corrected syntax error which eliminated the diff --git a/TAO/IIOP/lib/any.cpp b/TAO/IIOP/lib/any.cpp index 315e8deac30..fa2a88eba5f 100644 --- a/TAO/IIOP/lib/any.cpp +++ b/TAO/IIOP/lib/any.cpp @@ -3,33 +3,34 @@ // Copyright 1994-1995 by Sun Microsystems Inc. // All Rights Reserved // -// ORB: Implementation of CORBA_Any -// -// This includes three constructors, a destructor, and a "replace" method -// for the "Any" data type. "Any" values pair a pointer to a data structure -// in the native binary representation (e.g. C struct) with a TypeCode that -// describes that data structure. -// -// The copy constructor and the destructor each use the TypeCode interpreter -// with specialized "visit" callback routines. The "visit" routines are -// used respectively to make "deep copies" and perform "deep frees" of the -// aritrary values as described by the "Any" value's typecode. -// -// Note that these "visit" routines are called directly, and they choose -// whether or not to use the TypeCode interpreter to examine constituents. -// In the simple cases, the "visit" routines can do their work without any -// further calls; only for constructed types is the interpreter's knowledge -// really required. -// -// THREADING NOTE: "Any" is a data structure which must be protected by -// external critical sections. Like simpler numeric types, "Any" instances -// are accessed and modified atomically. This implementation is reentrant, -// so that independent "Any" values may be manipulated concurrently when -// the underlying programming environment is itself reentrant. -// -// COM NOTE: Yes, this is a utility data type whose implementation is +// ORB: Implementation of CORBA_Any +// +// This includes three constructors, a destructor, and a "replace" +// method for the "Any" data type. "Any" values pair a pointer to a +// data structure in the native binary representation (e.g. C struct) +// with a TypeCode that describes that data structure. +// +// The copy constructor and the destructor each use the TypeCode +// interpreter with specialized "visit" callback routines. The +// "visit" routines are used respectively to make "deep copies" and +// perform "deep frees" of the aritrary values as described by the +// "Any" value's typecode. +// +// Note that these "visit" routines are called directly, and they +// choose whether or not to use the TypeCode interpreter to examine +// constituents. In the simple cases, the "visit" routines can do +// their work without any further calls; only for constructed types is +// the interpreter's knowledge really required. +// +// THREADING NOTE: "Any" is a data structure which must be protected +// by external critical sections. Like simpler numeric types, "Any" +// instances are accessed and modified atomically. This +// implementation is reentrant, so that independent "Any" values may +// be manipulated concurrently when the underlying programming +// environment is itself reentrant. +// +// COM NOTE: Yes, this is a utility data type whose implementation is // fully exposed. Factories for these are not normally used in C++. -// #include <assert.h> #include <limits.h> @@ -41,290 +42,291 @@ #include <initguid.h> -#if !defined(__ACE_INLINE__) +#if !defined (__ACE_INLINE__) # include "any.i" #endif CORBA_TypeCode_ptr -CORBA_Any::type () const +CORBA_Any::type (void) const { - return _type; + return _type; } void * -CORBA_Any::value () const +CORBA_Any::value (void) const { - return _value; + return _value; } -// // Default "Any" constructor -- initializes to nulls per the // OMG C++ mapping. // // NOTE: null (zero) typecode pointers are also treated as // the null typecode ... -// -CORBA_Any::CORBA_Any () + +CORBA_Any::CORBA_Any (void) { - _type = _tc_CORBA_Null; - _value = 0; - _orb_owns_data = CORBA_B_FALSE; - _refcnt = 1; + _type = _tc_CORBA_Null; + _value = 0; + _orb_owns_data = CORBA_B_FALSE; + _refcnt = 1; } - -// // The more common "Any" constructor has its own copy of a // typecode, and either holds or "consumes" an arbitrary data // value satisfying the normal binary interface rules. -// -CORBA_Any::CORBA_Any ( - CORBA_TypeCode_ptr tc, - void *value, - CORBA_Boolean orb_owns_data -) : - _value (value), - _orb_owns_data (orb_owns_data) + +CORBA_Any::CORBA_Any (CORBA_TypeCode_ptr tc, + void *value, + CORBA_Boolean orb_owns_data) + + : _value (value) , + _orb_owns_data (orb_owns_data) { - _type = tc; - tc->AddRef (); - _refcnt = 1; + _type = tc; + tc->AddRef (); + _refcnt = 1; } - -// // Helper routine for "Any" copy constructor ... // // "Deep Copy" from source to dest. Memory is always there to be // copied to ... if this calls itself recursively, it ensures that -// this remains true (only really an issue for sequences). +// this remains true (only really an issue for sequences) . // // This shows the main reason to pass two values to the "visit" -// function used by the TypeCode interpreter: it allows the copy -// to be made without using any additional temporary memory. Most -// other such "visit" routines use only a single value. This is -// also slightly atypical in that it doesn't use the "context". -// +// function used by the TypeCode interpreter: it allows the copy to be +// made without using any additional temporary memory. Most other +// such "visit" routines use only a single value. This is also +// slightly atypical in that it doesn't use the "context". + static CORBA_TypeCode::traverse_status -deep_copy ( - CORBA_TypeCode_ptr tc, - const void *source, - const void *dest, - void *, // no context - CORBA_Environment &env -) +deep_copy (CORBA_TypeCode_ptr tc, + const void *source, + const void *dest, + void *, // no context + CORBA_Environment &env) { - CORBA_TypeCode::traverse_status retval; - CORBA_TCKind my_kind; + CORBA_TypeCode::traverse_status retval; + CORBA_TCKind my_kind; - if (!tc) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return CORBA_TypeCode::TRAVERSE_STOP; + if (!tc) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO) ); + return CORBA_TypeCode::TRAVERSE_STOP; } - my_kind = tc->kind (env); - - if (env.exception_type () != NO_EXCEPTION) - return CORBA_TypeCode::TRAVERSE_STOP; - - // - // Deep copy from "source" to "dest" ... this code "knows" a bit about - // representations, verify it when porting to oddball platforms with - // non-IEEE floating point values or atypical byte and word sizes. - // - // See the TypeCode interpreter code for more details about the - // representational assumptions here. - // - retval = CORBA_TypeCode::TRAVERSE_CONTINUE; - - switch (my_kind) { - case tk_null: - case tk_void: - break; + my_kind = tc->kind (env); + + if (env.exception_type () != NO_EXCEPTION) + return CORBA_TypeCode::TRAVERSE_STOP; + + // Deep copy from "source" to "dest" ... this code "knows" a bit + // about representations, verify it when porting to oddball + // platforms with non-IEEE floating point values or atypical byte + // and word sizes. + // + // See the TypeCode interpreter code for more details about the + // representational assumptions here. + + retval = CORBA_TypeCode::TRAVERSE_CONTINUE; + + switch (my_kind) + { + case tk_null: + case tk_void: + break; - case tk_char: - case tk_octet: - *(CORBA_Octet *)dest = *(CORBA_Octet *)source; - break; - - case tk_short: - case tk_ushort: - *(CORBA_Short *)dest = *(CORBA_Short *)source; - break; - - case tk_wchar: - *(CORBA_WChar *)dest = *(CORBA_WChar *)source; - break; - - case tk_long: - case tk_ulong: - case tk_float: - *(CORBA_Long *)dest = *(CORBA_Long *)source; - break; - - case tk_longlong: - case tk_ulonglong: - case tk_double: - *(CORBA_LongLong *)dest = *(CORBA_LongLong *)source; - break; - - case tk_longdouble: - *(CORBA_LongDouble *)dest = *(CORBA_LongDouble *)source; - break; - - case tk_boolean: - *(CORBA_Boolean *)dest = *(CORBA_Boolean *)source; - break; - - case tk_any: - (void) new (dest) CORBA_Any (*(CORBA_Any*)source); - break; - - case tk_TypeCode: - if ((*(CORBA_TypeCode_ptr *)source) != 0) - dest = source; - else - dest = _tc_CORBA_Null; - ((CORBA_TypeCode_ptr)dest)->AddRef (); - break; - - case tk_Principal: - { - CORBA_Principal_ptr src, dst; - - src = *(CORBA_Principal_ptr *)source; - dst = *(CORBA_Principal_ptr *)dest = new CORBA_Principal; - - // - // Principals are just opaque IDs ... copy them - // - assert (src->id.length <= UINT_MAX); - dst->id.length = dst->id.maximum = src->id.length; - if (dst->id.length > 0) { - dst->id.buffer = new CORBA_Octet [(unsigned) dst->id.length]; - ACE_OS::memcpy (dst->id.buffer, src->id.buffer, - (size_t) dst->id.length); - } else { - dst->id.buffer = 0; - } - } - break; - - case tk_objref: - *(CORBA_Object_ptr *)dest = CORBA_Object:: - _duplicate (*(CORBA_Object_ptr *) source); - break; - - case tk_sequence: - { - CORBA_OctetSeq *src, *dst; - CORBA_TypeCode_ptr tcp; - size_t size; - - // - // Rely on binary format of sequences -- all are the - // same except for the type pointed to by "buffer" - // - src = (CORBA_OctetSeq *)source; - dst = (CORBA_OctetSeq *)dest; - - assert (src->length <= UINT_MAX); - dst->length = dst->maximum = src->length; - - // - // Get the size of each "buffer" element - // - tcp = tc->typecode_param (0, env); - if (env.exception () != 0) { - retval = CORBA_TypeCode::TRAVERSE_STOP; - break; - } - - size = tcp->size (env); - if (env.exception () != 0) { - retval = CORBA_TypeCode::TRAVERSE_STOP; - break; - } - tcp->Release (); - - // - // Now allocate a new (uninitialized) buffer of the right - // size to hold that many elements ... fall through and - // let a general traverse fill in those buffer elements. - // - size *= (size_t) src->length; - dst->buffer = new CORBA_Octet [size]; - } - // FALLTHROUGH - - case tk_struct: - case tk_union: - case tk_array: - case tk_alias: - return tc->traverse (source, dest, - (CORBA_TypeCode::VisitRoutine) deep_copy, 0, env); - - case tk_except: - // - // Exceptions in memory have a "hidden" typecode up front, - // used to ensure that memory is appropriately freed and - // to hold the exception ID. We just copy that typecode, - // the traverse code ignores it completely. - // - *(CORBA_TypeCode_ptr *) dest = *(CORBA_TypeCode_ptr *) source; - (void) (*(CORBA_TypeCode_ptr *) dest)->AddRef (); - return tc->traverse (source, dest, - (CORBA_TypeCode::VisitRoutine) deep_copy, 0, env); - - case tk_enum: - *(int *)dest = *(int *)source; - break; - - case tk_string: - *(CORBA_String *)dest = - CORBA_string_copy (*(CORBA_String *)source); - break; - - case tk_wstring: - *(CORBA_WString *)dest = - CORBA_wstring_copy (*(CORBA_WString *)source); - break; - - default: - dmsg ("deep copy default case ?"); - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - retval = CORBA_TypeCode::TRAVERSE_STOP; - break; + case tk_char: + case tk_octet: + *(CORBA_Octet *) dest = *(CORBA_Octet *) source; + break; + + case tk_short: + case tk_ushort: + *(CORBA_Short *) dest = *(CORBA_Short *) source; + break; + + case tk_wchar: + *(CORBA_WChar *) dest = *(CORBA_WChar *) source; + break; + + case tk_long: + case tk_ulong: + case tk_float: + *(CORBA_Long *) dest = *(CORBA_Long *) source; + break; + + case tk_longlong: + case tk_ulonglong: + case tk_double: + *(CORBA_LongLong *) dest = *(CORBA_LongLong *) source; + break; + + case tk_longdouble: + *(CORBA_LongDouble *) dest = *(CORBA_LongDouble *) source; + break; + + case tk_boolean: + *(CORBA_Boolean *) dest = *(CORBA_Boolean *) source; + break; + + case tk_any: + (void) new (dest) CORBA_Any (*(CORBA_Any*) source); + break; + + case tk_TypeCode: + if ((*(CORBA_TypeCode_ptr *) source) != 0) + dest = source; + else + dest = _tc_CORBA_Null; + ((CORBA_TypeCode_ptr) dest)->AddRef (); + break; + + case tk_Principal: + { + CORBA_Principal_ptr src, dst; + + src = *(CORBA_Principal_ptr *) source; + dst = *(CORBA_Principal_ptr *) dest = new CORBA_Principal; + + // Principals are just opaque IDs ... copy them + + assert (src->id.length <= UINT_MAX); + dst->id.length = dst->id.maximum = src->id.length; + + if (dst->id.length > 0) + { + dst->id.buffer = new CORBA_Octet [ (unsigned) dst->id.length]; + ACE_OS::memcpy (dst->id.buffer, src->id.buffer, + (size_t) dst->id.length); + } + else + dst->id.buffer = 0; + } + break; + + case tk_objref: + *(CORBA_Object_ptr *) dest = CORBA_Object:: + _duplicate (*(CORBA_Object_ptr *) source); + break; + + case tk_sequence: + { + CORBA_OctetSeq *src, *dst; + CORBA_TypeCode_ptr tcp; + size_t size; + + // Rely on binary format of sequences -- all are the same + // except for the type pointed to by "buffer" + + src = (CORBA_OctetSeq *) source; + dst = (CORBA_OctetSeq *) dest; + + assert (src->length <= UINT_MAX); + dst->length = dst->maximum = src->length; + + // Get the size of each "buffer" element + + tcp = tc->typecode_param (0, env); + + if (env.exception () != 0) + { + retval = CORBA_TypeCode::TRAVERSE_STOP; + break; + } + + size = tcp->size (env); + + if (env.exception () != 0) + { + retval = CORBA_TypeCode::TRAVERSE_STOP; + break; + } + tcp->Release (); + + // Now allocate a new (uninitialized) buffer of the right size + // to hold that many elements ... fall through and let a + // general traverse fill in those buffer elements. + + size *= (size_t) src->length; + dst->buffer = new CORBA_Octet [size]; + } + // FALLTHROUGH + + case tk_struct: + case tk_union: + case tk_array: + case tk_alias: + return tc->traverse (source, + dest, + (CORBA_TypeCode::VisitRoutine) deep_copy, + 0, + env); + + case tk_except: + // Exceptions in memory have a "hidden" typecode up front, used + // to ensure that memory is appropriately freed and to hold the + // exception ID. We just copy that typecode, the traverse code + // ignores it completely. + + *(CORBA_TypeCode_ptr *) dest = *(CORBA_TypeCode_ptr *) source; + (void) (*(CORBA_TypeCode_ptr *) dest)->AddRef (); + + return tc->traverse (source, + dest, + (CORBA_TypeCode::VisitRoutine) deep_copy, + 0, + env); + + case tk_enum: + *(int *) dest = *(int *) source; + break; + + case tk_string: + *(CORBA_String *) dest = + CORBA_string_copy (*(CORBA_String *) source); + break; + + case tk_wstring: + *(CORBA_WString *) dest = + CORBA_wstring_copy (*(CORBA_WString *) source); + break; + + default: + dmsg ("deep copy default case ?"); + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO) ); + retval = CORBA_TypeCode::TRAVERSE_STOP; + break; } - return retval; + return retval; } - -// // Copy constructor for "Any". -// -CORBA_Any::CORBA_Any (const CORBA_Any &src) + +CORBA_Any::CORBA_Any (const CORBA_Any &src) { - CORBA_Environment env; - size_t size; + CORBA_Environment env; + size_t size; - if (src._type != 0) - _type = src._type; - else - _type = _tc_CORBA_Null; + if (src._type != 0) + _type = src._type; + else + _type = _tc_CORBA_Null; - _type->AddRef (); - _orb_owns_data = CORBA_B_TRUE; + _type->AddRef (); + _orb_owns_data = CORBA_B_TRUE; - size = _type->size (env); // XXX check error status - _value = (char *) calloc (1, size); + size = _type->size (env); // XXX check error status + _value = (char *) calloc (1, size); - (void) _type->traverse (src._value, _value, - (CORBA_TypeCode::VisitRoutine) deep_copy, 0, env); + (void) _type->traverse (src._value, + _value, + (CORBA_TypeCode::VisitRoutine) deep_copy, + 0, + env); } - -// // Helper routine for "Any" destructor. // // This frees all the memory pointed to by any given value held inside @@ -334,326 +336,317 @@ CORBA_Any::CORBA_Any (const CORBA_Any &src) // This is one of the simplest typecode interpreter callbacks, since // in most cases it does nothing. Also, it uses neither the second // value nor the context parameter. -// + static CORBA_TypeCode::traverse_status -deep_free ( - CORBA_TypeCode_ptr tc, - const void *value, - const void *, // value2 unused - void *, // context unused - CORBA_Environment &env -) +deep_free (CORBA_TypeCode_ptr tc, + const void *value, + const void *, // value2 unused + void *, // context unused + CORBA_Environment &env) { - // - // don't do anything if the value is a null pointer - // - if (!value) - return CORBA_TypeCode::TRAVERSE_CONTINUE; - - CORBA_TypeCode::traverse_status retval; - CORBA_TCKind my_kind; - - if (!tc) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return CORBA_TypeCode::TRAVERSE_STOP; + // Don't do anything if the value is a null pointer. + + if (!value) + return CORBA_TypeCode::TRAVERSE_CONTINUE; + + CORBA_TypeCode::traverse_status retval; + CORBA_TCKind my_kind; + + if (!tc) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO) ); + return CORBA_TypeCode::TRAVERSE_STOP; } - my_kind = tc->kind (env); - - if (env.exception_type () != NO_EXCEPTION) - return CORBA_TypeCode::TRAVERSE_STOP; - - // - // Free only embedded pointers ... which don't exist in most - // primitive types. - // - retval = CORBA_TypeCode::TRAVERSE_CONTINUE; - switch (my_kind) { - case tk_struct: - case tk_union: - case tk_array: - case tk_alias: - return tc->traverse (value, 0, - (CORBA_TypeCode::VisitRoutine) deep_free, 0, env); - - // - // XXX: Exceptions are currently leaked because of bugs - // lurking in this area. Keep in mind that there are - // two things to free: (a) the typecode in the exception - // base class; (b) any pointers held by a user-defined - // exception, such as an objref or string. - // - // Since this code does nothing, it should leak BOTH of those - // kinds of memory. Since it's not supposed to be called - // except when the exception really is being freed, it should - // only be called when the reference count in the exception - // base class is zero. - // - // It's not clear which of those assertions actually hold. - // - // The code SHOULD be just like the traverse() call for a - // structure, with (a) a precondition that the reference - // count is zero, (b) an assertion that the typecode in the - // exception and "tc" are equivalent, (c) releasing that - // typecode found within the exception. - // - case tk_except: - return retval; - - - case tk_sequence: - retval = tc->traverse (value, 0, - (CORBA_TypeCode::VisitRoutine) deep_free, 0, env); - delete ((CORBA_OctetSeq *)value)->buffer; - break; - - case tk_TypeCode: - if ((*(CORBA_TypeCode_ptr *)value) != 0) - (*(CORBA_TypeCode_ptr *)value)->Release (); - break; - - case tk_Principal: - CORBA_release (*(CORBA_Principal_ptr *)value); - break; - - case tk_objref: - CORBA_release (*(CORBA_Object_ptr *)value); - break; - - case tk_string: - CORBA_string_free (*(CORBA_String *)value); - break; - - case tk_wstring: - CORBA_wstring_free (*(CORBA_WString *)value); - break; - - case tk_any: -#ifdef __BORLANDC__ - // - // XXX BC++ doesn't yet accept explicit calls to destructors - // with this syntax. A simple workaround must exist, though; - // other explicit destructor calls work. - // - dmsg ("Delete Any-in-Any ... memory leak with BC++ 4.5"); + my_kind = tc->kind (env); + + if (env.exception_type () != NO_EXCEPTION) + return CORBA_TypeCode::TRAVERSE_STOP; + + // Free only embedded pointers ... which don't exist in most + // primitive types. + + retval = CORBA_TypeCode::TRAVERSE_CONTINUE; + switch (my_kind) + { + case tk_struct: + case tk_union: + case tk_array: + case tk_alias: + return tc->traverse (value, + 0, + (CORBA_TypeCode::VisitRoutine) deep_free, + 0, + env); + + // XXX: Exceptions are currently leaked because of bugs lurking + // in this area. Keep in mind that there are two things to + // free: (a) the typecode in the exception base class; (b) any + // pointers held by a user-defined exception, such as an objref + // or string. + // + // Since this code does nothing, it should leak BOTH of those + // kinds of memory. Since it's not supposed to be called except + // when the exception really is being freed, it should only be + // called when the reference count in the exception base class + // is zero. + // + // It's not clear which of those assertions actually hold. + // + // The code SHOULD be just like the traverse () call for a + // structure, with (a) a precondition that the reference count + // is zero, (b) an assertion that the typecode in the exception + // and "tc" are equivalent, (c) releasing that typecode found + // within the exception. + // + case tk_except: + return retval; + + case tk_sequence: + retval = tc->traverse (value, + 0, + (CORBA_TypeCode::VisitRoutine) deep_free, + 0, + env); + delete ((CORBA_OctetSeq *) value)->buffer; + break; + + case tk_TypeCode: + if ((*(CORBA_TypeCode_ptr *) value) != 0) + (*(CORBA_TypeCode_ptr *) value)->Release (); + break; + + case tk_Principal: + CORBA_release (*(CORBA_Principal_ptr *) value); + break; + + case tk_objref: + CORBA_release (*(CORBA_Object_ptr *) value); + break; + + case tk_string: + CORBA_string_free (*(CORBA_String *) value); + break; + + case tk_wstring: + CORBA_wstring_free (*(CORBA_WString *) value); + break; + + case tk_any: +#ifdef __BORLANDC__ + // XXX BC++ doesn't yet accept explicit calls to destructors + // with this syntax. A simple workaround must exist, though; + // other explicit destructor calls work. + + dmsg ("Delete Any-in-Any ... memory leak with BC++ 4.5"); #else - ((CORBA_Any *)value)->~CORBA_Any (); + ((CORBA_Any *) value)->~CORBA_Any (); #endif - break; + break; - default: - return CORBA_TypeCode::TRAVERSE_CONTINUE; + default: + return CORBA_TypeCode::TRAVERSE_CONTINUE; } - if (env.exception_type () != NO_EXCEPTION) - return CORBA_TypeCode::TRAVERSE_STOP; - else - return retval; + if (env.exception_type () != NO_EXCEPTION) + return CORBA_TypeCode::TRAVERSE_STOP; + else + return retval; } - -// // Destructor for an "Any" deep-frees memory if needed. // -// NOTE that the assertion below will fire on application programmer errors, -// such as using AddRef/Release out of sync with the true lifetime of an Any -// value allocated on the stack. BUT it involves changing the refcounting -// policy so that it's initialized to zero, not one ... which policy affects -// the whole source base, and not just this data type. Get to this later. -// -CORBA_Any::~CORBA_Any () +// NOTE that the assertion below will fire on application programmer +// errors, such as using AddRef/Release out of sync with the true +// lifetime of an Any value allocated on the stack. BUT it involves +// changing the refcounting policy so that it's initialized to zero, +// not one ... which policy affects the whole source base, and not +// just this data type. Get to this later. + +CORBA_Any::~CORBA_Any (void) { - CORBA_Environment env; + CORBA_Environment env; - // assert (_refcnt == 0); + // assert (_refcnt == 0); - if (_orb_owns_data) { - (void) deep_free (_type, _value, 0, 0, env); - delete _value; + if (_orb_owns_data) + { + (void) deep_free (_type, _value, 0, 0, env); + delete _value; } - if (_type) - _type->Release (); -} + if (_type) + _type->Release (); +} -// // all-at-once replacement of the contents of an "Any" -// + void -CORBA_Any::replace ( - CORBA_TypeCode_ptr tc, - const void *v, - CORBA_Boolean orb_owns_data, - CORBA_Environment &env -) +CORBA_Any::replace (CORBA_TypeCode_ptr tc, + const void *v, + CORBA_Boolean orb_owns_data, + CORBA_Environment &env) { - if (_orb_owns_data) { - (void) deep_free (_type, _value, 0, 0, env); - delete _value; + if (_orb_owns_data) + { + (void) deep_free (_type, _value, 0, 0, env); + delete _value; } - if (_type != 0) - _type->Release (); + if (_type != 0) + _type->Release (); - env.clear (); + env.clear (); - _type = tc; - tc->AddRef (); - _value = (void *) v; - _orb_owns_data = orb_owns_data; + _type = tc; + tc->AddRef (); + _value = (void *) v; + _orb_owns_data = orb_owns_data; } -// // For COM -- IUnKnown operations -// // {A201E4C8-F258-11ce-9598-0000C07CA898} DEFINE_GUID (IID_CORBA_Any, 0xa201e4c8, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); - ULONG __stdcall -CORBA_Any::AddRef () +CORBA_Any::AddRef (void) { - ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); + ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, lock_, 0); return ++_refcnt; } -ULONG -__stdcall -CORBA_Any::Release () +ULONG __stdcall +CORBA_Any::Release (void) { - ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); + ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, lock_, 0); - if (--_refcnt != 0) + if (--_refcnt != 0) return _refcnt; - guard.release(); + guard.release (); delete this; return 0; } -HRESULT -__stdcall -CORBA_Any::QueryInterface ( - REFIID riid, - void **ppv -) +HRESULT __stdcall +CORBA_Any::QueryInterface (REFIID riid, + void **ppv) { *ppv = 0; - if (IID_CORBA_Any == riid || IID_IUnknown == riid) + if (IID_CORBA_Any == riid || IID_IUnknown == riid) *ppv = this; - if (*ppv == 0) + if (*ppv == 0) return ResultFromScode (E_NOINTERFACE); - (void) AddRef (); + (void) AddRef (); return NOERROR; } - -// // VARIANT conversions -// // copy constructor -CORBA_Any::CORBA_Any (const VARIANT &src) + +CORBA_Any::CORBA_Any (const VARIANT &src) { - _orb_owns_data = CORBA_B_TRUE; - _refcnt = 1; - _type = _tc_CORBA_Void; - _value = 0; + _orb_owns_data = CORBA_B_TRUE; + _refcnt = 1; + _type = _tc_CORBA_Void; + _value = 0; - *this = src; + *this = src; } // assignment operator CORBA_Any & -CORBA_Any::operator = (const VARIANT &src) +CORBA_Any::operator = (const VARIANT &src) { - this->~CORBA_Any (); - - assert ((src.vt & 0xB000) == 0); // XXX better, report exception - - switch (src.vt & 0x0fff) { - case VT_EMPTY: - _type = _tc_CORBA_Void; - _value = 0; - break; - - case VT_NULL: - _type = _tc_CORBA_Null; - _value = 0; - break; - - case VT_I2: - _type = _tc_CORBA_Short; - _value = new CORBA_Short ((src.vt & VT_BYREF) - ? (*src.piVal) : src.iVal); - break; - - case VT_I4: - _type = _tc_CORBA_Long; - _value = new CORBA_Long ((src.vt & VT_BYREF) - ? (*src.plVal) : src.lVal); - break; - - case VT_R4: - _type = _tc_CORBA_Float; - _value = new CORBA_Float ((src.vt & VT_BYREF) - ? (*src.pfltVal) : src.fltVal); - break; - - case VT_R8: - _type = _tc_CORBA_Double; - _value = new CORBA_Double ((src.vt & VT_BYREF) - ? (*src.pdblVal) : src.dblVal); - break; + this->~CORBA_Any (); + + assert ((src.vt & 0xB000) == 0); // XXX better, report exception + + switch (src.vt & 0x0fff) + { + case VT_EMPTY: + _type = _tc_CORBA_Void; + _value = 0; + break; + + case VT_NULL: + _type = _tc_CORBA_Null; + _value = 0; + break; + + case VT_I2: + _type = _tc_CORBA_Short; + _value = new CORBA_Short ((src.vt & VT_BYREF) + ? (*src.piVal) : src.iVal); + break; + + case VT_I4: + _type = _tc_CORBA_Long; + _value = new CORBA_Long ((src.vt & VT_BYREF) + ? (*src.plVal) : src.lVal); + break; + + case VT_R4: + _type = _tc_CORBA_Float; + _value = new CORBA_Float ((src.vt & VT_BYREF) + ? (*src.pfltVal) : src.fltVal); + break; + + case VT_R8: + _type = _tc_CORBA_Double; + _value = new CORBA_Double ((src.vt & VT_BYREF) + ? (*src.pdblVal) : src.dblVal); + break; // case VT_CY: // case VT_DATE: - // XXX convert currency and date to TBD CORBA conventions + // XXX convert currency and date to TBD CORBA conventions // case VT_BSTR: - // XXX convert to CORBA string + // XXX convert to CORBA string // case VT_DISPATCH: // case VT_UNKNOWN: // case VT_VARIANT: - // XXX convert to CORBA objref or appropriate pseudo-objref + // XXX convert to CORBA objref or appropriate pseudo-objref // case VT_BOOL: - // XXX convert to CORBA boolean + // XXX convert to CORBA boolean // case VT_ERROR: - // XXX what to do? - - case VT_UI1: - _type = _tc_CORBA_Octet; - _value = new CORBA_Octet ((src.vt & VT_BYREF) - ? (*src.pbVal) : src.bVal); - break; - - default: - // XXX report some exception ... throw it? - _type = _tc_CORBA_Void; - _value = 0; - break; + // XXX what to do? + + case VT_UI1: + _type = _tc_CORBA_Octet; + _value = new CORBA_Octet ((src.vt & VT_BYREF) + ? (*src.pbVal) : src.bVal); + break; + + default: + // XXX report some exception ... throw it? + _type = _tc_CORBA_Void; + _value = 0; + break; } - return *this; + return *this; } -CORBA_Any::operator VARIANT () +CORBA_Any::operator VARIANT () { - VARIANT retval; + VARIANT retval; - // XXX convert it ... or report exception somehow! + // XXX convert it ... or report exception somehow! - retval.vt = VT_EMPTY; - return retval; + retval.vt = VT_EMPTY; + return retval; } diff --git a/TAO/IIOP/lib/any.i b/TAO/IIOP/lib/any.i index be7d694577f..6bd4c901add 100644 --- a/TAO/IIOP/lib/any.i +++ b/TAO/IIOP/lib/any.i @@ -1,19 +1,16 @@ -ACE_INLINE -void* +ACE_INLINE void * CORBA_Any::operator new (size_t, const void *p) { return (void *) p; } -ACE_INLINE -void* +ACE_INLINE void * CORBA_Any::operator new (size_t s) { return ::operator new (s); } -ACE_INLINE -void +ACE_INLINE void CORBA_Any::operator delete (void *p) { ::operator delete (p); diff --git a/TAO/IIOP/lib/boa.cpp b/TAO/IIOP/lib/boa.cpp index 5d5e0b2fd41..681c1c5a6a4 100644 --- a/TAO/IIOP/lib/boa.cpp +++ b/TAO/IIOP/lib/boa.cpp @@ -3,13 +3,12 @@ // Copyright 1994-1995 by Sun Microsystems Inc. // All Rights Reserved // -// BOA initialisation -- both anonymous and (for system bootstrapping) +// BOA initialisation -- both anonymous and (for system bootstrapping) // named BOAs. // // XXX at this time, there's a strong linkage between this code and // the modules knowing about IIOP. In the future, a looser coupling // between OA initialiszation and protocol components is desired. -// #include <assert.h> #include <stdio.h> @@ -32,19 +31,19 @@ // {A201E4C8-F258-11ce-9598-0000C07CA898} DEFINE_GUID (IID_BOA, -0xa201e4c8, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); +0xa201e4c8, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98) ; // destructor -TAO_Object_Table::~TAO_Object_Table() +TAO_Object_Table::~TAO_Object_Table (void) { } -// // A "Named BOA" is used in bootstrapping some part of the ORB since -// it's name-to-address binding is managed by the OS. Examples of such -// bindings are /etc/services (for TCP) and /etc/rpc (for ONC RPC). The -// nam" of a BOA is only guaranteed to be unique within the domain of a -// single system, as a rule; two hosts would have distinct "king" BOAs. +// it's name-to-address binding is managed by the OS. Examples of +// such bindings are /etc/services (for TCP) and /etc/rpc (for ONC +// RPC) . The nam" of a BOA is only guaranteed to be unique within +// the domain of a single system, as a rule; two hosts would have +// distinct "king" BOAs. // // For network endpoints, most such names are manually administered. // Some other namespaces (AF_UNIX filesystem names for example) have a @@ -55,135 +54,134 @@ TAO_Object_Table::~TAO_Object_Table() // // XXX the coupling could stand to be looser here, so this module did // not know specifically about the Internet ORB !! -// + CORBA_BOA_ptr CORBA_BOA::get_named_boa (CORBA_ORB_ptr orb, CORBA_String name, - CORBA_Environment &env) + CORBA_Environment &env) { env.clear (); - // // If the ORB is an Internet ORB, we know this must be a TCP OA. - // { - IIOP_ORB *internet; + IIOP_ORB *internet; - if (orb->QueryInterface (IID_IIOP_ORB, (void **)&internet) == NOERROR) + if (orb->QueryInterface (IID_IIOP_ORB, (void **) &internet) == NOERROR) { ROA* tcp_oa; internet->Release (); - // - // ROA initialization with name specified; it'll - // come from /etc/services if it's not a port number. - // - ACE_INET_Addr boa_name(name, INADDR_ANY); + // ROA initialization with name specified; it'll come from + // /etc/services if it's not a port number. + + ACE_INET_Addr boa_name (name, INADDR_ANY); + tcp_oa = ROA::init (orb, boa_name, env); - if (env.exception () != 0) + + if (env.exception () != 0) return 0; else return tcp_oa; // derives from BOA } } - // // We don't know how to deal with this kind of ORB. Report error. - // - env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); + + env.exception (new CORBA_BAD_PARAM (COMPLETED_NO) ); return 0; } - -// // An "Anonymous" BOA is used more routinely. The name used doesn't // matter to anyone; it is only used to create object references with // a short lifespan, namely that of the process acquiring this BOA. -// + CORBA_BOA_ptr -CORBA_BOA::get_boa(CORBA_ORB_ptr orb, - CORBA_Environment &env) +CORBA_BOA::get_boa (CORBA_ORB_ptr orb, + CORBA_Environment &env) { env.clear (); - // // If the ORB is an Internet ORB, we know this must be a TCP OA. - // { IIOP_ORB *internet; - if (orb->QueryInterface (IID_IIOP_ORB, (void **)&internet) == NOERROR) + if (orb->QueryInterface (IID_IIOP_ORB, (void **) &internet) == NOERROR) { ROA* tcp_oa; internet->Release (); - // // ROA initialization with null name means anonymous OA - // - ACE_INET_Addr anonymous((unsigned short)0, INADDR_ANY); + + ACE_INET_Addr anonymous ((unsigned short) 0, INADDR_ANY); + tcp_oa = ROA::init (orb, anonymous, env); - if (env.exception () != 0) + + if (env.exception () != 0) return 0; else return tcp_oa; // derives from BOA } } - // // We don't know how to deal with this kind of ORB. Report error. - // - env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); + + env.exception (new CORBA_BAD_PARAM (COMPLETED_NO) ); return 0; } -void CORBA_BOA::dispatch(CORBA_OctetSeq &key, - CORBA_ServerRequest &req, - void *context, - CORBA_Environment &env) +void CORBA_BOA::dispatch (CORBA_OctetSeq &key, + CORBA_ServerRequest &req, + void *context, + CORBA_Environment &env) { TAO_Skeleton skel; // pointer to function pointer for the operation CORBA_Object_ptr obj; // object that will be looked up based on the key - CORBA_OctetSeq *obj_key; + CORBA_OctetSeq *obj_key; CORBA_String opname; #if 0 - // this whole thing doesn't seem to be right since the context will be the - // key of just one object + // this whole thing doesn't seem to be right since the context will + // be the key of just one object obj_key = (CORBA_OctetSeq *) context; if (obj_key->length != key.length || ACE_OS::memcmp (obj_key->buffer, key.buffer, obj_key->length) != 0) { - env.exception (new CORBA_OBJECT_NOT_EXIST (COMPLETED_NO)); + env.exception (new CORBA_OBJECT_NOT_EXIST (COMPLETED_NO) ); #ifdef DEBUG - if (debug_level) + if (debug_level) dmsg_opaque ("request to nonexistent object, key = ", key.buffer, key.length); #endif return; } -#endif - // get the skeleton - if (this->find(key, obj) != -1) +#endif /* 0 */ + + // Get the skeleton + + // @@ Please add more comments here. This is a very important part + // of the code. + + if (this->find (key, obj) != -1) { - opname = req.op_name(); - if (obj->find(opname, skel) != -1) - { - skel(req, obj, env); // really should be scheduled . - } + opname = req.op_name (); + + if (obj->find (opname, skel) != -1) + skel (req, obj, env); // really should be scheduled . else { - // this may fail in which case, we must try out the default operations - // such as "_is_a", "non_existent", "hash", ... At this time, we try the - // "is_a" method + // this may fail in which case, we must try out the default + // operations such as "_is_a", "non_existent", "hash", + // ... At this time, we try the "is_a" method } } - // we need to pass this skel and associated information to the scheduler. How - // do we do it?? + + // We need to pass this skel and associated information to the + // scheduler. How do we do it?? } -#if !defined(__ACE_INLINE__) +#if !defined (__ACE_INLINE__) # include "boa.i" #endif diff --git a/TAO/IIOP/lib/boa.i b/TAO/IIOP/lib/boa.i index 48460b19d9e..b2f896ad4be 100644 --- a/TAO/IIOP/lib/boa.i +++ b/TAO/IIOP/lib/boa.i @@ -1,14 +1,14 @@ -ACE_INLINE -int -CORBA_BOA::bind(const CORBA_OctetSeq &key, CORBA_Object_ptr obj) +ACE_INLINE int +CORBA_BOA::bind (const CORBA_OctetSeq &key, + CORBA_Object_ptr obj) { - return objtable_->bind(key, obj); + return objtable_->bind (key, obj); } -ACE_INLINE -int -CORBA_BOA::find(const CORBA_OctetSeq &key, CORBA_Object_ptr &obj) +ACE_INLINE int +CORBA_BOA::find (const CORBA_OctetSeq &key, + CORBA_Object_ptr &obj) { - return objtable_->find(key, obj); + return objtable_->find (key, obj); } diff --git a/TAO/IIOP/lib/cdr.cpp b/TAO/IIOP/lib/cdr.cpp index dd4ee29f45b..efc8c525e82 100644 --- a/TAO/IIOP/lib/cdr.cpp +++ b/TAO/IIOP/lib/cdr.cpp @@ -1,460 +1,439 @@ -// @(#)cdr.cpp 1.2 95/11/04 +// @(#)cdr.cpp 1.2 95/11/04 // Copyright 1994-1995 by Sun Microsystems Inc. // All Rights Reserved // -// CDR: Encode/Decode basic machine data types +// CDR: Encode/Decode basic machine data types // -// Implementation of OMG "Common Data Representation" (CDR) ... there are -// one routine each for byte/halfword/word/doubleword put/get, which adjust -// to establish "natural" alignment (the bulk of the code) and then put or -// get with byteswapping as needed. +// Implementation of OMG "Common Data Representation" (CDR) ... there +// are one routine each for byte/halfword/word/doubleword put/get, +// which adjust to establish "natural" alignment (the bulk of the +// code) and then put or get with byteswapping as needed. // -// The implementation knows that native data formats are conformant with -// OMG-IDL's (and hence CDR's) size requirements, and relies on the fact -// that (for example) CORBA_Long is always four bytes long even if the -// environment's "int" is a different size. +// The implementation knows that native data formats are conformant +// with OMG-IDL's (and hence CDR's) size requirements, and relies on +// the fact that (for example) CORBA_Long is always four bytes long +// even if the environment's "int" is a different size. // -// char, octet 8 bits (1 byte) -// short, unsigned short 16 bits (2 bytes) -// long, unsigned long, float 32 bits (4 bytes) -// double, (unsigned) long long 64 bits (8 bytes) -// long double 128 bits (16 bytes) +// char, octet 8 bits (1 byte) +// short, unsigned short 16 bits (2 bytes) +// long, unsigned long, float 32 bits (4 bytes) +// double, (unsigned) long long 64 bits (8 bytes) +// long double 128 bits (16 bytes) // -// Moreover, this "knows" that the native 'char' represents ISO Latin/1 -// characters (an ASCII superset addressing Western European characters) -// and that "double" and "float" comply with the IEEE standards. (The -// "long double" may not be a native data type, though.) +// Moreover, this "knows" that the native 'char' represents ISO +// Latin/1 characters (an ASCII superset addressing Western European +// characters) and that "double" and "float" comply with the IEEE +// standards. (The "long double" may not be a native data type, +// though.) // -// THREADING NOTE: "CDR" is a data structure which must be protected by -// external critical sections. Like simpler numeric types, "CDR" instances -// are accessed and modified atomically. This implementation is reentrant, -// so that independent "CDR" values may be manipulated concurrently when -// the underlying programming environment is itself reentrant. -// - -#include <assert.h> -#include <limits.h> -#include <string.h> +// THREADING NOTE: "CDR" is a data structure which must be protected +// by external critical sections. Like simpler numeric types, "CDR" +// instances are accessed and modified atomically. This +// implementation is reentrant, so that independent "CDR" values may +// be manipulated concurrently when the underlying programming +// environment is itself reentrant. -#include <orb.h> +#include <assert.h> +#include <limits.h> +#include <string.h> -#include "debug.h" -#include "cdr.h" +#include <orb.h> +#include "debug.h" +#include "cdr.h" -// // ENCODING routines ... pad, store. Never swap. Padding uses // whatever value is already in the buffer. -// + CORBA_Boolean -CDR::put_byte ( - char c -) +CDR::put_byte (char c) { - if (remaining < sizeof (char) && grow (0) == CORBA_B_FALSE) - return CORBA_B_FALSE; + if (remaining < sizeof (char) && grow (0) == CORBA_B_FALSE) + return CORBA_B_FALSE; - *next++ = (unsigned char) c; - remaining--; - return CORBA_B_TRUE; + *next++ = (u_char) c; + remaining--; + return CORBA_B_TRUE; } - CORBA_Boolean -CDR::put_short ( - CORBA_Short s -) +CDR::put_short (CORBA_Short s) { - register unsigned char *tmp_next; - register unsigned temp; - - // - // Adjust pointer and count of remaining bytes; maybe - // grow the buffer if there's not enough left - // - tmp_next = ptr_align_binary (next, SHORT_SIZE); - temp = SHORT_SIZE + (tmp_next - next); - if (temp > remaining) { - if (grow (0) == CORBA_B_FALSE) - return CORBA_B_FALSE; - tmp_next = next + temp - SHORT_SIZE; + register u_char *tmp_next; + register u_int temp; + + // Adjust pointer and count of remaining bytes; maybe + // grow the buffer if there's not enough left + + tmp_next = ptr_align_binary (next, SHORT_SIZE); + temp = SHORT_SIZE + (tmp_next - next); + + if (temp > remaining) + { + if (grow (0) == CORBA_B_FALSE) + return CORBA_B_FALSE; + tmp_next = next + temp - SHORT_SIZE; } - remaining -= temp; - // - // copy the half word, native byte order - // - *(CORBA_Short *)tmp_next = s; - next = tmp_next + SHORT_SIZE; - return CORBA_B_TRUE; + remaining -= temp; + + // copy the half word, native byte order + + *(CORBA_Short *) tmp_next = s; + next = tmp_next + SHORT_SIZE; + return CORBA_B_TRUE; } CORBA_Boolean -CDR::put_long ( - CORBA_Long l -) +CDR::put_long (CORBA_Long l) { - register unsigned char *tmp_next; - register unsigned temp; - - // - // Adjust pointer and count of remaining bytes; maybe - // grow the buffer if there's not enough left - // - tmp_next = ptr_align_binary (next, LONG_SIZE); - temp = LONG_SIZE + (tmp_next - next); - if (temp > remaining) { - if (grow (0) == CORBA_B_FALSE) - return CORBA_B_FALSE; - tmp_next = next + temp - LONG_SIZE; + register u_char *tmp_next; + register u_int temp; + + // Adjust pointer and count of remaining bytes; maybe + // grow the buffer if there's not enough left + + tmp_next = ptr_align_binary (next, LONG_SIZE); + temp = LONG_SIZE + (tmp_next - next); + + if (temp > remaining) + { + if (grow (0) == CORBA_B_FALSE) + return CORBA_B_FALSE; + tmp_next = next + temp - LONG_SIZE; } - remaining -= temp; - // - // copy the word, native byte order - // - *(CORBA_Long *)tmp_next = l; + remaining -= temp; - next = tmp_next + LONG_SIZE; - return CORBA_B_TRUE; + // copy the word, native byte order + + *(CORBA_Long *) tmp_next = l; + + next = tmp_next + LONG_SIZE; + return CORBA_B_TRUE; } CORBA_Boolean -CDR::put_longlong ( - const CORBA_LongLong &ll -) +CDR::put_longlong (const CORBA_LongLong &ll) { - register unsigned char *tmp_next; - register unsigned temp; - - // - // Adjust pointer and count of remaining bytes; maybe - // grow the buffer if there's not enough left - // - tmp_next = ptr_align_binary (next, LONGLONG_SIZE); - temp = LONGLONG_SIZE + (tmp_next - next); - if (temp > remaining) { - if (grow (0) == CORBA_B_FALSE) - return CORBA_B_FALSE; - tmp_next = next + temp - LONGLONG_SIZE; + register u_char *tmp_next; + register u_int temp; + + // Adjust pointer and count of remaining bytes; maybe grow the + // buffer if there's not enough left + + tmp_next = ptr_align_binary (next, LONGLONG_SIZE); + temp = LONGLONG_SIZE + (tmp_next - next); + + if (temp > remaining) + { + if (grow (0) == CORBA_B_FALSE) + return CORBA_B_FALSE; + tmp_next = next + temp - LONGLONG_SIZE; } - remaining -= temp; + remaining -= temp; - // - // copy the double word in "native" byte order. - // - *(CORBA_LongLong *)tmp_next = ll; - next = tmp_next + LONGLONG_SIZE; - return CORBA_B_TRUE; + // copy the double word in "native" byte order. + + *(CORBA_LongLong *) tmp_next = ll; + next = tmp_next + LONGLONG_SIZE; + return CORBA_B_TRUE; } CORBA_Boolean -CDR::put_longdouble ( - CORBA_LongDouble &ld -) +CDR::put_longdouble (CORBA_LongDouble &ld) { - register unsigned char *tmp_next; - register unsigned temp; - - // - // Adjust pointer and count of remaining bytes; maybe - // grow the buffer if there's not enough left - // - tmp_next = ptr_align_binary (next, LONGDOUBLE_SIZE); - temp = LONGDOUBLE_SIZE + (tmp_next - next); - if (temp > remaining) { - if (grow (0) == CORBA_B_FALSE) - return CORBA_B_FALSE; - tmp_next = next + temp - LONGDOUBLE_SIZE; + register u_char *tmp_next; + register u_int temp; + + // Adjust pointer and count of remaining bytes; maybe + // grow the buffer if there's not enough left + + tmp_next = ptr_align_binary (next, LONGDOUBLE_SIZE); + temp = LONGDOUBLE_SIZE + (tmp_next - next); + + if (temp > remaining) + { + if (grow (0) == CORBA_B_FALSE) + return CORBA_B_FALSE; + tmp_next = next + temp - LONGDOUBLE_SIZE; } - remaining -= temp; + remaining -= temp; - // - // copy the long double in "native" byte order. - // - *(CORBA_LongDouble *)tmp_next = ld; - next = tmp_next + LONGDOUBLE_SIZE; - return CORBA_B_TRUE; + // copy the long double in "native" byte order. + *(CORBA_LongDouble *) tmp_next = ld; + next = tmp_next + LONGDOUBLE_SIZE; + return CORBA_B_TRUE; } - -// // DECODING routines ... adjust pointer, then byteswap as needed. -// CORBA_Boolean -CDR::get_byte ( - char &c -) +CDR::get_byte (char &c) { - if (remaining < sizeof (char)) - return CORBA_B_FALSE; + if (remaining < sizeof (char)) + return CORBA_B_FALSE; - c = (char) *next++; - remaining--; - return CORBA_B_TRUE; + c = (char) *next++; + remaining--; + return CORBA_B_TRUE; } - CORBA_Boolean -CDR::get_short ( - CORBA_Short &s -) +CDR::get_short (CORBA_Short &s) { - register unsigned char *tmp_next; - register unsigned temp; - - // - // Adjust pointer and count of remaining bytes - // - tmp_next = ptr_align_binary (next, SHORT_SIZE); - temp = SHORT_SIZE + (tmp_next - next); - if (temp > remaining) - return CORBA_B_FALSE; - remaining -= temp; - - // - // decode halfword, swapping as needed - // - if (!do_byteswap) { - s = *(CORBA_Short *)tmp_next; - next = tmp_next + SHORT_SIZE; - } else { - register unsigned char *sp = (unsigned char *) &s; - - sp [1] = *tmp_next++; - sp [0] = *tmp_next++; - next = tmp_next; + register u_char *tmp_next; + register u_int temp; + + // Adjust pointer and count of remaining bytes + + tmp_next = ptr_align_binary (next, SHORT_SIZE); + temp = SHORT_SIZE + (tmp_next - next); + + if (temp > remaining) + return CORBA_B_FALSE; + remaining -= temp; + + // decode halfword, swapping as needed + + if (!do_byteswap) + { + s = *(CORBA_Short *) tmp_next; + next = tmp_next + SHORT_SIZE; + } + else + { + register u_char *sp = (u_char *) &s; + + sp [1] = *tmp_next++; + sp [0] = *tmp_next++; + next = tmp_next; } - return CORBA_B_TRUE; + return CORBA_B_TRUE; } CORBA_Boolean -CDR::get_long ( - CORBA_Long &l -) +CDR::get_long (CORBA_Long &l) { - register unsigned char *tmp_next; - register unsigned temp; - - // - // Adjust pointer and count of remaining bytes - // - tmp_next = ptr_align_binary (next, LONG_SIZE); - temp = LONG_SIZE + (tmp_next - next); - if (temp > remaining) - return CORBA_B_FALSE; - remaining -= temp; - - // - // decode word, swapping as needed - // - if (!do_byteswap) { - l = *(CORBA_Long *)tmp_next; - next = tmp_next + LONG_SIZE; - } else { - register unsigned char *lp = (unsigned char *) &l; - - // - // NOTE: environment-specific speedups abound for this kind - // of stuff. This generic code takes advanage of none of them. - // - lp [3] = *tmp_next++; - lp [2] = *tmp_next++; - lp [1] = *tmp_next++; - lp [0] = *tmp_next++; - next = tmp_next; + register u_char *tmp_next; + register u_int temp; + + // Adjust pointer and count of remaining bytes + + tmp_next = ptr_align_binary (next, LONG_SIZE); + temp = LONG_SIZE + (tmp_next - next); + if (temp > remaining) + return CORBA_B_FALSE; + remaining -= temp; + + // decode word, swapping as needed + + if (!do_byteswap) + { + l = *(CORBA_Long *) tmp_next; + next = tmp_next + LONG_SIZE; + } + else + { + register u_char *lp = (u_char *) &l; + + // NOTE: environment-specific speedups abound for this kind of + // stuff. This generic code takes advanage of none of them. + + lp [3] = *tmp_next++; + lp [2] = *tmp_next++; + lp [1] = *tmp_next++; + lp [0] = *tmp_next++; + next = tmp_next; } - return CORBA_B_TRUE; + return CORBA_B_TRUE; } CORBA_Boolean -CDR::get_longlong ( - CORBA_LongLong &ll -) +CDR::get_longlong (CORBA_LongLong &ll) { - register unsigned char *tmp_next; - register unsigned temp; - - // - // Adjust pointer and count of remaining bytes - // - tmp_next = ptr_align_binary (next, LONGLONG_SIZE); - temp = LONGLONG_SIZE + (tmp_next - next); - if (temp > remaining) - return CORBA_B_FALSE; - remaining -= temp; - - // - // decode doubleword, swapping as needed - // - if (!do_byteswap) { - ll = *(CORBA_LongLong *)tmp_next; - next = tmp_next + LONGLONG_SIZE; - } else { - register unsigned char *llp = (unsigned char *) ≪ - - // - // NOTE: environment-specific speedups abound for this kind - // of stuff. This generic code takes advanage of none of them. - // - llp [7] = *tmp_next++; - llp [6] = *tmp_next++; - llp [5] = *tmp_next++; - llp [4] = *tmp_next++; - llp [3] = *tmp_next++; - llp [2] = *tmp_next++; - llp [1] = *tmp_next++; - llp [0] = *tmp_next++; - next = tmp_next; + register u_char *tmp_next; + register u_int temp; + + // Adjust pointer and count of remaining bytes + + tmp_next = ptr_align_binary (next, LONGLONG_SIZE); + temp = LONGLONG_SIZE + (tmp_next - next); + if (temp > remaining) + return CORBA_B_FALSE; + remaining -= temp; + + // decode doubleword, swapping as needed + + if (!do_byteswap) + { + ll = *(CORBA_LongLong *) tmp_next; + next = tmp_next + LONGLONG_SIZE; + } + else + { + register u_char *llp = (u_char *) ≪ + + // NOTE: environment-specific speedups abound for this kind + // of stuff. This generic code takes advanage of none of them. + + llp [7] = *tmp_next++; + llp [6] = *tmp_next++; + llp [5] = *tmp_next++; + llp [4] = *tmp_next++; + llp [3] = *tmp_next++; + llp [2] = *tmp_next++; + llp [1] = *tmp_next++; + llp [0] = *tmp_next++; + next = tmp_next; } - return CORBA_B_TRUE; + return CORBA_B_TRUE; } - CORBA_Boolean -CDR::get_longdouble ( - CORBA_LongDouble &ld -) +CDR::get_longdouble (CORBA_LongDouble &ld) { - register unsigned char *tmp_next; - register unsigned temp; - - // - // Adjust pointer and count of remaining bytes - // - tmp_next = ptr_align_binary (next, LONGDOUBLE_SIZE); - temp = LONGDOUBLE_SIZE + (tmp_next - next); - if (temp > remaining) - return CORBA_B_FALSE; - remaining -= temp; - - // - // copy the long double, swapping bytes as needed - // - if (!do_byteswap) { - ld = *(CORBA_LongDouble *)tmp_next; - next = tmp_next + LONGDOUBLE_SIZE; - } else { - register unsigned char *ldp = (unsigned char *) &ld; - - // - // NOTE: this is a single SPARC V9 instruction - // - ldp [15] = *tmp_next++; - ldp [14] = *tmp_next++; - ldp [13] = *tmp_next++; - ldp [12] = *tmp_next++; - ldp [11] = *tmp_next++; - ldp [10] = *tmp_next++; - ldp [ 9] = *tmp_next++; - ldp [ 8] = *tmp_next++; - ldp [ 7] = *tmp_next++; - ldp [ 6] = *tmp_next++; - ldp [ 5] = *tmp_next++; - ldp [ 4] = *tmp_next++; - ldp [ 3] = *tmp_next++; - ldp [ 2] = *tmp_next++; - ldp [ 1] = *tmp_next++; - ldp [ 0] = *tmp_next++; - next = tmp_next; + register u_char *tmp_next; + register u_int temp; + + // Adjust pointer and count of remaining bytes + + tmp_next = ptr_align_binary (next, LONGDOUBLE_SIZE); + temp = LONGDOUBLE_SIZE + (tmp_next - next); + if (temp > remaining) + return CORBA_B_FALSE; + remaining -= temp; + + // copy the long double, swapping bytes as needed + + if (!do_byteswap) + { + ld = *(CORBA_LongDouble *) tmp_next; + next = tmp_next + LONGDOUBLE_SIZE; + } + else + { + register u_char *ldp = (u_char *) &ld; + + // NOTE: this is a single SPARC V9 instruction + + ldp [15] = *tmp_next++; + ldp [14] = *tmp_next++; + ldp [13] = *tmp_next++; + ldp [12] = *tmp_next++; + ldp [11] = *tmp_next++; + ldp [10] = *tmp_next++; + ldp [ 9] = *tmp_next++; + ldp [ 8] = *tmp_next++; + ldp [ 7] = *tmp_next++; + ldp [ 6] = *tmp_next++; + ldp [ 5] = *tmp_next++; + ldp [ 4] = *tmp_next++; + ldp [ 3] = *tmp_next++; + ldp [ 2] = *tmp_next++; + ldp [ 1] = *tmp_next++; + ldp [ 0] = *tmp_next++; + next = tmp_next; } - return CORBA_B_TRUE; + return CORBA_B_TRUE; } - CORBA_Boolean -CDR::skip_string () // ISO/1 or octet string +CDR::skip_string (void) // ISO/1 or octet string { - CORBA_ULong len; + CORBA_ULong len; - if (get_ulong (len) == CORBA_B_FALSE || len > remaining) - return CORBA_B_FALSE; // buffer's changed + if (get_ulong (len) == CORBA_B_FALSE || len > remaining) + return CORBA_B_FALSE; // buffer's changed - next += (unsigned) len; - remaining -= (unsigned) len; - return CORBA_B_TRUE; + next += (u_int) len; + remaining -= (u_int) len; + return CORBA_B_TRUE; } - -// // Grow the CDR buffer, either to a known size (incoming message) or // by a standard increment (creating outgoing message). // // We can't use realloc() because of a constraint that the part of the // buffer into which we marshal be aligned according to MAX_ALIGNMENT, // which can be a stronger requirement than malloc/realloc places on -// buffer. This makes growing a buffer on the encode side costly, since -// it can need to be done repetitively and copies more data each time. +// buffer. This makes growing a buffer on the encode side costly, +// since it can need to be done repetitively and copies more data each +// time. // -// NOTE: this code knows about what's involved in the constructor and +// NOTE: this code knows about what's involved in the constructor and // destructor, as it needs to invoke the constructor and do what the // destructor would do (and not in the normal order). It also knows // all other state that's significant. Change with care! // -// NOTE: arguably this is a good place to ensure that the memory's zeroed -// out to comply with Orange Book C2 "object reuse" (meaning data, like -// I/O buffers) policy. IIOP doesn't mandate such policies though. -// +// NOTE: arguably this is a good place to ensure that the memory's +// zeroed out to comply with Orange Book C2 "object reuse" (meaning +// data, like I/O buffers) policy. IIOP doesn't mandate such policies +// though. + CORBA_Boolean CDR::grow (size_t newsize) { - unsigned char *old_realbuf, *oldbuf; - size_t offset; - int old_do_swap = do_byteswap; - - // - // Iff old buffer was heap allocated, it gets freed soon. In any case, - // we need to know which bytes that have been marshaled or read thus - // far, so they'll also be in the newly grown buffer. - // - if (do_free) - old_realbuf = real_buffer; - else - old_realbuf = 0; - oldbuf = buffer; - assert ((next - buffer) < UINT_MAX); - offset = (unsigned) (next - buffer); - - // - // Calculate the new buffer's length; if growing for encode, we - // don't grow in "small" chunks because of the cost. - // - size_t new_len; - - if (newsize == 0) { - if (length < 4096) - new_len = length + 4096; - else - new_len = length * 2; - } else if (newsize <= length) { - return CORBA_B_TRUE; - } else - new_len = newsize; - - // - // Get a new buffer that's adequately aligned, and use it to - // reinitialize ourselves with the "free this buffer later" flag. - // - unsigned char *new_buffer; - - new_len += MAX_ALIGNMENT - 1; - if ((new_buffer = (unsigned char *) ACE_OS::malloc (new_len)) == 0) - return CORBA_B_FALSE; - - (void) new (this) CDR (new_buffer, new_len, MY_BYTE_SEX, 1); - - // - // Now restore all the relevant old state that we saved earlier, - // and free the original buffer if needed. (The first buffer is - // normally stack-allocated and so mustn't be freed this way.) - // - do_byteswap = old_do_swap; - ACE_OS::memcpy (buffer, oldbuf, offset); - skip_bytes (offset); - - if (old_realbuf) - ACE_OS::free ((char *) old_realbuf); - + u_char *old_realbuf; + u_char *oldbuf; + size_t offset; + int old_do_swap = do_byteswap; + + // Iff old buffer was heap allocated, it gets freed soon. In any + // case, we need to know which bytes that have been marshaled or + // read thus far, so they'll also be in the newly grown buffer. + + if (do_free) + old_realbuf = real_buffer; + else + old_realbuf = 0; + oldbuf = buffer; + assert ((next - buffer) < UINT_MAX); + offset = (u_int) (next - buffer); + + // Calculate the new buffer's length; if growing for encode, we + // don't grow in "small" chunks because of the cost. + + size_t new_len; + + if (newsize == 0) + { + // @@ Can we replace the magic number 4096 with a const or enum? + if (length < 4096) + new_len = length + 4096; + else + new_len = length * 2; + } + else if (newsize <= length) return CORBA_B_TRUE; + else + new_len = newsize; + + // Get a new buffer that's adequately aligned, and use it to + // reinitialize ourselves with the "free this buffer later" flag. + + u_char *new_buffer; + + new_len += MAX_ALIGNMENT - 1; + + // Is there a reason we use malloc here and not new? + new_buffer = (u_char *) ACE_OS::malloc (new_len); + + if (new_buffer == 0) + return CORBA_B_FALSE; + + (void) new (this) CDR (new_buffer, new_len, MY_BYTE_SEX, 1); + + // Now restore all the relevant old state that we saved earlier, and + // free the original buffer if needed. (The first buffer is + // normally stack-allocated and so mustn't be freed this way.) + + do_byteswap = old_do_swap; + ACE_OS::memcpy (buffer, oldbuf, offset); + skip_bytes (offset); + + if (old_realbuf) + ACE_OS::free ((char *) old_realbuf); + + return CORBA_B_TRUE; } diff --git a/TAO/IIOP/lib/cdr.i b/TAO/IIOP/lib/cdr.i index fc6e73e699e..50e5e33ae4f 100644 --- a/TAO/IIOP/lib/cdr.i +++ b/TAO/IIOP/lib/cdr.i @@ -29,103 +29,89 @@ CDR::~CDR (void) delete real_buffer; } -ACE_INLINE -void* +ACE_INLINE void * CDR::operator new (size_t, void *_FAR p) { return p; } -ACE_INLINE -void* +ACE_INLINE void * CDR::operator new (size_t s) { return ::operator new (s); } -ACE_INLINE -void +ACE_INLINE void CDR::operator delete (void *p) { ::operator delete (p); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::put_char (CORBA_Char c) { return put_byte ((char) c); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::put_wchar (CORBA_WChar wc) { - // "wchar_t" isn't always 2 bytes, such systems might need - // further conversion (e.g. hosts with multibyte characters - // native, rather than UNICODE) + // "wchar_t" isn't always 2 bytes, such systems might need further + // conversion (e.g. hosts with multibyte characters native, rather + // than UNICODE) return put_short ((short) wc); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::put_boolean (CORBA_Boolean b) { return put_byte ((char) (b != CORBA_B_FALSE)); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::put_octet (CORBA_Octet o) { return put_byte ((char) o); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::put_ushort (CORBA_UShort s) { return put_short ((CORBA_Short) s); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::put_ulong (CORBA_ULong l) { return put_long ((CORBA_Long) l); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::put_ulonglong (const CORBA_ULongLong &ll) { return put_longlong ((CORBA_LongLong &) ll); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::put_float (float f) { return put_long (*(CORBA_Long *) &f); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::put_double (const double &d) { return put_longlong (*(CORBA_LongLong *) &d); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::get_char (CORBA_Char &o) { return this->get_byte ((char &) o); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::get_wchar (CORBA_WChar &wc) { short s; @@ -137,8 +123,7 @@ CDR::get_wchar (CORBA_WChar &wc) return retval; } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::get_boolean (CORBA_Boolean &b) { CORBA_Char c; @@ -151,50 +136,43 @@ CDR::get_boolean (CORBA_Boolean &b) return retval; } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::get_octet (CORBA_Octet &o) { return this->get_byte ((char &) o); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::get_ushort (CORBA_UShort &s) { return this->get_short ((short&) s); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::get_ulong (CORBA_ULong &l) { return this->get_long ((CORBA_Long &) l); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::get_ulonglong (const CORBA_ULongLong &ull) { return this->get_longlong ((CORBA_LongLong &) ull); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::get_float (float &f) { return this->get_long ((CORBA_Long &) f); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::get_double (double &d) { return this->get_longlong ((CORBA_LongLong &) d); } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CDR::skip_bytes (u_int nbytes) { if (remaining < nbytes) @@ -204,8 +182,7 @@ CDR::skip_bytes (u_int nbytes) return CORBA_B_TRUE; } -ACE_INLINE -void +ACE_INLINE void CDR::setup_encapsulation (u_char *buf, u_int len) { // Also used when interpreting typecodes, but more generally when @@ -218,8 +195,7 @@ CDR::setup_encapsulation (u_char *buf, u_int len) do_free = 0; } -ACE_INLINE -size_t +ACE_INLINE size_t CDR::bytes_remaining (void) { return remaining; diff --git a/TAO/IIOP/lib/connect.cpp b/TAO/IIOP/lib/connect.cpp index 8f332744e80..41a5bd2a93d 100644 --- a/TAO/IIOP/lib/connect.cpp +++ b/TAO/IIOP/lib/connect.cpp @@ -1,65 +1,59 @@ -// = LIB -// TAO -// = FILENAME -// connect.cpp -// = AUTHOR -// Chris Cleeland -// = VERSION -// $Id$ +// $Id$ #include "connect.h" #include "roa.h" #include "debug.h" - -ROA_Handler::ROA_Handler(ACE_Thread_Manager* t) - : SUPERCLASS(t) +ROA_Handler::ROA_Handler (ACE_Thread_Manager* t) + : SUPERCLASS (t) { - // Grab the singleton...at some later point in time - // we can provide an argumented CTOR to have per-instance - // parameters. - params_ = TAO_OA_PARAMS::instance(); - ACE_ASSERT (params_ != 0); + // Grab the singleton...at some later point in time we can provide + // an argumented CTOR to have per-instance parameters. + params_ = TAO_OA_PARAMS::instance (); + ACE_ASSERT (params_ != 0); } int -ROA_Handler::open(void*) +ROA_Handler::open (void*) { ACE_INET_Addr addr; - if (this->peer().get_remote_addr(addr) == -1) + if (this->peer ().get_remote_addr (addr) == -1) return -1; ACE_DEBUG ((LM_DEBUG, - "(%P|%t) %sconnection from client %s\n", - params_->using_threads() ? "threaded " : "", - addr.get_host_name())); - + " (%P|%t) %sconnection from client %s\n", + params_->using_threads () ? "threaded " : "", + addr.get_host_name ())); return 0; } int -ROA_Handler::handle_close(ACE_HANDLE fd, ACE_Reactor_Mask rm) +ROA_Handler::handle_close (ACE_HANDLE handle, + ACE_Reactor_Mask rm) { - ACE_DEBUG ((LM_DEBUG, "(%P|%t) ROA_Handler::handle_close(%d,%d)\n", fd, rm)); - return SUPERCLASS::handle_close(fd, rm); + ACE_DEBUG ((LM_DEBUG, " (%P|%t) ROA_Handler::handle_close (%d,%d)\n", handle, rm)); + return SUPERCLASS::handle_close (handle, rm); } int -ROA_Handler::svc() +ROA_Handler::svc (void) { int result = 0; - ACE_DEBUG ((LM_DEBUG, "(%P|%t) ROA_Handler::svc begin\n")); - while ((result = handle_input()) >= 0) + ACE_DEBUG ((LM_DEBUG, " (%P|%t) ROA_Handler::svc begin\n")); + + // @@ This is an important method, please add a comment here. + + while ((result = handle_input ()) >= 0) continue; - ACE_DEBUG ((LM_DEBUG, "(%P|%t) ROA_Handler::svc end\n")); + ACE_DEBUG ((LM_DEBUG, " (%P|%t) ROA_Handler::svc end\n")); return result; } int -ROA_Handler::handle_input(ACE_HANDLE fd) +ROA_Handler::handle_input (ACE_HANDLE handle) { // CJCXXX The tasks of this method should change to something like // the following: @@ -70,22 +64,22 @@ ROA_Handler::handle_input(ACE_HANDLE fd) CORBA_Environment env; TAO_Dispatch_Context ctx; - ctx.oa_ = params_->oa(); - ctx.endpoint_ = peer(); + ctx.oa_ = params_->oa (); + ctx.endpoint_ = peer (); // CJCXXX Knowledge of these will move into the OA so they don't // have to be copied every time. Also, these should be set in the - // by a call to register_object() or somesuch, because there will + // by a call to register_object () or somesuch, because there will // be a different upcall and forwarder for every object (or is it // for every TYPE of object?). I need to rename "context" so that // it has a more meaningful name. - ctx.skeleton_ = params_->upcall(); - ctx.context_ = params_->context(); - ctx.check_forward_ = params_->forwarder(); + ctx.skeleton_ = params_->upcall (); + ctx.context_ = params_->context (); + ctx.check_forward_ = params_->forwarder (); int ret; - switch(params_->oa()->handle_message (ctx, env)) + switch (params_->oa ()->handle_message (ctx, env)) { case 1: default: @@ -98,24 +92,24 @@ ROA_Handler::handle_input(ACE_HANDLE fd) break; } - // // Don't report any errors from the application/skeleton back to the // top level ... the application already has a variety of means to // pass whatever data needs passing, and we don't need to confuse // things by mixing ORB and application errors here. - // - if (env.exception () != 0) { - dexc (env, "ROA_Handler, handle incoming message"); - env.clear (); - } + + if (env.exception () != 0) + { + dexc (env, "ROA_Handler, handle incoming message"); + env.clear (); + } return ret; } -#if ! defined(__ACE_INLINE__) +#if ! defined (__ACE_INLINE__) # include "connect.i" #endif -#if defined(ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) // Direct template class ACE_Acceptor<ROA_Handler, ACE_SOCK_ACCEPTOR>; template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; diff --git a/TAO/IIOP/lib/connmgr.cpp b/TAO/IIOP/lib/connmgr.cpp index 8c9e8d38df7..829d0b3d738 100644 --- a/TAO/IIOP/lib/connmgr.cpp +++ b/TAO/IIOP/lib/connmgr.cpp @@ -5,26 +5,26 @@ // IIOP: Simple asymmetric TCP connection manager // // This has been multithreaded with a very simple strategy, optimizing -// for "lightly threaded" clients rather than maximal sharing of system -// resources (connections, time) in concurrent environments. Two locks -// are used, one each for client and server sides. +// for "lightly threaded" clients rather than maximal sharing of +// system resources (connections, time) in concurrent environments. +// Two locks are used, one each for client and server sides. // -// The expectation is: threads have a refcount on an endpoint only while -// a call's active. Between calls, they release the endpoint record. If -// need be, the file descriptor in the record may be set to a negative -// number, and the descriptor closed (e.g. on unrecoverable error). +// The expectation is: threads have a refcount on an endpoint only +// while a call's active. Between calls, they release the endpoint +// record. If need be, the file descriptor in the record may be set +// to a negative number, and the descriptor closed (e.g. on +// unrecoverable error). // // The tricky issues have been strongly avoided. Particularly, on any // given connection no multiplexing is done; that simplifies this code -// substantially, as well as the protocol code that'd otherwise need to -// dispatch IIOP replies to arbitrary client threads. This costs most if -// several "long" (time-wise) calls are made concurrently. -// -// Similarly, condition variables aren't used to allow concurrent access -// to connection tables during "long" operations: name service lookups, -// connection establishment, or both. Initial connection establishment, -// including use of hostname aliases, pays this cost. +// substantially, as well as the protocol code that'd otherwise need +// to dispatch IIOP replies to arbitrary client threads. This costs +// most if several "long" (time-wise) calls are made concurrently. // +// Similarly, condition variables aren't used to allow concurrent +// access to connection tables during "long" operations: name service +// lookups, connection establishment, or both. Initial connection +// establishment, including use of hostname aliases, pays this cost. #include <assert.h> #if !defined (VXWORKS) @@ -58,25 +58,23 @@ #include "thread.h" #include "debug.h" - -// // We tell the kernel to queue no more than LISTEN_LIMIT connection // requests ... traditionally, BSD implementations max out at 5, but // more recent implementations have no OS limit. -// -#define LISTEN_LIMIT 5 // traditional maximum +#define LISTEN_LIMIT 5 // traditional maximum + +// Lists holding the connections managed in this module: one for +// outgoing connections (client list), the other for incoming ones +// (server list). // -// Lists holding the connections managed in this module: one for outgoing -// connections (client list), the other for incoming ones (server list). -// -// NOTE: with multiple OAs, it'll be desirable to let each OA have its own -// server endpoint list so OAs can manage requests (and their threading) -// separately. -// -static client_endpoint *client_list; -static server_endpoint *server_list; +// NOTE: with multiple OAs, it'll be desirable to let each OA have its +// own server endpoint list so OAs can manage requests (and their +// threading) separately. +// @@ Can we remove this stuff now? +static client_endpoint *client_list; +static server_endpoint *server_list; #ifdef _POSIX_THREADS // @@ -88,42 +86,36 @@ static server_endpoint *server_list; static pthread_mutex_t client_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t server_lock = PTHREAD_MUTEX_INITIALIZER; -// // We need to cleanly indicate to select()ing server threads that a // a connection has been returned to their purview. The simplest way // is for them to wake up normally ... e.g. by data arriving. We use // writes on a private pipe: that's what signal_fd is for. -// -static ACE_HANDLE signal_fd; -// +static ACE_HANDLE signal_fd; + // Conceptually, each TCP OA listens to a single "in" signal FD. But // we only support one of them for now. -// -static ACE_HANDLE signal_in_fd; -#endif // _POSIX_THREADS +static ACE_HANDLE signal_in_fd; +#endif /* _POSIX_THREADS */ -// // Release ... must be reentrant in threaded systems. -// + void -client_endpoint::release () +client_endpoint::release (void) { #ifdef _POSIX_THREADS - Critical region (&client_lock); + Critical region (&client_lock); #endif // _POSIX_THREADS - assert (refcount == 1); - refcount--; + assert (refcount == 1); + refcount--; } +// Gets or makes a connection to the indicated host@port, or reports +// an exception explaining why it couldn't. -// -// Gets or makes a connection to the indicated host@port, or reports an -// exception explaining why it couldn't. -// client_endpoint * client_endpoint::lookup ( char *host, diff --git a/TAO/IIOP/lib/corbacom.cpp b/TAO/IIOP/lib/corbacom.cpp index 627b42e153b..7fa4f49375a 100644 --- a/TAO/IIOP/lib/corbacom.cpp +++ b/TAO/IIOP/lib/corbacom.cpp @@ -3,7 +3,6 @@ // All Rights Reserved // // ORB: support for primitive data types -// #include <assert.h> #include <limits.h> @@ -14,26 +13,24 @@ # include <widec.h> #endif +// String utility support; this can need to be integrated with the +// ORB's own memory allocation subsystem. -// -// String utility support; this can need to be integrated with -// the ORB's own memory allocation subsystem. -// CORBA_String CORBA_string_alloc (CORBA_ULong len) { - return new CORBA_Char [(size_t)(len + 1)]; + return new CORBA_Char [(size_t)(len + 1)]; } CORBA_String CORBA_string_copy (const CORBA_Char *const str) { - if (!str) - return 0; + if (!str) + return 0; - CORBA_String retval = CORBA_string_alloc (strlen (str)); + CORBA_String retval = CORBA_string_alloc (strlen (str)); - return ACE_OS::strcpy (retval, str); + return ACE_OS::strcpy (retval, str); } CORBA_String @@ -45,104 +42,102 @@ CORBA_string_dup (const CORBA_Char *const str) void CORBA_string_free (CORBA_Char *const str) { - delete str; + delete str; } // ---------------------------------------------------------------------- // String_var type // ---------------------------------------------------------------------- -CORBA_String_var::CORBA_String_var() +CORBA_String_var::CORBA_String_var (void) { this->ptr_ = 0; } -CORBA_String_var::~CORBA_String_var() +CORBA_String_var::~CORBA_String_var (void) { - if (this->ptr_ != 0){ - CORBA_string_free(this->ptr_); - } + if (this->ptr_ != 0) + CORBA_string_free (this->ptr_); } -CORBA_String_var::CORBA_String_var(char* p) - :ptr_(p) +CORBA_String_var::CORBA_String_var (char *p) + : ptr_ (p) { // argument is consumed. p should never be NULL } -CORBA_String_var::CORBA_String_var(const char* p) - : ptr_(CORBA_string_dup((char *)p)) +CORBA_String_var::CORBA_String_var (const char *p) + : ptr_ (CORBA_string_dup ((char *)p)) { } -CORBA_String_var::CORBA_String_var(const CORBA_String_var& r) +CORBA_String_var::CORBA_String_var (const CORBA_String_var& r) { - this->ptr_ = CORBA_string_dup(r.ptr_); + this->ptr_ = CORBA_string_dup (r.ptr_); } -CORBA_String_var& -CORBA_String_var::operator=(char* p) +CORBA_String_var & +CORBA_String_var::operator= (char *p) { - if (this->ptr_ != p){ - if (this->ptr_ != 0){ - CORBA_string_free(this->ptr_); + if (this->ptr_ != p) + { + if (this->ptr_ != 0) + CORBA_string_free (this->ptr_); + this->ptr_ = p; } - this->ptr_ = p; - } return *this; } -CORBA_String_var& -CORBA_String_var::operator=(const char* p) +CORBA_String_var & +CORBA_String_var::operator= (const char *p) { - if (this->ptr_ != 0){ - CORBA_string_free(this->ptr_); - } - this->ptr_ = CORBA_string_dup(p); + if (this->ptr_ != 0) + CORBA_string_free (this->ptr_); + this->ptr_ = CORBA_string_dup (p); return *this; } -CORBA_String_var& -CORBA_String_var::operator=(const CORBA_String_var& r) +CORBA_String_var & +CORBA_String_var::operator= (const CORBA_String_var& r) { - if (this->ptr_ != 0){ - CORBA_string_free(this->ptr_); - } - this->ptr_ = CORBA_string_dup(r.ptr_); + if (this->ptr_ != 0) + CORBA_string_free (this->ptr_); + this->ptr_ = CORBA_string_dup (r.ptr_); return *this; } -CORBA_Char& CORBA_String_var::operator[](CORBA_ULong index) +CORBA_Char & +CORBA_String_var::operator[] (CORBA_ULong index) { // we need to verify bounds else raise some exception return this->ptr_[index]; } -CORBA_Char CORBA_String_var::operator[](CORBA_ULong index) const +CORBA_Char +CORBA_String_var::operator[] (CORBA_ULong index) const { // we need to verify bounds else raise some exception return this->ptr_[index]; } #if !defined (HAVE_WIDEC_H) -// -// NOTE: assuming that these don't exist unless they're declared in +// NOTE: assuming that these don't exist unless they're declared in // that header file ... -// extern "C" unsigned wslen (const CORBA_WChar *str) { - unsigned len = 0; + u_int len = 0; - while (*str++) - len++; - return len; + while (*str++) + len++; + return len; } extern "C" CORBA_WChar * -wscpy (CORBA_WChar *dest, const CORBA_WChar *src) +wscpy (CORBA_WChar *dest, + const CORBA_WChar *src) { CORBA_WChar *retval = dest; @@ -150,32 +145,30 @@ wscpy (CORBA_WChar *dest, const CORBA_WChar *src) continue; return retval; } - #endif // HAVE_WIDEC_H -// // Wide Character string utility support; this can need to be // integrated with the ORB's own memory allocation subsystem. -// + CORBA_WString CORBA_wstring_alloc (CORBA_ULong len) { - return new CORBA_WChar [(size_t) (len + 1)]; + return new CORBA_WChar [(size_t) (len + 1)]; } CORBA_WString CORBA_wstring_copy (const CORBA_WChar *const str) { - if (*str) - return 0; + if (*str) + return 0; - CORBA_WString retval = CORBA_wstring_alloc (wslen (str)); - return wscpy (retval, str); + CORBA_WString retval = CORBA_wstring_alloc (wslen (str)); + return wscpy (retval, str); } void CORBA_wstring_free (CORBA_WChar *const str) { - delete str; + delete str; } diff --git a/TAO/IIOP/lib/corbacom.h b/TAO/IIOP/lib/corbacom.h index 8c5134f3220..db9c9e11912 100644 --- a/TAO/IIOP/lib/corbacom.h +++ b/TAO/IIOP/lib/corbacom.h @@ -1,10 +1,20 @@ // This may look like C, but it's really -*- C++ -*- + +// ============================================================================ +// +// = LIBRARY +// TAO +// +// = FILENAME +// corbacom.h // -// @(#) $Id$ -// Copyright 1995 by Sun Microsystems, Inc. -// All Rights Reserved +// = DESCRIPTION +// CORBA C/C++/COM mapping for Win32 // -// CORBA C/C++/COM mapping for Win32 +// = AUTHOR +// Copyright 1994-1995 by Sun Microsystems Inc. +// +// ============================================================================ #if !defined (TAO_CORBACOM_H) #define TAO_CORBACOM_H @@ -21,15 +31,14 @@ typedef int CORBA_Boolean; enum { CORBA_B_FALSE = 0, CORBA_B_TRUE = 1 }; #endif /* "bool" not builtin */ -typedef u_char CORBA_Octet; +typedef u_char CORBA_Octet; -typedef short CORBA_Short; -typedef u_short CORBA_UShort; +typedef short CORBA_Short; +typedef u_short CORBA_UShort; + +// CORBA "Long" (and its unsigned cousin) are 32 bits, just like on +// almost all C/C++ compilers. -// -// CORBA "Long" (and its unsigned cousin) are 32 bits, just like -// on almost all C/C++ compilers. -// #if SIZEOF_LONG == 4 typedef long CORBA_Long; typedef u_long CORBA_ULong; @@ -39,8 +48,8 @@ typedef int CORBA_Long; typedef u_int CORBA_ULong; #endif /* SIZEOF_LONG != 4 */ -// 94-9-32 Appendix A, also the OMG C++ mapping, stipulate that -// 64 bit integers are "LongLong". +// 94-9-32 Appendix A, also the OMG C++ mapping, stipulate that 64 bit +// integers are "LongLong". // // NOTE: those are IDL extensions, not yet standard. diff --git a/TAO/IIOP/lib/debug.cpp b/TAO/IIOP/lib/debug.cpp index fd6401cdd24..443b30f15dc 100644 --- a/TAO/IIOP/lib/debug.cpp +++ b/TAO/IIOP/lib/debug.cpp @@ -1,16 +1,15 @@ -// @(#)debug.cpp 1.3 95/10/02 +// @ (#)debug.cpp 1.3 95/10/02 // Copyright 1994-1995 by Sun Microsystems Inc. // All Rights Reserved // // ORB: Simple debug/trace support // -// THREADING NOTE: the global values here (debug_{level,filter,stream) are -// assumed to be modified "safely", e.g. in the main thread as part of -// process initialization. They are treated as immutable values through -// all of this debuging package. -// -// XXX on Windows, make it always use OutputDebugString() instead of stdio +// THREADING NOTE: the global values here (debug_{level,filter,stream) +// are assumed to be modified "safely", e.g. in the main thread as +// part of process initialization. They are treated as immutable +// values through all of this debuging package. // +// XXX on Windows, make it always use OutputDebugString () instead of stdio #include <assert.h> #include <limits.h> @@ -32,22 +31,17 @@ #endif - - - #ifndef _POSIX_THREADS // _POSIX_THREAD_SAFE_FUNCTIONS implied -#define flockfile(f) -#define funlockfile(f) +#define flockfile (f) +#define funlockfile (f) #endif // _POSIX_THREADS -unsigned debug_level = 0; -char *debug_filter = "l"; -static FILE *debug_stream = stderr; +u_int debug_level = 0; +char *debug_filter = "l"; +static FILE *debug_stream = stderr; - -// // The rest of this file is not needed without -DDEBUG, and unless the -// vfprintf() call is available it can't work. +// vfprintf () call is available it can't work. // // NOTE: some older platforms have "_doprnt" that provides much the // same functionality ... this could be modified to use that routine @@ -60,7 +54,7 @@ static FILE *debug_stream = stderr; // the thread ID. This lets messages from different sources be safely // disentangled, even though they're interspersed in the output stream. // -static pid_t my_pid; +static pid_t my_pid; #if defined (unix) || defined (VXWORKS) @@ -68,40 +62,40 @@ static pid_t my_pid; // // Use POSIX initialization support to initialize just once. // -static pthread_once_t debug_init = PTHREAD_ONCE_INIT; +static pthread_once_t debug_init = PTHREAD_ONCE_INIT; -#define setup() pthread_once(&debug_init, setup_once) +#define setup () pthread_once (&debug_init, setup_once) static void setup_once () { - my_pid = ACE_OS::getpid (); + my_pid = ACE_OS::getpid (); } static void emit_prefix (FILE *stream) { - pthread_t self = pthread_self (); + pthread_t self = pthread_self (); - ACE_OS::fprintf (stream, "p%ld t%ld: ", (long) my_pid, (long) self); + ACE_OS::fprintf (stream, "p%ld t%ld: ", (long) my_pid, (long) self); } #else // !defined (_POSIX_THREADS) -// // Without threads, guard initialization so it can be repeated, // and don't emit the thread ID in the messages. -// + static void -setup () +setup (void) { - if (my_pid == 0) { - my_pid = ACE_OS::getpid (); - // other setup goes here + if (my_pid == 0) + { + my_pid = ACE_OS::getpid (); + // other setup goes here } } -#define emit_prefix(stream) fprintf (stream, "p%ld: ", (long) my_pid) +#define emit_prefix (stream) fprintf (stream, "p%ld: ", (long) my_pid) #endif // !_POSIX_THREADS #elif defined (_WIN32) @@ -111,15 +105,14 @@ setup () // this code doesn't yet support Win32 threads. // static void -setup () +setup (void) { - if (my_pid == 0) { - my_pid = GetCurrentProcessId (); - // other setup goes here - } + if (my_pid == 0) + my_pid = GetCurrentProcessId (); + // other setup goes here } -#define emit_prefix(stream) fprintf (stream, "p%ld: ", my_pid) +#define emit_prefix (stream) fprintf (stream, "p%ld: ", my_pid) #else @@ -128,209 +121,218 @@ setup () void _EXPFUNC -dmsg_filter ( - const char *_FAR categories, - const char *_FAR fmt, - ... -) +dmsg_filter (const char *_FAR categories, + const char *_FAR fmt, + ...) { - const char *cp; + const char *cp; - if (!categories || !debug_filter) - return; + if (!categories || !debug_filter) + return; - if (*debug_filter != '*') { // filter with "*" --> all pass - for (cp = categories; *cp; cp++) - if (strchr (debug_filter, *cp) != 0) - break; + if (*debug_filter != '*') + { // filter with "*" --> all pass + for (cp = categories; *cp; cp++) + if (strchr (debug_filter, *cp) != 0) + break; - if (!*cp) - return; + if (!*cp) + return; } - va_list ap; + va_list ap; - setup (); - flockfile (debug_stream); - emit_prefix (debug_stream); + setup (); + flockfile (debug_stream); + emit_prefix (debug_stream); - switch (*cp) { // standard categories - case 'l': ACE_OS::fprintf (debug_stream, "(LEAK) "); break; + switch (*cp) + { // standard categories + case 'l': ACE_OS::fprintf (debug_stream, " (LEAK) "); break; } - va_start (ap, fmt); - vfprintf (debug_stream, fmt, ap); - va_end (ap); - if (strchr (fmt, '\n') == 0) - ACE_OS::fprintf (debug_stream, "\n"); - funlockfile (debug_stream); + + va_start (ap, fmt); + vfprintf (debug_stream, fmt, ap); + va_end (ap); + if (strchr (fmt, '\n') == 0) + ACE_OS::fprintf (debug_stream, "\n"); + funlockfile (debug_stream); #if defined (_WIN32) - OutputDebugString ("called dmsg_filter\n"); // experimental + OutputDebugString ("called dmsg_filter\n"); // experimental #endif } void _EXPFUNC -dmsg_filter (unsigned level, const char *_FAR fmt, ...) +dmsg_filter (u_int level, + const char *_FAR fmt, + ...) { - if (level > debug_level) - return; - - va_list ap; - - setup (); - flockfile (debug_stream); - emit_prefix (debug_stream); - va_start (ap, fmt); - vfprintf (debug_stream, fmt, ap); - va_end (ap); - if (strchr (fmt, '\n') == 0) - ACE_OS::fprintf (debug_stream, "\n"); - funlockfile (debug_stream); + if (level > debug_level) + return; + + va_list ap; + + setup (); + flockfile (debug_stream); + emit_prefix (debug_stream); + va_start (ap, fmt); + vfprintf (debug_stream, fmt, ap); + va_end (ap); + if (strchr (fmt, '\n') == 0) + ACE_OS::fprintf (debug_stream, "\n"); + funlockfile (debug_stream); #if defined (_WIN32) - OutputDebugString ("called dmsg_filter\n"); // experimental + OutputDebugString ("called dmsg_filter\n"); // experimental #endif } void _EXPFUNC -dmsg_v (const char *_FAR fmt, ...) +dmsg_v (const char *_FAR fmt, + ...) { - va_list ap; - - setup (); - flockfile (debug_stream); - emit_prefix (debug_stream); - va_start (ap, fmt); - vfprintf (debug_stream, fmt, ap); - va_end (ap); - if (strchr (fmt, '\n') == 0) - ACE_OS::fprintf (debug_stream, "\n"); - funlockfile (debug_stream); + va_list ap; + + setup (); + flockfile (debug_stream); + emit_prefix (debug_stream); + va_start (ap, fmt); + vfprintf (debug_stream, fmt, ap); + va_end (ap); + if (strchr (fmt, '\n') == 0) + ACE_OS::fprintf (debug_stream, "\n"); + funlockfile (debug_stream); #if defined (_WIN32) - OutputDebugString ("called dmsg_v\n"); // experimental + OutputDebugString ("called dmsg_v\n"); // experimental #endif } void _EXPFUNC -_dmsg_x ( - CORBA_Environment _FAR &env, - const char *_FAR info -) +_dmsg_x (CORBA_Environment _FAR &env, + const char *_FAR info) { - const CORBA_Exception *ex = env.exception (); - - setup (); - flockfile (debug_stream); - emit_prefix (debug_stream); - ACE_OS::fprintf (debug_stream, "exception '%s' at '%s'\n", ex->id (), info); - if (env.exception_type () == SYSTEM_EXCEPTION) { - CORBA_SystemException *sysex = (CORBA_SystemException *)ex; - - emit_prefix (debug_stream); - ACE_OS::fprintf (debug_stream, "minor %#lx, completion %#lx\n", - sysex->minor (), (long) sysex->completion ()); + const CORBA_Exception *ex = env.exception (); + + setup (); + flockfile (debug_stream); + emit_prefix (debug_stream); + ACE_OS::fprintf (debug_stream, "exception '%s' at '%s'\n", ex->id (), info); + if (env.exception_type () == SYSTEM_EXCEPTION) + { + CORBA_SystemException *sysex = (CORBA_SystemException *) ex; + + emit_prefix (debug_stream); + ACE_OS::fprintf (debug_stream, "minor %#lx, completion %#lx\n", + sysex->minor (), (long) sysex->completion ()); } - funlockfile (debug_stream); + funlockfile (debug_stream); #if defined (_WIN32) - OutputDebugString ("called _dmsg_x\n"); // experimental + OutputDebugString ("called _dmsg_x\n"); // experimental #endif } void _EXPFUNC -dmsg_opaque ( - char *_FAR label, - unsigned char *_FAR buffer, - unsigned long len) +dmsg_opaque (char *_FAR label, + u_char *_FAR buffer, + u_long len) { - setup (); - flockfile (debug_stream); - emit_prefix (debug_stream); - ACE_OS::fprintf (debug_stream, "%s ", label); - - if (len == 0 || !buffer) - ACE_OS::fprintf (debug_stream, "(empty)"); - else if (len > UINT_MAX) - ACE_OS::fprintf (debug_stream, "Oversized opaque data: %ld bytes", len); - else { - unsigned i; - - for (i = 0; i < len; i++) - if (!isprint (buffer [i])) - break; + setup (); + flockfile (debug_stream); + emit_prefix (debug_stream); + ACE_OS::fprintf (debug_stream, "%s ", label); + + if (len == 0 || !buffer) + ACE_OS::fprintf (debug_stream, " (empty)"); + else if (len > UINT_MAX) + ACE_OS::fprintf (debug_stream, "Oversized opaque data: %ld bytes", len); + else + { + u_int i; + + for (i = 0; i < len; i++) + if (!isprint (buffer [i])) + break; - if (i < len) { - if (len >= 20) - ACE_OS::fprintf (debug_stream, "%ld bytes binary data", len); - else { - ACE_OS::fprintf (debug_stream, "binary data {%2X", buffer [0]); - for (i = 1; i < len; i++) - ACE_OS::fprintf (debug_stream, ", %2x", buffer [i]); - ACE_OS::fprintf (debug_stream, "}"); + if (i < len) + { + if (len >= 20) + ACE_OS::fprintf (debug_stream, "%ld bytes binary data", len); + else + { + ACE_OS::fprintf (debug_stream, "binary data {%2X", buffer [0]); + for (i = 1; i < len; i++) + ACE_OS::fprintf (debug_stream, ", %2x", buffer [i]); + ACE_OS::fprintf (debug_stream, "}"); } - } else { - if (len >= 50) - ACE_OS::fprintf (debug_stream, "%ld bytes string data", len); - else - ACE_OS::fprintf (debug_stream, "string data { \"%.*s\" }", - (int) len, buffer); + } + else + { + if (len >= 50) + ACE_OS::fprintf (debug_stream, "%ld bytes string data", len); + else + ACE_OS::fprintf (debug_stream, "string data { \"%.*s\" }", + (int) len, buffer); } } - ACE_OS::fprintf (debug_stream, "\n"); - funlockfile (debug_stream); + ACE_OS::fprintf (debug_stream, "\n"); + funlockfile (debug_stream); #if defined (_WIN32) - OutputDebugString ("called dmsg_opaque\n"); // experimental + OutputDebugString ("called dmsg_opaque\n"); // experimental #endif } void _EXPFUNC -dmsg_opaque_full ( - char *_FAR label, - const unsigned char *_FAR buffer, - unsigned long len) +dmsg_opaque_full (char *_FAR label, + const u_char *_FAR buffer, + u_long len) { - setup (); - flockfile (debug_stream); - - emit_prefix (debug_stream); - ACE_OS::fprintf (debug_stream, "%s ", label); - - if (len == 0 || !buffer) - ACE_OS::fprintf (debug_stream, "(empty)"); - else { - unsigned i; - - for (i = 0; i < len; i++) - { - if (i == 0) - ACE_OS::fprintf(debug_stream, "\nhex: "); - else if ((i % 32) == 0) - ACE_OS::fprintf(debug_stream, "\n "); - else if ((i % 4) == 0) - ACE_OS::fprintf(debug_stream, " "); - ACE_OS::fprintf(debug_stream, "%02x", buffer[i]); - } - for (i = 0; i < len; i++) - { - if (i == 0) - ACE_OS::fprintf(debug_stream, "\nchars: "); - else if ((i % 32) == 0) - ACE_OS::fprintf(debug_stream, "\n "); - else if ((i % 4) == 0) - ACE_OS::fprintf(debug_stream, " "); - ACE_OS::fprintf(debug_stream, "%c ", - (isprint(buffer[i]) ? buffer[i] : '?')); - - } - ACE_OS::fprintf(debug_stream, "\n"); + setup (); + flockfile (debug_stream); + + emit_prefix (debug_stream); + ACE_OS::fprintf (debug_stream, "%s ", label); + + if (len == 0 || !buffer) + ACE_OS::fprintf (debug_stream, " (empty)"); + else + { + u_int i; + + for (i = 0; i < len; i++) + { + if (i == 0) + ACE_OS::fprintf (debug_stream, "\nhex: "); + else if ((i % 32) == 0) + ACE_OS::fprintf (debug_stream, "\n "); + else if ((i % 4) == 0) + ACE_OS::fprintf (debug_stream, " "); + ACE_OS::fprintf (debug_stream, "%02x", buffer[i]); + } + + for (i = 0; i < len; i++) + { + if (i == 0) + ACE_OS::fprintf (debug_stream, "\nchars: "); + else if ((i % 32) == 0) + ACE_OS::fprintf (debug_stream, "\n "); + else if ((i % 4) == 0) + ACE_OS::fprintf (debug_stream, " "); + ACE_OS::fprintf (debug_stream, "%c ", + (isprint (buffer[i]) ? buffer[i] : '?')); + + } + + ACE_OS::fprintf (debug_stream, "\n"); } - ACE_OS::fprintf (debug_stream, "\n"); - funlockfile (debug_stream); + ACE_OS::fprintf (debug_stream, "\n"); + funlockfile (debug_stream); #if defined (_WIN32) - OutputDebugString ("called dmsg_opaque_full\n"); // experimental + OutputDebugString ("called dmsg_opaque_full\n"); // experimental #endif } diff --git a/TAO/IIOP/lib/except.cpp b/TAO/IIOP/lib/except.cpp index 3f2b0398a34..27c6c6b1f8f 100644 --- a/TAO/IIOP/lib/except.cpp +++ b/TAO/IIOP/lib/except.cpp @@ -6,7 +6,6 @@ // // THREADING NOTE: calling thread handles mutual exclusion policy // on all of these data structures. -// #include <assert.h> #include <limits.h> @@ -26,8 +25,6 @@ # include <widec.h> #endif - - // {77420082-F276-11ce-9598-0000C07CA898} DEFINE_GUID (IID_CORBA_Exception, 0x77420082, 0xf276, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); @@ -41,84 +38,75 @@ DEFINE_GUID (IID_CORBA_SystemException, 0x77420084, 0xf276, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); -CORBA_Exception::CORBA_Exception ( - CORBA_TypeCode_ptr tc -) : - _type (tc), - _refcnt (1) +CORBA_Exception::CORBA_Exception (CORBA_TypeCode_ptr tc) + : _type (tc), + _refcnt (1) { - if (_type) - _type->AddRef (); - assert (_type != 0); - assert (_refcnt > 0); + if (_type) + _type->AddRef (); + assert (_type != 0); + assert (_refcnt > 0); } -CORBA_Exception::CORBA_Exception ( - const CORBA_Exception &src -) : - _type (src._type), - _refcnt (1) +CORBA_Exception::CORBA_Exception (const CORBA_Exception &src) + : _type (src._type), + _refcnt (1) { - if (_type) - _type->AddRef (); - assert (_type != 0); - assert (_refcnt > 0); + if (_type) + _type->AddRef (); + assert (_type != 0); + assert (_refcnt > 0); } -// // NOTE: It's this code, not anything defined in a subclass, which // is responsible for releasing any storage owned by the exception. // It can do this because it's got the typecode. -// -CORBA_Exception::~CORBA_Exception () + +CORBA_Exception::~CORBA_Exception (void) { - assert (_refcnt == 0); - assert (_type != 0); + assert (_refcnt == 0); + assert (_type != 0); - assert (1 == 2); + assert (1 == 2); } CORBA_Exception & -CORBA_Exception::operator = ( - const CORBA_Exception &src -) +CORBA_Exception::operator = (const CORBA_Exception &src) { - if (_type) - _type->Release (); - _type = src._type; - if (_type) - _type->AddRef (); - assert (_type != 0); - assert (_refcnt > 0); - - return *this; + if (_type) + _type->Release (); + _type = src._type; + if (_type) + _type->AddRef (); + assert (_type != 0); + assert (_refcnt > 0); + + return *this; } const CORBA_String -CORBA_Exception::id () const +CORBA_Exception::id (void) const { - CORBA_Environment env; + CORBA_Environment env; - assert (_refcnt > 0); - if (_type) - return _type->id (env); - else - return 0; + assert (_refcnt > 0); + if (_type) + return _type->id (env); + else + return 0; } const CORBA_TypeCode_ptr -CORBA_Exception::type () const +CORBA_Exception::type (void) const { - assert (_refcnt > 0); - return _type; + assert (_refcnt > 0); + return _type; } -// // For COM -- IUnKnown operations -// -ULONG -__stdcall -CORBA_Exception::AddRef () + +ULONG __stdcall +CORBA_Exception::AddRef (void) { ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); @@ -126,9 +114,8 @@ CORBA_Exception::AddRef () return ++_refcnt; } -ULONG -__stdcall -CORBA_Exception::Release () +ULONG __stdcall +CORBA_Exception::Release (void) { ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); @@ -141,171 +128,160 @@ CORBA_Exception::Release () // CORBA_TypeCode_ptr tc = _type->_duplicate (); - { CORBA_Any free_it_all (_type, this, CORBA_B_TRUE); } + { + CORBA_Any free_it_all (_type, this, CORBA_B_TRUE); + } // tc->Release (); return 0; } -HRESULT -__stdcall -CORBA_Exception::QueryInterface ( - REFIID riid, - void **ppv -) +HRESULT __stdcall +CORBA_Exception::QueryInterface (REFIID riid, + void **ppv) { - assert (_refcnt > 0); - *ppv = 0; + assert (_refcnt > 0); + *ppv = 0; - if (IID_CORBA_Exception == riid || IID_IUnknown == riid) - *ppv = this; + if (IID_CORBA_Exception == riid || IID_IUnknown == riid) + *ppv = this; - // - // XXX this approach needs modifying to enable returning - // UserException, SystemException, and other kinds of pointers. - // + // XXX this approach needs modifying to enable returning + // UserException, SystemException, and other kinds of pointers. - if (*ppv == 0) - return ResultFromScode (E_NOINTERFACE); + if (*ppv == 0) + return ResultFromScode (E_NOINTERFACE); - (void) AddRef (); - return NOERROR; + (void) AddRef (); + return NOERROR; } - -// // Avoid zillions of not-quite-inlined copies of utilities. -// -CORBA_UserException::CORBA_UserException ( - CORBA_TypeCode_ptr tc -) : - CORBA_Exception (tc) + +CORBA_UserException::CORBA_UserException (CORBA_TypeCode_ptr tc) + : CORBA_Exception (tc) { } -CORBA_UserException::~CORBA_UserException () +CORBA_UserException::~CORBA_UserException (void) { } -CORBA_SystemException::CORBA_SystemException ( - CORBA_TypeCode_ptr tc, - CORBA_ULong code, - CORBA_CompletionStatus completed -) : - _minor (code), - _completed (completed), - CORBA_Exception (tc) +CORBA_SystemException::CORBA_SystemException (CORBA_TypeCode_ptr tc, + CORBA_ULong code, + CORBA_CompletionStatus completed) + : _minor (code), + _completed (completed), + CORBA_Exception (tc) { } -CORBA_SystemException::~CORBA_SystemException () +CORBA_SystemException::~CORBA_SystemException (void) { } +#define NUM_SYS_EXCEPTIONS 26 // update correctly! +#define TC_BUFLEN 160 // preallocated tc buffer -#define NUM_SYS_EXCEPTIONS 26 // update correctly! -#define TC_BUFLEN 160 // preallocated tc buffer - -static CORBA_TypeCode_ptr sys_exceptions [NUM_SYS_EXCEPTIONS]; -CORBA_ExceptionList __system_exceptions; +static CORBA_TypeCode_ptr sys_exceptions [NUM_SYS_EXCEPTIONS]; +CORBA_ExceptionList __system_exceptions; -// // Make the TypeCode for a standard exception ... note that "buffer" // holds the (unscoped) name originally, and is then overwritten. // // When used correctly, initializing system exceptions is only an // exercise in CPU time; it allocates no new memory. -// + static void -make_standard_typecode ( - CORBA_TypeCode_ptr tcp, - const char *name, - unsigned char *buffer, - size_t buflen, - CORBA_Environment &env -) +make_standard_typecode (CORBA_TypeCode_ptr tcp, + const char *name, + unsigned char *buffer, + size_t buflen, + CORBA_Environment &env) { - static const char *minor = "minor"; - static const char *completion = "completion"; - - static const unsigned long oc_completion_status [] = { - 1, // byte order flag, tricky - 0, 0, // type ID omitted - 3, // three members - 0, 0, // ... whose names are all omitted - 0, 0, - 0, 0 - }; - static CORBA_TypeCode - tc_completion_status (tk_enum, sizeof oc_completion_status, - (unsigned char *)&oc_completion_status, CORBA_B_FALSE); - static const CORBA_TypeCode_ptr completion_status = &tc_completion_status; - - - // - // Create a CDR stream ... juggle the alignment here a bit, we - // know it's good enough for tye typecode. - // - CDR stream (0, buflen); - - stream.next = stream.buffer = buffer; - - // - // into CDR stream, stuff (in order): - // - byte order flag [4 bytes] - // - exception ID [27 + N bytes] - // - exception name [4 + N bytes ] - // - number of members (2) [4 bytes ] - // - foreach member, { name string, typecode } [~40 bytes] - // - char full_id [100], *strptr = (char *) &full_id; - - (void) ACE_OS::sprintf (full_id, "IDL:omg.org/CORBA/%s:1.0", name); - assert (strlen (full_id) <= sizeof full_id); - - if (stream.put_byte (MY_BYTE_SEX) != CORBA_B_TRUE - || CDR::encoder (_tc_CORBA_String, &strptr, 0, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE - || CDR::encoder (_tc_CORBA_String, &name, 0, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE - || stream.put_ulong (2L) != CORBA_B_TRUE - || CDR::encoder (_tc_CORBA_String, &minor, 0, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE - || CDR::encoder (_tc_CORBA_TypeCode, &_tc_CORBA_ULong, 0, - &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE - || CDR::encoder (_tc_CORBA_String, &completion, 0, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE - || CDR::encoder (_tc_CORBA_TypeCode, &completion_status, 0, - &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE) { - env.exception (new CORBA_INITIALIZE (COMPLETED_NO)); - return; - } - - // - // OK, we stuffed the buffer we were given (or grew a bigger one; - // hope to avoid that during initialization). Now build and return - // a TypeCode, saving it away in the list of ones that the ORB will - // always accept as part of any operation response! - // - sys_exceptions [__system_exceptions.length++] - = new (tcp) CORBA_TypeCode (tk_except, - stream.next - stream.buffer, - stream.buffer, CORBA_B_FALSE); - - assert (tcp->_length <= TC_BUFLEN); + static const char *minor = "minor"; + static const char *completion = "completion"; + + static const unsigned long oc_completion_status [] = + { + 1, // byte order flag, tricky + 0, 0, // type ID omitted + 3, // three members + 0, 0, // ... whose names are all omitted + 0, 0, + 0, 0 + }; + static CORBA_TypeCode + tc_completion_status (tk_enum, + sizeof oc_completion_status, + (unsigned char *) &oc_completion_status, + CORBA_B_FALSE); + + static const CORBA_TypeCode_ptr completion_status = &tc_completion_status; + + // Create a CDR stream ... juggle the alignment here a bit, we + // know it's good enough for tye typecode. + + CDR stream (0, buflen); + + stream.next = stream.buffer = buffer; + + // into CDR stream, stuff (in order): + // - byte order flag [4 bytes] + // - exception ID [27 + N bytes] + // - exception name [4 + N bytes ] + // - number of members (2) [4 bytes ] + // - foreach member, { name string, typecode } [~40 bytes] + + char full_id [100], *strptr = (char *) &full_id; + + (void) ACE_OS::sprintf (full_id, "IDL:omg.org/CORBA/%s:1.0", name); + assert (strlen (full_id) <= sizeof full_id); + + if (stream.put_byte (MY_BYTE_SEX) != CORBA_B_TRUE + || CDR::encoder (_tc_CORBA_String, + &strptr, 0, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE + || CDR::encoder (_tc_CORBA_String, + &name, 0, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE + || stream.put_ulong (2L) != CORBA_B_TRUE + || CDR::encoder (_tc_CORBA_String, + &minor, 0, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE + || CDR::encoder (_tc_CORBA_TypeCode, + &_tc_CORBA_ULong, 0, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE + || CDR::encoder (_tc_CORBA_String, + &completion, 0, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE + || CDR::encoder (_tc_CORBA_TypeCode, + &completion_status, 0, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) { + env.exception (new CORBA_INITIALIZE (COMPLETED_NO)); return; + } + + // OK, we stuffed the buffer we were given (or grew a bigger one; + // hope to avoid that during initialization). Now build and return + // a TypeCode, saving it away in the list of ones that the ORB will + // always accept as part of any operation response! + + sys_exceptions [__system_exceptions.length++] + = new (tcp) CORBA_TypeCode (tk_except, + stream.next - stream.buffer, + stream.buffer, CORBA_B_FALSE); + + assert (tcp->_length <= TC_BUFLEN); + return; } +// List of standard/system exceptions ... used to create static +// storage for their typecodes, then later to initialize that storage +// using the routine above. (It's just too painful to init these +// typecodes statically in all cases!) -// -// List of standard/system exceptions ... used to create static storage -// for their typecodes, then later to initialize that storage using the -// routine above. (It's just too painful to init these typecodes -// statically in all cases!) -// #define STANDARD_EXCEPTION_LIST \ SYSEX (UNKNOWN) \ SYSEX (BAD_PARAM) \ @@ -334,13 +310,12 @@ make_standard_typecode ( SYSEX (OBJ_ADAPTER) \ SYSEX (DATA_CONVERSION) -// // Declare static storage for these ... the buffer is "naturally" // aligned and overwritten. // // XXX this actually doesn't guarantee "natural" alignment, but // it works that way in most systems. -// + #define SYSEX(name) \ static long tc_buf_ ## name [TC_BUFLEN / sizeof (long)]; \ static CORBA_TypeCode tc_std_ ## name (tk_except); \ @@ -348,168 +323,158 @@ make_standard_typecode ( STANDARD_EXCEPTION_LIST #undef SYSEX +// Runtime initialization of all standard exception typecodes. Called +// from CORBA::ORB::init(). -// -// Runtime initialization of all standard exception typecodes. -// Called from CORBA::ORB::init(). -// void __TC_init_standard_exceptions (CORBA_Environment &env) { - // - // Initialize the list of system exceptions, used when - // unmarshaling. - // - __system_exceptions.length = 0; - __system_exceptions.maximum = NUM_SYS_EXCEPTIONS; - __system_exceptions.buffer = &sys_exceptions [0]; + // Initialize the list of system exceptions, used when + // unmarshaling. + __system_exceptions.length = 0; + __system_exceptions.maximum = NUM_SYS_EXCEPTIONS; + __system_exceptions.buffer = &sys_exceptions [0]; - // - // Initialize the typecodes. - // + // Initialize the typecodes. #define SYSEX(name) \ - if (env.exception () == 0) \ - make_standard_typecode (&tc_std_ ## name, #name, \ - (unsigned char *) tc_buf_ ## name, \ - sizeof tc_buf_ ## name, env); + if (env.exception () == 0) \ + make_standard_typecode (&tc_std_ ## name, #name, \ + (unsigned char *) tc_buf_ ## name, \ + sizeof tc_buf_ ## name, env); - STANDARD_EXCEPTION_LIST + STANDARD_EXCEPTION_LIST #undef SYSEX -} + } #undef STANDARD_EXCEPTION_LIST -// // Static initialization of the two user-defined exceptions that // are part of the ORB. -// -static CORBA_Octet tc_buf_Bounds [] = { - 0, 0, 0, 0, // big endian, padded - 0, 0, 0, 38, // strlen (id) + 1 - 'I', 'D', 'L', ':', - 'o', 'm', 'g', '.', - 'o', 'r', 'g', '/', - 'C', 'O', 'R', 'B', - 'A', '/', 'T', 'y', - 'p', 'e', 'C', 'o', - 'd', 'e', '/', 'B', - 'o', 'u', 'n', 'd', - 's', ':', '1', '.', - '0', '\0', 0, 0, - 0, 0, 0, 0 // no members to this typecode + +static CORBA_Octet tc_buf_Bounds [] = +{ + 0, 0, 0, 0, // big endian, padded + 0, 0, 0, 38, // strlen (id) + 1 + 'I', 'D', 'L', ':', + 'o', 'm', 'g', '.', + 'o', 'r', 'g', '/', + 'C', 'O', 'R', 'B', + 'A', '/', 'T', 'y', + 'p', 'e', 'C', 'o', + 'd', 'e', '/', 'B', + 'o', 'u', 'n', 'd', + 's', ':', '1', '.', + '0', '\0', 0, 0, + 0, 0, 0, 0 // no members to this typecode }; -static CORBA_TypeCode tc_std_Bounds (tk_except, sizeof tc_buf_Bounds, - tc_buf_Bounds, CORBA_B_FALSE ); + +static CORBA_TypeCode tc_std_Bounds (tk_except, + sizeof tc_buf_Bounds, + tc_buf_Bounds, + CORBA_B_FALSE); + CORBA_TypeCode_ptr _tc_CORBA_Bounds = &tc_std_Bounds; -static CORBA_Octet tc_buf_BadKind [] = { - 0, 0, 0, 0, // big endian, padded - 0, 0, 0, 39, // strlen (id) + 1 - 'I', 'D', 'L', ':', - 'o', 'm', 'g', '.', - 'o', 'r', 'g', '/', - 'C', 'O', 'R', 'B', - 'A', '/', 'T', 'y', - 'p', 'e', 'C', 'o', - 'd', 'e', '/', 'B', - 'a', 'd', 'K', 'i', - 'n', 'd', ':', '1', - '.', '0', '\0', 0, - 0, 0, 0, 0 // no members to this typecode +static CORBA_Octet tc_buf_BadKind [] = +{ + 0, 0, 0, 0, // big endian, padded + 0, 0, 0, 39, // strlen (id) + 1 + 'I', 'D', 'L', ':', + 'o', 'm', 'g', '.', + 'o', 'r', 'g', '/', + 'C', 'O', 'R', 'B', + 'A', '/', 'T', 'y', + 'p', 'e', 'C', 'o', + 'd', 'e', '/', 'B', + 'a', 'd', 'K', 'i', + 'n', 'd', ':', '1', + '.', '0', '\0', 0, + 0, 0, 0, 0 // no members to this typecode }; -static CORBA_TypeCode tc_std_BadKind (tk_except, sizeof tc_buf_BadKind, - tc_buf_BadKind, CORBA_B_FALSE ); -CORBA_TypeCode_ptr _tc_CORBA_BadKind = &tc_std_BadKind; - +static CORBA_TypeCode tc_std_BadKind (tk_except, + sizeof tc_buf_BadKind, + tc_buf_BadKind, + CORBA_B_FALSE); +CORBA_TypeCode_ptr _tc_CORBA_BadKind = &tc_std_BadKind; -// // Convenience -- say if the exception is a system exception or not. -// + CORBA_ExceptionType -CORBA_Environment::exception_type () const +CORBA_Environment::exception_type (void) const { - static char sysex_prefix [] = "IDL:omg.org/CORBA/"; - static char typecode_extra [] = "TypeCode/"; + static char sysex_prefix [] = "IDL:omg.org/CORBA/"; + static char typecode_extra [] = "TypeCode/"; - if (!_exception) - return NO_EXCEPTION; + if (!_exception) + return NO_EXCEPTION; - // - // All exceptions currently (CORBA 2.0) defined in the CORBA - // scope are system exceptions ... except for a couple that - // are related to TypeCodes. - // - char *id = _exception->id (); + // All exceptions currently (CORBA 2.0) defined in the CORBA + // scope are system exceptions ... except for a couple that + // are related to TypeCodes. - if (ACE_OS::strncmp (id, sysex_prefix, sizeof sysex_prefix - 1) == 0 - && ACE_OS::strncmp (id + sizeof sysex_prefix - 1, - typecode_extra, sizeof typecode_extra - 1) != 0) - return SYSTEM_EXCEPTION; + char *id = _exception->id (); - return USER_EXCEPTION; -} + if (ACE_OS::strncmp (id, sysex_prefix, sizeof sysex_prefix - 1) == 0 + && ACE_OS::strncmp (id + sizeof sysex_prefix - 1, + typecode_extra, sizeof typecode_extra - 1) != 0) + return SYSTEM_EXCEPTION; + return USER_EXCEPTION; +} -// // Diagnostic utility routine: describe the exception onto // the standard I/O stream passed as a parameter. // // XXX make this a member function on "Environment" -// + void _EXPFUNC -print_exception ( - const CORBA_Exception *x, - const char *info, - FILE *stream -) +print_exception (const CORBA_Exception *x, + const char *info, + FILE *stream) { - CORBA_String id = x->id (); - - ACE_DEBUG((LM_ERROR, "EXCEPTION, %s\n", info)); - - // - // XXX get rid of this logic, and rely on some member function - // on Exception to say if it's user or system exception. - // - if (ACE_OS::strncmp ((char *) id, "IDL:omg.org/CORBA/", 10) == 0 - && ACE_OS::strncmp ((char *) id, "IDL:omg.org/CORBA/TypeCode/", 19) != 0 - ) { - // - // XXX this should be a QueryInterface call instead - // - CORBA_SystemException *x2 = (CORBA_SystemException *)x; - - // - // XXX there are a other few "user exceptions" in the CORBA scope, - // they're not all standard/system exceptions ... really need - // to either compare exhaustively against all those IDs (yeech) - // or (preferably) to represent the exception type directly in - // the exception value so it can be queried. - // - - ACE_DEBUG((LM_ERROR, "ACE_OS::system exception, ID '%s'\n", id)); - ACE_DEBUG((LM_ERROR, "minor code = %#lx, completed = ", x2->minor ())); - switch (x2->completion ()) { - case COMPLETED_YES: - fputs ("YES", stream); - break; - case COMPLETED_NO: - fputs ("NO", stream); - break; - case COMPLETED_MAYBE: - fputs ("MAYBE", stream); - break; - default: - fputs ("**garbage**", stream); - break; + CORBA_String id = x->id (); + + ACE_DEBUG ((LM_ERROR, "EXCEPTION, %s\n", info)); + + // XXX get rid of this logic, and rely on some member function + // on Exception to say if it's user or system exception. + + if (ACE_OS::strncmp ((char *) id, "IDL:omg.org/CORBA/", 10) == 0 + && ACE_OS::strncmp ((char *) id, "IDL:omg.org/CORBA/TypeCode/", 19) != 0) + { + // XXX this should be a QueryInterface call instead + CORBA_SystemException *x2 = (CORBA_SystemException *) x; + + // XXX there are a other few "user exceptions" in the CORBA + // scope, they're not all standard/system exceptions ... really + // need to either compare exhaustively against all those IDs + // (yeech) or (preferably) to represent the exception type + // directly in the exception value so it can be queried. + + ACE_DEBUG ((LM_ERROR, "ACE_OS::system exception, ID '%s'\n", id)); + ACE_DEBUG ((LM_ERROR, "minor code = %#lx, completed = ", x2->minor ())); + + switch (x2->completion ()) + { + case COMPLETED_YES: + fputs ("YES", stream); + break; + case COMPLETED_NO: + fputs ("NO", stream); + break; + case COMPLETED_MAYBE: + fputs ("MAYBE", stream); + break; + default: + fputs ("**garbage**", stream); + break; } - fputc ('\n', stream); - } else { - // - // XXX we can use the exception's typecode to dump all the data - // held within it ... - // - ACE_DEBUG((LM_ERROR, "user exception, ID '%s'\n", id)); + fputc ('\n', stream); } + else + // XXX we can use the exception's typecode to dump all the data + // held within it ... + + ACE_DEBUG ((LM_ERROR, "user exception, ID '%s'\n", id)); } diff --git a/TAO/IIOP/lib/factories.cpp b/TAO/IIOP/lib/factories.cpp index 1118f62ea4e..70702b486cf 100644 --- a/TAO/IIOP/lib/factories.cpp +++ b/TAO/IIOP/lib/factories.cpp @@ -15,8 +15,8 @@ TAO_Client_Connection_Handler::open(void *) } // Determine the appropriate default thread flags, based on system. -// When I put the concurrency strategy into the factory, then this will -// go away b/c the concurrency strategy will do this appropriate +// When I put the concurrency strategy into the factory, then this +// will go away b/c the concurrency strategy will do this appropriate // for each platform! # if defined(linux) # define ROA_DEFAULT_THREADFLAGS (THR_DETACHED) @@ -29,20 +29,21 @@ TAO_Client_Connection_Handler::open(void *) # endif TAO_Server_Factory::CONCURRENCY_STRATEGY* -TAO_Server_Factory::concurrency_strategy() +TAO_Server_Factory::concurrency_strategy () { - TAO_OA_Parameters* p = TAO_OA_PARAMS::instance(); + TAO_OA_Parameters* p = TAO_OA_PARAMS::instance (); - if (p->using_threads()) + if (p->using_threads ()) { // Set the strategy parameters - threaded_strategy_.open(ACE_Service_Config::thr_mgr(), ROA_DEFAULT_THREADFLAGS); + threaded_strategy_.open (ACE_Service_Config::thr_mgr (), + ROA_DEFAULT_THREADFLAGS); concurrency_strategy_ = &threaded_strategy_; } else { - reactive_strategy_.open(ACE_Service_Config::reactor()); + reactive_strategy_.open (ACE_Service_Config::reactor ()); concurrency_strategy_ = &reactive_strategy_; } @@ -50,47 +51,47 @@ TAO_Server_Factory::concurrency_strategy() } TAO_Object_Table* -TAO_Server_Factory::object_lookup_strategy() +TAO_Server_Factory::object_lookup_strategy (void) { - TAO_OA_Parameters* p = TAO_OA_PARAMS::instance(); + TAO_OA_Parameters* p = TAO_OA_PARAMS::instance (); // Since these are dynamically created, when do they get destroyed? - switch(p->demux_strategy()) + switch (p->demux_strategy ()) { case TAO_OA_Parameters::TAO_LINEAR: - this->objtable_ = new TAO_Linear_ObjTable (p->tablesize()); + this->objtable_ = new TAO_Linear_ObjTable (p->tablesize ()); break; case TAO_OA_Parameters::TAO_USER_DEFINED: // it is assumed that the user would have used the hooks to supply a // user-defined instance of the object table - ACE_ASSERT(this->objtable_ != 0); + ACE_ASSERT (this->objtable_ != 0); break; case TAO_OA_Parameters::TAO_ACTIVE_DEMUX: break; case TAO_OA_Parameters::TAO_DYNAMIC_HASH: default: - this->objtable_ = new TAO_Dynamic_Hash_ObjTable (p->tablesize()); + this->objtable_ = new TAO_Dynamic_Hash_ObjTable (p->tablesize ()); } return this->objtable_; } -TAO_Client_Factory::TAO_Client_Factory() +TAO_Client_Factory::TAO_Client_Factory (void) { - // When should I do this open()? It seems like this is way too early, - // but doing it in the accessor for connector() seems like it would be - // too late as well. - connector_.open(ACE_Service_Config::reactor(), - &null_creation_strategy_, - &caching_connect_strategy_, -#if defined(TAO_HAS_CLIENT_CONCURRENCY) - concurrency_strategy_() + // When should I do this open ()? It seems like this is way too + // early, but doing it in the accessor for connector () seems like + // it would be too late as well. + connector_.open (ACE_Service_Config::reactor (), + &null_creation_strategy_, + &caching_connect_strategy_, +#if defined (TAO_HAS_CLIENT_CONCURRENCY) + concurrency_strategy_ () #else - 0 -#endif - ); + 0 +#endif /* TAO_HAS_CLIENT_CONCURRENCY */ + ); } -#if defined(ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) template class ACE_Thread_Strategy<ROA_Handler>; template class ACE_Concurrency_Strategy<ROA_Handler>; template class ACE_Reactive_Strategy<ROA_Handler>; @@ -101,4 +102,4 @@ template class ACE_Accept_Strategy<ROA_Handler, ACE_SOCK_ACCEPTOR>; template class ACE_Cached_Connect_Strategy<CLIENT_HANDLER, ACE_SOCK_STREAM, ACE_SYNCH_RW_MUTEX>; template class ACE_NOOP_Creation_Strategy<CLIENT_HANDLER>; template class ACE_Strategy_Connector<CLIENT_HANDLER, ACE_SOCK_STREAM>; -#endif +#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */ diff --git a/TAO/IIOP/lib/factories.i b/TAO/IIOP/lib/factories.i index cab82fa4614..7a6b238aca0 100644 --- a/TAO/IIOP/lib/factories.i +++ b/TAO/IIOP/lib/factories.i @@ -1,63 +1,56 @@ ACE_INLINE -TAO_Client_Connection_Handler::TAO_Client_Connection_Handler(ACE_Thread_Manager* thrmgr) - : in_use_(0) +TAO_Client_Connection_Handler::TAO_Client_Connection_Handler (ACE_Thread_Manager* thrmgr) + : in_use_ (0) { } -ACE_INLINE -CORBA_Boolean -TAO_Client_Connection_Handler::in_use(void) +ACE_INLINE CORBA_Boolean +TAO_Client_Connection_Handler::in_use (void) { return in_use_; } -ACE_INLINE -void -TAO_Client_Connection_Handler::in_use(CORBA_Boolean flag) +ACE_INLINE void +TAO_Client_Connection_Handler::in_use (CORBA_Boolean flag) { in_use_ = flag; } -ACE_INLINE -TAO_Server_Factory::CREATION_STRATEGY* -TAO_Server_Factory::creation_strategy() +ACE_INLINE TAO_Server_Factory::CREATION_STRATEGY * +TAO_Server_Factory::creation_strategy (void) { return 0; } -ACE_INLINE -TAO_Server_Factory::ACCEPT_STRATEGY* -TAO_Server_Factory::accept_strategy() +ACE_INLINE TAO_Server_Factory::ACCEPT_STRATEGY * +TAO_Server_Factory::accept_strategy (void) { return 0; } -ACE_INLINE -TAO_Server_Factory::SCHEDULING_STRATEGY* -TAO_Server_Factory::scheduling_strategy() +ACE_INLINE TAO_Server_Factory::SCHEDULING_STRATEGY * +TAO_Server_Factory::scheduling_strategy (void) { return 0; } -#if defined(TAO_HAS_CLIENT_CONCURRENCY) -ACE_INLINE -TAO_Client_Factory::CONCURRENCY_STRATEGY* -TAO_Client_Factory::concurrency_strategy() +#if defined (TAO_HAS_CLIENT_CONCURRENCY) +ACE_INLINE TAO_Client_Factory::CONCURRENCY_STRATEGY * +TAO_Client_Factory::concurrency_strategy (void) { return 0; } -#endif +#endif /* TAO_HAS_CLIENT_CONCURRENCY */ ACE_INLINE -TAO_Server_Factory::TAO_Server_Factory() - : concurrency_strategy_(0), - objtable_(0) +TAO_Server_Factory::TAO_Server_Factory (void) + : concurrency_strategy_ (0), + objtable_ (0) { } -ACE_INLINE -void -TAO_Server_Factory::object_lookup_strategy(TAO_Object_Table *ot) +ACE_INLINE void +TAO_Server_Factory::object_lookup_strategy (TAO_Object_Table *ot) { this->objtable_ = ot; // we assume ownership } diff --git a/TAO/IIOP/lib/giop.cpp b/TAO/IIOP/lib/giop.cpp index d3450ca770b..4c1e5f957ae 100644 --- a/TAO/IIOP/lib/giop.cpp +++ b/TAO/IIOP/lib/giop.cpp @@ -4,38 +4,41 @@ // // GIOP: Utility routines for sending, receiving GIOP messages // -// Note that the Internet IOP is just the TCP-specific mapping of -// the General IOP. Areas where other protocols may map differently +// Note that the Internet IOP is just the TCP-specific mapping of the +// General IOP. Areas where other protocols may map differently // include use of record streams (TCP has none), orderly disconnect // (TCP has it), endpoint addressing (TCP uses host + port), security // (Internet security should be leveraged by IIOP) and more. // -// NOTE: There are a few places where this code knows that it's really -// talking IIOP instead of GIOP. No rush to fix this so long as we are -// really not running atop multiple connection protocols. +// NOTE: There are a few places where this code knows that it's really +// talking IIOP instead of GIOP. No rush to fix this so long as we +// are really not running atop multiple connection protocols. // -// THREADING NOTE: currently, the connection manager eliminates tricky -// threading issues by providing this code with the same programming model -// both in threaded and unthreaded environments. Since the GIOP APIs were -// all designed to be reentrant, this makes threading rather simple! +// THREADING NOTE: currently, the connection manager eliminates tricky +// threading issues by providing this code with the same programming +// model both in threaded and unthreaded environments. Since the GIOP +// APIs were all designed to be reentrant, this makes threading rather +// simple! // -// That threading model is that the thread making (or handling) a call is -// given exclusive access to a connection for the duration of a call, so -// that no multiplexing or demultiplexing is needed. That is, locking is -// at the "connection level" rather than "message level". +// That threading model is that the thread making (or handling) a call +// is given exclusive access to a connection for the duration of a +// call, so that no multiplexing or demultiplexing is needed. That +// is, locking is at the "connection level" rather than "message +// level". // // The down side of this simple threading model is that utilization of -// system resources (mostly connections, but to some extent network I/O) -// in some kinds of environments can be inefficient. However, simpler -// threading models are much easier to get properly debugged, and often -// perform better. Also, such environments haven't been seen to be any -// kind of problem; the model can be changed later if needed, it's just an -// internal implementation detail. Any portable ORB client is not allowed -// to rely on semantic implications of such a model. -// -// XXX there is lots of unverified I/O here. In all cases, if an error -// is detected when marshaling or unmarshaling, it should be reported. +// system resources (mostly connections, but to some extent network +// I/O) in some kinds of environments can be inefficient. However, +// simpler threading models are much easier to get properly debugged, +// and often perform better. Also, such environments haven't been +// seen to be any kind of problem; the model can be changed later if +// needed, it's just an internal implementation detail. Any portable +// ORB client is not allowed to rely on semantic implications of such +// a model. // +// XXX there is lots of unverified I/O here. In all cases, if an +// error is detected when marshaling or unmarshaling, it should be +// reported. #include <assert.h> #include <limits.h> @@ -45,16 +48,12 @@ #include "ace/SOCK_Stream.h" +// @@ Are the following #include's necessary if we use ACE? + #if (unix) || defined (VXWORKS) # include <sys/types.h> # include <sys/socket.h> -#if 0 - // Use normal file I/O where possible, it's better tuned. -# define send(s,buf,len,zero) write(s,buf,len) -# define recv(s,buf,len,zero) read(s,buf,len) -#endif - #else # include <winsock.h> @@ -67,62 +66,66 @@ #include "thread.h" #include "giop.h" +// defined by GIOP 1.0 protocol +#define TAO_GIOP_HEADER_LEN 12 -#define GIOP_HDR_LEN 12 // defined by GIOP 1.0 protocol - - -// // Apart from the length word, headers are specified to be arrays of // bytes. They're dealt with as such, rather than using CDR routines, // to speed up the critical paths for message read and write. -// + static inline CORBA_Boolean -start_message ( - GIOP::MsgType type, - CDR &msg -) +start_message (GIOP::MsgType type, + CDR &msg) { - msg.next = msg.buffer; // for reused streams - msg.remaining = msg.length; + msg.next = msg.buffer; // for reused streams + msg.remaining = msg.length; - if (msg.bytes_remaining () < GIOP_HDR_LEN) - return CORBA_B_FALSE; + if (msg.bytes_remaining () < TAO_GIOP_HEADER_LEN) + return CORBA_B_FALSE; - msg.next [0] = 'G'; - msg.next [1] = 'I'; - msg.next [2] = 'O'; - msg.next [3] = 'P'; + msg.next [0] = 'G'; + msg.next [1] = 'I'; + msg.next [2] = 'O'; + msg.next [3] = 'P'; - msg.next [4] = GIOP::MY_MAJOR; - msg.next [5] = GIOP::MY_MINOR; - msg.next [6] = MY_BYTE_SEX; - msg.next [7] = (unsigned char) type; + msg.next [4] = GIOP::MY_MAJOR; + msg.next [5] = GIOP::MY_MINOR; + msg.next [6] = MY_BYTE_SEX; + msg.next [7] = (u_char) type; - msg.skip_bytes (GIOP_HDR_LEN); - return CORBA_B_TRUE; + msg.skip_bytes (TAO_GIOP_HEADER_LEN); + return CORBA_B_TRUE; } #ifdef DEBUG static const char digits [] = "0123456789ABCD"; -static const char *names [] = { - "Request", "Reply", "CancelRequest", - "LocateRequest", "LocateReply", - "CloseConnection", "MessageError" +static const char *names [] = +{ + "Request", + "Reply", + "CancelRequest", + "LocateRequest", + "LocateReply", + "CloseConnection", + "MessageError" }; static void -dump_msg (const char *label, const unsigned char *ptr, size_t len) +dump_msg (const char *label, + const u_char *ptr, + size_t len) { - if (debug_level >= 2) { - dmsg_v ("%s GIOP v%c.%c msg, %d data bytes, %s endian, %s\n", - label, digits [ptr [4]], digits [ptr [5]], - len - GIOP_HDR_LEN, - (ptr [6] == MY_BYTE_SEX) ? "my" : "other", - (ptr [7] <= GIOP::MessageError) - ? names [ptr [7]] : "UNKNOWN TYPE"); - - if (debug_level >= 4) - dmsg_opaque_full("data bytes", ptr, len); + if (debug_level >= 2) + { + dmsg_v ("%s GIOP v%c.%c msg, %d data bytes, %s endian, %s\n", + label, digits [ptr [4]], digits [ptr [5]], + len - TAO_GIOP_HEADER_LEN, + (ptr [6] == MY_BYTE_SEX) ? "my" : "other", + (ptr [7] <= GIOP::MessageError) + ? names [ptr [7]] : "UNKNOWN TYPE"); + + if (debug_level >= 4) + dmsg_opaque_full("data bytes", ptr, len); } } @@ -131,204 +134,215 @@ dump_msg (const char *label, const unsigned char *ptr, size_t len) #endif // !DEBUG CORBA_Boolean -GIOP::send_message(CDR& stream, ACE_SOCK_Stream& peer) +GIOP::send_message (CDR &stream, + ACE_SOCK_Stream &peer) { - ACE_HANDLE h = peer.get_handle(); - CORBA_Boolean r = send_message(stream, h); - peer.set_handle(h); + ACE_HANDLE h = peer.get_handle (); + + CORBA_Boolean r = send_message (stream, h); + peer.set_handle (h); return r; } CORBA_Boolean -GIOP::send_message (CDR& stream, ACE_HANDLE& connection) +GIOP::send_message (CDR &stream, + ACE_HANDLE &connection) { - char *buf = (char *) stream.buffer; - size_t buflen = stream.next - stream.buffer; - int writelen; - - assert (buflen == (stream.length - stream.remaining)); + char *buf = (char *) stream.buffer; + size_t buflen = stream.next - stream.buffer; + int writelen; - // - // Patch the message length in the GIOP header; it's always at the - // same eight byte offset into the message. - // - // NOTE: Here would also be a fine place to calculate a digital - // signature for the message and place it into a preallocated - // slot in the "ServiceContext". Similarly, this is a good spot - // to encrypt messages (or just the message bodies) if that's - // needed in this particular environment and that isn't handled - // by the networking infrastructure (e.g. IPSEC). - // - *(CORBA_Long *)(stream.buffer + 8) = - (CORBA_Long) (buflen - GIOP_HDR_LEN); + assert (buflen == (stream.length - stream.remaining)); - // - // Strictly speaking, should not need to loop here because the - // socket never gets set to a nonblocking mode ... some Linux - // versions seem to need it though. Leaving it costs little. - // - dump_msg ("send", stream.buffer, buflen); - while (buflen > 0) { - if (buflen > stream.length) { - dmsg2 ("?? writebuf, buflen %u > length %u\n", - buflen, stream.length); - return CORBA_B_FALSE; + // Patch the message length in the GIOP header; it's always at the + // same eight byte offset into the message. + // + // NOTE: Here would also be a fine place to calculate a digital + // signature for the message and place it into a preallocated slot + // in the "ServiceContext". Similarly, this is a good spot to + // encrypt messages (or just the message bodies) if that's needed in + // this particular environment and that isn't handled by the + // networking infrastructure (e.g. IPSEC). + + *(CORBA_Long *) (stream.buffer + 8) = + (CORBA_Long) (buflen - TAO_GIOP_HEADER_LEN); + + // Strictly speaking, should not need to loop here because the + // socket never gets set to a nonblocking mode ... some Linux + // versions seem to need it though. Leaving it costs little. + + dump_msg ("send", stream.buffer, buflen); + while (buflen > 0) + { + if (buflen > stream.length) + { + dmsg2 ("?? writebuf, buflen %u > length %u\n", + buflen, stream.length); + return CORBA_B_FALSE; } - writelen = ACE::send (connection, (char _FAR *) buf, buflen); + + writelen = ACE::send (connection, (char _FAR *) buf, buflen); #ifdef DEBUG - dmsg_filter (6, "wrote %d bytes to connection %d", - writelen, connection); + dmsg_filter (6, "wrote %d bytes to connection %d", + writelen, connection); #endif // DEBUG - assert ((writelen >= 0 && - ((size_t)writelen) <= buflen) || writelen == -1); + assert ((writelen >= 0 + && ((size_t)writelen) <= buflen) || writelen == -1); - // - // On error or EOF, report the fault, close the connection, and - // mark it as unusable/defunct. - // - // XXX on client side write errors, we may hit the case that - // the server did a clean shutdown but we've not yet read the - // GIOP::CloseConnection message. If we get an error, we need - // to see if there is such a message waiting for us, and if so - // we should cause (full) rebinding to take place. - // - if (writelen == -1) { - dsockerr ("OutgoingMessage::writebuf()"); - dmsg1 ("closing conn %d after fault", connection); - ACE_OS::closesocket (connection); - connection = ACE_INVALID_HANDLE; - return CORBA_B_FALSE; - } else if (writelen == 0) { - dmsg1 ("OutgoingMessage::writebuf() ... EOF, closing conn %d", - connection); - ACE_OS::closesocket (connection); - connection = ACE_INVALID_HANDLE; - return CORBA_B_FALSE; + // On error or EOF, report the fault, close the connection, and + // mark it as unusable/defunct. + // + // XXX on client side write errors, we may hit the case that + // the server did a clean shutdown but we've not yet read the + // GIOP::CloseConnection message. If we get an error, we need + // to see if there is such a message waiting for us, and if so + // we should cause (full) rebinding to take place. + + if (writelen == -1) + { + dsockerr ("OutgoingMessage::writebuf ()"); + dmsg1 ("closing conn %d after fault", connection); + ACE_OS::closesocket (connection); + connection = ACE_INVALID_HANDLE; + return CORBA_B_FALSE; + } + else if (writelen == 0) + { + dmsg1 ("OutgoingMessage::writebuf () ... EOF, closing conn %d", + connection); + ACE_OS::closesocket (connection); + connection = ACE_INVALID_HANDLE; + return CORBA_B_FALSE; } - if ((buflen -= writelen) != 0) - buf += writelen; + if ((buflen -= writelen) != 0) + buf += writelen; #ifdef DEBUG - // - // NOTE: this should never be seen. However, on Linux - // it's been seen with UNIX domain sockets. - // - if (buflen) - dmsg_filter (8, "%u more bytes to write...\n", buflen); + // + // NOTE: this should never be seen. However, on Linux + // it's been seen with UNIX domain sockets. + // + if (buflen) + dmsg_filter (8, "%u more bytes to write...\n", buflen); #endif } - return CORBA_B_TRUE; + return CORBA_B_TRUE; } - -// -// Server sends an "I'm shutting down now, any requests you've sent me +// Server sends an "I'm shutting down now, any requests you've sent me // can be retried" message to the server. The message is prefab, for // simplicity. // -// NOTE: this is IIOP-specific though it doesn't look like it is. It -// relies on a TCP-ism: orderly disconnect, which doesn't exist in all +// NOTE: this is IIOP-specific though it doesn't look like it is. It +// relies on a TCP-ism: orderly disconnect, which doesn't exist in all // transport protocols. Versions of GIOP atop some transport that's // lacking orderly disconnect must define some transport-specific -// handshaking (e.g. the XNS/SPP handshake convention) in order to know -// that the same transport semantics are provided when shutdown is begun -// with messages "in flight". (IIOP doesn't report false errors in the -// case of "clean shutdown", because it relies on orderly disconnect as -// provided by TCP. This quality of service is required to write robust -// distributed systems.) -// +// handshaking (e.g. the XNS/SPP handshake convention) in order to +// know that the same transport semantics are provided when shutdown +// is begun with messages "in flight". (IIOP doesn't report false +// errors in the case of "clean shutdown", because it relies on +// orderly disconnect as provided by TCP. This quality of service is +// required to write robust distributed systems.) + static const char -close_message [GIOP_HDR_LEN] = { - 'G', 'I', 'O', 'P', - GIOP::MY_MAJOR, GIOP::MY_MINOR, MY_BYTE_SEX, GIOP::CloseConnection, - 0, 0, 0, 0 +close_message [TAO_GIOP_HEADER_LEN] = +{ + 'G', 'I', 'O', 'P', + GIOP::MY_MAJOR, + GIOP::MY_MINOR, + MY_BYTE_SEX, + GIOP::CloseConnection, + 0, 0, 0, 0 }; - void -GIOP::close_connection (ACE_SOCK_Stream& peer, void* unused) +GIOP::close_connection (ACE_SOCK_Stream &peer, + void *unused) { - ACE_HANDLE h = peer.get_handle(); - close_connection(h, unused); - peer.set_handle(h); + ACE_HANDLE h = peer.get_handle (); + close_connection (h, unused); + peer.set_handle (h); } void -GIOP::close_connection (ACE_HANDLE& fd, void* unused) +GIOP::close_connection (ACE_HANDLE &handle, + void *unused) { - // - // It's important that we use a reliable shutdown after we send - // this message, so we know it's received. - // - // XXX should recv and discard queued data for portability; note - // that this won't block (long) since we never set SO_LINGER - // - dump_msg ("send", (const unsigned char *) close_message, GIOP_HDR_LEN); - (void) ACE::send (fd, close_message, GIOP_HDR_LEN); - (void) ACE_OS::shutdown (fd, 2); - (void) ACE_OS::closesocket (fd); - dmsg1 ("shut down socket %d", fd); - fd = ACE_INVALID_HANDLE; + // It's important that we use a reliable shutdown after we send + // this message, so we know it's received. + // + // XXX should recv and discard queued data for portability; note + // that this won't block (long) since we never set SO_LINGER + + dump_msg ("send", (const u_char *) close_message, TAO_GIOP_HEADER_LEN); + (void) ACE::send (handle, close_message, TAO_GIOP_HEADER_LEN); + (void) ACE_OS::shutdown (handle, 2); + (void) ACE_OS::closesocket (handle); + dmsg1 ("shut down socket %d", handle); + handle = ACE_INVALID_HANDLE; } -// // Send an "I can't understand you" message -- again, the message is -// prefabricated for simplicity. This implies abortive disconnect -// (at the application level, if not at the level of TCP). +// prefabricated for simplicity. This implies abortive disconnect (at +// the application level, if not at the level of TCP). // // NOTE that IIOP will still benefit from TCP's orderly disconnect. -// + static const char -error_message [GIOP_HDR_LEN] = { - 'G', 'I', 'O', 'P', - GIOP::MY_MAJOR, GIOP::MY_MINOR, MY_BYTE_SEX, GIOP::MessageError, - 0, 0, 0, 0 +error_message [TAO_GIOP_HEADER_LEN] = +{ + 'G', 'I', 'O', 'P', + GIOP::MY_MAJOR, + GIOP::MY_MINOR, + MY_BYTE_SEX, + GIOP::MessageError, + 0, 0, 0, 0 }; static inline void -send_error (ACE_HANDLE &fd) +send_error (ACE_HANDLE &handle) { - dump_msg ("send", (const unsigned char *) error_message, GIOP_HDR_LEN); - (void) ACE::send (fd, error_message, GIOP_HDR_LEN); - (void) ACE_OS::shutdown (fd, 2); - (void) ACE_OS::closesocket (fd); - dmsg1 ("aborted socket %d", fd); - fd = ACE_INVALID_HANDLE; + dump_msg ("send", (const u_char *) error_message, TAO_GIOP_HEADER_LEN); + (void) ACE::send (handle, error_message, TAO_GIOP_HEADER_LEN); + (void) ACE_OS::shutdown (handle, 2); + (void) ACE_OS::closesocket (handle); + dmsg1 ("aborted socket %d", handle); + handle = ACE_INVALID_HANDLE; } static inline void -send_error(ACE_SOCK_Stream& peer) +send_error (ACE_SOCK_Stream &peer) { - ACE_HANDLE h = peer.get_handle(); - send_error(h); - peer.set_handle(h); + ACE_HANDLE h = peer.get_handle (); + send_error (h); + peer.set_handle (h); } +// @@ Can't we remove this stuff and replace it with recv_n() on the +// <peer>? -// // Loop on data read ... this is required with some implementations of -// sockets (e.g. winsock, HP/UX) since even when async mode is not set, -// recv() won't block until the requested amount of data is available. -// +// sockets (e.g. winsock, HP/UX) since even when async mode is not +// set, recv () won't block until the requested amount of data is +// available. + static int -read_buffer ( - ACE_SOCK_Stream& peer, - char* buf, - size_t len -) +read_buffer (ACE_SOCK_Stream &peer, + char *buf, + size_t len) { int bytes_read = 0; while (len != 0) { - int retval; + int retval; - retval = peer.recv(buf, len); + retval = peer.recv (buf, len); #ifdef DEBUG - dmsg_filter (6, "read %d bytes from connection: %d", retval, peer.get_handle()); + dmsg_filter (6, "read %d bytes from connection: %d", retval, peer.get_handle ()); #endif if (retval <= 0) // EOF or error return retval; @@ -341,841 +355,827 @@ read_buffer ( return bytes_read; } - -// // Read the message header, plus any data part of the message, setting -// stuff up so that CDR byteswaps data as appropriate. Errors are reported -// to be MessageError messages. -// -// NOTE: this code is structured to issue two read() calls for each -// incoming message. Alternative structures (e.g. with a user-space buffer -// per connection, or networking code handing off entire GIOP messages) can -// reduce the overhead of these calls to the networking code; correctness -// and simplicity drove this implementation more than efficiency. +// stuff up so that CDR byteswaps data as appropriate. Errors are +// reported to be MessageError messages. // -// NOTE: as always, counting system calls associated with I/O gives you -// a good basic understanding of the tuning issues. On the server side, -// there is normally select/read/read/write per invocation. The call to -// select() can be omitted by allocating a thread to each connection; in -// some cases, that alone has almost doubled performance. The two read() -// calls can be made into one by fancy buffering. How fast could it be -// with both optimizations applied? +// NOTE: this code is structured to issue two read () calls for each +// incoming message. Alternative structures (e.g. with a user-space +// buffer per connection, or networking code handing off entire GIOP +// messages) can reduce the overhead of these calls to the networking +// code; correctness and simplicity drove this implementation more +// than efficiency. // +// NOTE: as always, counting system calls associated with I/O gives +// you a good basic understanding of the tuning issues. On the server +// side, there is normally select/read/read/write per invocation. The +// call to select () can be omitted by allocating a thread to each +// connection; in some cases, that alone has almost doubled +// performance. The two read () calls can be made into one by fancy +// buffering. How fast could it be with both optimizations applied? + GIOP::MsgType -GIOP::read_message (ACE_HANDLE& fd, CDR& msg, CORBA_Environment& env) +GIOP::read_message (ACE_HANDLE &handle, + CDR &msg, + CORBA_Environment &env) { ACE_SOCK_Stream s; - s.set_handle(fd); - return read_message(s, msg, env); + s.set_handle (handle); + return read_message (s, msg, env); } GIOP::MsgType -GIOP::read_message (ACE_SOCK_Stream& connection, CDR& msg, CORBA_Environment& env) +GIOP::read_message (ACE_SOCK_Stream &connection, + CDR &msg, + CORBA_Environment &env) { GIOP::MsgType retval; - CORBA_ULong message_size; + CORBA_ULong message_size; - // // Read the message header off the wire. // - // THREADING NOTE: the connection manager handed us this connection + // THREADING NOTE: the connection manager handed us this connection // for exclusive use, so we need not worry about having two threads // interleave reads of partial messages. This model is excellent // for "lightly threaded" systems (as will be the majority in the // near future) but makes less effective use of connection resources // as the "duty factor" goes down because of either long calls or // bursty contention during numerous short calls to the same server. - // - assert (msg.length > GIOP_HDR_LEN); - msg.next = msg.buffer; - msg.remaining = GIOP_HDR_LEN; + assert (msg.length > TAO_GIOP_HEADER_LEN); - char *bufptr = (char _FAR *) msg.buffer; - int len; + msg.next = msg.buffer; + msg.remaining = TAO_GIOP_HEADER_LEN; - // + char *bufptr = (char _FAR *) msg.buffer; + int len = read_buffer (connection, bufptr, TAO_GIOP_HEADER_LEN); // Read the header into the buffer. - // - if ((len = read_buffer (connection, bufptr, GIOP_HDR_LEN)) - != GIOP_HDR_LEN) { - if (len == 0) { // EOF - dmsg1 ("Header EOF ... peer probably aborted connection %d", - connection); - return EndOfFile; - // XXX should probably find some way to report this without - // an exception, since for most servers it's not an error. - // Is it _never_ an error? Not sure ... - // - } else if (len < 0) { // error - dsockerr ("GIOP::read_message header"); - } else { // short read ... - dmsg ("read message header failed (short)"); + + if (len != TAO_GIOP_HEADER_LEN) + { + if (len == 0) + { // EOF + dmsg1 ("Header EOF ... peer probably aborted connection %d", + connection); + return EndOfFile; + // XXX should probably find some way to report this without + // an exception, since for most servers it's not an error. + // Is it _never_ an error? Not sure ... + // + } + else if (len < 0) // error + dsockerr ("GIOP::read_message header"); + else // short read ... + dmsg ("read message header failed (short)"); + + env.exception (new CORBA_COMM_FAILURE (COMPLETED_MAYBE)); + return MessageError; } - env.exception (new CORBA_COMM_FAILURE (COMPLETED_MAYBE)); - return MessageError; - } - // - // NOTE: if message headers, or whome messages, get encrypted in + // NOTE: if message headers, or whome messages, get encrypted in // application software (rather than by the network infrastructure) - // they should be decrypted here ... - // + // they should be decrypted here ... - // // First make sure it's a GIOP message of any version. - // - if (!(msg.buffer [0] == 'G' && msg.buffer [1] == 'I' - && msg.buffer [2] == 'O' && msg.buffer [3] == 'P')) { - env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); // header - dmsg ("bad header, magic word"); - return MessageError; - } - // - // Then make sure the major version is ours, and the minor version is - // one that we understand. - // - if (!(msg.buffer [4] == MY_MAJOR && msg.buffer [5] <= MY_MINOR)) { - env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); // header - dmsg ("bad header, version"); - return MessageError; - } + if (!(msg.buffer [0] == 'G' + && msg.buffer [1] == 'I' + && msg.buffer [2] == 'O' + && msg.buffer [3] == 'P')) + { + env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); // header + dmsg ("bad header, magic word"); + return MessageError; + } + + // Then make sure the major version is ours, and the minor version + // is one that we understand. + + if (!(msg.buffer [4] == MY_MAJOR && msg.buffer [5] <= MY_MINOR)) + { + env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); // header + dmsg ("bad header, version"); + return MessageError; + } - // // Get the message type out and adjust the buffer's records to record // that we've read everything except the length. - // - retval = (GIOP::MsgType) msg.buffer [7]; + + retval = (GIOP::MsgType) msg.buffer[7]; msg.skip_bytes (8); - // - // Make sure byteswapping is done if needed, and then read the message - // size (appropriately byteswapped). - // + // Make sure byteswapping is done if needed, and then read the + // message size (appropriately byteswapped). + msg.do_byteswap = (msg.buffer [6] != MY_BYTE_SEX); msg.get_ulong (message_size); + // Make sure we have the full length in memory, growing the buffer + // if needed. // - // Make sure we have the full length in memory, growing the - // buffer if needed. - // - // NOTE: We could overwrite these few bytes of header... they're + // NOTE: We could overwrite these few bytes of header... they're // left around for now as a debugging aid. - // + assert (message_size <= UINT_MAX); - if ((GIOP_HDR_LEN + message_size) > msg.length) - msg.grow ((size_t) (GIOP_HDR_LEN + message_size)); + if ((TAO_GIOP_HEADER_LEN + message_size) > msg.length) + msg.grow ((size_t) (TAO_GIOP_HEADER_LEN + message_size)); msg.remaining = (size_t) message_size; - bufptr = (char *) & msg.buffer [GIOP_HDR_LEN]; + bufptr = (char *) & msg.buffer [TAO_GIOP_HEADER_LEN]; - // // Read the rest of this message into the buffer. - // - if ((len = read_buffer (connection, bufptr, (size_t) message_size)) - != (int) message_size) { - if (len == 0) { - dmsg1 ("read message body, EOF on fd %d", connection); - } else if (len < 0) { - dperror ("GIOP::read_message() body"); - } else { - dmsg2 ("short read, only %d of %d bytes", len, message_size); - } - // clean up, and ... - env.exception (new CORBA_COMM_FAILURE (COMPLETED_MAYBE)); // body - dmsg ("couldn't read rest of message"); - return MessageError; - } + len = read_buffer (connection, bufptr, (size_t) message_size); - dump_msg ("recv", msg.buffer, (size_t)(message_size + GIOP_HDR_LEN)); + if (len != (int) message_size) + { + if (len == 0) + dmsg1 ("read message body, EOF on handle %d", connection); + else if (len < 0) + dperror ("GIOP::read_message () body"); + else + dmsg2 ("short read, only %d of %d bytes", len, message_size); + + // clean up, and ... + env.exception (new CORBA_COMM_FAILURE (COMPLETED_MAYBE)); // body + dmsg ("couldn't read rest of message"); + return MessageError; + } + + dump_msg ("recv", msg.buffer, (size_t) (message_size + TAO_GIOP_HEADER_LEN)); return retval; } - -// // Normal invocations don't involve any heap allocation; messages are -// constructed into stack-based buffers and are read into those buffers -// too. Larger buffers are heap-allocated as needed. +// constructed into stack-based buffers and are read into those +// buffers too. Larger buffers are heap-allocated as needed. // // The constraint on request IDs is that no two requests from the same -// client with the same ID are outstanding at the same time. In single -// threaded environments, this is met by any number whatever. When -// multiple threads are used, we eliminate the need for any locked state -// by using the thread ID as the request ID, since any given thread -// has at most one request outstanding at a time. -// -// NOTE: this means that if "deferred synchronous" calls get supported, -// it's done by creating a thread internally to make the call. That is -// less disruptive (and error prone) in general than restructuring an ORB -// core in terms of asynchrony. +// client with the same ID are outstanding at the same time. In +// single threaded environments, this is met by any number whatever. +// When multiple threads are used, we eliminate the need for any +// locked state by using the thread ID as the request ID, since any +// given thread has at most one request outstanding at a time. // - -GIOP::Invocation::Invocation ( - IIOP_Object *data, - const char *operation, - CORBA_Boolean is_roundtrip -) : - _data (data), - opname (operation), - do_rsvp (is_roundtrip), - stream (&buffer [0], sizeof buffer) +// NOTE: this means that if "deferred synchronous" calls get +// supported, it's done by creating a thread internally to make the +// call. That is less disruptive (and error prone) in general than +// restructuring an ORB core in terms of asynchrony. + +GIOP::Invocation::Invocation (IIOP_Object *data, + const char *operation, + CORBA_Boolean is_roundtrip) + : _data (data), + opname (operation), + do_rsvp (is_roundtrip), + stream (&buffer [0], sizeof buffer) { // The assumption that thread ids are ints is false and horribly // implementation-dependent, so this code just sucks. But, at least - // it will compile on multiple platforms through the magic of ACE :-/ + // it will compile on multiple platforms through the magic of ACE + // :-/ //assert (sizeof (CORBA_ULong) == sizeof (ACE_thread_t)); - ACE_thread_t me = ACE_OS::thr_self(); + ACE_thread_t me = ACE_OS::thr_self (); my_request_id = 0; // Copy in only as many bytes are valid, or only as many as we have - // room for, whichever is less. - // -------> What a friggin' HACK!?!?! - memcpy(&my_request_id, &me, ACE_MIN(sizeof(me), sizeof(my_request_id))); + // room for, whichever is less. -------> What a friggin' HACK!?!?! + memcpy (&my_request_id, &me, ACE_MIN (sizeof (me), sizeof (my_request_id))); } -GIOP::Invocation::~Invocation () +GIOP::Invocation::~Invocation (void) { - handle_.in_use(CORBA_B_FALSE); + handle_.in_use (CORBA_B_FALSE); } +// Octet codes for the parameters of the "Opaque" (sequence of octet) +// data type used various places internally ... a CDR encapsulation +// holding two parameters (like all sequence TypeCodes). // -// Octet codes for the parameters of the "Opaque" (sequence of octet) data -// type used various places internally ... a CDR encapsulation holding two -// parameters (like all sequence TypeCodes). -// -// NOTE: this **MUST** be longword aligned, which is why it's coded as a -// longword array not an octet array. Just sticking a long in for padding -// won't work with compilers that optimize unused data out of existence. -// -static const CORBA_Long _oc_opaque [] = { // CDR typecode octets - 1, // native endian + padding; "tricky" - 10, // ... (sequence of) octets - 0 // ... unbounded +// NOTE: this **MUST** be longword aligned, which is why it's coded as +// a longword array not an octet array. Just sticking a long in for +// padding won't work with compilers that optimize unused data out of +// existence. + +static const CORBA_Long _oc_opaque [] = +{ // CDR typecode octets + 1, // native endian + padding; "tricky" + 10, // ... (sequence of) octets + 0 // ... unbounded }; -CORBA_TypeCode TC_opaque (tk_sequence, - sizeof _oc_opaque, (unsigned char *) &_oc_opaque, - CORBA_B_FALSE); - +CORBA_TypeCode TC_opaque (tk_sequence, + sizeof _oc_opaque, + (u_char *) &_oc_opaque, + CORBA_B_FALSE); + +// Octet codes for the parameters of the ServiceContextList TypeCode +// ... this is a CDR encapsulation holding two parameters (like all +// sequences): a TypeCode, and the bounds of the sequence (zero in +// this case). // -// Octet codes for the parameters of the ServiceContextList TypeCode ... -// this is a CDR encapsulation holding two parameters (like all sequences): -// a TypeCode, and the bounds of the sequence (zero in this case). -// -// This is complicated since the Typecode for the data type for the sequence -// members is complex, a structure that nests two further typecodes (one is -// a sequence). +// This is complicated since the Typecode for the data type for the +// sequence members is complex, a structure that nests two further +// typecodes (one is a sequence). // // NOTE: this must be longword aligned! -// -static const CORBA_Long _oc_svc_ctx_list [] = { - // START bytes of encapsulation 0 - 1, // native endian + padding; "tricky" - // - // FIRST sequence param: typecode for struct is complex, - // and so uses a nested encapsulation. - // - tk_struct, - 72, // length of encapsulation 1 +static const CORBA_Long _oc_svc_ctx_list [] = +{ + // START bytes of encapsulation 0 + 1, // native endian + padding; "tricky" - // START bytes of encapsulation 1 (struct params) - 1, // native endian + padding; "tricky" - 1, 0, // type ID omitted: null string - 1, 0, // name omitted "ServiceContext" + // + // FIRST sequence param: typecode for struct is complex, + // and so uses a nested encapsulation. + // + tk_struct, + 72, // length of encapsulation 1 - 2, // two struct elements + // START bytes of encapsulation 1 (struct params) + 1, // native endian + padding; "tricky" + 1, 0, // type ID omitted: null string + 1, 0, // name omitted "ServiceContext" - // - // First structure element: name, typecode for ULong - // - // NOTE: to be more strictly correct this could be a tk_alias - // typecode ... - // - 1, 0, // name omitted: "context_id" - tk_long, + 2, // two struct elements - // - // Second structure element: name, typecode for sequence of octet; - // the typecode for sequence of octet is complex, there's a second - // level of nested encapuslation here. - // - 1, 0, // name omitted: "context_data" - tk_sequence, // sequence typecode - 16, // length of encapsulation 2 + // First structure element: name, typecode for ULong + // + // NOTE: to be more strictly correct this could be a tk_alias + // typecode ... - // START bytes of encapsulation 2 (sequence params) - 1, // native endian + padding; "tricky" - 1, 0, // type ID omitted: null string - tk_octet, // (sequence of) octet - 0, // ... unbounded length - // END bytes of encapsulation 2 (sequence params) + 1, 0, // name omitted: "context_id" + tk_long, - // END bytes of encapsulation 1 (struct params) + // Second structure element: name, typecode for sequence of octet; + // the typecode for sequence of octet is complex, there's a second + // level of nested encapuslation here. - // - // SECOND sequence param: bound of sequence (none) - // - 0 // unbounded seq of ServiceContext - // END bytes of encapsulation 0 (sequence params) + 1, 0, // name omitted: "context_data" + tk_sequence, // sequence typecode + 16, // length of encapsulation 2 + + // START bytes of encapsulation 2 (sequence params) + 1, // native endian + padding; "tricky" + 1, 0, // type ID omitted: null string + tk_octet, // (sequence of) octet + 0, // ... unbounded length + // END bytes of encapsulation 2 (sequence params) + + // END bytes of encapsulation 1 (struct params) + + // SECOND sequence param: bound of sequence (none) + 0 // unbounded seq of ServiceContext + // END bytes of encapsulation 0 (sequence params) }; -static CORBA_TypeCode TC_ServiceContextList (tk_sequence, - sizeof _oc_svc_ctx_list, (unsigned char *) &_oc_svc_ctx_list, - CORBA_B_FALSE); +static CORBA_TypeCode TC_ServiceContextList (tk_sequence, + sizeof _oc_svc_ctx_list, + (u_char *) &_oc_svc_ctx_list, + CORBA_B_FALSE); -// // The public API involves creating an invocation, starting it, filling // in request parameters, actually performing the invocation, getting // response parameters, and then cleaning up. Sometimes they must be // restarted (e.g. request forwarding). This is the start/restart entry. -// + void -GIOP::Invocation::start ( - CORBA_Environment &env -) +GIOP::Invocation::start (CORBA_Environment &env) { - const opaque *key; + const opaque *key; + + // First try to bind to the appropriate address. We do that here + // since we may get forwarded to a different objref in the course of + // any given call, with new start () call each time. It's not + // cached in the objref data since the connections change + // asynchronously from objref invocations and this simplifies + // connection management. + // + // THREADING NOTE: this connection is reserved to this call. Also, + // starting at this point in the call, new forwarding information + // will not be used until/unless the call is reissued. Correctness + // is not affected, the call will just be forwarded later than it + // might be in a more complex implementation. - // - // First try to bind to the appropriate address. We do that here since - // we may get forwarded to a different objref in the course of any - // given call, with new start() call each time. It's not cached in - // the objref data since the connections change asynchronously from - // objref invocations and this simplifies connection management. - // - // THREADING NOTE: this connection is reserved to this call. Also, - // starting at this point in the call, new forwarding information will - // not be used until/unless the call is reissued. Correctness is not - // affected, the call will just be forwarded later than it might be - // in a more complex implementation. - // - assert (endpoint == 0); - assert (_data != 0); + assert (endpoint == 0); + assert (_data != 0); - ACE_GUARD(ACE_Thread_Mutex, guard, lock_); + ACE_GUARD (ACE_Thread_Mutex, guard, lock_); -#if !defined(USE_OLD_CODE) - // Get a CORBA_Object_ptr from _data using QueryInterface() - CORBA_Object_ptr obj = 0; +#if !defined (USE_OLD_CODE) + // Get a CORBA_Object_ptr from _data using QueryInterface () + CORBA_Object_ptr obj = 0; - (void) _data->QueryInterface (IID_CORBA_Object, (void **)&obj); + (void) _data->QueryInterface (IID_CORBA_Object, (void **)&obj); - // Get a pointer to the orb from the object - CORBA_ORB_ptr orb = obj->orb(); + // Get a pointer to the orb from the object + CORBA_ORB_ptr orb = obj->orb (); - // Get a reference to the client connector - TAO_Client_Factory::CONNECTOR* con = 0; - con = (orb->client_factory()).connector(); + // Get a reference to the client connector + TAO_Client_Factory::CONNECTOR* con = 0; + con = (orb->client_factory ()).connector (); - // Determine the object key and the address to which we'll need a connection - ACE_INET_Addr server_addr; + // Determine the object key and the address to which we'll need a connection + ACE_INET_Addr server_addr; - if (data_->fwd_profile != 0) - { - key = &data_->fwd_profile->object_key; - server_addr.set(data_->fwd_profile->port, data_->fwd_profile->host); - } - else - { - key = &data_->profile.object_key; - server_addr.set(data_->profile.port, data_->profile.host); - } + if (data_->fwd_profile != 0) + { + key = &data_->fwd_profile->object_key; + server_addr.set (data_->fwd_profile->port, data_->fwd_profile->host); + } + else + { + key = &data_->profile.object_key; + server_addr.set (data_->profile.port, data_->profile.host); + } - // Establish the connection and get back a Client_Connection_Handler - if (con->connect(handler_, server_addr) == -1) - { - // @@ Need to figure out which exception to set...this one - // is pretty vague. - env.exception (new CORBA_COMM_FAILURE (COMPLETED_NO)); - } + // Establish the connection and get back a Client_Connection_Handler + if (con->connect (handler_, server_addr) == -1) + // @@ Need to figure out which exception to set...this one is + // pretty vague. + env.exception (new CORBA_COMM_FAILURE (COMPLETED_NO)); - // Use the ACE_SOCK_Stream from the Client_Connection_Handler - // for communication inplace of the endpoint used below. + // Use the ACE_SOCK_Stream from the Client_Connection_Handler for + // communication inplace of the endpoint used below. #else - if (_data->fwd_profile != 0) { - key = &_data->fwd_profile->object_key; - endpoint = client_endpoint::lookup ( - (char *)_data->fwd_profile->host, - _data->fwd_profile->port, env); - } else { - key = &_data->profile.object_key; - endpoint = client_endpoint::lookup ( - (char *)_data->profile.host, - _data->profile.port, env); + if (_data->fwd_profile != 0) + { + key = &_data->fwd_profile->object_key; + endpoint = client_endpoint::lookup ((char *)_data->fwd_profile->host, + _data->fwd_profile->port, env); + } + else + { + key = &_data->profile.object_key; + endpoint = client_endpoint::lookup ((char *)_data->profile.host, + _data->profile.port, env); } - if (env.exception () != 0) { - dexc (env, "invoke, lookup client endpoint"); - return; + if (env.exception () != 0) + { + dexc (env, "invoke, lookup client endpoint"); + return; } #endif - // - // POLICY DECISION: If the client expects most agents to forward, then - // it could try to make sure that it's been forwarded at least once by - // eliciting it with a LocateRequest message. (Further hinting in the - // IIOP::ProfileData could help!) - // - // That scenario does not match an "Inter" ORB Protocol well, since - // bridges chain calls rather than forwarding them. It does match - // some kinds of "Intra" ORB scenarios well, with many agents that - // spawn new processes talking to their clients across the net. - // - // At this time, the policy noted above is followed in the sense - // that this software does NOT expect most agents to forward, so it - // doesn't bother to probe. Correctness is not affected; this is - // only a quality-of-service policy. It affects mostly performance, - // but the "best efforts" semantics for "oneway" messages would also - // be impacted in that some (by definition, buggy!) code which used - // only "oneway" messages might not work at all. - // + // POLICY DECISION: If the client expects most agents to forward, + // then it could try to make sure that it's been forwarded at least + // once by eliciting it with a LocateRequest message. (Further + // hinting in the IIOP::ProfileData could help!) + // + // That scenario does not match an "Inter" ORB Protocol well, since + // bridges chain calls rather than forwarding them. It does match + // some kinds of "Intra" ORB scenarios well, with many agents that + // spawn new processes talking to their clients across the net. + // + // At this time, the policy noted above is followed in the sense + // that this software does NOT expect most agents to forward, so it + // doesn't bother to probe. Correctness is not affected; this is + // only a quality-of-service policy. It affects mostly performance, + // but the "best efforts" semantics for "oneway" messages would also + // be impacted in that some (by definition, buggy!) code which used + // only "oneway" messages might not work at all. - // - // Build the outgoing message, starting with generic GIOP header. - // - CORBA_Boolean bt = start_message(Request, stream); - if (bt != CORBA_B_TRUE) { - env.exception (new CORBA_MARSHAL (COMPLETED_NO)); - return; + // Build the outgoing message, starting with generic GIOP header. + + CORBA_Boolean bt = start_message (Request, stream); + + if (bt != CORBA_B_TRUE) + { + env.exception (new CORBA_MARSHAL (COMPLETED_NO)); + return; } - // - // Then fill in the rest of the RequestHeader - // - // The first element of header is service context list; transactional - // context would be acquired here using the transaction service APIs. - // Other kinds of context are as yet undefined. - // - // Last element of request header is the principal; no portable way - // to get it, we just pass empty principal (convention: indicates - // "anybody"). Steps upward in security include passing an unverified - // user ID, and then verifying the message (i.e. a dummy service context - // entry is set up to hold a digital signature for this message, then - // patched shortly before it's sent). - // - static CORBA_Principal_ptr anybody = 0; - static ServiceContextList svc_ctx; // all zeroes + // Then fill in the rest of the RequestHeader + // + // The first element of header is service context list; + // transactional context would be acquired here using the + // transaction service APIs. Other kinds of context are as yet + // undefined. + // + // Last element of request header is the principal; no portable way + // to get it, we just pass empty principal (convention: indicates + // "anybody"). Steps upward in security include passing an + // unverified user ID, and then verifying the message (i.e. a dummy + // service context entry is set up to hold a digital signature for + // this message, then patched shortly before it's sent). + // + static CORBA_Principal_ptr anybody = 0; + static ServiceContextList svc_ctx; // all zeroes - if (CDR::encoder (&TC_ServiceContextList, 0, &svc_ctx, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE) - return; + if (CDR::encoder (&TC_ServiceContextList, 0, &svc_ctx, &stream, env) + != CORBA_TypeCode::TRAVERSE_CONTINUE) + return; - if (!stream.put_ulong (my_request_id) || !stream.put_boolean (do_rsvp)) { - env.exception (new CORBA_MARSHAL (COMPLETED_NO)); - return; + if (!stream.put_ulong (my_request_id) + || !stream.put_boolean (do_rsvp)) + { + env.exception (new CORBA_MARSHAL (COMPLETED_NO)); + return; } - if (CDR::encoder (&TC_opaque, key, 0, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE - || CDR::encoder (_tc_CORBA_String, &opname, 0, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE - || CDR::encoder (_tc_CORBA_Principal, &anybody, 0, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE) - return; // right after fault - else - return; // no fault reported + if (CDR::encoder (&TC_opaque, + key, 0, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE + || CDR::encoder (_tc_CORBA_String, + &opname, 0, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE + || CDR::encoder (_tc_CORBA_Principal, + &anybody, 0, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) + return; // right after fault + else + return; // no fault reported } -extern CORBA_ExceptionList __system_exceptions; +extern CORBA_ExceptionList __system_exceptions; + +// Send request, block until any reply comes back, and unmarshal reply +// parameters as appropriate. -// -// Send request, block until any reply comes back, and unmarshal -// reply parameters as appropriate. -// GIOP::ReplyStatusType -GIOP::Invocation::invoke ( - CORBA_ExceptionList &exceptions, - CORBA_Environment &env -) +GIOP::Invocation::invoke (CORBA_ExceptionList &exceptions, + CORBA_Environment &env) { - // - // Send Request, return on error or if we're done - // - if (!GIOP::send_message (stream, endpoint->fd)) { - // - // send_message() closed the connection; we just release it here. - // - // XXX highly desirable to know whether we wrote _any_ data; if - // we wrote none, then there's no chance the call completed and - // applications don't have to deal with those nasty indeterminate - // states where they can't immediatly tell if what's safe to do. - // - // XXX also, there might have been a GIOP::CloseConnection message - // in the input queue. If so, this request should be treated as - // a (full) "rebind" case. Can't do that from this point in the - // code however! Some minor restructuring needs to happen. - // - endpoint = 0; - env.exception (new CORBA_COMM_FAILURE (COMPLETED_MAYBE)); - return SYSTEM_EXCEPTION; + // Send Request, return on error or if we're done + + if (!GIOP::send_message (stream, endpoint->fd)) + { + // send_message () closed the connection; we just release it here. + // + // XXX highly desirable to know whether we wrote _any_ data; if + // we wrote none, then there's no chance the call completed and + // applications don't have to deal with those nasty + // indeterminate states where they can't immediatly tell if + // what's safe to do. + // + // XXX also, there might have been a GIOP::CloseConnection + // message in the input queue. If so, this request should be + // treated as a (full) "rebind" case. Can't do that from this + // point in the code however! Some minor restructuring needs to + // happen. + // + endpoint = 0; + env.exception (new CORBA_COMM_FAILURE (COMPLETED_MAYBE)); + return SYSTEM_EXCEPTION; } - if (!do_rsvp) - return NO_EXCEPTION; + if (!do_rsvp) + return NO_EXCEPTION; - // - // This blocks until the response is read. In the current version, - // there is only one client thread that ever uses this connection, so - // most response messages are illegal. - // - // THREADING NOTE: to make more efficient use of connection resources, - // we'd multiplex I/O on connections. For example, one thread would write - // its GIOP::Request (or GIOP::LocateRequest etc) message and block for - // the response, then another would do the same thing. When a response - // came back, it would be handed to the thread which requested it. - // - // Currently the connection manager doesn't support such fine grained - // connection locking, and also this server implementation wouldn't - // take advantage of that potential concurrency in requests either. - // There are often performance losses coming from fine-grained locks - // being used inappropriately; there's some evidence that locking at - // the level of requests loses on at least some platforms. - // - // XXX In all MT environments, there's a cancellation point lurking - // here; need to investigate. Client threads would frequently be - // canceled sometime during read_message ... the correct action to - // take on being canceled is to issue a CancelRequest message to - // the server and then imediately let other client-side cancellation - // handlers do their jobs. - // - // In C++, that basically means to unwind the stack using almost normal - // procedures: all destructors should fire, and some "catch" blocks - // should probably be able to handle things like releasing pointers. - // (Without unwinding the C++ stack, resources that must be freed by - // thread cancellation won't be freed, and the process won't continue - // to function correctly.) The tricky part is that according to POSIX, - // all C stack frames must also have their (explicitly coded) handlers - // called. We assume a POSIX.1c/C/C++ environment. - // - switch (GIOP::read_message (endpoint->fd, stream, env)) { - case Reply: - // handle reply ... must be right one etc - break; + // This blocks until the response is read. In the current version, + // there is only one client thread that ever uses this connection, + // so most response messages are illegal. + // + // THREADING NOTE: to make more efficient use of connection + // resources, we'd multiplex I/O on connections. For example, one + // thread would write its GIOP::Request (or GIOP::LocateRequest etc) + // message and block for the response, then another would do the + // same thing. When a response came back, it would be handed to the + // thread which requested it. + // + // Currently the connection manager doesn't support such fine + // grained connection locking, and also this server implementation + // wouldn't take advantage of that potential concurrency in requests + // either. There are often performance losses coming from + // fine-grained locks being used inappropriately; there's some + // evidence that locking at the level of requests loses on at least + // some platforms. + // + // XXX In all MT environments, there's a cancellation point lurking + // here; need to investigate. Client threads would frequently be + // canceled sometime during read_message ... the correct action to + // take on being canceled is to issue a CancelRequest message to the + // server and then imediately let other client-side cancellation + // handlers do their jobs. + // + // In C++, that basically means to unwind the stack using almost + // normal procedures: all destructors should fire, and some "catch" + // blocks should probably be able to handle things like releasing + // pointers. (Without unwinding the C++ stack, resources that must + // be freed by thread cancellation won't be freed, and the process + // won't continue to function correctly.) The tricky part is that + // according to POSIX, all C stack frames must also have their + // (explicitly coded) handlers called. We assume a POSIX.1c/C/C++ + // environment. + // + switch (GIOP::read_message (endpoint->fd, stream, env)) + { + case Reply: + // handle reply ... must be right one etc + break; - case CloseConnection: - // - // Special case of forwarding -- server was closing the connection, - // which just indicates resource constraints, not an error. The - // client is effectively "forwarded" to the same server! - // - // However, we must reinitialize the forwarding chain, since the - // resource being reclaimed might also have been the process, not - // just the connection. Without reinitializing, we'd give false - // error reports to applications. - // - { - ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, SYSTEM_EXCEPTION); + case CloseConnection: + // Special case of forwarding -- server was closing the + // connection, which just indicates resource constraints, not an + // error. The client is effectively "forwarded" to the same + // server! + // + // However, we must reinitialize the forwarding chain, since the + // resource being reclaimed might also have been the process, + // not just the connection. Without reinitializing, we'd give + // false error reports to applications. + { + ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, lock_, SYSTEM_EXCEPTION); - delete _data->fwd_profile; - _data->fwd_profile = 0; + delete _data->fwd_profile; + _data->fwd_profile = 0; - (void) ACE_OS::closesocket (endpoint->fd); - endpoint->fd = ACE_INVALID_HANDLE; - endpoint = 0; - return LOCATION_FORWARD; - } + (void) ACE_OS::closesocket (endpoint->fd); + endpoint->fd = ACE_INVALID_HANDLE; + endpoint = 0; + return LOCATION_FORWARD; + } - case Request: - case CancelRequest: - case LocateRequest: - case LocateReply: - default: - // - // These are all illegal messages to find. If found, they could be - // indicative of client bugs (lost track of input stream) or server - // bugs; maybe the request was acted on, maybe not, we can't tell. - // - dmsg ("illegal message in response to my Request!"); - env.exception (new CORBA_COMM_FAILURE (COMPLETED_MAYBE)); - // FALLTHROUGH ... + case Request: + case CancelRequest: + case LocateRequest: + case LocateReply: + default: + // These are all illegal messages to find. If found, they could + // be indicative of client bugs (lost track of input stream) or + // server bugs; maybe the request was acted on, maybe not, we + // can't tell. + dmsg ("illegal message in response to my Request!"); + env.exception (new CORBA_COMM_FAILURE (COMPLETED_MAYBE)); + // FALLTHROUGH ... - case MessageError: - // - // Couldn't read it for some reason ... exception's set already, - // so just tell the other end about the trouble (closing the - // connection) and return. - // - send_error (endpoint->fd); - return SYSTEM_EXCEPTION; + case MessageError: + // Couldn't read it for some reason ... exception's set already, + // so just tell the other end about the trouble (closing the + // connection) and return. + send_error (endpoint->fd); + return SYSTEM_EXCEPTION; } - // - // Process reply message. Again, due to the single threading in this - // code, only the reply to this request is allowed to be coming back. - // - // NOTE: if the response really _isn't_ for this thread, it's now - // treated as an error in which synchronization can't be recovered. - // There might be cases where it _could_ be recovered ... e.g. maybe - // for some reason the previous call couldn't pick up its response. - // It'd be worth investigating (and handling) any such cases. - // - // NOTE: since this implementation supports no ORB services (notably, - // the transaction service, which is the only one that's currently - // defined), the reply context is discarded. Normally it'd be fed, - // component at a time, to the relevant services. - // - // NOTE: As security support kicks in, this is the right place to - // verify a digital signature, if that is required in this particular - // runtime security environment. How to know if that's the case? - // It's likely that standard Internet IPSEC infrastructure (RFC 1825 - // through 1827, and successors) will be used to enforce many security - // policies; integrity and privacy guarantees may be provided by the - // network, and need no support here. - // - ServiceContextList reply_ctx; - CORBA_ULong request_id; - CORBA_ULong reply_status; // GIOP::ReplyStatusType - - if (CDR::decoder (&TC_ServiceContextList, &reply_ctx, 0, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE) { - send_error (endpoint->fd); - return SYSTEM_EXCEPTION; + // Process reply message. Again, due to the single threading in + // this code, only the reply to this request is allowed to be coming + // back. + // + // NOTE: if the response really _isn't_ for this thread, it's now + // treated as an error in which synchronization can't be recovered. + // There might be cases where it _could_ be recovered ... e.g. maybe + // for some reason the previous call couldn't pick up its response. + // It'd be worth investigating (and handling) any such cases. + // + // NOTE: since this implementation supports no ORB services + // (notably, the transaction service, which is the only one that's + // currently defined), the reply context is discarded. Normally + // it'd be fed, component at a time, to the relevant services. + // + // NOTE: As security support kicks in, this is the right place to + // verify a digital signature, if that is required in this + // particular runtime security environment. How to know if that's + // the case? It's likely that standard Internet IPSEC + // infrastructure (RFC 1825 through 1827, and successors) will be + // used to enforce many security policies; integrity and privacy + // guarantees may be provided by the network, and need no support + // here. + + ServiceContextList reply_ctx; + CORBA_ULong request_id; + CORBA_ULong reply_status; // GIOP::ReplyStatusType + + if (CDR::decoder (&TC_ServiceContextList, &reply_ctx, 0, &stream, env) + != CORBA_TypeCode::TRAVERSE_CONTINUE) + { + send_error (endpoint->fd); + return SYSTEM_EXCEPTION; } - delete reply_ctx.buffer; + delete reply_ctx.buffer; - if (!stream.get_ulong (request_id) - || request_id != my_request_id - || !stream.get_ulong (reply_status) - || reply_status > LOCATION_FORWARD) { - send_error (endpoint->fd); - env.exception (new CORBA_COMM_FAILURE (COMPLETED_MAYBE)); - dmsg ("bad Response header"); - return SYSTEM_EXCEPTION; + if (!stream.get_ulong (request_id) + || request_id != my_request_id + || !stream.get_ulong (reply_status) + || reply_status > LOCATION_FORWARD) + { + send_error (endpoint->fd); + env.exception (new CORBA_COMM_FAILURE (COMPLETED_MAYBE)); + dmsg ("bad Response header"); + return SYSTEM_EXCEPTION; } - // - // If there was no exception, let the caller parse the normal response. - // Otherwise parse and handle the response; we always know how to deal - // with the standard exceptions, and the caller provides a list of - // allowed user-defined exceptions so that we know how to unmarshal - // those too (without IFR consultation). - // - // When requests are forwarded, we just store the revised profile data - // in this objref structure. The expectation is that the call will - // be reissued until someone gives up on a forwarding chain, and that - // other calls will reap the benefit of the forwarding work by this - // thread. - // - // NOTE: should ensure that from here on, all system exceptions - // return COMPLETED_YES status ... even ones reported by code which - // we call. - // - switch (reply_status) { - case NO_EXCEPTION: - break; - - case USER_EXCEPTION: - case SYSTEM_EXCEPTION: - { - CORBA_String exception_id; - - // - // Pull the exception ID out of the marshaling buffer. - // + // If there was no exception, let the caller parse the normal + // response. Otherwise parse and handle the response; we always + // know how to deal with the standard exceptions, and the caller + // provides a list of allowed user-defined exceptions so that we + // know how to unmarshal those too (without IFR consultation). + // + // When requests are forwarded, we just store the revised profile + // data in this objref structure. The expectation is that the call + // will be reissued until someone gives up on a forwarding chain, + // and that other calls will reap the benefit of the forwarding work + // by this thread. + // + // NOTE: should ensure that from here on, all system exceptions + // return COMPLETED_YES status ... even ones reported by code which + // we call. + + switch (reply_status) + { + case NO_EXCEPTION: + break; + + case USER_EXCEPTION: + case SYSTEM_EXCEPTION: + { + CORBA_String exception_id; + + // Pull the exception ID out of the marshaling buffer. + { + CORBA_ULong len; + + // + // Read "length" field of string, so "next" points + // right at the null-terminated ID. Then get the ID. + // + if (stream.get_ulong (len) != CORBA_B_TRUE + || len > stream.remaining) { - CORBA_ULong len; - - // - // Read "length" field of string, so "next" points - // right at the null-terminated ID. Then get the ID. - // - if (stream.get_ulong (len) != CORBA_B_TRUE - || len > stream.remaining) { - send_error (endpoint->fd); - env.exception (new CORBA_MARSHAL (COMPLETED_YES)); - return SYSTEM_EXCEPTION; - } - exception_id = (CORBA_String) stream.next; - stream.skip_bytes (len); + send_error (endpoint->fd); + env.exception (new CORBA_MARSHAL (COMPLETED_YES)); + return SYSTEM_EXCEPTION; } + exception_id = (CORBA_String) stream.next; + stream.skip_bytes (len); + } - // - // User and system exceptions differ only in what table of - // exception typecodes is searched. - // - CORBA_ExceptionList *xlist; - - if (reply_status == USER_EXCEPTION) - xlist = &exceptions; - else - xlist = &__system_exceptions; - - // - // Find it in the operation description and then use that to get - // the typecode. Use it to unmarshal the exception's value; if - // that exception is not allowed by this operation, fail (next). - // - unsigned i; - CORBA_TypeCode_ptr *tcp; - - for (i = 0, tcp = xlist->buffer; - i < xlist->length; - i++, tcp++) { - CORBA_String xid; - - xid = (*tcp)->id (env); - if (env.exception () != 0) { - dexc (env, "invoke(), get exception ID"); - send_error (endpoint->fd); - return SYSTEM_EXCEPTION; - } + // User and system exceptions differ only in what table of + // exception typecodes is searched. + CORBA_ExceptionList *xlist; - if (strcmp ((char *)exception_id, (char *)xid) == 0) { - size_t size; - CORBA_Exception *exception; + if (reply_status == USER_EXCEPTION) + xlist = &exceptions; + else + xlist = &__system_exceptions; - size = (*tcp)->size (env); - if (env.exception () != 0) { - dexc (env, "invoke(), get exception size"); - send_error (endpoint->fd); - return SYSTEM_EXCEPTION; - } + // Find it in the operation description and then use that to get + // the typecode. Use it to unmarshal the exception's value; if + // that exception is not allowed by this operation, fail (next). - // - // Create the exception, fill in the generic parts - // such as vtable, typecode ptr, refcount ... we - // need to clean them all up together, in case of - // errors unmarshaling. - // - exception = new (new char [size]) CORBA_Exception (*tcp); - - if (CDR::decoder (*tcp, exception, 0, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE) { - delete exception; - dmsg2 ("invoke, unmarshal %s exception %s", - (reply_status == USER_EXCEPTION) - ? "user" : "system", - exception_id); - send_error (endpoint->fd); - return SYSTEM_EXCEPTION; - } - env.exception (exception); - return (GIOP::ReplyStatusType) reply_status; - } - } + u_int i; + CORBA_TypeCode_ptr *tcp; - // - // If we couldn't find this exception's typecode, report it as - // an OA error since the skeleton passed an exception that was - // not allowed by the operation's IDL definition. In the case - // of a dynamic skeleton it's actually an implementation bug. - // - // It's known to be _very_ misleading to try reporting this as - // any kind of marshaling error (unless minor codes are made - // to be _very_ useful) ... folk try to find/fix ORB bugs that - // don't exist, not bugs in/near the implementation code. - // - if (reply_status == USER_EXCEPTION) - env.exception (new CORBA_OBJ_ADAPTER (COMPLETED_YES)); - else - env.exception (new CORBA_INTERNAL (COMPLETED_MAYBE)); - return SYSTEM_EXCEPTION; - } - // NOTREACHED + for (i = 0, tcp = xlist->buffer; + i < xlist->length; + i++, tcp++) + { + CORBA_String xid; - case LOCATION_FORWARD: - { - CORBA_Object_ptr obj; - IIOP_Object *obj2; - - // - // Unmarshal the object we _should_ be calling. We know - // that one of the facets of this object will be an IIOP - // invocation profile. - // - if (CDR::decoder (_tc_CORBA_Object, &obj, 0, &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE - || obj->QueryInterface (IID_IIOP_Object, (void **)&obj2) != NOERROR) + xid = (*tcp)->id (env); + if (env.exception () != 0) { - dexc (env, "invoke, location forward"); + dexc (env, "invoke (), get exception ID"); send_error (endpoint->fd); return SYSTEM_EXCEPTION; } - CORBA_release (obj); - - // - // Make a copy of the IIOP profile in the forwarded objref, - // reusing memory where practical. Then delete the forwarded - // objref, retaining only its profile. - // - // XXX add and use a "forward count", to prevent loss of data - // in forwarding chains during concurrent calls -- only a - // forward that's a response to the current fwd_profile should - // be recorded here. (This is just an optimization, and is - // not related to correctness.) - // - ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, SYSTEM_EXCEPTION); - - delete _data->fwd_profile; - _data->fwd_profile = new IIOP::ProfileBody (obj2->profile); - - obj2->Release (); - - env.clear (); - - // - // Make sure a new connection is used next time. - // - endpoint = 0; - } - break; + + if (ACE_OS::strcmp ((char *)exception_id, (char *)xid) == 0) + { + size_t size; + CORBA_Exception *exception; + + size = (*tcp)->size (env); + if (env.exception () != 0) + { + dexc (env, "invoke (), get exception size"); + send_error (endpoint->fd); + return SYSTEM_EXCEPTION; + } + + // Create the exception, fill in the generic parts + // such as vtable, typecode ptr, refcount ... we need + // to clean them all up together, in case of errors + // unmarshaling. + + exception = new (new char [size]) CORBA_Exception (*tcp); + + if (CDR::decoder (*tcp, exception, 0, &stream, env) + != CORBA_TypeCode::TRAVERSE_CONTINUE) + { + delete exception; + dmsg2 ("invoke, unmarshal %s exception %s", + (reply_status == USER_EXCEPTION) + ? "user" : "system", + exception_id); + send_error (endpoint->fd); + return SYSTEM_EXCEPTION; + } + env.exception (exception); + return (GIOP::ReplyStatusType) reply_status; + } + } + + // If we couldn't find this exception's typecode, report it as + // an OA error since the skeleton passed an exception that was + // not allowed by the operation's IDL definition. In the case + // of a dynamic skeleton it's actually an implementation bug. + // + // It's known to be _very_ misleading to try reporting this as + // any kind of marshaling error (unless minor codes are made + // to be _very_ useful) ... folk try to find/fix ORB bugs that + // don't exist, not bugs in/near the implementation code. + + if (reply_status == USER_EXCEPTION) + env.exception (new CORBA_OBJ_ADAPTER (COMPLETED_YES)); + else + env.exception (new CORBA_INTERNAL (COMPLETED_MAYBE)); + return SYSTEM_EXCEPTION; + } + // NOTREACHED + + case LOCATION_FORWARD: + { + CORBA_Object_ptr obj; + IIOP_Object *obj2; + + // Unmarshal the object we _should_ be calling. We know that + // one of the facets of this object will be an IIOP invocation + // profile. + + if (CDR::decoder (_tc_CORBA_Object, + &obj, 0, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE + || obj->QueryInterface (IID_IIOP_Object, + (void **)&obj2) != NOERROR) + { + dexc (env, "invoke, location forward"); + send_error (endpoint->fd); + return SYSTEM_EXCEPTION; + } + CORBA_release (obj); + + // Make a copy of the IIOP profile in the forwarded objref, + // reusing memory where practical. Then delete the forwarded + // objref, retaining only its profile. + // + // XXX add and use a "forward count", to prevent loss of data + // in forwarding chains during concurrent calls -- only a + // forward that's a response to the current fwd_profile should + // be recorded here. (This is just an optimization, and is not + // related to correctness.) + + ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, lock_, SYSTEM_EXCEPTION); + + delete _data->fwd_profile; + _data->fwd_profile = new IIOP::ProfileBody (obj2->profile); + + obj2->Release (); + + env.clear (); + + // + // Make sure a new connection is used next time. + // + endpoint = 0; + } + break; } - // - // All standard exceptions from here on in the call path know for certain - // that the call "completed" ... except in the case of system exceptions - // which say otherwise, and for LOCATION_FORWARD responses. - // - return (GIOP::ReplyStatusType) reply_status; -} + // All standard exceptions from here on in the call path know for + // certain that the call "completed" ... except in the case of + // system exceptions which say otherwise, and for LOCATION_FORWARD + // responses. + return (GIOP::ReplyStatusType) reply_status; +} -// // Generic server side read + dispatch one message; returns when that // bit of work is complete. // // In the typical case, the request and response buffers live on the // stack so that the heap never gets used. These grow if needed. -// -int GIOP::incoming_message(ACE_SOCK_Stream& peer, - ForwardFunc check_forward, - RequestHandler handle_request, - void* context, - CORBA_Environment& env) -/*int -GIOP::incoming_message ( - ACE_SOCK_Stream& peer, - LocateStatusType check_forward ( - opaque &key, - CORBA_Object_ptr &objref, - void *context - ), - void handle_request ( - RequestHeader &req, - CDR &req_body, - CDR *reply, - void *context, - CORBA_Environment &env - ), - void *context, - CORBA_Environment &env -) + +int GIOP::incoming_message (ACE_SOCK_Stream &peer, + ForwardFunc check_forward, + RequestHandler handle_request, + void *context, + CORBA_Environment &env) + /* +int +GIOP::incoming_message (ACE_SOCK_Stream &peer, + LocateStatusType check_forward (opaque &key, + CORBA_Object_ptr &objref, + void *context), + void handle_request (RequestHeader &req, + CDR &req_body, + CDR *reply, + void *context, + CORBA_Environment &env), + void *context, + CORBA_Environment &env) */ { int retval = 1; // 1==success, 0==eof, -1==error - unsigned char buffer [CDR::DEFAULT_BUFSIZE]; - CDR msg (&buffer [0], sizeof buffer); + u_char buffer [CDR::DEFAULT_BUFSIZE]; + CDR msg (&buffer [0], sizeof buffer); switch (read_message (peer, msg, env)) { - // - // These messages should never be sent to the server; it's an error - // if the peer tries. Set the environment accordingly, as it's not - // yet been reported as an error. - // + // These messages should never be sent to the server; it's an + // error if the peer tries. Set the environment accordingly, as + // it's not yet been reported as an error. case Reply: case LocateReply: case CloseConnection: @@ -1184,13 +1184,12 @@ GIOP::incoming_message ( env.exception (new CORBA_COMM_FAILURE (COMPLETED_NO)); // FALLTHROUGH + // read_message () has already set some error in the environment + // for all "MessageError" cases, so don't clobber it. // - // read_message() has already set some error in the environment for - // all "MessageError" cases, so don't clobber it. - // - // General error recovery is to send MessageError to the peer just - // in case (it'll fail on EOF) and then close the connection. - // + // General error recovery is to send MessageError to the peer + // just in case (it'll fail on EOF) and then close the + // connection. case MessageError: retval = -1; send_error (peer); @@ -1203,142 +1202,167 @@ GIOP::incoming_message ( // This is the common case! case Request: { - RequestHeader req; - CORBA_Boolean hdr_status; + RequestHeader req; + CORBA _Boolean hdr_status; - // // Tear out the service context ... we currently ignore it, // but it should probably be passed to each ORB service as // appropriate (e.g. transactions, security). // - // NOTE: As security support kicks in, this is a good place - // to verify a digital signature, if that is required in this + // NOTE: As security support kicks in, this is a good place to + // verify a digital signature, if that is required in this // security environment. It may be required even when using // IPSEC security infrastructure. - // + hdr_status = CDR::decoder (&TC_ServiceContextList, - &req.service_info, 0, &msg, env); + &req.service_info, + 0, + &msg, + env); - // // Get the rest of the request header ... - // + hdr_status = hdr_status && msg.get_ulong (req.request_id); hdr_status = hdr_status && msg.get_boolean (req.response_expected); - hdr_status = hdr_status && CDR::decoder (&TC_opaque, &req.object_key, - 0, &msg, env); - hdr_status = hdr_status && CDR::decoder (_tc_CORBA_String, &req.operation, - 0, &msg, env); + hdr_status = hdr_status && CDR::decoder (&TC_opaque, + &req.object_key, + 0, + &msg, + env); + hdr_status = hdr_status && CDR::decoder (_tc_CORBA_String, + &req.operation, + 0, + &msg, + env); hdr_status = hdr_status && CDR::decoder (_tc_CORBA_Principal, - &req.requesting_principal, 0, &msg, env); - + &req.requesting_principal, + 0, + &msg, + env); // XXX check whether hdr_status identifies a header // unmarshaling error, and handle appropriately #ifdef DEBUG - if (debug_level >= 3) { - dmsg_v ("%sRequest ID %#lx from FD %d", + if (debug_level >= 3) + { + dmsg_v ("%sRequest ID %#lx from FD %d", req.response_expected ? "" : "Oneway ", - req.request_id, peer.get_handle()); - if (debug_level >= 4) { - dmsg_opaque ("object key", req.object_key.buffer, - req.object_key.length); - dmsg_v (" opname '%s'", req.operation); - if (req.requesting_principal) - dmsg_opaque ("client principal", - req.requesting_principal->id.buffer, - req.requesting_principal->id.length); - else - dmsg (" client principal (EMPTY)"); - } - - // NOTE: describe any service context, and how - // many bytes of non-header data were sent. - } + req.request_id, peer.get_handle ()); + if (debug_level >= 4) + { + dmsg_opaque ("object key", req.object_key.buffer, + req.object_key.length); + dmsg_v (" opname '%s'", req.operation); + if (req.requesting_principal) + dmsg_opaque ("client principal", + req.requesting_principal->id.buffer, + req.requesting_principal->id.length); + else + dmsg (" client principal (EMPTY)"); + } + + // NOTE: describe any service context, and how many bytes + // of non-header data were sent. + } #endif // DEBUG - // // Verify that we're to dispatch the request within this // particular process. - // - if (check_forward != 0) { - LocateStatusType status; - CORBA_Object_ptr fwd_ref = 0; - - status = check_forward (req.object_key, fwd_ref, context); - if (status != OBJECT_HERE) { - ServiceContextList resp_ctx; - unsigned char buf2 [CDR::DEFAULT_BUFSIZE]; - CDR response (&buf2 [0], - sizeof buf2); - - start_message (Reply, response); - resp_ctx.length = 0; - CDR::encoder (&TC_ServiceContextList, &resp_ctx, - 0, &response, env); - response.put_ulong (req.request_id); - // - // If we're not sending a response, just clean up. - // - if (!req.response_expected) { - if (status == OBJECT_FORWARD) - CORBA_release (fwd_ref); + if (check_forward != 0) + { + LocateStatusType status; + CORBA_Object_ptr fwd_ref = 0; + + status = check_forward (req.object_key, fwd_ref, context); + if (status != OBJECT_HERE) + { + ServiceContextList resp_ctx; + u_char buf2 [CDR::DEFAULT_BUFSIZE]; + CDR response (&buf2 [0], sizeof buf2); + + start_message (Reply, response); + resp_ctx.length = 0; + CDR::encoder (&TC_ServiceContextList, + &resp_ctx, + 0, + &response, + env); + response.put_ulong (req.request_id); + + // If we're not sending a response, just clean up. + + if (!req.response_expected) + { + if (status == OBJECT_FORWARD) + CORBA_release (fwd_ref); // // Else either forward the request ... // - } else if (status == OBJECT_FORWARD) { - dmsg ("forwarding Request message"); - response.put_ulong (LOCATION_FORWARD); - CDR::encoder (_tc_CORBA_Object, &fwd_ref, - 0, &response, env); - CORBA_release (fwd_ref); - (void) send_message (response, peer); + } + else if (status == OBJECT_FORWARD) + { + dmsg ("forwarding Request message"); + response.put_ulong (LOCATION_FORWARD); + CDR::encoder (_tc_CORBA_Object, + &fwd_ref, + 0, + &response, + env); + CORBA_release (fwd_ref); + (void) send_message (response, peer); - // // ... or report exception that the object doesn't exist. - // - } else { - CORBA_OBJECT_NOT_EXIST exc (COMPLETED_YES); + } + else + { + CORBA_OBJECT_NOT_EXIST exc (COMPLETED_YES); - response.put_ulong (SYSTEM_EXCEPTION); - (void) CDR::encoder (_tc_CORBA_OBJECT_NOT_EXIST, - &exc, 0, &response, env); + response.put_ulong (SYSTEM_EXCEPTION); - (void) send_message (response, peer); - } + (void) CDR::encoder (_tc_CORBA_OBJECT_NOT_EXIST, + &exc, + 0, + &response, + env); - delete req.object_key.buffer; - CORBA_string_free (req.operation); - return retval; - } - } + (void) send_message (response, peer); + } + delete req.object_key.buffer; + CORBA_string_free (req.operation); + return retval; + } + } - // // So, we read a request, now dispatch it using something more // primitive than a CORBA2 ServerRequest pseudo-object. - // - if (req.response_expected) { - ServiceContextList resp_ctx; - unsigned char buf2 [CDR::DEFAULT_BUFSIZE]; - CDR response (&buf2 [0], sizeof buf2); - start_message (Reply, response); - resp_ctx.length = 0; - CDR::encoder (&TC_ServiceContextList, &resp_ctx, - 0, &response, env); - response.put_ulong (req.request_id); + if (req.response_expected) + { + ServiceContextList resp_ctx; + u_char buf2 [CDR::DEFAULT_BUFSIZE]; + CDR response (&buf2 [0], sizeof buf2); - handle_request (req, msg, &response, context, env); + start_message (Reply, response); + resp_ctx.length = 0; + CDR::encoder (&TC_ServiceContextList, + &resp_ctx, + 0, + &response, + env); + response.put_ulong (req.request_id); - // - // "handle_request" routine puts ReplyStatusType then - // parameters. - // - (void) send_message (response, peer); - } else + handle_request (req, msg, &response, context, env); + + // "handle_request" routine puts ReplyStatusType then + // parameters. + + (void) send_message (response, peer); + } + else handle_request (req, msg, 0, context, env); delete req.object_key.buffer; @@ -1346,76 +1370,78 @@ GIOP::incoming_message ( } break; - // // Forward requests as needed; if caller hasn't provided code to // support forwarding, we default to doing no forwarding. - // case LocateRequest: { - CORBA_ULong request_id; - opaque key; - - msg.get_ulong (request_id); - CDR::decoder (&TC_opaque, &key, 0, &msg, env); - - // - // we've read the request header; send a LocateReply - // - unsigned char resp [CDR::DEFAULT_BUFSIZE]; - CDR response (resp, sizeof resp); - CORBA_Object_ptr fwd_ref = 0; - - start_message (LocateReply, response); - response.put_ulong (request_id); - if (check_forward == 0) { - response.put_ulong (OBJECT_HERE); - dmsg ("LocateRequest response: object is (always) here!"); - } else { - LocateStatusType status; - - status = check_forward (key, fwd_ref, context); - response.put_ulong ((CORBA_ULong) status); - if (status == OBJECT_FORWARD) { - dmsg ("LocateRequest response: forward requests"); - CDR::encoder (_tc_CORBA_Object, &fwd_ref, 0, - &response, env); - } else if (status == OBJECT_HERE) { - dmsg ("LocateRequest response: object is here!"); - } else { - dmsg ("LocateRequest response: no such object"); - } - } - (void) send_message (response, peer); + CORBA_ULong request_id; + opaque key; + + msg.get_ulong (request_id); + CDR::decoder (&TC_opaque, &key, 0, &msg, env); + + // we've read the request header; send a LocateReply + + u_char resp [CDR::DEFAULT_BUFSIZE]; + CDR response (resp, sizeof resp); + CORBA_Object_ptr fwd_ref = 0; + + start_message (LocateReply, response); + response.put_ulong (request_id); + + if (check_forward == 0) + { + response.put_ulong (OBJECT_HERE); + dmsg ("LocateRequest response: object is (always) here!"); + } + else + { + LocateStatusType status; + + status = check_forward (key, fwd_ref, context); + response.put_ulong ((CORBA_ULong) status); + + if (status == OBJECT_FORWARD) + { + dmsg ("LocateRequest response: forward requests"); + CDR::encoder (_tc_CORBA_Object, &fwd_ref, 0, + &response, env); + } + else if (status == OBJECT_HERE) + dmsg ("LocateRequest response: object is here!"); + else + dmsg ("LocateRequest response: no such object"); + } + (void) send_message (response, peer); } break; - // // Cancel request -- ignored this implementation. // - // THREADING NOTE: Handling it would require (a) some thread to read - // the CancelRequest while one was working on handling the Request, - // (b) a way to find the thread working on that request, (c) using - // thread cancellation to alert that thread that the work it's - // been doing can safely be discarded. Also of course (d) making - // the various worker threads cleanly handle cancellation, and - // (e) modifying client code to send a CancelRequest when it's - // been canceled. - // + // THREADING NOTE: Handling it would require (a) some thread to + // read the CancelRequest while one was working on handling the + // Request, (b) a way to find the thread working on that request, + // (c) using thread cancellation to alert that thread that the + // work it's been doing can safely be discarded. Also of course + // (d) making the various worker threads cleanly handle + // cancellation, and (e) modifying client code to send a + // CancelRequest when it's been canceled. + case CancelRequest: { - CORBA_ULong request_id; + CORBA_ULong request_id; - msg.get_ulong (request_id); + msg.get_ulong (request_id); } break; - } - // ... error if unconsumed data remains; is this the spot to test that? + // ... error if unconsumed data remains; is this the spot to test + // that? return retval; } -#if defined(ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) template class autorelease<client_endpoint>; template class CORBA_SEQUENCE<GIOP::ServiceContext>; template class CORBA_SEQUENCE<CORBA_Octet>; diff --git a/TAO/IIOP/lib/iiopobj.cpp b/TAO/IIOP/lib/iiopobj.cpp index 12d5af2835b..571dc794563 100644 --- a/TAO/IIOP/lib/iiopobj.cpp +++ b/TAO/IIOP/lib/iiopobj.cpp @@ -5,9 +5,8 @@ // IIOP Bridge: CORBA::Object operations // // Some CORBA::Object and other operations are specific to this IIOP -// based implementation, and can neither be used by other kinds of objref -// nor have a default implementation. -// +// based implementation, and can neither be used by other kinds of +// objref nor have a default implementation. #include <assert.h> #include <limits.h> @@ -34,103 +33,98 @@ IIOP::ProfileBody::ProfileBody (const IIOP::ProfileBody &src) host = ACE_OS::strdup (src.host); object_key.length = object_key.maximum = src.object_key.length; + object_key.buffer = (CORBA_Octet *) ACE_OS::malloc (object_key.maximum); + (void) ACE_OS::memcpy (object_key.buffer, src.object_key.buffer, object_key.length); } -IIOP::ProfileBody::ProfileBody(const IIOP::Version& v, - const CORBA_String& h, - const CORBA_UShort& p, - const opaque& key) +IIOP::ProfileBody::ProfileBody(const IIOP::Version &v, + const CORBA_String &h, + const CORBA_UShort &p, + const opaque &key) : iiop_version(v), port(p) { host = ACE_OS::strdup(h); object_key.length = object_key.maximum = key.length; + object_key.buffer = (CORBA_Octet *) ACE_OS::malloc (object_key.maximum); + (void) ACE_OS::memcpy (object_key.buffer, key.buffer, object_key.length); } -// // Quick'n'dirty hash of objref data, for partitioning objrefs into sets // // NOTE that this must NOT go across the network! -// + CORBA_ULong -IIOP_Object::hash ( - CORBA_ULong max, - CORBA_Environment &env -) +IIOP_Object::hash (CORBA_ULong max, + CORBA_Environment &env) { - CORBA_ULong hashval; - - env.clear (); - - // - // Just grab a bunch of convenient bytes and hash them; could do - // more (hostname, full key, exponential hashing) but no real need - // to do so except if performance requires a more costly hash. - // - hashval = profile.object_key.length * profile.port; - hashval += profile.iiop_version.minor; - if (profile.object_key.length >= 4) { - hashval += profile.object_key.buffer [1]; - hashval += profile.object_key.buffer [3]; + CORBA_ULong hashval; + + env.clear (); + + // Just grab a bunch of convenient bytes and hash them; could do + // more (hostname, full key, exponential hashing) but no real need + // to do so except if performance requires a more costly hash. + + hashval = profile.object_key.length * profile.port; + hashval += profile.iiop_version.minor; + + if (profile.object_key.length >= 4) + { + hashval += profile.object_key.buffer [1]; + hashval += profile.object_key.buffer [3]; } - return hashval % max; + return hashval % max; } - -// -// Expensive comparison of objref data, to see if two objrefs certainly -// point at the same object. (It's quite OK for this to return FALSE, -// and yet have the two objrefs really point to the same object.) +// Expensive comparison of objref data, to see if two objrefs +// certainly point at the same object. (It's quite OK for this to +// return FALSE, and yet have the two objrefs really point to the same +// object.) // // NOTE that this must NOT go across the network! -// + CORBA_Boolean -IIOP_Object::is_equivalent ( - CORBA_Object_ptr other_obj, - CORBA_Environment &env -) +IIOP_Object::is_equivalent (CORBA_Object_ptr other_obj, + CORBA_Environment &env) { - IIOP::ProfileBody *body, *body2; - IIOP_Object *other_iiop_obj; - - env.clear (); - - if (CORBA_is_nil (other_obj) == CORBA_B_TRUE - || other_obj->QueryInterface (IID_IIOP_Object, - (void **)&other_iiop_obj) != NOERROR) - return CORBA_B_FALSE; - CORBA_release (other_obj); - - // - // Compare all the bytes of the object address -- must be the same - // - body = &profile; - body2 = &other_iiop_obj->profile; - - assert (body->object_key.length < UINT_MAX); - - return body->object_key.length == body2->object_key.length - && ACE_OS::memcmp (body->object_key.buffer, - body2->object_key.buffer, - (size_t) body->object_key.length) == 0 - && body->port == body2->port - && ACE_OS::strcmp ((char *)body->host, (char *)body2->host) == 0 - && body->iiop_version.minor == body2->iiop_version.minor - && body->iiop_version.major == body2->iiop_version.major; -} + IIOP::ProfileBody *body, *body2; + IIOP_Object *other_iiop_obj; + env.clear (); + + if (CORBA_is_nil (other_obj) == CORBA_B_TRUE + || other_obj->QueryInterface (IID_IIOP_Object, + (void **) &other_iiop_obj) != NOERROR) + return CORBA_B_FALSE; + CORBA_release (other_obj); + + // Compare all the bytes of the object address -- must be the same + + body = &profile; + body2 = &other_iiop_obj->profile; + + assert (body->object_key.length < UINT_MAX); + + return body->object_key.length == body2->object_key.length + && ACE_OS::memcmp (body->object_key.buffer, + body2->object_key.buffer, + (size_t) body->object_key.length) == 0 + && body->port == body2->port + && ACE_OS::strcmp ((char *)body->host, (char *)body2->host) == 0 + && body->iiop_version.minor == body2->iiop_version.minor + && body->iiop_version.major == body2->iiop_version.major; +} -// // For COM -- IUnknown operations -// // {A201E4C3-F258-11ce-9598-0000C07CA898} DEFINE_GUID (IID_IIOP_Object, @@ -148,22 +142,20 @@ DEFINE_GUID (IID_STUB_Object, DEFINE_GUID (IID_CORBA_Object, 0xa201e4c2, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); -// End - Added by BRM: 2/21/97 -// IID_STUB_Object and IID_CORBA_Object were not being defined. -// Need a central place for all of these macros. +// End - Added by BRM: 2/21/97 IID_STUB_Object and IID_CORBA_Object +// were not being defined. Need a central place for all of these +// macros. -ULONG -__stdcall -IIOP_Object::AddRef () +ULONG __stdcall +IIOP_Object::AddRef (void) { ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); return ++_refcount; } -ULONG -__stdcall -IIOP_Object::Release () +ULONG __stdcall +IIOP_Object::Release (void) { ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); @@ -176,10 +168,8 @@ IIOP_Object::Release () return 0; } - -// -// Note that (as of this writing) this is the only place all -// the interfaces to an "objref" come together: +// Note that (as of this writing) this is the only place all the +// interfaces to an "objref" come together: // // IUnknown ... this one // STUB_OBJECT ... inherited by this one @@ -187,28 +177,25 @@ IIOP_Object::Release () // // CORBA_Object ... contained within this; it delegates back // to this one as its "parent" -// -HRESULT -__stdcall -IIOP_Object::QueryInterface ( - REFIID riid, - void **ppv -) + +HRESULT __stdcall +IIOP_Object::QueryInterface (REFIID riid, + void **ppv) { - *ppv = 0; + *ppv = 0; - if (IID_IIOP_Object == riid - || IID_STUB_Object == riid - || IID_IUnknown == riid) - *ppv = this; - else if (IID_CORBA_Object == riid) - *ppv = &base; + if (IID_IIOP_Object == riid + || IID_STUB_Object == riid + || IID_IUnknown == riid) + *ppv = this; + else if (IID_CORBA_Object == riid) + *ppv = &base; - if (*ppv == 0) - return ResultFromScode (E_NOINTERFACE); + if (*ppv == 0) + return ResultFromScode (E_NOINTERFACE); - (void) AddRef (); - return NOERROR; + (void) AddRef (); + return NOERROR; } //TAO extensions diff --git a/TAO/IIOP/lib/iiopobj.i b/TAO/IIOP/lib/iiopobj.i index b80a152577e..24a4eca82e4 100644 --- a/TAO/IIOP/lib/iiopobj.i +++ b/TAO/IIOP/lib/iiopobj.i @@ -1,30 +1,30 @@ ACE_INLINE -IIOP::Version::Version(CORBA_Octet maj, CORBA_Octet min) - : major(maj), - minor(min) +IIOP::Version::Version (CORBA_Octet maj, CORBA_Octet min) + : major (maj), + minor (min) {} ACE_INLINE -IIOP::ProfileBody::ProfileBody() - : host(0) +IIOP::ProfileBody::ProfileBody (void) + : host (0) {} ACE_INLINE -IIOP::ProfileBody::~ProfileBody() +IIOP::ProfileBody::~ProfileBody (void) { - ACE_OS::free(host); - ACE_OS::free(object_key.buffer); + ACE_OS::free (host); + ACE_OS::free (object_key.buffer); } ACE_INLINE -IIOP_Object::~IIOP_Object() +IIOP_Object::~IIOP_Object (void) { - assert(_refcount == 0); + assert (_refcount == 0); delete fwd_profile; } ACE_INLINE -IIOP_Object::IIOP_Object(char *repository_id) +IIOP_Object::IIOP_Object (char *repository_id) : fwd_profile (0), base (this), STUB_Object (repository_id), diff --git a/TAO/IIOP/lib/iioporb.cpp b/TAO/IIOP/lib/iioporb.cpp index 967900058fd..bf235b96594 100644 --- a/TAO/IIOP/lib/iioporb.cpp +++ b/TAO/IIOP/lib/iioporb.cpp @@ -4,9 +4,8 @@ // // IIOP: ORB pseudo-object // -// This includes objref stringification/destringification for IIOP object -// references. -// +// This includes objref stringification/destringification for IIOP +// object references. #include <assert.h> #include <limits.h> @@ -23,12 +22,10 @@ #include "iioporb.h" #include "iiopobj.h" - static const char ior_prefix [] = "IOR:"; static const char iiop_prefix [] = "iiop:"; static const char xchars [] = "0123456789abcdef"; - #if !defined(__ACE_INLINE__) # include "iioporb.i" #endif @@ -37,100 +34,96 @@ static const char xchars [] = "0123456789abcdef"; // hex conversion utilities // static inline char -nibble2hex (unsigned n) +nibble2hex (u_int n) { - return xchars [n & 0x0f]; + return xchars [n & 0x0f]; } -static inline -unsigned char +static inline u_char hex2byte (char c) { - if (isdigit (c)) - return (unsigned char) (c - '0'); - else if (islower (c)) - return (unsigned char) (10 + c - 'a'); - else - return (unsigned char) (10 + c - 'A'); + if (isdigit (c)) + return (u_char) (c - '0'); + else if (islower (c)) + return (u_char) (10 + c - 'a'); + else + return (u_char) (10 + c - 'A'); } - -// // Objref stringification -// + CORBA_String IIOP_ORB::object_to_string (CORBA_Object_ptr obj, CORBA_Environment &env) { env.clear (); - // // Application writer controls what kind of objref strings they get, // maybe along with other things, by how they initialize the ORB. - // + if (use_omg_ior_format) { - // // By default, orbs use IOR strings; these are ugly (and error - // prone) but specified by CORBA. + // prone) but specified by CORBA. // // XXX there should be a simple way to reuse this code in other // ORB implementations ... - // - unsigned char *bytes, buf [BUFSIZ]; - CDR cdr(buf, sizeof buf, MY_BYTE_SEX); + + u_char *bytes; + u_char buf [BUFSIZ]; + CDR cdr (buf, sizeof buf, MY_BYTE_SEX); bytes = buf; (void) ACE_OS::memset (bytes, 0, BUFSIZ); // support limited oref ACE_OS::strcmp - // // Marshal the objref into an encapsulation bytestream. - // (void) cdr.put_char (MY_BYTE_SEX); - if (CDR::encoder (_tc_CORBA_Object, &obj, 0, &cdr, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) + if (CDR::encoder (_tc_CORBA_Object, + &obj, 0, + &cdr, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) return 0; - // - // Now hexify the encapsulated CDR data into a string, - // and return that string. - // - CORBA_String string, cp; - size_t len = cdr.length - cdr.remaining; + // Now hexify the encapsulated CDR data into a string, and + // return that string. + + CORBA_String cp; + size_t len = cdr.length - cdr.remaining; + + CORBA_String string = CORBA_string_alloc (sizeof ior_prefix + 2 * len); - string = CORBA_string_alloc (sizeof ior_prefix + 2 * len); - ACE_OS::strcpy ((char *)string, ior_prefix); + ACE_OS::strcpy ((char *) string, ior_prefix); - for (cp = (CORBA_String) ACE_OS::strchr ((char *)string, ':') + 1, bytes = cdr.buffer; + for (cp = (CORBA_String) ACE_OS::strchr ((char *) string, ':') + 1, bytes = cdr.buffer; len--; bytes++) { *cp++ = nibble2hex ((*bytes) >> 4); *cp++ = nibble2hex (*bytes); } + *cp = 0; return string; } else { + // The "internet" ORB uses readable URL style objrefs, as used + // in the World Wide Web. // - // The "internet" ORB uses readable URL style objrefs, as - // used in the World Wide Web. - // - // NOTE: the version ID in the string is ugly but we can't + // NOTE: the version ID in the string is ugly but we can't // realistically eliminate it by any "assume 1.0" strategy... - // Similarly with the port, because there's no single IIOP - // port to which we could default. - // + // Similarly with the port, because there's no single IIOP port + // to which we could default. + static const char digits [] = "0123456789"; - // // This only works for IIOP objrefs. If we're handed an objref // that's not an IIOP objref, fail -- application must use an // ORB that's configured differently. - // - IIOP_Object *obj2; - if (obj->QueryInterface (IID_IIOP_Object, (void **)&obj2) != NOERROR) + IIOP_Object *obj2; + + if (obj->QueryInterface (IID_IIOP_Object, + (void **) &obj2) != NOERROR) { env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); return 0; @@ -139,18 +132,18 @@ IIOP_ORB::object_to_string (CORBA_Object_ptr obj, if (!obj2) // null? return CORBA_string_copy ((CORBA_String) iiop_prefix); - char buf [BUFSIZ + 2]; + char buf [BUFSIZ + 2]; ACE_OS::sprintf (buf, "%s%c.%c//%s:%d/", iiop_prefix, digits [obj2->profile.iiop_version.major], digits [obj2->profile.iiop_version.minor], obj2->profile.host, obj2->profile.port); - char *cp = ACE_OS::strchr (buf, 0); - unsigned len; - unsigned char *byte; + char *cp = ACE_OS::strchr (buf, 0); + u_int len; + u_char *byte; - for (len = (unsigned) obj2->profile.object_key.length, + for (len = (u_int) obj2->profile.object_key.length, byte = obj2->profile.object_key.buffer; cp < &buf [BUFSIZ] && len != 0; len--, byte++) @@ -161,11 +154,9 @@ IIOP_ORB::object_to_string (CORBA_Object_ptr obj, continue; } - // // NOTE: this could run two characters past &buf[BUFSIZ], // which is why buf is exactly two characters bigger than // that ... saves coding a test here. - // *cp++ = '\\'; *cp++ = nibble2hex (*byte & 0x0f); *cp++ = nibble2hex ((*byte >> 4) & 0x0f); @@ -180,87 +171,80 @@ IIOP_ORB::object_to_string (CORBA_Object_ptr obj, } } - -// // Destringify OMG-specified "IOR" string. // -// XXX there should be a simple way to reuse this code in other -// ORB implementations ... -// +// XXX there should be a simple way to reuse this code in other ORB +// implementations ... + static CORBA_Object_ptr ior_string_to_object (CORBA_String str, CORBA_Environment &env) { - // - // Unhex the bytes, and make a CDR deencapsulation stream - // from the resulting data. - // - unsigned char *buffer = new unsigned char [1 + ACE_OS::strlen ((char *) str) / 2]; - char *tmp = (char *)str; - size_t len = 0; + // Unhex the bytes, and make a CDR deencapsulation stream from the + // resulting data. + + u_char *buffer = new u_char [1 + ACE_OS::strlen ((char *) str) / 2]; + char *tmp = (char *) str; + size_t len = 0; while (tmp [0] && tmp [1]) { - unsigned char byte; + u_char byte; if (!(isxdigit (tmp [0]) && isxdigit (tmp [1]))) break; - byte = (unsigned char) (hex2byte (tmp [0]) << 4); + byte = (u_char) (hex2byte (tmp [0]) << 4); byte |= hex2byte (tmp [1]); buffer [len++] = byte; tmp += 2; } - if (tmp [0] && !isspace (tmp [0])) { - delete buffer; - env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); - return 0; - } - // - // Create deencapsulation stream ... then unmarshal objref - // from that stream. - // - CDR stream; - CORBA_Object_ptr objref; - - stream.setup_encapsulation (buffer, len); - if (CDR::decoder (_tc_CORBA_Object, &objref, 0, &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) + if (tmp [0] && !isspace (tmp [0])) { - objref = 0; + delete buffer; + env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); + return 0; } - delete buffer; + // Create deencapsulation stream ... then unmarshal objref from that + // stream. + + CDR stream; + CORBA_Object_ptr objref; + + stream.setup_encapsulation (buffer, len); + if (CDR::decoder (_tc_CORBA_Object, + &objref, 0, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) + objref = 0; + + delete [] buffer; return objref; } - -// // Destringify URL style IIOP objref. -// + static CORBA_Object_ptr iiop_string_to_object (CORBA_String string, CORBA_Environment &env) { - // // NIL objref encodes as just "iiop:" ... which has already been // removed, so we see it as an empty string. - // + if (!string || !*string) return 0; - // // type ID not encoded in this string ... makes narrowing rather // expensive, though it does ensure that type-safe narrowing code // gets thoroughly excercised/debugged! - // - IIOP_Object *data = new IIOP_Object (0); // null type ID - // + IIOP_Object *data = new IIOP_Object (0); // null type ID + // Remove the "N.N//" prefix, and verify the version's one // that we accept - // + if (isdigit (string [0]) && isdigit (string [2]) && string [1] == '.' && string [3] == '/' && string [4] == '/') { @@ -274,6 +258,7 @@ iiop_string_to_object (CORBA_String string, data->Release (); return 0; } + if (data->profile.iiop_version.major != IIOP::MY_MAJOR || data->profile.iiop_version.minor > IIOP::MY_MINOR) { @@ -282,12 +267,11 @@ iiop_string_to_object (CORBA_String string, return 0; } - // // Pull off the "hostname:port/" part of the objref - // - char *cp; - if ((cp = ACE_OS::strchr (string, ':'))== 0) + char *cp = ACE_OS::strchr (string, ':'); + + if (cp == 0) { env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); data->Release (); @@ -295,12 +279,18 @@ iiop_string_to_object (CORBA_String string, } data->profile.host = CORBA_string_alloc (1 + cp - string); - for (cp = data->profile.host; *string != ':'; *cp++ = *string++) + + for (cp = data->profile.host; + *string != ':'; + *cp++ = *string++) continue; + *cp = 0; string++; - if ((cp = ACE_OS::strchr ((char *)string, '/')) == 0) + cp = ACE_OS::strchr ((char *)string, '/'); + + if (cp == 0) { env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); CORBA_string_free (data->profile.host); @@ -311,17 +301,17 @@ iiop_string_to_object (CORBA_String string, data->profile.port = (short) ACE_OS::atoi ((char *)string); string = ++cp; - // // Parse the key ... it's ASCII plus hex escapes for everything // nonprintable. This assumes that printable ASCII is the common // case ... but since stringification is uncommon, no big deal. - // - data->profile.object_key.buffer = (unsigned char *) CORBA_string_copy (string); - // + data->profile.object_key.buffer = (u_char *) CORBA_string_copy (string); + // Strip out whitespace and adjust length accordingly. - // - for (cp = (char *) data->profile.object_key.buffer; *cp; cp++) + + for (cp = (char *) data->profile.object_key.buffer; + *cp; + cp++) { if (!isprint (*cp)) { @@ -329,39 +319,35 @@ iiop_string_to_object (CORBA_String string, break; } } + string = (char *) data->profile.object_key.buffer; data->profile.object_key.length = ACE_OS::strlen (string); data->profile.object_key.maximum = data->profile.object_key.length; - // // Strip out hex escapes and adjust the key's length appropriately. - // + while ((cp = ACE_OS::strchr ((char *)data->profile.object_key.buffer, '\\')) != 0) { *cp = (CORBA_Char) (hex2byte ((char) cp [1]) << 4); *cp |= (CORBA_Char) hex2byte ((char) cp [2]); cp++; - size_t len = ACE_OS::strlen (cp); + size_t len = ACE_OS::strlen (cp); ACE_OS::memcpy (cp, cp+2, len - 2); data->profile.object_key.length -= 2; } - // // Return the objref. - // - CORBA_Object_ptr obj; + CORBA_Object_ptr obj; - (void) data->QueryInterface (IID_CORBA_Object, (void **)&obj); + (void) data->QueryInterface (IID_CORBA_Object, (void **)&obj); data->Release (); return obj; } - -// // Destringify arbitrary objrefs. -// + CORBA_Object_ptr IIOP_ORB::string_to_object (CORBA_String str, CORBA_Environment &env) @@ -373,14 +359,13 @@ IIOP_ORB::string_to_object (CORBA_String str, // Use the prefix code to choose which destringify algorithm to use. if (ACE_OS::strncmp ((char *)str, iiop_prefix, sizeof iiop_prefix - 1) == 0) obj = iiop_string_to_object (str + sizeof iiop_prefix - 1, env); - else if (ACE_OS::strncmp ((char *)str, ior_prefix, sizeof ior_prefix - 1) == 0) obj = ior_string_to_object (str + sizeof ior_prefix - 1, env); // If we got a good object, then let it know who we are, otherwise // set the proper exception. if (obj != 0) - obj->orb(this); + obj->orb (this); else env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); @@ -388,17 +373,13 @@ IIOP_ORB::string_to_object (CORBA_String str, return obj; } -// // COM IUnknown support -// // {A201E4C4-F258-11ce-9598-0000C07CA898} DEFINE_GUID (IID_IIOP_ORB, 0xa201e4c4, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); - -HRESULT -__stdcall +HRESULT __stdcall IIOP_ORB::QueryInterface (REFIID riid, void **ppv) { @@ -420,6 +401,6 @@ IIOP_ORB::QueryInterface (REFIID riid, return NOERROR; } -#if defined(ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) template class ACE_Singleton<IIOP_ORB, ACE_Thread_Mutex>; #endif diff --git a/TAO/IIOP/lib/iioporb.i b/TAO/IIOP/lib/iioporb.i index 8f2929c78cd..1fd03209faf 100644 --- a/TAO/IIOP/lib/iioporb.i +++ b/TAO/IIOP/lib/iioporb.i @@ -1,13 +1,11 @@ -ACE_INLINE -void -IIOP_ORB::use_omg_ior_format(CORBA_Boolean ior) +ACE_INLINE void +IIOP_ORB::use_omg_ior_format (CORBA_Boolean ior) { use_omg_ior_format_ = ior; } -ACE_INLINE -CORBA_Boolean -IIOP_ORB::use_omg_ior_format(void) +ACE_INLINE CORBA_Boolean +IIOP_ORB::use_omg_ior_format (void) { return use_omg_ior_format_; } diff --git a/TAO/IIOP/lib/interp.cpp b/TAO/IIOP/lib/interp.cpp index b3b3eebe505..2bfeb77d337 100644 --- a/TAO/IIOP/lib/interp.cpp +++ b/TAO/IIOP/lib/interp.cpp @@ -2,65 +2,69 @@ // Copyright 1994-1995 by Sun Microsystems Inc. // All Rights Reserved // -// TYPECODE: interpreter, traverses data structures +// TYPECODE: interpreter, traverses data structures // -// This uses the standard C/C++ representation for data, and knows how to -// do things like align and pad according to standard rules. It is driven -// by CDR marshaled representations of TypeCodes. +// This uses the standard C/C++ representation for data, and knows how +// to do things like align and pad according to standard rules. It is +// driven by CDR marshaled representations of TypeCodes. // -// It does two key things: (a) calculate size and alignment restrictions -// for the data type described by any given typecode; and (b) "visits" -// each element of a data type in the order those elements are defined -// in the type's IDL definition. -// -// A typical use is that some application-specific "visit" function will -// be called with a typecode and data value. Then that "visit" function -// may choose to use the interpreter's knowledge of the environment's -// size, padding, and alignment rules to help it examine each of the -// constituents of complex data values. It does so by making a call to -// TypeCode::traverse(), and passing itself for future recursive calls. +// It does two key things: (a) calculate size and alignment +// restrictions for the data type described by any given typecode; and +// (b) "visits" each element of a data type in the order those +// elements are defined in the type's IDL definition. // +// A typical use is that some application-specific "visit" function +// will be called with a typecode and data value. Then that "visit" +// function may choose to use the interpreter's knowledge of the +// environment's size, padding, and alignment rules to help it examine +// each of the constituents of complex data values. It does so by +// making a call to TypeCode::traverse(), and passing itself for +// future recursive calls. // // NOTE that this module has system dependent parts, and so should be -// examined when porting to new CPU architectures, compilers, and so forth -// to make sure it correctly implements the appropriate binary interfaces. +// examined when porting to new CPU architectures, compilers, and so +// forth to make sure it correctly implements the appropriate binary +// interfaces. // -// Issues of concern are primarily that sizes and representations of CORBA -// primitive data types are correct (key issues are verified when the -// ORB initializes) and that the alignment rules are recognized. +// Issues of concern are primarily that sizes and representations of +// CORBA primitive data types are correct (key issues are verified +// when the ORB initializes) and that the alignment rules are +// recognized. // -// Also, exceptions have vtables in them, which may cause trouble if they -// aren't located at the very beginning by the compiler in question. +// Also, exceptions have vtables in them, which may cause trouble if +// they aren't located at the very beginning by the compiler in +// question. // // So for example, moving to another CPU architecture which still uses -// standard sized two's complement integers and IEEE floating point, and -// expects "natural" alignment, won't be hard. Even using PC style -// tightly packed data is simple; the alignment rules are just simpler. -// Most volume microprocessors used in 1995 are correctly supported. -// -// Using data representations that are far from the standard C/C++ style -// data layout is probably not practical with this implementation. LISP -// systems, as one example, probably won't use "in-memory" representations -// much like C/C++, even though its "wire form" could directly match CDR. -// -// -// ALSO, the treatment of exceptions may need to be examined in language -// environments which actually rely on C++ exceptions. The RTTI data that -// identifies exceptions can easily be ignored by this interpreter (if it's -// taught about that compiler's RTTI) but it may not be practical for any -// code not generated by that specific C++ compiler to store such data in -// the right place to look like a C++ exception, or to throw exceptions -// when that's needed. (RTTI == "Run Time Typing Information", needed to -// make C++ exceptions work correctly and partially exposed to users by -// the ANSI standards comittee. It provides type-safe "downcasting" and -// other features previously unavailable in C++.) -// -// -// THREADING NOTE: Data structures being traversed should only be modified -// by the thread doing the traversal. The interpretive code itself is -// reentrant (recursive!) so presents no threading issues; only the data -// being fed to the interpreter must be protected against concurrency. -// +// standard sized two's complement integers and IEEE floating point, +// and expects "natural" alignment, won't be hard. Even using PC +// style tightly packed data is simple; the alignment rules are just +// simpler. Most volume microprocessors used in 1995 are correctly +// supported. +// +// Using data representations that are far from the standard C/C++ +// style data layout is probably not practical with this +// implementation. LISP systems, as one example, probably won't use +// "in-memory" representations much like C/C++, even though its "wire +// form" could directly match CDR. +// +// ALSO, the treatment of exceptions may need to be examined in +// language environments which actually rely on C++ exceptions. The +// RTTI data that identifies exceptions can easily be ignored by this +// interpreter (if it's taught about that compiler's RTTI) but it may +// not be practical for any code not generated by that specific C++ +// compiler to store such data in the right place to look like a C++ +// exception, or to throw exceptions when that's needed. (RTTI == +// "Run Time Typing Information", needed to make C++ exceptions work +// correctly and partially exposed to users by the ANSI standards +// comittee. It provides type-safe "downcasting" and other features +// previously unavailable in C++.) +// +// THREADING NOTE: Data structures being traversed should only be +// modified by the thread doing the traversal. The interpretive code +// itself is reentrant (recursive!) so presents no threading issues; +// only the data being fed to the interpreter must be protected +// against concurrency. #include <assert.h> #include <limits.h> @@ -70,147 +74,141 @@ #include "debug.h" #include "cdr.h" +// Utility routines are used to manipulate CDR-encapsulated TypeCode +// parameter lists, calculating the size and alignment of the data +// type being described. The TCKind value has always been removed +// from the CDR stream when these calculator routines get called. +typedef size_t attribute_calculator (CDR *stream, + size_t &alignment, + CORBA_Environment &env); -// -// Utility routines are used to manipulate CDR-encapsulated TypeCode parameter -// lists, calculating the size and alignment of the data type being described. -// The TCKind value has always been removed from the CDR stream when these -// calculator routines get called. -// -typedef size_t -attribute_calculator ( - CDR *stream, - size_t &alignment, - CORBA_Environment &env -); +static attribute_calculator calc_struct_attributes; +static attribute_calculator calc_exception_attributes; +static attribute_calculator calc_union_attributes; +static attribute_calculator calc_alias_attributes; +static attribute_calculator calc_array_attributes; -static attribute_calculator calc_struct_attributes; -static attribute_calculator calc_exception_attributes; -static attribute_calculator calc_union_attributes; -static attribute_calculator calc_alias_attributes; -static attribute_calculator calc_array_attributes; +// Other utility routines are used to skip the parameter lists when +// they're not needed. - -// -// Other utility routines are used to skip the parameter -// lists when they're not needed. -// -typedef CORBA_Boolean param_skip_rtn (CDR *); +typedef CORBA_Boolean param_skip_rtn (CDR *); static CORBA_Boolean skip_encapsulation (CDR *stream) { - return stream->skip_string (); + return stream->skip_string (); } static CORBA_Boolean skip_long (CDR *stream) { - CORBA_ULong scratch; + CORBA_ULong scratch; - return stream->get_ulong (scratch); + return stream->get_ulong (scratch); } - -// // Table supporting calculation of size and alignment requirements for // any one instance of a given data types. // -// This is indexed via CDR's TCKind values, which are "frozen" as part of the -// CDR standard. Entries hold either the size and alignment values for that -// data type, or a pointer to a function that is used to calculate those -// values. Function pointers are normally needed only for constructed types. -// -// A "skipper" routine is provided for some data types whose size is known -// statically (e.g. objrefs, structures, strings) but whose typecodes have -// parameters that sometimes need to be ignored when found in a CDR stream. -// Any attribute calculator routine always skips parameters in the CDR input -// stream, so no type with such a routine also needs a "skipper". -// -// Rather than growing a set of processor-specific #ifdefs, we calculate -// most of this table (except functions) at ORB initialization time. -// -struct table_element { - size_t size; - size_t alignment; - attribute_calculator *calc; - param_skip_rtn *skipper; +// This is indexed via CDR's TCKind values, which are "frozen" as part +// of the CDR standard. Entries hold either the size and alignment +// values for that data type, or a pointer to a function that is used +// to calculate those values. Function pointers are normally needed +// only for constructed types. +// +// A "skipper" routine is provided for some data types whose size is +// known statically (e.g. objrefs, structures, strings) but whose +// typecodes have parameters that sometimes need to be ignored when +// found in a CDR stream. Any attribute calculator routine always +// skips parameters in the CDR input stream, so no type with such a +// routine also needs a "skipper". +// +// Rather than growing a set of processor-specific #ifdefs, we +// calculate most of this table (except functions) at ORB +// initialization time. + +struct table_element +{ + size_t size; + size_t alignment; + attribute_calculator *calc; + param_skip_rtn *skipper; }; -static table_element -table [TC_KIND_COUNT] = { - { 0, 1, 0 }, // tk_null - { 0, 1, 0 }, // tk_void - - { 0, 1, 0, 0 }, // tk_short - { 0, 1, 0, 0 }, // tk_long - { 0, 1, 0, 0 }, // tk_ushort - { 0, 1, 0, 0 }, // tk_ulong - - { 0, 1, 0, 0 }, // tk_float - { 0, 1, 0, 0 }, // tk_double - - { 0, 1, 0, 0 }, // tk_boolean - { 0, 1, 0, 0 }, // tk_char - { 0, 1, 0, 0 }, // tk_octet - { 0, 1, 0, 0 }, // tk_any - - { 0, 1, 0, 0 }, // tk_TypeCode - { 0, 1, 0, 0 }, // tk_Principal - { 0, 1, 0, skip_encapsulation }, // tk_objref - - { 0, 1, calc_struct_attributes, 0 }, // tk_struct - { 0, 1, calc_union_attributes, 0 }, // tk_union - - { 0, 1, 0, skip_encapsulation }, // tk_enum - { 0, 1, 0, skip_long }, // tk_string - { 0, 1, 0, skip_encapsulation }, // tk_sequence - { 0, 1, calc_array_attributes, 0 }, // tk_array - - // - // Two TCKind values added in 94-11-7 - // - { 0, 1, calc_alias_attributes, 0 }, // tk_alias - { 0, 1, calc_exception_attributes, 0 }, // tk_except - - // - // Five extended IDL data types, defined in Appendix A of 94-9-32 - // but here with different numeric TCKind codes. These types - // represent extensions to CORBA (specifically, to IDL) which are - // not yet standardized. - // - { 0, 1, 0, 0 }, // tk_longlong - { 0, 1, 0, 0 }, // tk_ulonglong - { 0, 1, 0, 0 }, // tk_longdouble - { 0, 1, 0, 0 }, // tk_wchar - { 0, 1, 0, skip_long } // tk_wstring +static table_element table [TC_KIND_COUNT] = +{ + { 0, 1, 0 }, // tk_null + { 0, 1, 0 }, // tk_void + + { 0, 1, 0, 0 }, // tk_short + { 0, 1, 0, 0 }, // tk_long + { 0, 1, 0, 0 }, // tk_ushort + { 0, 1, 0, 0 }, // tk_ulong + + { 0, 1, 0, 0 }, // tk_float + { 0, 1, 0, 0 }, // tk_double + + { 0, 1, 0, 0 }, // tk_boolean + { 0, 1, 0, 0 }, // tk_char + { 0, 1, 0, 0 }, // tk_octet + { 0, 1, 0, 0 }, // tk_any + + { 0, 1, 0, 0 }, // tk_TypeCode + { 0, 1, 0, 0 }, // tk_Principal + { 0, 1, 0, skip_encapsulation }, // tk_objref + + { 0, 1, calc_struct_attributes, 0 }, // tk_struct + { 0, 1, calc_union_attributes, 0 }, // tk_union + + { 0, 1, 0, skip_encapsulation }, // tk_enum + { 0, 1, 0, skip_long }, // tk_string + { 0, 1, 0, skip_encapsulation }, // tk_sequence + { 0, 1, calc_array_attributes, 0 }, // tk_array + + // + // Two TCKind values added in 94-11-7 + // + { 0, 1, calc_alias_attributes, 0 }, // tk_alias + { 0, 1, calc_exception_attributes, 0 }, // tk_except + + // + // Five extended IDL data types, defined in Appendix A of 94-9-32 + // but here with different numeric TCKind codes. These types + // represent extensions to CORBA (specifically, to IDL) which are + // not yet standardized. + // + { 0, 1, 0, 0 }, // tk_longlong + { 0, 1, 0, 0 }, // tk_ulonglong + { 0, 1, 0, 0 }, // tk_longdouble + { 0, 1, 0, 0 }, // tk_wchar + { 0, 1, 0, skip_long } // tk_wstring }; +// Runtime initialization of the table above; note that this compiles +// down to a set of assignment statements, with the real work done by +// the C++ compiler when this file gets compiled. +// +// "Natural alignment" is a policy that the processor controls the +// alignment of data based on its type. There's variation; some CPUs +// have a maximum alignment requirement of two or four bytes, others +// have some type-specific exceptions to the normal "alignment == +// size" rule. +// +// "Fixed" alignment ignores data type when establishing alignment; +// not all processors support such policies, and those which do often +// pay a cost to do so (viz. RISC/CISC discussions). The primary +// example of an OS family that chose "fixed" alignment is Microsoft's +// x86 systems, which normally align on one byte boundaries to promote +// data space efficiency. +// +// NOTE: typical PC compiler options let you specify other alignments, +// but none are "natural". Also, they don't apply consistently to all +// data types. Change the "one byte" assumption with extreme caution! +// And make sure all header files (e.g. generated by an IDL compiler) +// make sure that alignment of IDL-defined data types is consistent +// (one byte). -// -// Runtime initialization of the table above; note that this compiles down -// to a set of assignment statements, with the real work done by the C++ -// compiler when this file gets compiled. -// -// "Natural alignment" is a policy that the processor controls the alignment -// of data based on its type. There's variation; some CPUs have a maximum -// alignment requirement of two or four bytes, others have some type-specific -// exceptions to the normal "alignment == size" rule. -// -// "Fixed" alignment ignores data type when establishing alignment; not all -// processors support such policies, and those which do often pay a cost to -// do so (viz. RISC/CISC discussions). The primary example of an OS family -// that chose "fixed" alignment is Microsoft's x86 systems, which normally -// align on one byte boundaries to promote data space efficiency. -// -// -// NOTE: typical PC compiler options let you specify other alignments, but -// none are "natural". Also, they don't apply consistently to all data types. -// Change the "one byte" assumption with extreme caution! And make sure all -// header files (e.g. generated by an IDL compiler) make sure that alignment -// of IDL-defined data types is consistent (one byte). -// #if defined (unix) || defined (VXWORKS) #define setup_entry(x,t) \ { \ @@ -235,53 +233,50 @@ table [TC_KIND_COUNT] = { #endif -// // Fills in fixed size and alignment values. -// + void -__TC_init_table () +__TC_init_table (void) { - setup_entry (CORBA_Short, tk_short); - setup_entry (CORBA_Long, tk_long); - setup_entry (CORBA_UShort, tk_ushort); - setup_entry (CORBA_ULong, tk_ulong); - - setup_entry (CORBA_Float, tk_float); - setup_entry (CORBA_Double, tk_double); - - setup_entry (CORBA_Boolean, tk_boolean); - setup_entry (CORBA_Char, tk_char); - setup_entry (CORBA_Octet, tk_octet); - setup_entry (CORBA_Any, tk_any); - - setup_entry (CORBA_TypeCode_ptr, tk_TypeCode); - setup_entry (CORBA_Principal_ptr, tk_Principal); - setup_entry (CORBA_Object_ptr, tk_objref); - - enum generic_enum {a, b, c, d}; - - // XXX workaround for G++ 2.6.3 bug - // setup_entry (generic_enum, tk_enum); - table [tk_enum].size = sizeof (generic_enum); - table [tk_enum].alignment = sizeof (generic_enum); - - setup_entry (CORBA_String, tk_string); - setup_entry (CORBA_OctetSeq, tk_sequence); - - setup_entry (CORBA_LongLong, tk_longlong); - setup_entry (CORBA_ULongLong, tk_ulonglong); - setup_entry (CORBA_LongDouble, tk_longdouble); - setup_entry (CORBA_WChar, tk_wchar); - setup_entry (CORBA_WString, tk_wstring); + setup_entry (CORBA_Short, tk_short); + setup_entry (CORBA_Long, tk_long); + setup_entry (CORBA_UShort, tk_ushort); + setup_entry (CORBA_ULong, tk_ulong); + + setup_entry (CORBA_Float, tk_float); + setup_entry (CORBA_Double, tk_double); + + setup_entry (CORBA_Boolean, tk_boolean); + setup_entry (CORBA_Char, tk_char); + setup_entry (CORBA_Octet, tk_octet); + setup_entry (CORBA_Any, tk_any); + + setup_entry (CORBA_TypeCode_ptr, tk_TypeCode); + setup_entry (CORBA_Principal_ptr, tk_Principal); + setup_entry (CORBA_Object_ptr, tk_objref); + + enum generic_enum {a, b, c, d}; + + // XXX workaround for G++ 2.6.3 bug + // setup_entry (generic_enum, tk_enum); + table [tk_enum].size = sizeof (generic_enum); + table [tk_enum].alignment = sizeof (generic_enum); + + setup_entry (CORBA_String, tk_string); + setup_entry (CORBA_OctetSeq, tk_sequence); + + setup_entry (CORBA_LongLong, tk_longlong); + setup_entry (CORBA_ULongLong, tk_ulonglong); + setup_entry (CORBA_LongDouble, tk_longdouble); + setup_entry (CORBA_WChar, tk_wchar); + setup_entry (CORBA_WString, tk_wstring); } #undef setup - -// -// For a given typecode, figure out its size and alignment needs. This -// version is used mostly when traversing other typecodes, and follows -// these rules: +// For a given typecode, figure out its size and alignment needs. +// This version is used mostly when traversing other typecodes, and +// follows these rules: // // - Some typecodes are illegal (can't be nested inside others); // - Indirections are allowed; @@ -289,208 +284,202 @@ __TC_init_table () // // When the routine returns, the stream has skipped this TypeCode. // -// "size" is returned, "alignment" is an 'out' parameter. If it is non-null, -// "tc" is initialized to hold the contents of the TypeCode; it depends on -// the contents of the original stream to be valid. -// -// XXX explore splitting apart returning the size/alignment data and the -// TypeCode initialization; union traversal would benefit a bit, but it -// would need more than that to make it as speedy as struct traversal. +// "size" is returned, "alignment" is an 'out' parameter. If it is +// non-null, "tc" is initialized to hold the contents of the TypeCode; +// it depends on the contents of the original stream to be valid. // +// XXX explore splitting apart returning the size/alignment data and +// the TypeCode initialization; union traversal would benefit a bit, +// but it would need more than that to make it as speedy as struct +// traversal. + static size_t -calc_nested_size_and_alignment ( - CORBA_TypeCode_ptr tc, - CDR *original_stream, - size_t &alignment, - CORBA_Environment &env -) +calc_nested_size_and_alignment (CORBA_TypeCode_ptr tc, + CDR *original_stream, + size_t &alignment, + CORBA_Environment &env) { - // - // Get the "kind" ... if this is an indirection, this is a - // guess which will soon be updated. - // - CORBA_ULong temp; - CORBA_TCKind kind; + // Get the "kind" ... if this is an indirection, this is a guess + // which will soon be updated. + CORBA_ULong temp; + CORBA_TCKind kind; - if (original_stream->get_ulong (temp) == CORBA_B_FALSE) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + if (original_stream->get_ulong (temp) == CORBA_B_FALSE) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - env.clear (); - kind = (CORBA_TCKind) temp; + env.clear (); + kind = (CORBA_TCKind) temp; - // - // Check for indirection, setting up the right CDR stream to - // use when getting the rest of the parameters. (We rely on - // the fact that indirections may not point to indirections.) - // - CDR indirected_stream; - CDR *stream; + // Check for indirection, setting up the right CDR stream to use + // when getting the rest of the parameters. (We rely on the fact + // that indirections may not point to indirections.) + CDR indirected_stream; + CDR *stream; - if (kind == ~0) { - CORBA_Long offset; + if (kind == ~0) + { + CORBA_Long offset; - // - // Get indirection, sanity check it, set up new stream - // pointing there. - // - // XXX access to "real" size limit for this typecode and - // use it to check for errors before indirect and to limit - // the new stream's length. ULONG_MAX is too much! - // - if (!original_stream->get_long (offset) - || offset >= -8 - || ((-offset) & 0x03) != 0) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + // Get indirection, sanity check it, set up new stream pointing + // there. + // + // XXX access to "real" size limit for this typecode and use it + // to check for errors before indirect and to limit the new + // stream's length. ULONG_MAX is too much! + + if (!original_stream->get_long (offset) + || offset >= -8 + || ((-offset) & 0x03) != 0) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - offset -= 4; // correct for get_long update + offset -= 4; // correct for get_long update - indirected_stream.next = original_stream->next + (ptr_arith_t) offset; - indirected_stream.remaining = (size_t) ULONG_MAX; - stream = &indirected_stream; + indirected_stream.next = original_stream->next + (ptr_arith_t) offset; + indirected_stream.remaining = (size_t) ULONG_MAX; + stream = &indirected_stream; - // - // Fetch indirected-to TCKind, deducing byte order. - // - if (*indirected_stream.next == 0) // big-endian? - indirected_stream.do_byteswap = (MY_BYTE_SEX != 0); - else - indirected_stream.do_byteswap = (MY_BYTE_SEX == 0); - - if (!indirected_stream.get_ulong (temp)) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + // Fetch indirected-to TCKind, deducing byte order. + + if (*indirected_stream.next == 0) // big-endian? + indirected_stream.do_byteswap = (MY_BYTE_SEX != 0); + else + indirected_stream.do_byteswap = (MY_BYTE_SEX == 0); + + if (!indirected_stream.get_ulong (temp)) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - kind = (CORBA_TCKind) temp; + kind = (CORBA_TCKind) temp; - } else - stream = original_stream; + } + else + stream = original_stream; - // - // Check for illegal TCKind enum values ... out of range, or which - // represent data values that can't be nested. (Some can't even - // exist freestanding!) - // - if (kind >= TC_KIND_COUNT - || kind <= tk_void - || kind == tk_except) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + // Check for illegal TCKind enum values ... out of range, or which + // represent data values that can't be nested. (Some can't even + // exist freestanding!) + + if (kind >= TC_KIND_COUNT + || kind <= tk_void + || kind == tk_except) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - // - // Use attribute calculator routine if it exists; these are needed - // only for variable-sized data types, with encapsulated parameter - // lists that affect the size and alignment of "top level" memory - // needed to hold an instance of this type. - // - if (table [kind].calc != 0) { - assert (table [kind].size == 0); + // Use attribute calculator routine if it exists; these are needed + // only for variable-sized data types, with encapsulated parameter + // lists that affect the size and alignment of "top level" memory + // needed to hold an instance of this type. - // - // Pull encapsulation length out of the stream. - // - if (stream->get_ulong (temp) == CORBA_B_FALSE) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + if (table [kind].calc != 0) + { + assert (table [kind].size == 0); + + // Pull encapsulation length out of the stream. + if (stream->get_ulong (temp) == CORBA_B_FALSE) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - // - // Initialize the TypeCode if requested - // - if (tc) { - tc->_kind = kind; - tc->_buffer = stream->next; - tc->_length = temp; + // Initialize the TypeCode if requested + if (tc) + { + tc->_kind = kind; + tc->_buffer = stream->next; + tc->_length = temp; } - // - // Set up a separate stream for the parameters; it may easily - // have a different byte order, and this is as simple a way - // as any to ensure correctness. Then use the calculator - // routine to calculate size and alignment. - // - CDR sub_encapsulation; - size_t size; + // Set up a separate stream for the parameters; it may easily + // have a different byte order, and this is as simple a way as + // any to ensure correctness. Then use the calculator routine + // to calculate size and alignment. - assert (temp <= UINT_MAX); - sub_encapsulation.setup_encapsulation (stream->next, (size_t) temp); - size = table [kind].calc (&sub_encapsulation, alignment, env); + CDR sub_encapsulation; + size_t size; - // - // Check for garbage at end of parameter lists, or other cases - // where parameters and the size allocated to them don't jive. - // - stream->skip_bytes ((unsigned) temp); - if (stream->next != sub_encapsulation.next) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + assert (temp <= UINT_MAX); + sub_encapsulation.setup_encapsulation (stream->next, (size_t) temp); + size = table [kind].calc (&sub_encapsulation, alignment, env); + + // Check for garbage at end of parameter lists, or other cases + // where parameters and the size allocated to them don't jive. + + stream->skip_bytes ((unsigned) temp); + if (stream->next != sub_encapsulation.next) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - return size; + return size; } - assert (table [kind].size != 0); // fixed size data type + assert (table [kind].size != 0); // fixed size data type - // - // Reinitialize the TypeCode if requested; this consumes any TypeCode - // parameters in the stream. They only exist for TCKind values that - // have parameters, but which represent fixed-size data types in the - // binary representation: tk_string, tk_wstring, tk_objref, tk_enum, - // and tk_sequence. - // - if (tc) { - CORBA_ULong len; - - tc->_kind = kind; - switch (kind) { - default: - assert (table [kind].skipper == 0); - break; - - case tk_string: - case tk_wstring: - if (stream->get_ulong (len) == CORBA_B_FALSE) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + // Reinitialize the TypeCode if requested; this consumes any + // TypeCode parameters in the stream. They only exist for TCKind + // values that have parameters, but which represent fixed-size data + // types in the binary representation: tk_string, tk_wstring, + // tk_objref, tk_enum, and tk_sequence. + + if (tc) + { + CORBA_ULong len; + + tc->_kind = kind; + switch (kind) + { + default: + assert (table [kind].skipper == 0); + break; + + case tk_string: + case tk_wstring: + if (stream->get_ulong (len) == CORBA_B_FALSE) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - tc->_length = len; - break; - - case tk_enum: - case tk_objref: - case tk_sequence: - if (stream->get_ulong (len) == CORBA_B_FALSE) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + tc->_length = len; + break; + + case tk_enum: + case tk_objref: + case tk_sequence: + if (stream->get_ulong (len) == CORBA_B_FALSE) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - tc->_length = len; + tc->_length = len; - assert (len < UINT_MAX); - tc->_buffer = stream->next; - stream->skip_bytes ((unsigned) len); - break; + assert (len < UINT_MAX); + tc->_buffer = stream->next; + stream->skip_bytes ((unsigned) len); + break; } - // - // Otherwise, consume any parameters without stuffing them into - // a temporary TypeCode. - // - } else if (table [kind].skipper != 0 - && table [kind].skipper (stream) == CORBA_B_FALSE) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + // Otherwise, consume any parameters without stuffing them into + // a temporary TypeCode. + } + else if (table [kind].skipper != 0 + && table [kind].skipper (stream) == CORBA_B_FALSE) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - // - // Return statically known values. - // - alignment = table [kind].alignment; - return table [kind].size; + // Return statically known values. + alignment = table [kind].alignment; + return table [kind].size; } - -// // Given typecode bytes for a structure (or exception), figure out its // alignment and size; return size, alignment is an 'out' parameter. // Only "tk_struct" (or "tk_except") has been taken out of the stream @@ -502,1014 +491,939 @@ calc_nested_size_and_alignment ( // // This routine recognizes that exceptions are just structs with some // additional information. Different environments may differ in what -// that additional information is, so this routine may need to be taught -// about compiler-specific representation of that additional "RTTI" data. -// +// that additional information is, so this routine may need to be +// taught about compiler-specific representation of that additional +// "RTTI" data. + static size_t -calc_struct_and_except_attributes ( - CDR *stream, - size_t &alignment, - CORBA_Boolean is_exception, - CORBA_Environment &env -) +calc_struct_and_except_attributes (CDR *stream, + size_t &alignment, + CORBA_Boolean is_exception, + CORBA_Environment &env) { - CORBA_ULong members; - size_t size; + CORBA_ULong members; + size_t size; + + // Exceptions are like structs, with key additions (all of which + // might need to be be applied to structures!): vtable, typecode, + // and refcount. The size must include these "hidden" members. + // + // NOTE: in environments with "true" C++ exceptions, there may need + // to be a slot for additional "RTTI" information; maybe it is part + // of the vtable, or maybe not. Or, that information (needed to + // determine which 'catch' clauses apply) may only be provided by + // the compiler to the runtime support for the "throw" statement. + + if (is_exception) + { + size = sizeof (CORBA_Exception); + alignment = table [tk_TypeCode].alignment; + } + else + { + alignment = 1; + size = 0; + } - // - // Exceptions are like structs, with key additions (all of which - // might need to be be applied to structures!): vtable, typecode, - // and refcount. The size must include these "hidden" members. - // - // NOTE: in environments with "true" C++ exceptions, there may - // need to be a slot for additional "RTTI" information; maybe it - // is part of the vtable, or maybe not. Or, that information - // (needed to determine which 'catch' clauses apply) may only be - // provided by the compiler to the runtime support for the "throw" - // statement. - // - if (is_exception) { - size = sizeof (CORBA_Exception); - alignment = table [tk_TypeCode].alignment; - } else { - alignment = 1; - size = 0; + // skip rest of header (type ID and name) and collect the number of + // struct members + + if (!stream->skip_string () + || !stream->skip_string () + || !stream->get_ulong (members)) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - // - // skip rest of header (type ID and name) and collect the - // number of struct members - // - if (!stream->skip_string () - || !stream->skip_string () - || !stream->get_ulong (members)) { + // iterate over all the members, skipping their names and looking + // only at type data. + + for ( ; members != 0; members--) { + size_t member_size; + size_t member_alignment; + + // Skip name of the member. + if (!stream->skip_string ()) + { env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); return 0; - } + } - // - // iterate over all the members, skipping their names and - // looking only at type data. - // - for ( ; members != 0; members--) { - size_t member_size, member_alignment; + // Get size and alignment of the member, accounting for + // indirection and the various kinds of parameter encoding. - // - // Skip name of the member. - // - if (!stream->skip_string ()) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } + member_size = calc_nested_size_and_alignment (0, + stream, + member_alignment, + env); + if (env.exception () != 0) + return 0; - // - // Get size and alignment of the member, accounting for - // indirection and the various kinds of parameter encoding. - // - member_size = calc_nested_size_and_alignment (0, stream, - member_alignment, env); - if (env.exception () != 0) - return 0; + // Round up the struct size to handle member alignment (by adding + // internal padding), then update the current size to handle the + // member's size. - // - // Round up the struct size to handle member alignment (by - // adding internal padding), then update the current size - // to handle the member's size. - // - size = (size_t) align_binary (size, member_alignment); - size += member_size; + size = (size_t) align_binary (size, member_alignment); + size += member_size; - // - // Finally update the overall structure alignment requirement, - // if this element must be more strongly aligned. - // - if (member_alignment > alignment) - alignment = member_alignment; - }; + // Finally update the overall structure alignment requirement, if + // this element must be more strongly aligned. - // - // Round up the structure size to match its overall alignment. - // This adds tail padding, if needed. - // - return (size_t) align_binary (size, alignment); -} + if (member_alignment > alignment) + alignment = member_alignment; + }; + // Round up the structure size to match its overall alignment. This + // adds tail padding, if needed. + return (size_t) align_binary (size, alignment); +} -// // Calculate size and alignment for a structure. -// + static size_t -calc_struct_attributes ( - CDR *stream, - size_t &alignment, - CORBA_Environment &env -) +calc_struct_attributes (CDR *stream, + size_t &alignment, + CORBA_Environment &env) { - return calc_struct_and_except_attributes (stream, - alignment, CORBA_B_FALSE, env); + return calc_struct_and_except_attributes (stream, + alignment, + CORBA_B_FALSE, + env); } - -// // Calculate size and alignment for an exception. -// + static size_t -calc_exception_attributes ( - CDR *stream, - size_t &alignment, - CORBA_Environment &env -) +calc_exception_attributes (CDR *stream, + size_t &alignment, + CORBA_Environment &env) { - return calc_struct_and_except_attributes (stream, - alignment, CORBA_B_TRUE, env); + return calc_struct_and_except_attributes (stream, + alignment, + CORBA_B_TRUE, + env); } - -// // Calculate and return sizes for both parts of a union, as needed by // other code. Return value is the overall size. The padded size of // the discriminant is needed to traverse the two values separately. // Unfortunately that is not quite practical to do with a single pass -// over the typecode: the inter-element padding changes depending on +// over the typecode: the inter-element padding changes depending on // the strictest alignment required by _any_ arm of the union. -// + static size_t -calc_key_union_attributes ( - CDR *stream, - size_t &overall_alignment, - size_t &discrim_size_with_pad, - CORBA_Environment &env -) +calc_key_union_attributes (CDR *stream, + size_t &overall_alignment, + size_t &discrim_size_with_pad, + CORBA_Environment &env) { - CORBA_ULong members; - CORBA_ULong temp; - size_t discrim_size; - size_t value_alignment, value_size; - - overall_alignment = value_alignment = 1; - value_size = discrim_size_with_pad = 0; - - // - // Skip initial optional members (type ID and name). - // - if (!stream->skip_string () // type ID - || !stream->skip_string ()) { // typedef name - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + CORBA_ULong members; + CORBA_ULong temp; + size_t discrim_size; + size_t value_alignment; + size_t value_size; + + overall_alignment = value_alignment = 1; + value_size = discrim_size_with_pad = 0; + + // Skip initial optional members (type ID and name). + + if (!stream->skip_string () // type ID + || !stream->skip_string ()) + { // typedef name + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - // - // Calculate discriminant size and alignment: it's the first - // member of the "struct" representing the union. We detect - // illegal discriminant kinds a bit later. - // - CORBA_TypeCode discrim_tc (tk_void); + // Calculate discriminant size and alignment: it's the first member + // of the "struct" representing the union. We detect illegal + // discriminant kinds a bit later. + + CORBA_TypeCode discrim_tc (tk_void); + + discrim_size = calc_nested_size_and_alignment (&discrim_tc, + stream, + overall_alignment, + env); + if (env.exception () != 0) + return 0; + + // skip "default used" indicator, and save "member count" + + if (!stream->get_ulong (temp) // default used + || !stream->get_ulong (members)) + { // member count + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } - discrim_size = calc_nested_size_and_alignment (&discrim_tc, - stream, overall_alignment, env); - if (env.exception () != 0) - return 0; + // iterate over the tuples for all the members; all we care about is + // their types, which can affect either alignment or padding + // requirement for the union part of the construct. - // - // skip "default used" indicator, and save "member count" - // - if (!stream->get_ulong (temp) // default used - || !stream->get_ulong (members)) { // member count - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } + for ( ; members != 0; members--) { + size_t member_size, member_alignment; + // Skip member label; its size varies with discriminant type, but + // here we don't care about its content. This is where illegal + // discriminant kinds are detected. // - // iterate over the tuples for all the members; all we care about - // is their types, which can affect either alignment or padding - // requirement for the union part of the construct. - // - for ( ; members != 0; members--) { - size_t member_size, member_alignment; + // NOTE: This modifies 94-9-32 Appendix A to stipulate that + // "long long" values are not legal as discriminants. - // - // Skip member label; its size varies with discriminant type, but - // here we don't care about its content. This is where illegal - // discriminant kinds are detected. - // - // NOTE: This modifies 94-9-32 Appendix A to stipulate that - // "long long" values are not legal as discriminants. - // - switch (discrim_tc._kind) { - case tk_short: - case tk_ushort: - case tk_wchar: - { - CORBA_Short s; - - if (!stream->get_short (s)) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } - } - break; + switch (discrim_tc._kind) + { + case tk_short: + case tk_ushort: + case tk_wchar: + { + CORBA_Short s; - case tk_long: - case tk_ulong: - case tk_enum: + if (!stream->get_short (s)) { - CORBA_Long l; - - if (!stream->get_long (l)) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - break; + } + break; - case tk_boolean: - case tk_char: - { - char c; + case tk_long: + case tk_ulong: + case tk_enum: + { + CORBA_Long l; - if (!stream->get_byte (c)) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } + if (!stream->get_long (l)) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - break; - - default: - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; } + break; - // - // We also don't care about any member name. - // - if (!stream->skip_string ()) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + case tk_boolean: + case tk_char: + { + char c; + + if (!stream->get_byte (c)) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } } + break; - // - // Get the member size and alignment. - // - member_size = calc_nested_size_and_alignment (0, stream, - member_alignment, env); - if (env.exception () != 0) - return 0; + default: + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } - // - // Save the largest member and alignment. They don't need to - // be changed in sync -- e.g. "long double" size is larger - // than its alignment restriction on SPARC, x86, and some m68k - // platforms. - // - if (member_size > value_size) - value_size = member_size; - if (member_alignment > value_alignment) - value_alignment = member_alignment; - } + // We also don't care about any member name. - // - // Round up the discriminator's size to include padding it needs - // in order to be followed by the value. - // - discrim_size_with_pad = (size_t) - align_binary (discrim_size, value_alignment); + if (!stream->skip_string ()) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } - // - // Now calculate the overall size of the structure, which is the - // discriminator, inter-element padding, value, and tail padding. - // We know all of those except tail padding, which is a function - // of the overall alignment. (Ensures that arrays of these can - // be safely allocated and accessed!) - // - if (value_alignment > overall_alignment) - overall_alignment = value_alignment; + // Get the member size and alignment. - return (size_t) align_binary (discrim_size_with_pad + value_size, - overall_alignment); + member_size = calc_nested_size_and_alignment (0, + stream, + member_alignment, + env); + if (env.exception () != 0) + return 0; + + // Save the largest member and alignment. They don't need to be + // changed in sync -- e.g. "long double" size is larger than its + // alignment restriction on SPARC, x86, and some m68k platforms. + if (member_size > value_size) + value_size = member_size; + if (member_alignment > value_alignment) + value_alignment = member_alignment; + } + + // Round up the discriminator's size to include padding it needs in + // order to be followed by the value. + discrim_size_with_pad = (size_t) align_binary (discrim_size, + value_alignment); + + // Now calculate the overall size of the structure, which is the + // discriminator, inter-element padding, value, and tail padding. + // We know all of those except tail padding, which is a function of + // the overall alignment. (Ensures that arrays of these can be + // safely allocated and accessed!) + + if (value_alignment > overall_alignment) + overall_alignment = value_alignment; + + return (size_t) align_binary (discrim_size_with_pad + value_size, + overall_alignment); } - -// // Calculate size and alignment for a CORBA discriminated union. // -// Note that this is really a two-element structure. The first element -// is the discriminator; the second is the value. All normal structure -// padding/alignment rules apply. In particular, all arms of the -// union have the same initial address (adequately aligned for any -// of the members). -// +// Note that this is really a two-element structure. The first +// element is the discriminator; the second is the value. All normal +// structure padding/alignment rules apply. In particular, all arms +// of the union have the same initial address (adequately aligned for +// any of the members). + static size_t -calc_union_attributes ( - CDR *stream, - size_t &alignment, - CORBA_Environment &env -) +calc_union_attributes (CDR *stream, + size_t &alignment, + CORBA_Environment &env) { - size_t scratch; + size_t scratch; - return calc_key_union_attributes (stream, alignment, scratch, env); + return calc_key_union_attributes (stream, alignment, scratch, env); } - -// // Calculate size and alignment for a typedeffed type. -// + static size_t -calc_alias_attributes ( - CDR *stream, - size_t &alignment, - CORBA_Environment &env -) +calc_alias_attributes (CDR *stream, + size_t &alignment, + CORBA_Environment &env) { - // - // Skip type ID and name in the parameter stream - // - if (!stream->skip_string () // type ID - || !stream->skip_string () // typedef name - ) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + // Skip type ID and name in the parameter stream + + if (!stream->skip_string () // type ID + || !stream->skip_string ()) // typedef name + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - // - // The typedef is identical to the type for which it stands. - // - return calc_nested_size_and_alignment (0, stream, alignment, env); + // The typedef is identical to the type for which it stands. + return calc_nested_size_and_alignment (0, stream, alignment, env); } - -// // Calculate size and alignment of an array. (All such arrays are -// described as single dimensional, even though the IDL definition -// may specify a multidimensional array ... such arrays are treated -// as nested single dimensional arrays.) -// +// described as single dimensional, even though the IDL definition may +// specify a multidimensional array ... such arrays are treated as +// nested single dimensional arrays.) + static size_t -calc_array_attributes ( - CDR *stream, - size_t &alignment, - CORBA_Environment &env -) +calc_array_attributes (CDR *stream, + size_t &alignment, + CORBA_Environment &env) { - size_t member_size; - CORBA_ULong member_count; + size_t member_size; + CORBA_ULong member_count; - // - // get size and alignment of the array member - // - member_size = calc_nested_size_and_alignment (0, stream, alignment, env); - if (env.exception () != 0) - return 0; + // get size and alignment of the array member - // - // Get and check count of members. - // - if (stream->get_ulong (member_count) == CORBA_B_FALSE - || member_count > UINT_MAX) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + member_size = calc_nested_size_and_alignment (0, stream, alignment, env); + if (env.exception () != 0) + return 0; + + // Get and check count of members. + + if (stream->get_ulong (member_count) == CORBA_B_FALSE + || member_count > UINT_MAX) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - // - // Array size is a function only of member number and count - // - return member_size * (size_t) member_count; + // Array size is a function only of member number and count + return member_size * (size_t) member_count; } - -// // Visit each of the elements of a structure. -// -static -CORBA_TypeCode::traverse_status -struct_traverse ( - CDR *stream, - const void *value1, - const void *value2, - CORBA_TypeCode::traverse_status (_FAR *visit) ( - CORBA_TypeCode_ptr tc, - const void *value1, - const void *value2, - void *context, - CORBA_Environment &env - ), - void *context, - CORBA_Environment &env -) + +static CORBA_TypeCode::traverse_status +struct_traverse (CDR *stream, + const void *value1, + const void *value2, + CORBA_TypeCode::traverse_status (_FAR *visit) + (CORBA_TypeCode_ptr tc, + const void *value1, + const void *value2, + void *context, + CORBA_Environment &env), + void *context, + CORBA_Environment &env) { - // - // Skip over the type ID and type name in the parameters, then - // get the number of members. - // - CORBA_ULong members; + // Skip over the type ID and type name in the parameters, then get + // the number of members. + CORBA_ULong members; - if (!stream->skip_string () // type ID - || !stream->skip_string () // type name - || !stream->get_ulong (members)) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return CORBA_TypeCode::TRAVERSE_STOP; + if (!stream->skip_string () // type ID + || !stream->skip_string () // type name + || !stream->get_ulong (members)) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return CORBA_TypeCode::TRAVERSE_STOP; } - // - // Visit each member of the structure/exception. The initial - // pointer(s) point at the first values to visit. For structs - // we could avoid the inter-member padding ... not for the - // case of exceptions. No big deal. - // - // NOTE: For last element, could turn visit() call into something - // subject to compiler's tail call optimization and thus save - // a stack frame. - // - CORBA_TypeCode::traverse_status retval; + // Visit each member of the structure/exception. The initial + // pointer(s) point at the first values to visit. For structs we + // could avoid the inter-member padding ... not for the case of + // exceptions. No big deal. + // + // NOTE: For last element, could turn visit() call into something + // subject to compiler's tail call optimization and thus save a + // stack frame. - for (retval = CORBA_TypeCode::TRAVERSE_CONTINUE; - members != 0 && retval == CORBA_TypeCode::TRAVERSE_CONTINUE; - members--) { - CORBA_TypeCode member_tc (tk_null); - size_t size, alignment; + CORBA_TypeCode::traverse_status retval; - // - // Skip the member's name in the parameter list. - // - if (!stream->skip_string ()) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return CORBA_TypeCode::TRAVERSE_STOP; + for (retval = CORBA_TypeCode::TRAVERSE_CONTINUE; + members != 0 && retval == CORBA_TypeCode::TRAVERSE_CONTINUE; + members--) + { + CORBA_TypeCode member_tc (tk_null); + size_t size; + size_t alignment; + + // Skip the member's name in the parameter list. + + if (!stream->skip_string ()) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return CORBA_TypeCode::TRAVERSE_STOP; } - // - // Get the member's size, alignment, and a temporary TypeCode, - // skipping that TypeCode in the stream as we do so. - // - // This accounts for all variations: different or nonexistent - // parameter lists, errors such as out-of-range TCKind values - // or nested exceptions, and indirected typecodes. - // - size = calc_nested_size_and_alignment (&member_tc, stream, - alignment, env); - if (env.exception () != 0) - return CORBA_TypeCode::TRAVERSE_STOP; + // Get the member's size, alignment, and a temporary TypeCode, + // skipping that TypeCode in the stream as we do so. + // + // This accounts for all variations: different or nonexistent + // parameter lists, errors such as out-of-range TCKind values or + // nested exceptions, and indirected typecodes. + + size = calc_nested_size_and_alignment (&member_tc, + stream, + alignment, + env); + if (env.exception () != 0) + return CORBA_TypeCode::TRAVERSE_STOP; - // - // Pad the value pointers to account for the alignment requirements - // of this member, then visit. - // - value1 = ptr_align_binary ((const unsigned char *) value1, alignment); - value2 = ptr_align_binary ((const unsigned char *) value2, alignment); + // Pad the value pointers to account for the alignment + // requirements of this member, then visit. - retval = visit (&member_tc, value1, value2, context, env); + value1 = ptr_align_binary ((const u_char *) value1, alignment); + value2 = ptr_align_binary ((const u_char *) value2, alignment); + + retval = visit (&member_tc, value1, value2, context, env); - // - // Update 'value' pointers to account for the size of the - // values just visited. - // - value1 = size + (char *)value1; - value2 = size + (char *)value2; + // Update 'value' pointers to account for the size of the values + // just visited. + value1 = size + (char *)value1; + value2 = size + (char *)value2; - if (env.exception () != 0) - retval = CORBA_TypeCode::TRAVERSE_STOP; + if (env.exception () != 0) + retval = CORBA_TypeCode::TRAVERSE_STOP; } - return retval; + return retval; } - -// // cast the discriminant values to the right type and compare them. -// + static CORBA_Boolean -match_value ( - CORBA_TCKind kind, - CDR *tc_stream, - const void *value, - CORBA_Environment &env -) +match_value (CORBA_TCKind kind, + CDR *tc_stream, + const void *value, + CORBA_Environment &env) { - CORBA_Boolean retval = CORBA_B_FALSE; - - switch (kind) { - case tk_short: - case tk_ushort: - { - CORBA_UShort discrim; + CORBA_Boolean retval = CORBA_B_FALSE; - if (tc_stream->get_ushort (discrim) != CORBA_B_FALSE) { - retval = (discrim == *(CORBA_UShort *)value); - } else { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - } - } - break; - - case tk_long: - case tk_ulong: - { - CORBA_ULong discrim; - - if (tc_stream->get_ulong (discrim) != CORBA_B_FALSE) { - retval = (discrim == *(CORBA_ULong *)value); - } else { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - } - } - break; + switch (kind) + { + case tk_short: + case tk_ushort: + { + CORBA_UShort discrim; + + if (tc_stream->get_ushort (discrim) != CORBA_B_FALSE) + retval = (discrim == *(CORBA_UShort *)value); + else + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + } + break; + + case tk_long: + case tk_ulong: + { + CORBA_ULong discrim; + + if (tc_stream->get_ulong (discrim) != CORBA_B_FALSE) + retval = (discrim == *(CORBA_ULong *)value); + else + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + } + break; - case tk_enum: - { - CORBA_ULong discrim; - - if (tc_stream->get_ulong (discrim) != CORBA_B_FALSE) { - retval = (discrim == *(unsigned *)value); - } else { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - } - } - break; + case tk_enum: + { + CORBA_ULong discrim; + + if (tc_stream->get_ulong (discrim) != CORBA_B_FALSE) + retval = (discrim == *(unsigned *)value); + else + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + } + break; - case tk_boolean: - { - CORBA_Boolean discrim; - - if (tc_stream->get_boolean (discrim) != CORBA_B_FALSE) { - retval = (discrim == *(CORBA_Boolean *)value); - } else { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - } - } - break; - - case tk_char: - { - CORBA_Char discrim; - - if (tc_stream->get_char (discrim) != CORBA_B_FALSE) { - retval = (discrim == *(CORBA_Char *)value); - } else { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - } - } - break; + case tk_boolean: + { + CORBA_Boolean discrim; + + if (tc_stream->get_boolean (discrim) != CORBA_B_FALSE) + retval = (discrim == *(CORBA_Boolean *)value); + else + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + } + break; + + case tk_char: + { + CORBA_Char discrim; + + if (tc_stream->get_char (discrim) != CORBA_B_FALSE) + retval = (discrim == *(CORBA_Char *)value); + else + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + } + break; - case tk_wchar: - { - CORBA_WChar discrim; - - if (tc_stream->get_wchar (discrim) != CORBA_B_FALSE) { - retval = (discrim == *(CORBA_WChar *)value); - } else { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - } - } - break; + case tk_wchar: + { + CORBA_WChar discrim; + + if (tc_stream->get_wchar (discrim) != CORBA_B_FALSE) + retval = (discrim == *(CORBA_WChar *)value); + else + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + } + break; - - default: - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + default: + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); } - return retval; + return retval; } -// -// Visit the two elements of the union: the discrminant, and then any +// Visit the two elements of the union: the discrminant, and then any // specific value as indicated by the discriminant of value1. -// -static -CORBA_TypeCode::traverse_status -union_traverse ( - CDR *stream, - const void *value1, - const void *value2, - CORBA_TypeCode::traverse_status - (_FAR *visit) ( - CORBA_TypeCode_ptr tc, - const void *value1, - const void *value2, - void *context, - CORBA_Environment &env - ), - void *context, - CORBA_Environment &env -) + +static CORBA_TypeCode::traverse_status +union_traverse (CDR *stream, + const void *value1, + const void *value2, + CORBA_TypeCode::traverse_status (_FAR *visit) + (CORBA_TypeCode_ptr tc, + const void *value1, + const void *value2, + void *context, + CORBA_Environment &env), + void *context, + CORBA_Environment &env) { - size_t discrim_size_with_pad; + size_t discrim_size_with_pad; + + // Figure out size of discriminant plus padding, used to adjust + // value pointers later. This can't be calculated without looking + // at all branches of the union ... forcing union traversal to be a + // two-pass algorithm, unless/until some data gets squirreled away. + { + CDR temp_cdr; + size_t scratch; + + temp_cdr.next = stream->next; + temp_cdr.remaining = stream->remaining; + temp_cdr.do_byteswap = stream->do_byteswap; + temp_cdr.do_free = 0; + + (void) calc_key_union_attributes (&temp_cdr, + scratch, + discrim_size_with_pad, + env); + } + if (env.exception() != 0) + return CORBA_TypeCode::TRAVERSE_STOP; + + // Skip the optional type ID and type name. + if (!stream->skip_string () // type ID, hidden + || !stream->skip_string ()) + { // typedef name + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return CORBA_TypeCode::TRAVERSE_STOP; + } - // - // Figure out size of discriminant plus padding, used to adjust value - // pointers later. This can't be calculated without looking at all - // branches of the union ... forcing union traversal to be a two-pass - // algorithm, unless/until some data gets squirreled away. - // - { - CDR temp_cdr; - size_t scratch; + // Get and skip the discriminant's TypeCode. This allow for + // indirection (e.g. a complex enum discriminant). We use that + // TypeCode to visit the discriminant. + // + // We know the kind is legal and the TypeCode is valid because this + // repeats work we did earlier -- so checks are omitted. - temp_cdr.next = stream->next; - temp_cdr.remaining = stream->remaining; - temp_cdr.do_byteswap = stream->do_byteswap; - temp_cdr.do_free = 0; + CORBA_TypeCode discrim_tc (tk_null); - (void) calc_key_union_attributes (&temp_cdr, scratch, - discrim_size_with_pad, env); - } - if (env.exception() != 0) - return CORBA_TypeCode::TRAVERSE_STOP; + { + size_t scratch; - // - // Skip the optional type ID and type name. - // - if (!stream->skip_string () // type ID, hidden - || !stream->skip_string ()) { // typedef name - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return CORBA_TypeCode::TRAVERSE_STOP; - } + (void) calc_nested_size_and_alignment (&discrim_tc, + stream, + scratch, + env); + } - // - // Get and skip the discriminant's TypeCode. This allow for - // indirection (e.g. a complex enum discriminant). We use - // that TypeCode to visit the discriminant. - // - // We know the kind is legal and the TypeCode is valid because - // this repeats work we did earlier -- so checks are omitted. - // - CORBA_TypeCode discrim_tc (tk_null); + if (visit (&discrim_tc, + value1, + value2, + context, + env) == CORBA_TypeCode::TRAVERSE_STOP) + return CORBA_TypeCode::TRAVERSE_STOP; - { - size_t scratch; + // Adjust the pointers to point to the other member of the union; + // this ensures alignment for any of the values. Save the pointer + // to the discriminant though; we need it to find out which member + // to visit! - (void) calc_nested_size_and_alignment (&discrim_tc, - stream, scratch, env); - } - - if (visit (&discrim_tc, value1, value2, context, env) - == CORBA_TypeCode::TRAVERSE_STOP) - return CORBA_TypeCode::TRAVERSE_STOP; + const void *discrim_ptr = value1; - // - // Adjust the pointers to point to the other member of the - // union; this ensures alignment for any of the values. - // Save the pointer to the discriminant though; we need it - // to find out which member to visit! - // - const void *discrim_ptr = value1; + value1 = discrim_size_with_pad + (char *) value1; + value2 = discrim_size_with_pad + (char *) value2; - value1 = discrim_size_with_pad + (char *) value1; - value2 = discrim_size_with_pad + (char *) value2; + // Get the flag that tells if there's a "default" arm in this union, + // then the number of members in the union. - // - // Get the flag that tells if there's a "default" arm in this - // union, then the number of members in the union. - // - CORBA_Long default_used = 0; - CORBA_ULong member_count; + CORBA_Long default_used = 0; + CORBA_ULong member_count; - if (!stream->get_long (default_used)) { // default used - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return CORBA_TypeCode::TRAVERSE_STOP; + if (!stream->get_long (default_used)) + { + // default used + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return CORBA_TypeCode::TRAVERSE_STOP; } - if (!stream->get_ulong (member_count)) { // member count - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return CORBA_TypeCode::TRAVERSE_STOP; + if (!stream->get_ulong (member_count)) + { // member count + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return CORBA_TypeCode::TRAVERSE_STOP; } - // - // Scan to find the tuple whose value matches the discriminator. - // - // While we're scanning, record any default arm's information. - // If we can't find a match for the discriminant value, that arm - // will be used later. - // - unsigned char *default_tc_ptr = 0; - size_t default_tc_len; + // Scan to find the tuple whose value matches the discriminator. + // + // While we're scanning, record any default arm's information. If + // we can't find a match for the discriminant value, that arm will + // be used later. - while (member_count-- != 0) { - // - // Test to see if the discriminant value matches the one in - // the TypeCode; this skips the the discriminant value in - // this CDR stream. - // - CORBA_Boolean discrim_matched; + u_char *default_tc_ptr = 0; + size_t default_tc_len; - discrim_matched = match_value (discrim_tc._kind, - stream, discrim_ptr, env); - if (env.exception () != 0) - return CORBA_TypeCode::TRAVERSE_STOP; + while (member_count-- != 0) + { + // Test to see if the discriminant value matches the one in the + // TypeCode; this skips the the discriminant value in this CDR + // stream. - // - // Skip the name of the member; we never care about it. - // - if (!stream->skip_string ()) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return CORBA_TypeCode::TRAVERSE_STOP; - } + CORBA_Boolean discrim_matched; - // - // If this is the default member, remember where its - // typecode data is stored; we'll use it later. - // - if (default_used >= 0 && default_used-- == 0) { - default_tc_ptr = stream->next; - default_tc_len = stream->remaining; + discrim_matched = match_value (discrim_tc._kind, + stream, + discrim_ptr, + env); + if (env.exception () != 0) + return CORBA_TypeCode::TRAVERSE_STOP; + + // Skip the name of the member; we never care about it. + + if (!stream->skip_string ()) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return CORBA_TypeCode::TRAVERSE_STOP; } - // - // Get the TypeCode for this member. - // - // XXX we really don't care about size and alignment this time, - // only that we initialize the TypeCode. - // - CORBA_TypeCode tc (tk_null); - size_t scratch; + // If this is the default member, remember where its typecode + // data is stored; we'll use it later. - (void) calc_nested_size_and_alignment (&tc, stream, scratch, env); - if (env.exception () != 0) - return CORBA_TypeCode::TRAVERSE_STOP; + if (default_used >= 0 && default_used-- == 0) + { + default_tc_ptr = stream->next; + default_tc_len = stream->remaining; + } - // - // If we matched, visit the member and return. - // - if (discrim_matched) - return visit (&tc, value1, value2, context, env); - } + // Get the TypeCode for this member. + // + // XXX we really don't care about size and alignment this time, + // only that we initialize the TypeCode. - // - // If we get here, it means any default arm should be used. We - // know at least the basic sanity checks passed; we don't repeat. - // - if (default_tc_ptr) { - CDR temp_str; - size_t scratch; - CORBA_TypeCode tc (tk_null); + CORBA_TypeCode tc (tk_null); + size_t scratch; - temp_str.next = default_tc_ptr; - temp_str.remaining = default_tc_len; - temp_str.do_byteswap = stream->do_byteswap; + (void) calc_nested_size_and_alignment (&tc, stream, scratch, env); + if (env.exception () != 0) + return CORBA_TypeCode::TRAVERSE_STOP; - // - // Get and use the TypeCode. - // - // XXX we really don't care about size and alignment this time, - // only that we initialize the TypeCode. - // - (void) calc_nested_size_and_alignment (&tc, &temp_str, scratch, env); + // If we matched, visit the member and return. + if (discrim_matched) return visit (&tc, value1, value2, context, env); } - return CORBA_TypeCode::TRAVERSE_CONTINUE; -} - - -// -// For each node in "data", visit it. For singleton nodes that's all but -// a NOP; for structs, unions, etc it's more interesting. The visit routine -// can descend, if it chooses. -// -// NOTE: this does no memory allocation or deallocation except through use -// of the stack. Or at least, it should do none -- if you find that just -// traversing a data value allocates any memory, that's a bug to fix! -// -CORBA_TypeCode::traverse_status -CORBA_TypeCode::traverse ( - const void *value1, - const void *value2, - CORBA_TypeCode::traverse_status (_FAR *visit) ( - CORBA_TypeCode_ptr tc, - const void *value1, - const void *value2, - void *context, - CORBA_Environment &env - ), - void *context, - CORBA_Environment &env -) -{ - env.clear (); - // - // Quickly accomodate the bulk of cases, which are just (tail) calls - // to the visit() routine. We take advantage of the fact that these - // are largely in a convenient numeric range to work around poor - // optimization of "switch" code in some compilers. This improvement - // has in some cases been more than 5% faster (significant). - // - // NOTE: if for some reason the constants in the protocol spec - // (including Appendix A) change, this logic may need to be verified - // again. Luckily, changing protocol constants is quite rare; they - // normally just get added to (at the end). - // - if (_kind <= tk_objref - || (tk_longlong <= _kind && _kind <= tk_wstring)) - return visit (this, value1, value2, context, env); + // If we get here, it means any default arm should be used. We know + // at least the basic sanity checks passed; we don't repeat. - // - // Handle the cases that aren't in convenient numeric ranges. - // - traverse_status retval; + if (default_tc_ptr) + { + CDR temp_str; + size_t scratch; + CORBA_TypeCode tc (tk_null); - switch (_kind) { - case tk_string: - case tk_enum: - return visit (this, value1, value2, context, env); + temp_str.next = default_tc_ptr; + temp_str.remaining = default_tc_len; + temp_str.do_byteswap = stream->do_byteswap; + // Get and use the TypeCode. // - // Typedefs just add a delay, while we skip the typedef ID - // and name ... - // - case tk_alias: - { - CORBA_TypeCode_ptr tcp; - CORBA_Environment env2; - - // - // XXX rework for efficiency, this doesn't need to - // allocate memory during the traversal! - // - tcp = typecode_param (2, env); - if (env.exception () != 0) - return TRAVERSE_STOP; + // XXX we really don't care about size and alignment this time, + // only that we initialize the TypeCode. - retval = tcp->traverse (value1, value2, visit, context, env); + (void) calc_nested_size_and_alignment (&tc, &temp_str, scratch, env); + return visit (&tc, value1, value2, context, env); + } + return CORBA_TypeCode::TRAVERSE_CONTINUE; +} - tcp->Release (); - } - return retval; +// For each node in "data", visit it. For singleton nodes that's all +// but a NOP; for structs, unions, etc it's more interesting. The +// visit routine can descend, if it chooses. +// +// NOTE: this does no memory allocation or deallocation except through +// use of the stack. Or at least, it should do none -- if you find +// that just traversing a data value allocates any memory, that's a +// bug to fix! - // - // Exceptions in-memory are structures, except that there are data - // members "hidden" in front: vtable, typecode, refcount. We skip - // them, and allow the traversal code to account for the internal - // padding before the other elements of the exception. - // - // NOTE: see header comment re treatment of these values as "real" - // C++ exceptions. C++ RTTI data might need to be skipped. Also, - // see the comments in unmarshaling code: hard to throw these values. - // - // Not enough of the exception runtime is public for binary standards - // to exist for C++ exceptions yet. Compiler-specific code will need - // to handle examining, unmarshaling, and throwing of CORBA exceptions - // (in C++ environments) for some time. - // - case tk_except: - value1 = sizeof (CORBA_Exception) + (char *) value1; - value2 = sizeof (CORBA_Exception) + (char *) value2; - // FALLTHROUGH +CORBA_TypeCode::traverse_status +CORBA_TypeCode::traverse (const void *value1, + const void *value2, + CORBA_TypeCode::traverse_status (_FAR *visit) + (CORBA_TypeCode_ptr tc, + const void *value1, + const void *value2, + void *context, + CORBA_Environment &env), + void *context, + CORBA_Environment &env) +{ + env.clear (); + + // Quickly accomodate the bulk of cases, which are just (tail) calls + // to the visit() routine. We take advantage of the fact that these + // are largely in a convenient numeric range to work around poor + // optimization of "switch" code in some compilers. This + // improvement has in some cases been more than 5% faster + // (significant). + // + // NOTE: if for some reason the constants in the protocol spec + // (including Appendix A) change, this logic may need to be verified + // again. Luckily, changing protocol constants is quite rare; they + // normally just get added to (at the end). + // + if (_kind <= tk_objref + || (tk_longlong <= _kind && _kind <= tk_wstring)) + return visit (this, value1, value2, context, env); + + // Handle the cases that aren't in convenient numeric ranges. + + traverse_status retval; + + switch (_kind) + { + case tk_string: + case tk_enum: + return visit (this, value1, value2, context, env); - case tk_struct: - // - // XXX for OLE Automation, we'll probably need BOTH exceptions - // and structs to inherit IUnknown, hence we'll need to be - // skipping the vtable pointer ... - // - { - // - // Create the sub-encapsulation stream that holds the - // parameters for the typecode. - // - CDR stream; + // Typedefs just add a delay, while we skip the typedef ID + // and name ... - stream.setup_encapsulation (_buffer, (size_t) _length); + case tk_alias: + { + CORBA_TypeCode_ptr tcp; + CORBA_Environment env2; - return struct_traverse (&stream, value1, value2, - visit, context, env); - } + // XXX rework for efficiency, this doesn't need to allocate + // memory during the traversal! - case tk_union: - { - // - // visit the discriminant, then search the typecode for the - // relevant union member and then visit that member. - // - CDR stream; + tcp = typecode_param (2, env); + if (env.exception () != 0) + return TRAVERSE_STOP; - stream.setup_encapsulation (_buffer, (size_t) _length); + retval = tcp->traverse (value1, value2, visit, context, env); - return union_traverse (&stream, value1, value2, - visit, context, env); - } + tcp->Release (); + } + return retval; - // - // Sequences are just arrays with bound determined at runtime, rather - // than compile time. Multidimensional arrays are nested C-style: - // the leftmost dimension in the IDL definition is "outermost", etc. - // - { - CORBA_TypeCode_ptr tc2; - size_t size; - CORBA_ULong bounds; - CORBA_OctetSeq *seq; + // Exceptions in-memory are structures, except that there are data + // members "hidden" in front: vtable, typecode, refcount. We skip + // them, and allow the traversal code to account for the internal + // padding before the other elements of the exception. + // + // NOTE: see header comment re treatment of these values as "real" + // C++ exceptions. C++ RTTI data might need to be skipped. Also, + // see the comments in unmarshaling code: hard to throw these + // values. + // + // Not enough of the exception runtime is public for binary + // standards to exist for C++ exceptions yet. Compiler-specific + // code will need to handle examining, unmarshaling, and throwing + // of CORBA exceptions (in C++ environments) for some time. + case tk_except: + value1 = sizeof (CORBA_Exception) + (char *) value1; + value2 = sizeof (CORBA_Exception) + (char *) value2; + // FALLTHROUGH + + case tk_struct: + // XXX for OLE Automation, we'll probably need BOTH exceptions + // and structs to inherit IUnknown, hence we'll need to be + // skipping the vtable pointer ... + { + // Create the sub-encapsulation stream that holds the + // parameters for the typecode. + + CDR stream; + + stream.setup_encapsulation (_buffer, (size_t) _length); + + return struct_traverse (&stream, value1, value2, + visit, context, env); + } + + case tk_union: + { + // visit the discriminant, then search the typecode for the + // relevant union member and then visit that member. + CDR stream; + + stream.setup_encapsulation (_buffer, (size_t) _length); + + return union_traverse (&stream, value1, value2, + visit, context, env); + } + + // Sequences are just arrays with bound determined at runtime, + // rather than compile time. Multidimensional arrays are nested + // C-style: the leftmost dimension in the IDL definition is + // "outermost", etc. + { + CORBA_TypeCode_ptr tc2; + size_t size; + CORBA_ULong bounds; + CORBA_OctetSeq *seq; case tk_sequence: - // - // Find out how many elements there are, and adjust the - // data pointers to point to those elements rather than - // to the sequence itself. - // - seq = (CORBA_OctetSeq *)value1; - - bounds = seq->length; - value1 = seq->buffer; - - if (value2) { - seq = (CORBA_OctetSeq *)value2; - value2 = seq->buffer; - } - goto shared_seq_array_code; + // Find out how many elements there are, and adjust the data + // pointers to point to those elements rather than to the + // sequence itself. + seq = (CORBA_OctetSeq *)value1; + + bounds = seq->length; + value1 = seq->buffer; + + if (value2) + { + seq = (CORBA_OctetSeq *)value2; + value2 = seq->buffer; + } + goto shared_seq_array_code; case tk_array: - // - // Array bounds are in the typecode itself. - // - bounds = ulong_param (1, env); - if (env.exception () != 0) - return TRAVERSE_STOP; + // Array bounds are in the typecode itself. + bounds = ulong_param (1, env); + if (env.exception () != 0) + return TRAVERSE_STOP; shared_seq_array_code: - // - // Find element's type, and size ... - // - tc2 = typecode_param (0, env); - if (env.exception () != 0) - return TRAVERSE_STOP; - - size = tc2->size (env); - if (env.exception () != 0) - return TRAVERSE_STOP; - - // - // ... then visit the elements in order. - // - // NOTE: for last element, could turn visit() call into something - // subject to compiler's tail call optimization and thus save - // a stack frame - // - while (bounds--) { - if (visit (tc2, value1, value2, context, env) == TRAVERSE_STOP) - return TRAVERSE_STOP; - - value1 = size + (char *) value1; - value2 = size + (char *) value2; - } - CORBA_release (tc2); - env.clear (); - } - return TRAVERSE_CONTINUE; + // Find element's type, and size ... + tc2 = typecode_param (0, env); + if (env.exception () != 0) + return TRAVERSE_STOP; + + size = tc2->size (env); + if (env.exception () != 0) + return TRAVERSE_STOP; - // case ~0: // indirection, illegal at top level - default: // invalid/illegal - break; + // ... then visit the elements in order. + // + // NOTE: for last element, could turn visit() call into + // something subject to compiler's tail call optimization and + // thus save a stack frame + while (bounds--) + { + if (visit (tc2, value1, value2, context, env) == TRAVERSE_STOP) + return TRAVERSE_STOP; + + value1 = size + (char *) value1; + value2 = size + (char *) value2; + } + CORBA_release (tc2); + env.clear (); + } + return TRAVERSE_CONTINUE; + // case ~0: // indirection, illegal at top level + default: // invalid/illegal + break; } // end switch on typecode "kind" - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return TRAVERSE_STOP; + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return TRAVERSE_STOP; } +// Tell user the size of an instance of the data type described by +// this typecode ... typically used to allocate memory. -// -// Tell user the size of an instance of the data type described by this -// typecode ... typically used to allocate memory. -// size_t CORBA_TypeCode::size (CORBA_Environment &env) { - if (_kind >= TC_KIND_COUNT) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + if (_kind >= TC_KIND_COUNT) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - env.clear (); + env.clear (); - if (table [_kind].calc == 0) - return table [_kind].size; + if (table [_kind].calc == 0) + return table [_kind].size; - size_t alignment; - CDR stream; + size_t alignment; + CDR stream; - stream.setup_encapsulation (_buffer, (size_t) _length); + stream.setup_encapsulation (_buffer, (size_t) _length); - return table [_kind].calc (&stream, alignment, env); + return table [_kind].calc (&stream, alignment, env); } +// Tell user the alignment restriction for the data type described by +// an instance of this data type. Rarely used; provided for +// completeness. -// -// Tell user the alignment restriction for the data type described by an -// instance of this data type. Rarely used; provided for completeness. -// size_t CORBA_TypeCode::alignment (CORBA_Environment &env) { - if (_kind >= TC_KIND_COUNT) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + if (_kind >= TC_KIND_COUNT) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; } - env.clear (); + env.clear (); - if (table [_kind].calc == 0) - return table [_kind].alignment; + if (table [_kind].calc == 0) + return table [_kind].alignment; - size_t alignment; - CDR stream; + size_t alignment; + CDR stream; - stream.setup_encapsulation (_buffer, (size_t) _length); + stream.setup_encapsulation (_buffer, (size_t) _length); - (void) table [_kind].calc (&stream, alignment, env); - return alignment; + (void) table [_kind].calc (&stream, alignment, env); + return alignment; } diff --git a/TAO/IIOP/lib/invoke.cpp b/TAO/IIOP/lib/invoke.cpp index 7eb87532dd5..d3854f9a842 100644 --- a/TAO/IIOP/lib/invoke.cpp +++ b/TAO/IIOP/lib/invoke.cpp @@ -4,27 +4,29 @@ // // IIOP stub support for static and dynamic invocation // -// This file holds DII support, and an analagous interpreter that let static -// stubs be very small. It's specific to objrefs with IIOP::ProfileBody. +// This file holds DII support, and an analagous interpreter that let +// static stubs be very small. It's specific to objrefs with +// IIOP::ProfileBody. // -// NOTE: this may someday be moved within an IIOP class so that the public -// stub interface is completely independent of ORB/protocol internals. +// NOTE: this may someday be moved within an IIOP class so that the +// public stub interface is completely independent of ORB/protocol +// internals. // -// THREADING NOTE: Code below this point is of course thread-safe (at least -// on supported threaded platforms), so the caller of these routines need -// only ensure that the data being passed in is not being modified by any -// other thread. -// -// As an _experiment_ (to estimate the performance cost) remote calls are -// currently deemed "cancel-safe". That means that they can be called -// by threads when they're in asynchronous cancellation mode. The only -// effective way to do this is to disable async cancellation for the -// duration of the call. There are numerous rude interactions with code -// generators for C++ ... cancellation handlers just do normal stack -// unwinding like exceptions, but exceptions are purely synchronous and -// sophisticated code generators rely on that to generate better code, -// which in some cases may be very hard to unwind. +// THREADING NOTE: Code below this point is of course thread-safe (at +// least on supported threaded platforms), so the caller of these +// routines need only ensure that the data being passed in is not +// being modified by any other thread. // +// As an _experiment_ (to estimate the performance cost) remote calls +// are currently deemed "cancel-safe". That means that they can be +// called by threads when they're in asynchronous cancellation mode. +// The only effective way to do this is to disable async cancellation +// for the duration of the call. There are numerous rude interactions +// with code generators for C++ ... cancellation handlers just do +// normal stack unwinding like exceptions, but exceptions are purely +// synchronous and sophisticated code generators rely on that to +// generate better code, which in some cases may be very hard to +// unwind. #include <assert.h> #include <stdio.h> @@ -38,33 +40,33 @@ #include "connmgr.h" class ACE_Synchronous_Cancellation_Required -// = TITLE -// -// ACE_Synchronous_Cancellation_Required -// -// = DESCRIPTION -// -// Stick one of these at the beginning of a block that can't -// support asynchronous cancellation, and which must be -// cancel-safe. -// -// = EXAMPLE -// somefunc() -// { -// ACE_Synchronous_Cancellation_Required NOT_USED; -// ... -// } + // = TITLE + // + // ACE_Synchronous_Cancellation_Required + // + // = DESCRIPTION + // + // Stick one of these at the beginning of a block that can't + // support asynchronous cancellation, and which must be + // cancel-safe. + // + // = EXAMPLE + // somefunc() + // { + // ACE_Synchronous_Cancellation_Required NOT_USED; + // ... + // } { public: - // These should probably be in a separate inline file, but - // they're only used within this one file right now, and we - // always want them inlined, so here they sit. - ACE_Synchronous_Cancellation_Required() + // These should probably be in a separate inline file, but they're + // only used within this one file right now, and we always want them + // inlined, so here they sit. + ACE_Synchronous_Cancellation_Required (void) { - ACE_OS::thr_setcanceltype(THR_CANCEL_DEFERRED, &old_type_); + ACE_OS::thr_setcanceltype (THR_CANCEL_DEFERRED, &old_type_); } - ~ACE_Synchronous_Cancellation_Required() + ~ACE_Synchronous_Cancellation_Required (void) { int dont_care; ACE_OS::thr_setcanceltype(old_type_, &dont_care); @@ -73,69 +75,71 @@ private: int old_type_; }; +// "stub interpreter" for static stubs. IDL compiler (or human +// equivalent thereof :-) should just dump a read-only description of +// the call into "calldata" and do varargs calls to this routine, +// which does all the work. // -// "stub interpreter" for static stubs. IDL compiler (or human equivalent -// thereof :-) should just dump a read-only description of the call into -// "calldata" and do varargs calls to this routine, which does all the work. -// -// NOTE: This routine includes stub interpreter code, upon which a patent -// application is pending. -// +// NOTE: This routine includes stub interpreter code, upon which a +// patent application is pending. + void IIOP_Object::do_call (CORBA_Environment &env, // exception reporting const calldata *info, // call description - ... // ... any parameters -) + ...) // ... any parameters + { ACE_Synchronous_Cancellation_Required NOT_USED; - GIOP::Invocation call (this, info->opname, - info->is_roundtrip); + GIOP::Invocation call (this, + info->opname, + info->is_roundtrip); + // We may need to loop through here more than once if we're + // forwarded to some other object reference. // - // We may need to loop through here more than once if we're forwarded - // to some other object reference. - // - // NOTE: A quality-of-service policy may be useful to establish here, - // specifically one controlling how many times the call is reissued - // before failing the call on the assumption that something is broken. + // NOTE: A quality-of-service policy may be useful to establish + // here, specifically one controlling how many times the call is + // reissued before failing the call on the assumption that something + // is broken. // - // NOTE: something missing is a dynamic way to change the policy of + // NOTE: something missing is a dynamic way to change the policy of // whether to issue LocateRequest messages or not. This code uses a - // simple, fixed policy: never use LocateRequest messages. + // simple, fixed policy: never use LocateRequest messages. // for (;;) { - // // Start the call by constructing the request message header. - // + env.clear (); call.start (env); + if (env.exception ()) { dexc (env, "do_call, start request message"); return; } - // // Now, put all "in" and "inout" parameters into the request // message body. // - // Some "inout" data have an extra level of indirection, specified - // by the language mapping's memory allocation policies ... the - // indirection only shows up here when it's needed later for - // allocating "out" memory, otherwise there's just one indirection. - // - unsigned i; + // Some "inout" data have an extra level of indirection, + // specified by the language mapping's memory allocation + // policies ... the indirection only shows up here when it's + // needed later for allocating "out" memory, otherwise there's + // just one indirection. + + u_int i; const paramdata *pdp; va_list param_vector; va_start (param_vector, info); + for (i = 0, pdp = info->params; i < info->param_count; i++, pdp++) { - void *ptr = va_arg (param_vector, void *); + void *ptr = va_arg (param_vector, void *); if (pdp->mode == PARAM_IN) call.put_param (pdp->tc, ptr, env); @@ -155,12 +159,12 @@ IIOP_Object::do_call (CORBA_Environment &env, // exception reporting } va_end (param_vector); - // // Make the call ... blocking for response if needed. Note that - // "oneway" calls can't return any exceptions except system ones. - // - GIOP::ReplyStatusType status; - CORBA_ExceptionList exceptions; + // "oneway" calls can't return any exceptions except system + // ones. + + GIOP::ReplyStatusType status; + CORBA_ExceptionList exceptions; exceptions.length = exceptions.maximum = info->except_count; exceptions.buffer = (CORBA_TypeCode_ptr *) info->excepts; @@ -179,10 +183,9 @@ IIOP_Object::do_call (CORBA_Environment &env, // exception reporting || status == GIOP::USER_EXCEPTION) return; - // // Now, get all the "return", "out", and "inout" parameters from // the response message body. - // + if (status == GIOP::NO_EXCEPTION) { va_start (param_vector, info); @@ -190,26 +193,23 @@ IIOP_Object::do_call (CORBA_Environment &env, // exception reporting i < info->param_count; i++, pdp++) { - void *ptr = va_arg (param_vector, void *); + void *ptr = va_arg (param_vector, void *); if (pdp->mode == PARAM_RETURN || pdp->mode == PARAM_OUT || pdp->mode == PARAM_INOUT) { - // - // The language mapping's memory allocation policy says - // that some data is heap-allocated. This interpreter - // is told about the relevant policy by whoever built - // the operation description (e.g. the IDL compiler) so - // it doesn't have to know the policy associated with a - // particular language binding (e.g. C/C++ differ, and - // C++ even has different policies for different kinds - // of structures). - // + // The language mapping's memory allocation policy + // says that some data is heap-allocated. This + // interpreter is told about the relevant policy by + // whoever built the operation description (e.g. the + // IDL compiler) so it doesn't have to know the + // policy associated with a particular language + // binding (e.g. C/C++ differ, and C++ even has + // different policies for different kinds of + // structures). if (pdp->value_size == 0) - { - call.get_value (pdp->tc, ptr, env); - } + call.get_value (pdp->tc, ptr, env); else { // assert (value_size == tc->size()); @@ -228,20 +228,17 @@ IIOP_Object::do_call (CORBA_Environment &env, // exception reporting return; } - // // ... or maybe this request got forwarded to someplace else; send // the request there instead. - // assert (status == GIOP::LOCATION_FORWARD); } } +// DII analogue of the above. Differs in how the vararg calling +// convention is implemented -- DII doesn't use the normal call stack +// with its implicit typing, but iinstead uses heap-based arguments +// with explicit typing. -// -// DII analogue of the above. Differs in how the vararg calling convention -// is implemented -- DII doesn't use the normal call stack with its implicit -// typing, but iinstead uses heap-based arguments with explicit typing. -// void IIOP_Object::do_dynamic_call (const char *opname, // operation name CORBA_Boolean is_roundtrip, // results required? @@ -249,34 +246,30 @@ IIOP_Object::do_dynamic_call (const char *opname, // operation name CORBA_NamedValue_ptr result, // result CORBA_Flags flags, // per-call flag (one!) CORBA_ExceptionList &exceptions, // possible user exceptions - CORBA_Environment &env // exception reporting -) + CORBA_Environment &env) // exception reporting { ACE_Synchronous_Cancellation_Required NOT_USED; - GIOP::Invocation call (this, opname, is_roundtrip); + GIOP::Invocation call (this, opname, is_roundtrip); - // // Loop as needed for forwarding; see above. - // + for (;;) { - // // Start the call by constructing the request message header. - // env.clear (); call.start (env); + if (env.exception ()) { dexc (env, "do_call, start request message"); return; } - // // Now, put all "in" and "inout" parameters into the request // message body. - // - unsigned i; + + u_int i; for (i = 0; i < args->count (); i++) { @@ -295,10 +288,9 @@ IIOP_Object::do_dynamic_call (const char *opname, // operation name } } - // // Make the call ... blocking for response if needed. Note that // "oneway" calls can't return any exceptions except system ones. - // + GIOP::ReplyStatusType status; status = call.invoke (exceptions, env); @@ -312,25 +304,22 @@ IIOP_Object::do_dynamic_call (const char *opname, // operation name || status == GIOP::USER_EXCEPTION) return; - // // Now, get all the "return", "out", and "inout" parameters from the // response message body ... return parameter is first, the rest are // in the order defined in the IDL spec (which is also the order that // DII users are required to use). - // + if (status == GIOP::NO_EXCEPTION) { if (result != 0) { - - // // If caller didn't set OUT_LIST_MEMORY flag, allocate // memory for return value ... - // + if (!(flags & CORBA_OUT_LIST_MEMORY)) { - CORBA_TypeCode_ptr tcp; - size_t size; + CORBA_TypeCode_ptr tcp; + size_t size; tcp = result->value ()->type (); size = tcp->size (env); @@ -358,14 +347,12 @@ IIOP_Object::do_dynamic_call (const char *opname, // operation name if (value->flags () == CORBA_ARG_OUT || value->flags () == CORBA_ARG_INOUT) { - // // If caller didn't set OUT_LIST_MEMORY flag, allocate // memory for this parameter ... - // if (!(flags & CORBA_OUT_LIST_MEMORY)) { - CORBA_TypeCode_ptr tcp; - size_t size; + CORBA_TypeCode_ptr tcp; + size_t size; tcp = value->value ()->type (); size = tcp->size (env); @@ -394,9 +381,7 @@ IIOP_Object::do_dynamic_call (const char *opname, // operation name return; } - // // ... or maybe this request got forwarded to someplace else. - // assert (status == GIOP::LOCATION_FORWARD); } } diff --git a/TAO/IIOP/lib/marshal.cpp b/TAO/IIOP/lib/marshal.cpp index 6f0d77bc440..f37af656c17 100644 --- a/TAO/IIOP/lib/marshal.cpp +++ b/TAO/IIOP/lib/marshal.cpp @@ -4,38 +4,41 @@ // // CDR: Marshaling interpreter // -// This marshaling interpreter is driven by the typecode interpreter. The -// typecode interpreter understands each compiler environment's rules for -// data structure layout; this understands CDR's rules for on-the-wire data -// structure layout. +// This marshaling interpreter is driven by the typecode interpreter. +// The typecode interpreter understands each compiler environment's +// rules for data structure layout; this understands CDR's rules for +// on-the-wire data structure layout. // -// Apart from some high level rules related to construction of complex data -// types, the marshaling interpreter just knows how to encode primitive data -// types and allocate memory on decode. +// Apart from some high level rules related to construction of complex +// data types, the marshaling interpreter just knows how to encode +// primitive data types and allocate memory on decode. // -// NOTE: to reduce the amount of compiled code, this "knows" facts like -// native float/long/ulong being in legal CDR format, and that "char" is -// native in ISO Latin/1 (so no transformation is needed, and octet/char -// marshaling code is identical). On exotic platforms where this is not -// true, some of the merged "switch" branches will need to be split. +// NOTE: to reduce the amount of compiled code, this "knows" facts +// like native float/long/ulong being in legal CDR format, and that +// "char" is native in ISO Latin/1 (so no transformation is needed, +// and octet/char marshaling code is identical). On exotic platforms +// where this is not true, some of the merged "switch" branches will +// need to be split. // -// REMEMBER: goal is to have the typecode interpreter plus one side of the -// marshaling interpreter reside in a CPU's code cache; or at least to have -// as litle as possible _outside_ cache when marshaling. Compiled marshaling -// code will have a few less instructions, but most will of them will be -// outside the instruction cache; access time to get at them will be high. +// REMEMBER: goal is to have the typecode interpreter plus one side of +// the marshaling interpreter reside in a CPU's code cache; or at +// least to have as litle as possible _outside_ cache when marshaling. +// Compiled marshaling code will have a few less instructions, but +// most will of them will be outside the instruction cache; access +// time to get at them will be high. // -// NOTE: One interesting optimization is inlining the primitive put/get -// calls ... it'd typically save at least 40% in terms of instruction count -// on each of these critical paths by eliminating subroutine call overhead. -// Since it would increase code size, such changes might not be desirable -// on machines with small caches. Also, with network I/O being today's most -// significant bottleneck, such optimizations haven't been well explored. +// NOTE: One interesting optimization is inlining the primitive +// put/get calls ... it'd typically save at least 40% in terms of +// instruction count on each of these critical paths by eliminating +// subroutine call overhead. Since it would increase code size, such +// changes might not be desirable on machines with small caches. +// Also, with network I/O being today's most significant bottleneck, +// such optimizations haven't been well explored. // -// THREADING NOTE: The only threading concern is as always, that data -// structures being manipulated by any given thread must be reserved to -// it by some mechanism (e.g. mutex). This uses no mutable data outside -// of the thread stack, so the onus is entirely on the caller. +// THREADING NOTE: The only threading concern is as always, that data +// structures being manipulated by any given thread must be reserved +// to it by some mechanism (e.g. mutex). This uses no mutable data +// outside of the thread stack, so the onus is entirely on the caller. // #include <assert.h> @@ -48,507 +51,473 @@ #include "giop.h" - #if defined (HAVE_WIDEC_H) # include <widec.h> #else - extern "C" { - unsigned wslen (const CORBA_WChar *); - CORBA_WChar *wscpy (CORBA_WChar *, const CORBA_WChar *); - } +extern "C" +{ + u_int wslen (const CORBA_WChar *); + CORBA_WChar *wscpy (CORBA_WChar *, const CORBA_WChar *); +} #endif -extern CORBA_TypeCode TC_opaque; +extern CORBA_TypeCode TC_opaque; - -// -// Encode instances of arbitrary data types based only on typecode. "data" -// points to the data type; if it's not a primitve data type, the TypeCode -// interpreter is used to recursively encode its components. "context" is -// the marshaling stream on which to encode the data value. -// -// This is a fairly typical TypeCode interpreter visit() routine; it works -// on a single data value in conjunction with context information, and must -// handle all IDL data types. +// Encode instances of arbitrary data types based only on typecode. +// "data" points to the data type; if it's not a primitve data type, +// the TypeCode interpreter is used to recursively encode its +// components. "context" is the marshaling stream on which to encode +// the data value. // +// This is a fairly typical TypeCode interpreter visit() routine; it +// works on a single data value in conjunction with context +// information, and must handle all IDL data types. + CORBA_TypeCode::traverse_status -CDR::encoder ( - CORBA_TypeCode_ptr tc, - const void *data, - const void *, - void *context, - CORBA_Environment &env -) +CDR::encoder (CORBA_TypeCode_ptr tc, + const void *data, + const void *, + void *context, + CORBA_Environment &env) { - CORBA_Boolean continue_encoding = CORBA_B_TRUE; - CDR *stream = (CDR *)context; - - switch (tc->_kind) { - case tk_null: - case tk_void: - // nothing to encode! - break; - - case tk_char: - case tk_octet: - continue_encoding = stream->put_char (*(char *)data); - break; - - case tk_short: - case tk_ushort: - continue_encoding = stream->put_short (*(short *)data); - break; - - case tk_long: - case tk_ulong: - case tk_float: - continue_encoding = stream->put_long (*(CORBA_Long *)data); - break; - - case tk_double: - case tk_longlong: - case tk_ulonglong: - continue_encoding = stream->put_longlong (*(CORBA_LongLong *)data); - break; - - case tk_boolean: - continue_encoding = stream->put_boolean (*(CORBA_Boolean *)data); - break; - - case tk_enum: - { - // - // NOTE assumption that this is in-range. - // - // XXX should check this, it's a hard-to-recover error - // for the other side - // - unsigned value = *(unsigned *)data; - continue_encoding = stream->put_ulong (value); - } - break; + CORBA_Boolean continue_encoding = CORBA_B_TRUE; + CDR *stream = (CDR *) context; + + switch (tc->_kind) + { + case tk_null: + case tk_void: + // nothing to encode! + break; + + case tk_char: + case tk_octet: + continue_encoding = stream->put_char (*(char *) data); + break; + + case tk_short: + case tk_ushort: + continue_encoding = stream->put_short (*(short *) data); + break; + + case tk_long: + case tk_ulong: + case tk_float: + continue_encoding = stream->put_long (*(CORBA_Long *) data); + break; + + case tk_double: + case tk_longlong: + case tk_ulonglong: + continue_encoding = stream->put_longlong (*(CORBA_LongLong *) data); + break; + + case tk_boolean: + continue_encoding = stream->put_boolean (*(CORBA_Boolean *) data); + break; + + case tk_enum: + { + // NOTE assumption that this is in-range. + // + // XXX should check this, it's a hard-to-recover error for the + // other side + + u_int value = *(u_int *) data; + continue_encoding = stream->put_ulong (value); + } + break; + + case tk_any: + { + CORBA_Any *any = (CORBA_Any *) data; + + tc = any->type (); + if (encoder (_tc_CORBA_TypeCode, &tc, 0, context, env) + != CORBA_TypeCode::TRAVERSE_CONTINUE) + return CORBA_TypeCode::TRAVERSE_STOP; + + data = any->value (); + return encoder (tc, data, 0, context, env); + } + // NOTREACHED + + case tk_TypeCode: + { + CORBA_TypeCode_ptr tc2; + + tc2 = *(CORBA_TypeCode_ptr *) data; + + continue_encoding = stream->put_ulong ((CORBA_ULong) tc2->_kind); + if (continue_encoding == CORBA_B_FALSE) + break; + + switch (tc2->_kind) + { + // Most TypeCodes have empty parameter lists + default: + break; - case tk_any: - { - CORBA_Any *any = (CORBA_Any *)data; + // A few have "simple" parameter lists + case tk_string: + case tk_wstring: + continue_encoding = stream->put_ulong (tc2->_length); + break; - tc = any->type (); - if (encoder (_tc_CORBA_TypeCode, &tc, 0, context, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE) - return CORBA_TypeCode::TRAVERSE_STOP; + // Indirected typecodes can't occur at "top level" like + // this, only nested inside others! + case ~0: + dmsg ("indirected typecode at top level!"); + continue_encoding = CORBA_B_FALSE; + break; - data = any->value (); - return encoder (tc, data, 0, context, env); - } - // NOTREACHED - - case tk_TypeCode: - { - CORBA_TypeCode_ptr tc2; - - tc2 = *(CORBA_TypeCode_ptr *)data; - - continue_encoding = stream->put_ulong ((CORBA_ULong) tc2->_kind); - if (continue_encoding == CORBA_B_FALSE) - break; - - switch (tc2->_kind) { - // - // Most TypeCodes have empty parameter lists - // - default: - break; - - // - // A few have "simple" parameter lists - // - case tk_string: - case tk_wstring: - continue_encoding = stream->put_ulong (tc2->_length); - break; - - // - // Indirected typecodes can't occur at "top level" like - // this, only nested inside others! - // - case ~0: - dmsg ("indirected typecode at top level!"); - continue_encoding = CORBA_B_FALSE; - break; - - // - // The rest have "complex" parameter lists that are already - // encoded as bulk octets ... put length, then octets - // - case tk_objref: - case tk_struct: - case tk_union: - case tk_enum: - case tk_sequence: - case tk_array: - case tk_alias: - case tk_except: - { - unsigned i; - - continue_encoding = stream->put_ulong (tc2->_length); - for (i = 0; i < tc2->_length && continue_encoding; i++) - continue_encoding = - stream->put_octet (tc2->_buffer [i]); - } + // The rest have "complex" parameter lists that are + // already encoded as bulk octets ... put length, then + // octets. + case tk_objref: + case tk_struct: + case tk_union: + case tk_enum: + case tk_sequence: + case tk_array: + case tk_alias: + case tk_except: + { + continue_encoding = stream->put_ulong (tc2->_length); + + for (u_int i = 0; i < tc2->_length && continue_encoding; i++) + continue_encoding = stream->put_octet (tc2->_buffer [i]); } - } - break; - - case tk_Principal: - { - CORBA_Principal_ptr p = *(CORBA_Principal_ptr*) data; - unsigned i; - - if (p != 0) { - continue_encoding = stream->put_long (p->id.length); - for (i = 0; continue_encoding && i < p->id.length; i++) - continue_encoding = stream->put_octet (p->id.buffer [i]); - } else - continue_encoding = stream->put_long (0); - } - break; + } + } + break; + + case tk_Principal: + { + CORBA_Principal_ptr p = *(CORBA_Principal_ptr *) data; + + if (p != 0) + { + continue_encoding = stream->put_long (p->id.length); + + for (u_int i = 0; continue_encoding && i < p->id.length; i++) + continue_encoding = stream->put_octet (p->id.buffer [i]); + } + else + continue_encoding = stream->put_long (0); + } + break; + + case tk_objref: + + // Current version: objref is really an IIOP_Object. + // + // This will change in the future; STUB_Object knows how to + // marshal itself, that will be used. + // + // XXX this doesn't actually verify that the stuff got written + // OK to the "wire" ... + { + CORBA_Object_ptr obj = *(CORBA_Object_ptr *) data; + + // NIL objrefs ... marshal as empty type hint, no elements. + + if (CORBA_is_nil (obj)) + { + continue_encoding = + stream->put_ulong (1) // strlen + && stream->put_char (0) // NUL + && stream->put_ulong (0); // no profiles + break; + } - case tk_objref: - // - // Current version: objref is really an IIOP_Object. - // - // This will change in the future; STUB_Object knows how to - // marshal itself, that will be used. + // All other objrefs ... narrow to a "real type" that we + // recognize, then marshal. // - // XXX this doesn't actually verify that the stuff got written - // OK to the "wire" ... + // XXX this will be changed so it narrows to STUB_Object and + // then asks that surrogate/proxy to marshal itself. // - { - CORBA_Object_ptr obj = *(CORBA_Object_ptr *)data; - - // - // NIL objrefs ... marshal as empty type hint, no elements. - // - if (CORBA_is_nil (obj)) { - continue_encoding = - stream->put_ulong (1) // strlen - && stream->put_char (0) // NUL - && stream->put_ulong (0); // no profiles - break; - } - - // - // All other objrefs ... narrow to a "real type" that we - // recognize, then marshal. - // - // XXX this will be changed so it narrows to STUB_Object - // and then asks that surrogate/proxy to marshal itself. - // - // For now, the original code is minimally changed. - // - IIOP_Object *objdata; - IIOP::ProfileBody *profile; + // For now, the original code is minimally changed. + + IIOP_Object *objdata; + IIOP::ProfileBody *profile; + + if (obj->QueryInterface (IID_IIOP_Object, + (void **) &objdata) != NOERROR) + { + env.exception (new CORBA_MARSHAL (COMPLETED_NO)); + return CORBA_TypeCode::TRAVERSE_STOP; + } + obj->Release (); + profile = &objdata->profile; + + // STRING, a type ID hint + encoder (_tc_CORBA_String, &objdata->type_id, 0, context, env); + + // UNSIGNED LONG, value one, count of the sequence of + // encapsulated protocol profiles; + stream->put_ulong (1); + + // UNSIGNED LONG, tag for this protocol profile; + stream->put_ulong (IOP::TAG_INTERNET_IOP); + + // UNSIGNED LONG, number of succeeding bytes in the + // encapsulation. We don't actually need to make the + // encapsulation, as nothing needs stronger alignment than + // this longword; it guarantees the rest is aligned for us. + u_int hostlen; + + hostlen = ACE_OS::strlen ((char *) profile->host); + stream->put_ulong (1 // byte order + + 3 // version + pad byte + + 4 // sizeof (strlen) + + hostlen + 1 // strlen + null + + (~hostlen & 01) // optional pad byte + + 2 // port + + (hostlen & 02) // optional pad short + + 4 // sizeof (key length) + + profile->object_key.length); // key length + + // CHAR describing byte order, starting the encapsulation + + stream->put_char (MY_BYTE_SEX); + + // IIOP::Version, two characters (version 1.0) padding + stream->put_char (profile->iiop_version.major); + stream->put_char (profile->iiop_version.minor); + + // STRING hostname from profile + encoder (_tc_CORBA_String, &profile->host, 0, context, env); + + // UNSIGNED SHORT port number + stream->put_ushort (profile->port); + + // OCTET SEQUENCE for object key + encoder (&TC_opaque, &profile->object_key, 0, context, env); + } + break; + + case tk_sequence: + { + // First marshal the sequence length, verifying that it's + // within the sequence bounds ... + CORBA_OctetSeq *seq = (CORBA_OctetSeq *) data; + CORBA_ULong len = seq ? seq->length : 0; + + if (len > 0) + { + CORBA_ULong bounds; + + bounds = tc->ulong_param (1, env); + if (env.exception () != 0) + return CORBA_TypeCode::TRAVERSE_STOP; - if (obj->QueryInterface (IID_IIOP_Object, (void **)&objdata) - != NOERROR) { - env.exception (new CORBA_MARSHAL (COMPLETED_NO)); + if (bounds != 0 && len > bounds) + { + env.exception (new CORBA_BAD_PARAM (COMPLETED_MAYBE)); return CORBA_TypeCode::TRAVERSE_STOP; - } - obj->Release (); - profile = &objdata->profile; - - // - // STRING, a type ID hint - // - encoder (_tc_CORBA_String, &objdata->type_id, 0, context, env); - - // - // UNSIGNED LONG, value one, count of the sequence - // of encapsulated protocol profiles; - // + } + } + continue_encoding = stream->put_ulong (len); + + // Fast exit on error or empty sequence + if (!continue_encoding || len == 0) + break; + } + // FALLTHROUGH + + case tk_struct: + case tk_union: + case tk_array: + case tk_alias: + // Marshal each member in order. + return tc->traverse (data, 0, encoder, context, env); + + case tk_except: + // Convert the the "hidden" TypeCode at the beginning of the + // exception into an on-the-wire ID, then marshal the members in + // order (traversal skips that hidden typecode, and more). + // + // NOTE: This is asymmetric with respect to decoding the + // exception, since whoever decodes must pull off the ID and map + // it to the typecode to be used to unmarshal it (search among + // legal choices). + { + CORBA_String id = tc->id (env); + + if (env.exception () == 0) + { + continue_encoding = + encoder (_tc_CORBA_String, &id, 0, context, env) + == CORBA_TypeCode::TRAVERSE_CONTINUE + && tc->traverse (data, 0, encoder, context, env); + } + else + continue_encoding = CORBA_B_FALSE; + } + break; + + case tk_string: + { + CORBA_String str = *(CORBA_String *) data; + CORBA_ULong len; + CORBA_ULong bounds; + + // Be nice to programmers: treat nulls as empty strings not + // errors. (OMG-IDL supports languages that don't use the + // C/C++ notion of null v. empty strings; nulls aren't part of + // the OMG-IDL string model.) + if (str == 0) + { stream->put_ulong (1); + stream->put_char (0); + break; + } + + // Verify string satisfies bounds requirements. We're not so + // permissive as to send messages violating the interface spec + // by having excessively long strings! + bounds = tc->ulong_param (0, env); + if (env.exception () != 0) + return CORBA_TypeCode::TRAVERSE_STOP; + len = ACE_OS::strlen ((char *) str); + + if (bounds != 0 && len > bounds) + { + continue_encoding = CORBA_B_FALSE; + break; + } - // - // UNSIGNED LONG, tag for this protocol profile; - // - stream->put_ulong (IOP::TAG_INTERNET_IOP); - - // - // UNSIGNED LONG, number of succeeding bytes in the encapsulation. - // We don't actually need to make the encapsulation, as nothing - // needs stronger alignment than this longword; it guarantees - // the rest is aligned for us. - // - unsigned hostlen; - - hostlen = ACE_OS::strlen ((char *)profile->host); - stream->put_ulong ( - 1 // byte order - + 3 // version + pad byte - + 4 // sizeof (strlen) - + hostlen + 1 // strlen + null - + (~hostlen & 01) // optional pad byte - + 2 // port - + (hostlen & 02) // optional pad short - + 4 // sizeof (key length) - + profile->object_key.length); // key length - - // - // CHAR describing byte order, starting the encapsulation - // - stream->put_char (MY_BYTE_SEX); - - // - // IIOP::Version, two characters (version 1.0) - // padding - // - stream->put_char (profile->iiop_version.major); - stream->put_char (profile->iiop_version.minor); - - // - // STRING hostname from profile - // - encoder (_tc_CORBA_String, &profile->host, 0, context, env); - - // - // UNSIGNED SHORT port number - // - stream->put_ushort (profile->port); - - // - // OCTET SEQUENCE for object key - // - encoder (&TC_opaque, &profile->object_key, 0, context, env); - } - break; - - case tk_sequence: - { - // - // First marshal the sequence length, verifying that - // it's within the sequence bounds ... - // - CORBA_OctetSeq *seq = (CORBA_OctetSeq *) data; - CORBA_ULong len = seq ? seq->length : 0; - - if (len > 0) { - CORBA_ULong bounds; - - bounds = tc->ulong_param (1, env); - if (env.exception () != 0) - return CORBA_TypeCode::TRAVERSE_STOP; - - if (bounds != 0 && len > bounds) { - env.exception (new CORBA_BAD_PARAM (COMPLETED_MAYBE)); - return CORBA_TypeCode::TRAVERSE_STOP; - } - } - continue_encoding = stream->put_ulong (len); - - // - // Fast exit on error or empty sequence - // - if (!continue_encoding || len == 0) - break; - } - // FALLTHROUGH - - case tk_struct: - case tk_union: - case tk_array: - case tk_alias: - // - // Marshal each member in order. - // - return tc->traverse (data, 0, encoder, context, env); - - case tk_except: - // - // Convert the the "hidden" TypeCode at the beginning of the - // exception into an on-the-wire ID, then marshal the members - // in order (traversal skips that hidden typecode, and more). - // - // NOTE: This is asymmetric with respect to decoding the exception, - // since whoever decodes must pull off the ID and map it to the - // typecode to be used to unmarshal it (search among legal choices). - // - { - CORBA_String id = tc->id (env); - - if (env.exception () == 0) { - continue_encoding = - encoder (_tc_CORBA_String, &id, 0, context, env) - == CORBA_TypeCode::TRAVERSE_CONTINUE - && tc->traverse (data, 0, encoder, context, env); - } else - continue_encoding = CORBA_B_FALSE; - } - break; - - case tk_string: - { - CORBA_String str = *(CORBA_String *) data; - CORBA_ULong len, bounds; + // Encode the string, followed by a NUL character. - // - // Be nice to programmers: treat nulls as empty strings - // not errors. (OMG-IDL supports languages that don't use - // the C/C++ notion of null v. empty strings; nulls aren't - // part of the OMG-IDL string model.) - // - if (str == 0) { - stream->put_ulong (1); - stream->put_char (0); - break; - } + for (continue_encoding = stream->put_ulong (len + 1); + continue_encoding != CORBA_B_FALSE && *str; + continue_encoding = stream->put_char (*str++)) + continue; - // - // Verify string satisfies bounds requirements. We're not - // so permissive as to send messages violating the interface - // spec by having excessively long strings! - // - bounds = tc->ulong_param (0, env); - if (env.exception () != 0) - return CORBA_TypeCode::TRAVERSE_STOP; - len = ACE_OS::strlen ((char *)str); + stream->put_char (0); + } + break; - if (bounds != 0 && len > bounds) { - continue_encoding = CORBA_B_FALSE; - break; - } + case tk_wstring: + { + CORBA_WChar *str = *(CORBA_WChar **) data; + CORBA_ULong len; + CORBA_ULong bounds; - // - // Encode the string, followed by a NUL character. - // - continue_encoding = stream->put_ulong (len + 1); - while (continue_encoding != CORBA_B_FALSE && *str) - continue_encoding = stream->put_char (*str++); - stream->put_char (0); - } - break; + // Be nice to programmers: treat nulls as empty strings not + // errors. (OMG-IDL supports languages that don't use the + // C/C++ notion of null v. empty strings; nulls aren't part of + // the OMG-IDL string model.) - case tk_wstring: - { - CORBA_WChar *str = *(CORBA_WChar **) data; - CORBA_ULong len, bounds; + if (str == 0) + { + stream->put_ulong (1); + stream->put_wchar (0); + break; + } + + // Verify wide string satisfies bounds requirements. We're + // not so permissive as to send messages violating the + // interface spec by having excessively long strings! + + bounds = tc->ulong_param (0, env); + if (env.exception () != 0) + return CORBA_TypeCode::TRAVERSE_STOP; + len = wslen (str); + if (bounds != 0 && len > bounds) + { + continue_encoding = CORBA_B_FALSE; + break; + } - // - // Be nice to programmers: treat nulls as empty strings - // not errors. (OMG-IDL supports languages that don't use - // the C/C++ notion of null v. empty strings; nulls aren't - // part of the OMG-IDL string model.) - // - if (str == 0) { - stream->put_ulong (1); - stream->put_wchar (0); - break; - } + // Encode the wide string, followed by a NUL character. - // - // Verify wide string satisfies bounds requirements. We're - // not so permissive as to send messages violating the interface - // spec by having excessively long strings! - // - bounds = tc->ulong_param (0, env); - if (env.exception () != 0) - return CORBA_TypeCode::TRAVERSE_STOP; - len = wslen (str); - if (bounds != 0 && len > bounds) { - continue_encoding = CORBA_B_FALSE; - break; - } + for (continue_encoding = stream->put_ulong (wslen (str) + 1); + continue_encoding != CORBA_B_FALSE && *str; + continue_encoding = stream->put_wchar (*str++)) + continue; - // - // Encode the wide string, followed by a NUL character. - // - continue_encoding = stream->put_ulong (wslen (str) + 1); - while (continue_encoding != CORBA_B_FALSE && *str) - continue_encoding = stream->put_wchar (*str++); - stream->put_wchar (0); - } - break; + stream->put_wchar (0); + } + break; - case tk_longdouble: - continue_encoding = - stream->put_longdouble (*(CORBA_LongDouble *)data); - break; + case tk_longdouble: + continue_encoding = stream->put_longdouble (*(CORBA_LongDouble *) data); + break; - case tk_wchar: - continue_encoding = stream->put_wchar (*(CORBA_WChar *)data); - break; + case tk_wchar: + continue_encoding = stream->put_wchar (*(CORBA_WChar *) data); + break; // case ~0: - default: - dmsg ("encoder default case ?"); - continue_encoding = CORBA_B_FALSE; - break; + default: + dmsg ("encoder default case ?"); + continue_encoding = CORBA_B_FALSE; + break; } - if (continue_encoding == CORBA_B_FALSE) { - env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); - dmsg ("marshaling encoder detected error"); - return CORBA_TypeCode::TRAVERSE_STOP; + if (continue_encoding == CORBA_B_FALSE) + { + env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); + dmsg ("marshaling encoder detected error"); + return CORBA_TypeCode::TRAVERSE_STOP; } - return CORBA_TypeCode::TRAVERSE_CONTINUE; + return CORBA_TypeCode::TRAVERSE_CONTINUE; } - -// -// This table of TypeCode constants lets us unmarshal most typecodes using -// the predefined constants, rather than constantly reallocating them. -// -// XXX CFRONT-based compilers can't cope with this table initialization, -// and need some kind of init function. Luckily, they're increasingly -// rare in any "production" environment. +// This table of TypeCode constants lets us unmarshal most typecodes +// using the predefined constants, rather than constantly reallocating +// them. // +// XXX CFRONT-based compilers can't cope with this table +// initialization, and need some kind of init function. Luckily, +// they're increasingly rare in any "production" environment. + #if THE_COMPILER_CAN_FIND_THIS_PROPERLY -const // The extern reference in onc/xdr.cpp doesn't - // seem to be able to find this decl with as - // long as the const is part of it. I even - // tried changing the ref decl to have 'const' - // in it, to no avail. --cjc +// The extern reference in onc/xdr.cpp doesn't seem to be able to find +// this decl with as long as the const is part of it. I even tried +// changing the ref decl to have 'const' in it, to no avail. --cjc +const #endif -CORBA_TypeCode_ptr -__tc_consts [TC_KIND_COUNT] = { - _tc_CORBA_Null - , _tc_CORBA_Void - , _tc_CORBA_Short - , _tc_CORBA_Long - , _tc_CORBA_UShort - - , _tc_CORBA_ULong - , _tc_CORBA_Float - , _tc_CORBA_Double - , _tc_CORBA_Boolean - , _tc_CORBA_Char - - , _tc_CORBA_Octet - , _tc_CORBA_Any - , _tc_CORBA_TypeCode - , _tc_CORBA_Principal - , 0 // _tc_CORBA_Object ... type ID is CORBA::Object - - , 0 // tk_struct - , 0 // tk_union - , 0 // tk_enum - , 0 // _tc_CORBA_String ... unbounded - , 0 // tk_sequence - - , 0 // tk_array - - , 0 // tk_alias - , 0 // tk_except - - , _tc_CORBA_LongLong - , _tc_CORBA_ULongLong - , _tc_CORBA_LongDouble - , _tc_CORBA_WChar - , 0 // _tc_CORBA_WString ... unbounded +CORBA_TypeCode_ptr __tc_consts [TC_KIND_COUNT] = +{ + _tc_CORBA_Null + , _tc_CORBA_Void + , _tc_CORBA_Short + , _tc_CORBA_Long + , _tc_CORBA_UShort + + , _tc_CORBA_ULong + , _tc_CORBA_Float + , _tc_CORBA_Double + , _tc_CORBA_Boolean + , _tc_CORBA_Char + + , _tc_CORBA_Octet + , _tc_CORBA_Any + , _tc_CORBA_TypeCode + , _tc_CORBA_Principal + , 0 // _tc_CORBA_Object ... type ID is CORBA::Object + + , 0 // tk_struct + , 0 // tk_union + , 0 // tk_enum + , 0 // _tc_CORBA_String ... unbounded + , 0 // tk_sequence + + , 0 // tk_array + + , 0 // tk_alias + , 0 // tk_except + + , _tc_CORBA_LongLong + , _tc_CORBA_ULongLong + , _tc_CORBA_LongDouble + , _tc_CORBA_WChar + , 0 // _tc_CORBA_WString ... unbounded }; - -// // The decoder is exactly the reverse of the encoder, except that: // // * Unmarshaling some data types involve allocating memory. Such @@ -559,550 +528,545 @@ __tc_consts [TC_KIND_COUNT] = { // encapsulations. This means it must deal with "tk_indirect", // the magic value (~0) signifying typecode indirection. // -// This second case is identified by a bit of a hack: the second "data" -// value is used to hold the parent typecode, rather than being ignored. -// This means that all other invocations of decoder() ** MUST ** pass zero -// for the second data parameter, in case they decode a TypeCode. If they -// didn't, this case might be signified inappropriately. -// -// XXX desirable to have a less hacky solution to that ... pull that code -// out into a separate routine called both by CDR::decoder() and by the -// code retrieving typecode parameters from encapsulations. +// This second case is identified by a bit of a hack: the second +// "data" value is used to hold the parent typecode, rather than being +// ignored. This means that all other invocations of decoder() ** +// MUST ** pass zero for the second data parameter, in case they +// decode a TypeCode. If they didn't, this case might be signified +// inappropriately. // +// XXX desirable to have a less hacky solution to that ... pull that +// code out into a separate routine called both by CDR::decoder() and +// by the code retrieving typecode parameters from encapsulations. + CORBA_TypeCode::traverse_status -CDR::decoder ( - CORBA_TypeCode_ptr tc, - const void *data, - const void *parent_typecode, - void *context, - CORBA_Environment &env -) +CDR::decoder (CORBA_TypeCode_ptr tc, + const void *data, + const void *parent_typecode, + void *context, + CORBA_Environment &env) { - CORBA_Boolean continue_decoding = CORBA_B_TRUE; - CDR *stream = (CDR *)context; - - switch (tc->_kind) { - case tk_null: - case tk_void: - // nothing to decode! - break; + CORBA_Boolean continue_decoding = CORBA_B_TRUE; + CDR *stream = (CDR *) context; + + switch (tc->_kind) + { + case tk_null: + case tk_void: + // nothing to decode! + break; - case tk_char: - case tk_octet: - continue_decoding = stream->get_char (*(CORBA_Char *)data); - break; - - case tk_short: - case tk_ushort: - continue_decoding = stream->get_short (*(short *)data); - break; - - case tk_long: - case tk_ulong: - case tk_float: - continue_decoding = stream->get_long (*(CORBA_Long *)data); - break; - - case tk_longlong: - case tk_ulonglong: - case tk_double: - continue_decoding = stream->get_longlong (*(CORBA_LongLong *)data); - break; - - case tk_boolean: - continue_decoding = stream->get_boolean (*(CORBA_Boolean *)data); - break; - - case tk_enum: - { - CORBA_ULong val; - - // - // NOTE assumption that this is in-range. - // - // XXX should check this, it's rather hard to recover - // from such errors since they "do not occur" and are - // essentially never tested for. - // - continue_decoding = stream->get_ulong (val); - *(unsigned *)data = (unsigned) val; - } - break; - - case tk_any: - { - CORBA_Any *any = (CORBA_Any *)data; - CORBA_TypeCode_ptr tc2; - void *value; - - if (decoder (_tc_CORBA_TypeCode, &tc2, 0, context, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE) - return CORBA_TypeCode::TRAVERSE_STOP; - - value = new CORBA_Octet [tc2->size (env)]; - - if (decoder (tc2, value, 0, context, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE) { - delete value; - CORBA_release (tc2); - return CORBA_TypeCode::TRAVERSE_STOP; - } - (void) new (any) CORBA_Any (tc2, value, CORBA_B_TRUE); - } - break; - - case tk_TypeCode: - { - CORBA_ULong kind; - CORBA_TypeCode_ptr *tcp; - - continue_decoding = stream->get_ulong (kind); - if (continue_decoding == CORBA_B_FALSE) - break; - if (kind >= TC_KIND_COUNT) { - continue_decoding = CORBA_B_FALSE; - break; - } + case tk_char: + case tk_octet: + continue_decoding = stream->get_char (*(CORBA_Char *) data); + break; + + case tk_short: + case tk_ushort: + continue_decoding = stream->get_short (*(short *) data); + break; + + case tk_long: + case tk_ulong: + case tk_float: + continue_decoding = stream->get_long (*(CORBA_Long *) data); + break; + + case tk_longlong: + case tk_ulonglong: + case tk_double: + continue_decoding = stream->get_longlong (*(CORBA_LongLong *) data); + break; + + case tk_boolean: + continue_decoding = stream->get_boolean (*(CORBA_Boolean *) data); + break; + + case tk_enum: + { + CORBA_ULong val; + + // NOTE assumption that this is in-range. + // + // XXX should check this, it's rather hard to recover from + // such errors since they "do not occur" and are essentially + // never tested for. + continue_decoding = stream->get_ulong (val); + *(u_int *) data = (u_int) val; + } + break; + + case tk_any: + { + CORBA_Any *any = (CORBA_Any *) data; + CORBA_TypeCode_ptr tc2; + void *value; + + if (decoder (_tc_CORBA_TypeCode, + &tc2, 0, + context, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) + return CORBA_TypeCode::TRAVERSE_STOP; + + value = new CORBA_Octet[tc2->size (env)]; + + if (decoder (tc2, + value, 0, + context, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) + { + delete value; + CORBA_release (tc2); + return CORBA_TypeCode::TRAVERSE_STOP; + } + (void) new (any) CORBA_Any (tc2, value, CORBA_B_TRUE); + } + break; + + case tk_TypeCode: + { + CORBA_ULong kind; + CORBA_TypeCode_ptr *tcp; + + continue_decoding = stream->get_ulong (kind); + if (continue_decoding == CORBA_B_FALSE) + break; + if (kind >= TC_KIND_COUNT) + { + continue_decoding = CORBA_B_FALSE; + break; + } - tcp = (CORBA_TypeCode_ptr *)data; + tcp = (CORBA_TypeCode_ptr *) data; - // - // Typecodes with empty parameter lists all have preallocated - // constants. We use those to reduce memory consumption and - // heap access ... also, to speed things up! - // - if (((*tcp) = __tc_consts [(unsigned) kind]) != 0) { - *tcp = __tc_consts [(unsigned) kind]; - break; - } else switch (kind) { - // + // Typecodes with empty parameter lists all have preallocated + // constants. We use those to reduce memory consumption and + // heap access ... also, to speed things up! + + if (((*tcp) = __tc_consts [(u_int) kind]) != 0) + { + *tcp = __tc_consts [(u_int) kind]; + break; + } + else + switch (kind) + { // Need special handling for all kinds of typecodes that have // nonempty parameter lists ... - // - default: // error: missed a case! - env.exception (new CORBA_INTERNAL (COMPLETED_MAYBE)); - return CORBA_TypeCode::TRAVERSE_STOP; + default: // error: missed a case! + env.exception (new CORBA_INTERNAL (COMPLETED_MAYBE)); + return CORBA_TypeCode::TRAVERSE_STOP; - // // Some have "simple" parameter lists ... some of these also // have preallocated constants that could be used. - // - case tk_string: - case tk_wstring: - { - CORBA_ULong bound; - - continue_decoding = stream->get_ulong (bound); - if (continue_decoding) { - if (bound == 0) { - if (kind == tk_string) - *tcp = _tc_CORBA_String; - else - *tcp = _tc_CORBA_WString; - } else { - *tcp = new CORBA_TypeCode ((CORBA_TCKind) kind, - bound, 0, CORBA_B_TRUE); - } - } + case tk_string: + case tk_wstring: + { + CORBA_ULong bound; + + continue_decoding = stream->get_ulong (bound); + if (continue_decoding) { + if (bound == 0) { + if (kind == tk_string) + *tcp = _tc_CORBA_String; + else + *tcp = _tc_CORBA_WString; + } else { + *tcp = new CORBA_TypeCode ((CORBA_TCKind) kind, + bound, 0, CORBA_B_TRUE); + } } - break; - - // - // Indirected typecodes, illegal at "top level" but we allow - // unmarshaling of them here because we use the same code to - // read "off the wire" (where they're illegal) and to read - // out of an encapsulation stream. We distinguish the case - // where this is legal as described above. - // - case ~0: - { - CORBA_TypeCode_ptr parent; - - if (parent_typecode == 0) { - env.exception (new CORBA_INTERNAL (COMPLETED_MAYBE)); - return CORBA_TypeCode::TRAVERSE_STOP; - } - parent = (CORBA_TypeCode_ptr) parent_typecode; - - // - // Get the long indicating the encapsulation offset, - // then set up indirection stream that's like "stream" - // but has space enough only for the typecode and - // the length for the encapsulated parameters. - // - CDR indir_stream; - CORBA_Long offset; - - continue_decoding = stream->get_long (offset); - if (continue_decoding) - continue_decoding = (offset < 0); - if (continue_decoding) { - indir_stream.buffer = indir_stream.next - = stream->next + offset; - indir_stream.remaining = indir_stream.length = 8; - - // - // Reject indirections outside parent's scope. - // - if (indir_stream.next < parent->_buffer) - continue_decoding = CORBA_B_FALSE; - } - - // - // Get "kind" and length of target typecode - // - // XXX this currently assumes the TCKind to which - // we indirect is the same byte order as the "parent" - // typecode -- not the right assumption; see how - // the TypeCode interpreter does it. - // - CORBA_ULong indir_kind, indir_len; - - if (continue_decoding) - continue_decoding = stream->get_ulong (indir_kind); - if (continue_decoding - && indir_kind >= TC_KIND_COUNT) - continue_decoding = CORBA_B_FALSE; - if (continue_decoding) - continue_decoding = stream->get_ulong (indir_len); - - // - // Now construct indirected typecode. This shares the - // typecode octets with the "parent" typecode, increasing - // the amount of memory sharing and reducing the cost of - // getting typecodes. - // - if (continue_decoding) { - *tcp = new CORBA_TypeCode ( - (CORBA_TCKind) indir_kind, - indir_len, indir_stream.next, - CORBA_B_FALSE); - (*tcp)->_parent = parent; - parent->AddRef (); - } - } - break; - - // - // The rest have "complex" parameter lists that are - // encoded as bulk octets ... - // - case tk_objref: - case tk_struct: - case tk_union: - case tk_enum: - case tk_sequence: - case tk_array: - case tk_alias: - case tk_except: - { - unsigned len, i; - CORBA_ULong length; - CORBA_Octet *buffer; - - continue_decoding = stream->get_ulong (length); - if (!continue_decoding) - break; - - // if length > MAXUNSIGNED, error ... - len = (unsigned) length; - - buffer = new CORBA_Octet [len]; - - for (i = 0; i < len && continue_decoding; i++) - continue_decoding = stream->get_octet (buffer [i]); - - if (!continue_decoding) { - delete buffer; - break; - } - *tcp = new CORBA_TypeCode ((CORBA_TCKind)kind, - len, buffer, CORBA_B_TRUE); - } - } - } - break; - - case tk_Principal: - { - CORBA_Principal_ptr *pp = (CORBA_Principal_ptr *)data; - CORBA_ULong len; - - continue_decoding = stream->get_ulong (len); - if (len == 0) - *pp = 0; - else { - *pp = new CORBA_Principal; - (*pp)->id.buffer = new CORBA_Octet [(size_t) len]; - (*pp)->id.maximum = (*pp)->id.length = len; - - for (unsigned i = 0; - continue_decoding != CORBA_B_FALSE && i < len; - i++) - continue_decoding = stream->get_octet ( - (*pp)->id.buffer [i]); - } - } - break; + } + break; - case tk_objref: - { - // - // First, read the type hint. - // - CORBA_String type_hint; + // Indirected typecodes, illegal at "top level" but we + // allow unmarshaling of them here because we use the same + // code to read "off the wire" (where they're illegal) and + // to read out of an encapsulation stream. We distinguish + // the case where this is legal as described above. + case ~0: + { + CORBA_TypeCode_ptr parent; + + if (parent_typecode == 0) + { + env.exception (new CORBA_INTERNAL (COMPLETED_MAYBE)); + return CORBA_TypeCode::TRAVERSE_STOP; + } + parent = (CORBA_TypeCode_ptr) parent_typecode; + + // Get the long indicating the encapsulation offset, + // then set up indirection stream that's like "stream" + // but has space enough only for the typecode and the + // length for the encapsulated parameters. + CDR indir_stream; + CORBA_Long offset; + + continue_decoding = stream->get_long (offset); + if (continue_decoding) + continue_decoding = (offset < 0); + if (continue_decoding) + { + indir_stream.buffer = indir_stream.next + = stream->next + offset; + indir_stream.remaining = indir_stream.length = 8; + + // Reject indirections outside parent's scope. + if (indir_stream.next < parent->_buffer) + continue_decoding = CORBA_B_FALSE; + } + + // Get "kind" and length of target typecode + // + // XXX this currently assumes the TCKind to which we + // indirect is the same byte order as the "parent" + // typecode -- not the right assumption; see how the + // TypeCode interpreter does it. + + CORBA_ULong indir_kind; + CORBA_ULong indir_len; + + if (continue_decoding) + continue_decoding = stream->get_ulong (indir_kind); + if (continue_decoding + && indir_kind >= TC_KIND_COUNT) + continue_decoding = CORBA_B_FALSE; + if (continue_decoding) + continue_decoding = stream->get_ulong (indir_len); + + // Now construct indirected typecode. This shares the + // typecode octets with the "parent" typecode, + // increasing the amount of memory sharing and + // reducing the cost of getting typecodes. + if (continue_decoding) + { + *tcp = new CORBA_TypeCode ((CORBA_TCKind) indir_kind, + indir_len, + indir_stream.next, + CORBA_B_FALSE); + (*tcp)->_parent = parent; + parent->AddRef (); + } + } + break; - decoder (_tc_CORBA_String, &type_hint, 0, context, env); + // The rest have "complex" parameter lists that are + // encoded as bulk octets ... + case tk_objref: + case tk_struct: + case tk_union: + case tk_enum: + case tk_sequence: + case tk_array: + case tk_alias: + case tk_except: + { + u_int len; + u_int i; + CORBA_ULong length; + CORBA_Octet *buffer; + + continue_decoding = stream->get_ulong (length); + if (!continue_decoding) + break; + + // if length > MAXUNSIGNED, error ... + len = (u_int) length; + + buffer = new CORBA_Octet [len]; + + for (i = 0; i < len && continue_decoding; i++) + continue_decoding = stream->get_octet (buffer [i]); + + if (!continue_decoding) { + delete buffer; + break; + } + *tcp = new CORBA_TypeCode ((CORBA_TCKind) kind, + len, + buffer, + CORBA_B_TRUE); + } + } + } + break; + + case tk_Principal: + { + CORBA_Principal_ptr *pp = (CORBA_Principal_ptr *) data; + CORBA_ULong len; + + continue_decoding = stream->get_ulong (len); + if (len == 0) + *pp = 0; + else + { + *pp = new CORBA_Principal; + (*pp)->id.buffer = new CORBA_Octet [(size_t) len]; + (*pp)->id.maximum = (*pp)->id.length = len; + + for (u_int i = 0; + continue_decoding != CORBA_B_FALSE && i < len; + i++) + continue_decoding = stream->get_octet ((*pp)->id.buffer [i]); + } + } + break; + + case tk_objref: + { + // First, read the type hint. + + CORBA_String type_hint; + + decoder (_tc_CORBA_String, &type_hint, 0, context, env); + + // Read the profiles, discarding all until an IIOP profile + // comes by. Once we see an IIOP profile, ignore any further + // ones. + // + // XXX this will need to change someday to let different + // protocol code be accessed, not just IIOP. Protocol modules + // will be dynamically loaded from shared libraries via + // ORB_init(), and we just need to be able to access such + // preloaded libraries here as we unmarshal objrefs. - // - // Read the profiles, discarding all until an IIOP profile comes by. - // Once we see an IIOP profile, ignore any further ones. - // - // XXX this will need to change someday to let different protocol - // code be accessed, not just IIOP. Protocol modules will be - // dynamically loaded from shared libraries via ORB_init(), and - // we just need to be able to access such preloaded libraries here - // as we unmarshal objrefs. - // - CORBA_ULong profiles; - IIOP_Object *objdata = 0; + CORBA_ULong profiles; + IIOP_Object *objdata = 0; - stream->get_ulong (profiles); + stream->get_ulong (profiles); - // - // No profiles means a NIL objref. - // - if (profiles == 0) { - *(CORBA_Object_ptr *)data = CORBA_Object::_nil (); - delete type_hint; - break; - } - while (profiles-- != 0 && continue_decoding) { - CORBA_ULong tmp; - - stream->get_ulong (tmp); - if (tmp != IOP::TAG_INTERNET_IOP || objdata != 0) { - continue_decoding = stream->skip_string (); - continue; - } + // No profiles means a NIL objref. - // - // OK, we've got an IIOP profile. It's going to be - // encapsulated ProfileData. Create a new decoding - // stream and context for it, and tell the "parent" - // stream that this data isn't part of it any more. - // - continue_decoding = stream->get_ulong (tmp); - assert (stream->remaining >= tmp); + if (profiles == 0) + { + *(CORBA_Object_ptr *) data = CORBA_Object::_nil (); + delete type_hint; + break; + } - // - // Create the decoding stream from the encapsulation - // in the buffer, and skip the encapsulation. - // - CDR str; + while (profiles-- != 0 && continue_decoding) + { + CORBA_ULong tmp; - str.setup_encapsulation (stream->next, (size_t) tmp); + stream->get_ulong (tmp); - stream->next += (unsigned) tmp; - stream->remaining -= (unsigned) tmp; + if (tmp != IOP::TAG_INTERNET_IOP || objdata != 0) + { + continue_decoding = stream->skip_string (); + continue; + } - objdata = new IIOP_Object (type_hint); + // OK, we've got an IIOP profile. It's going to be + // encapsulated ProfileData. Create a new decoding stream + // and context for it, and tell the "parent" stream that + // this data isn't part of it any more. - IIOP::ProfileBody *profile = &objdata->profile; + continue_decoding = stream->get_ulong (tmp); + assert (stream->remaining >= tmp); - // - // Read and verify major, minor versions, ignoring - // IIOP profiles whose versions we don't understand. - // - // XXX this doesn't actually go back and skip the - // whole encapsulation... - // - if (!(str.get_octet (profile->iiop_version.major) - && profile->iiop_version.major == IIOP::MY_MAJOR - && str.get_octet (profile->iiop_version.minor) - && profile->iiop_version.minor <= IIOP::MY_MINOR)) { - dmsg2 ("detected new v%d.%d IIOP profile", - profile->iiop_version.major, - profile->iiop_version.minor); - objdata->type_id = 0; - objdata->Release (); - objdata = 0; - continue; - } - - // - // Get host and port - // - if (decoder (_tc_CORBA_String, &profile->host, 0, &str, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE - || !str.get_ushort (profile->port)) { - env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); - dmsg ("error decoding IIOP host/port"); - objdata->Release (); - return CORBA_TypeCode::TRAVERSE_STOP; - } + // Create the decoding stream from the encapsulation in + // the buffer, and skip the encapsulation. + CDR str; - // - // ... and object key - // - continue_decoding = - (decoder (&TC_opaque, &profile->object_key, 0, &str, env) - == CORBA_TypeCode::TRAVERSE_CONTINUE); - - if (str.remaining != 0) { - env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); - dmsg ("extra data at end of IIOP profile data"); - objdata->Release (); - return CORBA_TypeCode::TRAVERSE_STOP; - } - } - if (objdata == 0) { - env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); - dmsg2 ("no IIOP v%d.%d (or earlier) profile in IOR!", - IIOP::MY_MAJOR, IIOP::MY_MINOR); - return CORBA_TypeCode::TRAVERSE_STOP; - } else { - if (objdata->QueryInterface (IID_CORBA_Object, (void **) data) - != NOERROR) - continue_decoding = CORBA_B_FALSE; - objdata->Release (); - } - } - break; + str.setup_encapsulation (stream->next, (size_t) tmp); - case tk_sequence: - { - // - // First unmarshal the sequence length ... we trust it - // to be right here, on the "be gracious in what you - // accept" principle. We don't generate illegal sequences - // (i.e. length > bounds). - // - CORBA_OctetSeq *seq = (CORBA_OctetSeq *) data; + stream->next += (u_int) tmp; + stream->remaining -= (u_int) tmp; - continue_decoding = stream->get_ulong (seq->length); - seq->maximum = seq->length; - seq->buffer = 0; + objdata = new IIOP_Object (type_hint); - // - // Fast exit on empty sequences or errors - // - if (!continue_decoding || seq->length == 0) - break; + IIOP::ProfileBody *profile = &objdata->profile; + // Read and verify major, minor versions, ignoring IIOP + // profiles whose versions we don't understand. // - // ... then allocate the memory into which we'll unmarshal - // - CORBA_TypeCode_ptr tc2; - size_t size; - - tc2 = tc->typecode_param (0, env); - if (env.exception ()) - return CORBA_TypeCode::TRAVERSE_STOP; - - size = tc2->size (env); - if (env.exception ()) + // XXX this doesn't actually go back and skip the whole + // encapsulation... + if (!(str.get_octet (profile->iiop_version.major) + && profile->iiop_version.major == IIOP::MY_MAJOR + && str.get_octet (profile->iiop_version.minor) + && profile->iiop_version.minor <= IIOP::MY_MINOR)) + { + dmsg2 ("detected new v%d.%d IIOP profile", + profile->iiop_version.major, + profile->iiop_version.minor); + objdata->type_id = 0; + objdata->Release (); + objdata = 0; + continue; + } + + // Get host and port + if (decoder (_tc_CORBA_String, &profile->host, 0, &str, env) + != CORBA_TypeCode::TRAVERSE_CONTINUE + || !str.get_ushort (profile->port)) + { + env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); + dmsg ("error decoding IIOP host/port"); + objdata->Release (); return CORBA_TypeCode::TRAVERSE_STOP; + } - tc2->Release (); + // ... and object key - seq->buffer = new CORBA_Octet [size * (size_t) seq->maximum]; - } - // FALLTHROUGH + continue_decoding = decoder (&TC_opaque, + &profile->object_key, + 0, + &str, + env) == CORBA_TypeCode::TRAVERSE_CONTINUE; - case tk_struct: - case tk_union: - case tk_array: - case tk_alias: - // - // Unmarshal all the individual elements using the per-member - // description held in the "parent" TypeCode. - // + if (str.remaining != 0) + { + env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); + dmsg ("extra data at end of IIOP profile data"); + objdata->Release (); + return CORBA_TypeCode::TRAVERSE_STOP; + } + } + if (objdata == 0) + { + env.exception (new CORBA_MARSHAL (COMPLETED_MAYBE)); + dmsg2 ("no IIOP v%d.%d (or earlier) profile in IOR!", + IIOP::MY_MAJOR, IIOP::MY_MINOR); + return CORBA_TypeCode::TRAVERSE_STOP; + } + else + { + if (objdata->QueryInterface (IID_CORBA_Object, + (void **) data) != NOERROR) + continue_decoding = CORBA_B_FALSE; + objdata->Release (); + } + } + break; + + case tk_sequence: + { + // First unmarshal the sequence length ... we trust it to be + // right here, on the "be gracious in what you accept" + // principle. We don't generate illegal sequences + // (i.e. length > bounds). + + CORBA_OctetSeq *seq = (CORBA_OctetSeq *) data; + + continue_decoding = stream->get_ulong (seq->length); + seq->maximum = seq->length; + seq->buffer = 0; + + // Fast exit on empty sequences or errors + if (!continue_decoding || seq->length == 0) + break; + + // ... then allocate the memory into which we'll unmarshal + CORBA_TypeCode_ptr tc2; + size_t size; + + tc2 = tc->typecode_param (0, env); + if (env.exception ()) + return CORBA_TypeCode::TRAVERSE_STOP; + + size = tc2->size (env); + if (env.exception ()) + return CORBA_TypeCode::TRAVERSE_STOP; + + tc2->Release (); + + seq->buffer = new CORBA_Octet [size * (size_t) seq->maximum]; + } + // FALLTHROUGH + + case tk_struct: + case tk_union: + case tk_array: + case tk_alias: + // Unmarshal all the individual elements using the per-member + // description held in the "parent" TypeCode. - // FALLTHROUGH - - case tk_except: + // FALLTHROUGH + + case tk_except: + // For exceptions, the "hidden" type ID near the front of the + // on-wire representation was previously unmarshaled and mapped + // to the "tc" typcode we're using to traverse the memory ... + // at the same time its vtable, refcount, and other state was + // established. + // + // NOTE: This is asymmetric with respect to encoding exceptions. + return tc->traverse (data, 0, decoder, context, env); + + case tk_string: + { + CORBA_String str; + CORBA_ULong len = 0; + + // On decode, omit the check against specified string bounds, + // and cope with illegal "zero length" strings (all lengths on + // the wire must include a NUL). // - // For exceptions, the "hidden" type ID near the front of the - // on-wire representation was previously unmarshaled and mapped - // to the "tc" typcode we're using to traverse the memory ... - // at the same time its vtable, refcount, and other state was - // established. - // - // NOTE: This is asymmetric with respect to encoding exceptions. - // - return tc->traverse (data, 0, decoder, context, env); + // This is on the principle of being gracious in what we + // accept; we don't generate messages that fail to comply with + // protocol specs, but we will accept them when it's clear how + // to do so. + + continue_decoding = stream->get_ulong (len); + *((CORBA_String*) data) = str = new CORBA_Char [(size_t) (len)]; + + if (len != 0) + while (continue_decoding != CORBA_B_FALSE && len-- != 0) + { + continue_decoding = stream->get_char (*(CORBA_Char *) str); + str++; + } + break; + } - case tk_string: - { - CORBA_String str; - CORBA_ULong len = 0; + case tk_wstring: + { + CORBA_WChar *str; + CORBA_ULong len = 0; - // - // On decode, omit the check against specified string bounds, - // and cope with illegal "zero length" strings (all lengths - // on the wire must include a NUL). - // - // This is on the principle of being gracious in what we accept; - // we don't generate messages that fail to comply with protocol - // specs, but we will accept them when it's clear how to do so. - // - continue_decoding = stream->get_ulong (len); - *((CORBA_String*)data) = str = new CORBA_Char [(size_t) (len)]; - if (len != 0) - while (continue_decoding != CORBA_B_FALSE && len-- != 0) { - continue_decoding = stream->get_char (*(CORBA_Char *)str); - str++; - } - break; - } + // On decode, omit the check against specified wstring bounds, + // and cope with illegal "zero length" strings (all lengths on + // the wire must include a NUL). + // + // This is on the principle of being gracious in what we + // accept; we don't generate messages that fail to comply with + // protocol specs, but we will accept them when it's clear how + // to do so. - case tk_wstring: - { - CORBA_WChar *str; - CORBA_ULong len = 0; + continue_decoding = stream->get_ulong (len); - // - // On decode, omit the check against specified wstring bounds, - // and cope with illegal "zero length" strings (all lengths - // on the wire must include a NUL). - // - // This is on the principle of being gracious in what we accept; - // we don't generate messages that fail to comply with protocol - // specs, but we will accept them when it's clear how to do so. - // - continue_decoding = stream->get_ulong (len); - *((CORBA_WChar **)data) = str = new CORBA_WChar [(size_t) (len)]; - if (len != 0) { - while (continue_decoding != CORBA_B_FALSE && len--) { - continue_decoding = stream->get_wchar (*str); - str++; - } + *((CORBA_WChar **) data) = str = new CORBA_WChar [(size_t) (len)]; + + if (len != 0) + while (continue_decoding != CORBA_B_FALSE && len--) + { + continue_decoding = stream->get_wchar (*str); + str++; } - } - break; + } + break; - case tk_longdouble: - continue_decoding = - stream->get_longdouble (*(CORBA_LongDouble *)data); - break; + case tk_longdouble: + continue_decoding = stream->get_longdouble (*(CORBA_LongDouble *) data); + break; - case tk_wchar: - continue_decoding = stream->get_wchar (*(CORBA_WChar *)data); - break; + case tk_wchar: + continue_decoding = stream->get_wchar (*(CORBA_WChar *) data); + break; // case ~0: - default: - continue_decoding = CORBA_B_FALSE; - dmsg ("decode, default case?"); - break; + default: + continue_decoding = CORBA_B_FALSE; + dmsg ("decode, default case?"); + break; } - if (continue_decoding == CORBA_B_FALSE) { - env.exception (new CORBA_MARSHAL (COMPLETED_NO)); - dmsg ("marshaling decoder detected error"); - return CORBA_TypeCode::TRAVERSE_STOP; + if (continue_decoding == CORBA_B_FALSE) + { + env.exception (new CORBA_MARSHAL (COMPLETED_NO)); + dmsg ("marshaling decoder detected error"); + return CORBA_TypeCode::TRAVERSE_STOP; } - return CORBA_TypeCode::TRAVERSE_CONTINUE; + return CORBA_TypeCode::TRAVERSE_CONTINUE; } diff --git a/TAO/IIOP/lib/nvlist.cpp b/TAO/IIOP/lib/nvlist.cpp index c9253ce80e2..f9fe2742640 100644 --- a/TAO/IIOP/lib/nvlist.cpp +++ b/TAO/IIOP/lib/nvlist.cpp @@ -3,7 +3,7 @@ // All Rights Reserved // // Implementation of Named Value List -// + #include <assert.h> #if !defined (VXWORKS) #include <memory.h> @@ -14,28 +14,22 @@ #include "debug.h" - -// // COM's IUnknown support -// // {77420087-F276-11ce-9598-0000C07CA898} DEFINE_GUID (IID_CORBA_NamedValue, 0x77420087, 0xf276, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); - -ULONG -__stdcall -CORBA_NamedValue::AddRef () +ULONG __stdcall +CORBA_NamedValue::AddRef (void) { ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); return _refcount++; } -ULONG -__stdcall -CORBA_NamedValue::Release () +ULONG __stdcall +CORBA_NamedValue::Release (void) { ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); @@ -48,69 +42,59 @@ CORBA_NamedValue::Release () return 0; } -HRESULT -__stdcall -CORBA_NamedValue::QueryInterface ( - REFIID riid, - void **ppv -) +HRESULT __stdcall +CORBA_NamedValue::QueryInterface (REFIID riid, + void **ppv) { - *ppv = 0; + *ppv = 0; - if (IID_CORBA_NamedValue == riid || IID_IUnknown == riid) - *ppv = this; + if (IID_CORBA_NamedValue == riid || IID_IUnknown == riid) + *ppv = this; - if (*ppv == 0) - return ResultFromScode (E_NOINTERFACE); + if (*ppv == 0) + return ResultFromScode (E_NOINTERFACE); - (void) AddRef (); - return NOERROR; + (void) AddRef (); + return NOERROR; } -// // Reference counting for DII Request object -// + void CORBA_release (CORBA_NamedValue_ptr nv) { - if (nv) - nv->Release (); + if (nv) + nv->Release (); } CORBA_Boolean CORBA_is_nil (CORBA_NamedValue_ptr nv) { - return (CORBA_Boolean)(nv == 0); + return (CORBA_Boolean)(nv == 0); } -CORBA_NamedValue::~CORBA_NamedValue () +CORBA_NamedValue::~CORBA_NamedValue (void) { - if (_name) - CORBA_string_free ((CORBA_String)_name); + if (_name) + CORBA_string_free ((CORBA_String)_name); } - -// // COM's IUnknown support -// // {77420088-F276-11ce-9598-0000C07CA898} DEFINE_GUID (IID_CORBA_NVList, 0x77420088, 0xf276, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); - -ULONG -__stdcall -CORBA_NVList::AddRef () +ULONG __stdcall +CORBA_NVList::AddRef (void) { ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); return _refcount++; } -ULONG -__stdcall -CORBA_NVList::Release () +ULONG __stdcall +CORBA_NVList::Release (void) { ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); @@ -123,124 +107,117 @@ CORBA_NVList::Release () return 0; } -HRESULT -__stdcall -CORBA_NVList::QueryInterface ( - REFIID riid, - void **ppv -) +HRESULT __stdcall +CORBA_NVList::QueryInterface (REFIID riid, + void **ppv) { - *ppv = 0; + *ppv = 0; - if (IID_CORBA_NVList == riid || IID_IUnknown == riid) - *ppv = this; + if (IID_CORBA_NVList == riid || IID_IUnknown == riid) + *ppv = this; - if (*ppv == 0) - return ResultFromScode (E_NOINTERFACE); + if (*ppv == 0) + return ResultFromScode (E_NOINTERFACE); - (void) AddRef (); - return NOERROR; + (void) AddRef (); + return NOERROR; } -// // Reference counting for DII Request object -// + void CORBA_release (CORBA_NVList_ptr nvl) { - if (nvl) - nvl->Release (); + if (nvl) + nvl->Release (); } CORBA_Boolean CORBA_is_nil (CORBA_NVList_ptr nvl) { - return (CORBA_Boolean)(nvl == 0); + return (CORBA_Boolean)(nvl == 0); } -CORBA_NVList::~CORBA_NVList () +CORBA_NVList::~CORBA_NVList (void) { - unsigned i; - - for (i = 0; i < _len; i++) - (&_values [i])->~CORBA_NamedValue (); + for (u_int i = 0; i < _len; i++) + (&_values[i])->~CORBA_NamedValue (); - if (_values) - ACE_OS::free ((char *)_values); - _values = 0; - _len = _max = 0; + if (_values) + ACE_OS::free ((char *)_values); + _values = 0; + _len = _max = 0; } CORBA_NamedValue_ptr -CORBA_NVList::add_value ( - const CORBA_Char *name, - const CORBA_Any &value, - CORBA_Flags flags, - CORBA_Environment &env -) +CORBA_NVList::add_value (const CORBA_Char *name, + const CORBA_Any &value, + CORBA_Flags flags, + CORBA_Environment &env) { - env.clear (); + env.clear (); - if (!(flags & (CORBA_ARG_IN|CORBA_ARG_OUT|CORBA_ARG_INOUT))) { - env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); - return 0; + if (!(flags & (CORBA_ARG_IN | CORBA_ARG_OUT | CORBA_ARG_INOUT))) + { + env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); + return 0; } - // - // We track "_len" and "_max" like sequences do; mixing the - // "add_arg" and nvlist[i] style accessors produces undefined - // behaviour. - // - unsigned len = _len++; - - // - // Extend the array with an _initialized_ element ... relying on - // zeroed memory to be sufficiently initialized. - // - // XXX report malloc failures as errors -- how? - // - if (_values == 0) { - _values = (CORBA_NamedValue_ptr) - calloc (_len, sizeof (CORBA_NamedValue)); - _max = _len; - } else if (len >= _max) { - _values = (CORBA_NamedValue_ptr) ACE_OS::realloc ((char *)_values, - sizeof (CORBA_NamedValue) * _len); - (void) ACE_OS::memset (&_values [_max], 0, - sizeof (_values [_max]) * (_len - _max)); - _max = _len; + // We track "_len" and "_max" like sequences do; mixing the + // "add_arg" and nvlist[i] style accessors produces undefined + // behaviour. + u_int len = _len++; + + // Extend the array with an _initialized_ element ... relying on + // zeroed memory to be sufficiently initialized. + // + // XXX report malloc failures as errors -- how? + + if (_values == 0) + { + _values = (CORBA_NamedValue_ptr) + calloc (_len, sizeof (CORBA_NamedValue)); + _max = _len; + } + else if (len >= _max) + { + _values = (CORBA_NamedValue_ptr) ACE_OS::realloc ((char *)_values, + sizeof (CORBA_NamedValue) * _len); + (void) ACE_OS::memset (&_values[_max], 0, + sizeof (_values[_max]) * (_len - _max)); + _max = _len; } - assert (_values != 0); - - _values [len]._flags = flags; - _values [len]._name = CORBA_string_copy (name); - - if (flags & CORBA_IN_COPY_VALUE) { - // - // IN_COPY_VALUE means that the parameter is not "borrowed" - // by the ORB, but rather that the ORB copies its value. - // - // Initialize the newly allocated memory using a copy - // constructor that places the new "Any" value at just - // the right place, and makes a "deep copy" of the data. - // - (void) new (&_values [len]._any) CORBA_Any (value); - } else { - // - // The normal behaviour for parameters is that the ORB - // "borrows" their memory for the duration of calls. - // - // Initialize the newly allocated "Any" using a normal - // constructor that places the new "Any" value at just - // the right place, yet doesn't copy the memory (except - // for duplicating the typecode). - // - // NOTE: DSI has yet to be updated so that it's OK to - // use such application-allocated memory. It needs at - // least a "send the response now" call. - // - (void) new (&_values [len]._any) CORBA_Any (value.type (), - value.value (), CORBA_B_FALSE); + assert (_values != 0); + + _values[len]._flags = flags; + _values[len]._name = CORBA_string_copy (name); + + if (flags & CORBA_IN_COPY_VALUE) + { + // IN_COPY_VALUE means that the parameter is not "borrowed" by + // the ORB, but rather that the ORB copies its value. + // + // Initialize the newly allocated memory using a copy + // constructor that places the new "Any" value at just the right + // place, and makes a "deep copy" of the data. + (void) new (&_values[len]._any) CORBA_Any (value); + } + else + { + // The normal behaviour for parameters is that the ORB "borrows" + // their memory for the duration of calls. + // + // Initialize the newly allocated "Any" using a normal + // constructor that places the new "Any" value at just the right + // place, yet doesn't copy the memory (except for duplicating + // the typecode). + // + // NOTE: DSI has yet to be updated so that it's OK to use such + // application-allocated memory. It needs at least a "send the + // response now" call. + // + (void) new (&_values[len]._any) CORBA_Any (value.type (), + value.value (), CORBA_B_FALSE); } - return &_values [len]; + return &_values[len]; } diff --git a/TAO/IIOP/lib/object.cpp b/TAO/IIOP/lib/object.cpp index 9e1c2a35c34..671f9bf16f6 100644 --- a/TAO/IIOP/lib/object.cpp +++ b/TAO/IIOP/lib/object.cpp @@ -4,7 +4,6 @@ // All Rights Reserved // // ORB: CORBA::Object operations -// #include <assert.h> #include <limits.h> @@ -17,34 +16,33 @@ #include <initguid.h> - - -// // GET_INTERFACE ... send a simple call to the object, it returns // an InterfaceDef objref. -// -static const paramdata Object_get_interface_params [] = { - { _tc_CORBA_Object, PARAM_RETURN, 0 } - // XXX should be tc_InterfaceDef -}; -static const calldata Object_get_interface_calldata = { - "_interface", CORBA_B_TRUE, - 1, &Object_get_interface_params [0], - 0, 0 + +static const paramdata Object_get_interface_params [] = +{ + { _tc_CORBA_Object, PARAM_RETURN, 0 } + // XXX should be tc_InterfaceDef }; +static const calldata Object_get_interface_calldata = +{ + "_interface", + CORBA_B_TRUE, + 1, + &Object_get_interface_params [0], + 0, 0 +}; -CORBA_InterfaceDef_ptr -__stdcall +CORBA_InterfaceDef_ptr __stdcall CORBA_Object::_get_interface (CORBA_Environment &env) { - CORBA_InterfaceDef_ptr retval = 0; + CORBA_InterfaceDef_ptr retval = 0; - // - // At this time, we only have a single generic way to find the - // CORBA interface def for an object. - // - STUB_Object *istub; + // At this time, we only have a single generic way to find the CORBA + // interface def for an object. + + STUB_Object *istub; if (QueryInterface (IID_STUB_Object, (void **) &istub) != NOERROR) { @@ -53,59 +51,55 @@ CORBA_Object::_get_interface (CORBA_Environment &env) } Release (); - // - // NOTE: If istub->type_id is nonzero, we could try asking a - // "local" interface repository and avoid costly network I/O. - // (It's wrong to have different data associated with the same - // interface ID in different repositories; the interface is - // the interface, it doesn't change!) + // NOTE: If istub->type_id is nonzero, we could try asking a "local" + // interface repository and avoid costly network I/O. (It's wrong + // to have different data associated with the same interface ID in + // different repositories; the interface is the interface, it + // doesn't change!) // // We need to be prepared to ask the object itself for this - // information though, since there's no guarantee that any - // local interface repository will really have records of this - // particular interface. - // + // information though, since there's no guarantee that any local + // interface repository will really have records of this particular + // interface. istub->do_call (env, &Object_get_interface_calldata, &retval); return retval; } +// IS_A ... ask the object if it's an instance of the type whose +// logical type ID is passed as a parameter. -// -// IS_A ... ask the object if it's an instance of the type whose logical -// type ID is passed as a parameter. -// -static const paramdata Object_is_a_params [] = { - { _tc_CORBA_Boolean, PARAM_RETURN, 0 }, - { _tc_CORBA_String, PARAM_IN, 0 } -}; -static const calldata Object_is_a_calldata = { - "_is_a", CORBA_B_TRUE, - 2, &Object_is_a_params [0], - 0, 0 +static const paramdata Object_is_a_params [] = +{ + { _tc_CORBA_Boolean, PARAM_RETURN, 0 }, + { _tc_CORBA_String, PARAM_IN, 0 } }; +static const calldata Object_is_a_calldata = +{ + "_is_a", CORBA_B_TRUE, + 2, &Object_is_a_params [0], + 0, 0 +}; -CORBA_Boolean -__stdcall +CORBA_Boolean __stdcall CORBA_Object::_is_a (const CORBA_Char *type_id, CORBA_Environment &env) { - // - // At this time, we only have a single generic way to check the - // type of an object. - // - STUB_Object *istub; + // At this time, we only have a single generic way to check the type + // of an object. + STUB_Object *istub; - if (QueryInterface (IID_STUB_Object, (void **) &istub) != NOERROR) + if (QueryInterface (IID_STUB_Object, + (void **) &istub) != NOERROR) { env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); return CORBA_B_FALSE; } + Release (); - // - // NOTE: if istub->type_id is nonzero and we have local knowledge - // of it, we can answer this question without a costly remote call. + // NOTE: if istub->type_id is nonzero and we have local knowledge of + // it, we can answer this question without a costly remote call. // // That "local knowledge" could come from stubs or skeletons linked // into this process in the best case, or a "near" repository in a @@ -113,53 +107,54 @@ CORBA_Object::_is_a (const CORBA_Char *type_id, // about is the ID we have recorded, we don't need to ask about the // inheritance relationships at all! // - // In real systems having local knowledge will be common, though as the - // systems built atop ORBs become richer it'll also become common to - // have the "real type ID" not be directly understood because it's - // more deeply derived than any locally known types. + // In real systems having local knowledge will be common, though as + // the systems built atop ORBs become richer it'll also become + // common to have the "real type ID" not be directly understood + // because it's more deeply derived than any locally known types. // // XXX if type_id is that of CORBA::Object, "yes, we comply" :-) - // + if (istub->type_id != 0 && ACE_OS::strcmp ((char *)type_id, (char *)istub->type_id) == 0) return CORBA_B_TRUE; - // - // Our local knowledge about this type is insufficient to say whether - // this reference is to an object of a type which "is_a" subtype of - // the type whose ID is passed as a parameter. The implementation - // always knows the answer to that question, however! - // - CORBA_Boolean retval = CORBA_B_FALSE; + // Our local knowledge about this type is insufficient to say + // whether this reference is to an object of a type which "is_a" + // subtype of the type whose ID is passed as a parameter. The + // implementation always knows the answer to that question, however! + + CORBA_Boolean retval = CORBA_B_FALSE; istub->do_call (env, &Object_is_a_calldata, &retval, &type_id); return retval; } - -// // GET_IMPLEMENTATION ... send a simple call to the object, it returns // an ImplementationDef objref. -// -static const paramdata Object_get_implementation_params [] = { - { _tc_CORBA_Object, PARAM_RETURN, 0 } - // XXX should be tc_ImplementationDef -}; -static const calldata Object_get_implementation_calldata = { - "_implementation", CORBA_B_TRUE, - 1, &Object_get_implementation_params [0], - 0, 0 + +static const paramdata Object_get_implementation_params [] = +{ + { _tc_CORBA_Object, PARAM_RETURN, 0 } + // XXX should be tc_ImplementationDef }; +static const calldata Object_get_implementation_calldata = +{ + "_implementation", + CORBA_B_TRUE, + 1, + &Object_get_implementation_params [0], + 0, 0 +}; -CORBA_ImplementationDef_ptr -__stdcall +CORBA_ImplementationDef_ptr __stdcall CORBA_Object::_get_implementation (CORBA_Environment &env) { - STUB_Object *istub; + STUB_Object *istub; CORBA_ImplementationDef_ptr retval = 0; - if (QueryInterface (IID_STUB_Object, (void **) &istub) != NOERROR) + if (QueryInterface (IID_STUB_Object, + (void **) &istub) != NOERROR) { env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); return retval; @@ -170,31 +165,30 @@ CORBA_Object::_get_implementation (CORBA_Environment &env) return retval; } - -// // NON_EXISTENT ... send a simple call to the object, which will -// either elicit a FALSE response or a OBJECT_NOT_EXIST exception. -// In the latter case, return FALSE. -// -static const paramdata Object_non_existent_params [] = { - { _tc_CORBA_Boolean, PARAM_RETURN, 0 } -}; -static const calldata Object_non_existent_calldata = { - "_non_existent", CORBA_B_TRUE, - 1, &Object_non_existent_params [0], - 0, 0 +// either elicit a FALSE response or a OBJECT_NOT_EXIST exception. In +// the latter case, return FALSE. + +static const paramdata Object_non_existent_params [] = +{ + { _tc_CORBA_Boolean, PARAM_RETURN, 0 } }; +static const calldata Object_non_existent_calldata = +{ + "_non_existent", CORBA_B_TRUE, + 1, &Object_non_existent_params [0], + 0, 0 +}; -CORBA_Boolean -__stdcall +CORBA_Boolean __stdcall CORBA_Object::_non_existent (CORBA_Environment &env) { - CORBA_Boolean retval = CORBA_B_FALSE; - CORBA_Exception *x; - STUB_Object *istub; + CORBA_Boolean retval = CORBA_B_FALSE; + STUB_Object *istub; - if (QueryInterface (IID_STUB_Object, (void **) &istub) != NOERROR) + if (QueryInterface (IID_STUB_Object, + (void **) &istub) != NOERROR) { env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); return CORBA_B_FALSE; @@ -203,9 +197,11 @@ CORBA_Object::_non_existent (CORBA_Environment &env) istub->do_call (env, &Object_non_existent_calldata, &retval); - if ((x = env.exception ()) != 0) + CORBA_Exception *x = env.exception (); + + if (x != 0) { - char *id; + char *id; id = _tc_CORBA_OBJECT_NOT_EXIST->id (env); if (env.exception () == 0 @@ -214,9 +210,9 @@ CORBA_Object::_non_existent (CORBA_Environment &env) env.clear (); return CORBA_B_TRUE; } - // + // reporting a "real" exception ... - // + return CORBA_B_FALSE; } else @@ -226,19 +222,17 @@ CORBA_Object::_non_existent (CORBA_Environment &env) } } +// Quickly hash an object reference's representation data. Used to +// create hash tables. -// -// Quickly hash an object reference's representation data. -// Used to create hash tables. -// -CORBA_ULong -__stdcall +CORBA_ULong __stdcall CORBA_Object::_hash (CORBA_ULong maximum, CORBA_Environment &env) { - STUB_Object *istub; + STUB_Object *istub; - if (QueryInterface (IID_STUB_Object, (void **) &istub) != NOERROR) + if (QueryInterface (IID_STUB_Object, + (void **) &istub) != NOERROR) { env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); return CORBA_B_FALSE; @@ -248,20 +242,17 @@ CORBA_Object::_hash (CORBA_ULong maximum, return istub->hash (maximum, env); } - -// -// Compare two object references to see if they point to the -// same object. Used in linear searches, as in hash buckets. +// Compare two object references to see if they point to the same +// object. Used in linear searches, as in hash buckets. // // XXX would be useful to also have a trivalued comparison predicate, // such as strcmp(), to allow more comparison algorithms. -// -CORBA_Boolean -__stdcall + +CORBA_Boolean __stdcall CORBA_Object::_is_equivalent (CORBA_Object_ptr other_obj, CORBA_Environment &env) { - STUB_Object *istub; + STUB_Object *istub; if (other_obj == this) { @@ -269,7 +260,8 @@ CORBA_Object::_is_equivalent (CORBA_Object_ptr other_obj, return CORBA_B_TRUE; } - if (QueryInterface (IID_STUB_Object, (void **) &istub) != NOERROR) + if (QueryInterface (IID_STUB_Object, + (void **) &istub) != NOERROR) { env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); return CORBA_B_FALSE; @@ -279,14 +271,14 @@ CORBA_Object::_is_equivalent (CORBA_Object_ptr other_obj, return istub->is_equivalent (other_obj, env); } - // TAO's extension CORBA_String -CORBA_Object::_get_name(CORBA_Environment &env) +CORBA_Object::_get_name (CORBA_Environment &env) { - STUB_Object *istub; + STUB_Object *istub; - if (QueryInterface (IID_STUB_Object, (void **) &istub) != NOERROR) + if (QueryInterface (IID_STUB_Object, + (void **) &istub) != NOERROR) { env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); return 0; @@ -299,10 +291,7 @@ CORBA_Object::_get_name(CORBA_Environment &env) return 0; //otherwise } - -// // COM's IUnknown support -// #if unix || defined (VXWORKS) // diff --git a/TAO/IIOP/lib/object.i b/TAO/IIOP/lib/object.i index d1806684be4..86e6d9e6fcd 100644 --- a/TAO/IIOP/lib/object.i +++ b/TAO/IIOP/lib/object.i @@ -1,37 +1,31 @@ -ACE_INLINE -int -CORBA_Object::find(const CORBA_String& opname, TAO_Skeleton& skelfunc) +ACE_INLINE int +CORBA_Object::find (const CORBA_String& opname, TAO_Skeleton& skelfunc) { - return optable_->find(opname, skelfunc); + return optable_->find (opname, skelfunc); } -ACE_INLINE -int -CORBA_Object::bind(const CORBA_String& opname, const TAO_Skeleton skel_ptr) +ACE_INLINE int +CORBA_Object::bind (const CORBA_String& opname, const TAO_Skeleton skel_ptr) { - return optable_->bind(opname, skel_ptr); + return optable_->bind (opname, skel_ptr); } -ACE_INLINE -void* -CORBA_Object::get_subclass() +ACE_INLINE void * +CORBA_Object::get_subclass (void) { return sub_; } -// // CORBA dup/release build on top of COM's (why not). -// -ACE_INLINE -void + +ACE_INLINE void CORBA_release (CORBA_Object_ptr obj) { if (obj) obj->Release (); } -ACE_INLINE -CORBA_Object_ptr +ACE_INLINE CORBA_Object_ptr CORBA_Object::_duplicate (CORBA_Object_ptr obj) { if (obj) @@ -39,123 +33,99 @@ CORBA_Object::_duplicate (CORBA_Object_ptr obj) return obj; } -// // Null pointers represent nil objects. -// -ACE_INLINE -CORBA_Object_ptr -CORBA_Object::_nil () + +ACE_INLINE CORBA_Object_ptr +CORBA_Object::_nil (void) { return 0; } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CORBA_is_nil (CORBA_Object_ptr obj) { return (CORBA_Boolean) (obj == 0); } ACE_INLINE -TAO_Operation_Table::~TAO_Operation_Table() +TAO_Operation_Table::~TAO_Operation_Table (void) { } -// // Constructor and destructor are accessible to subclasses -// ACE_INLINE CORBA_Object::CORBA_Object (IUnknown *_jan) - : parent_(_jan), - orb_(0) + : parent_ (_jan), + orb_ (0) { // assert (parent != 0); // we removed this as it doesn't fit in our schema of things } -ACE_INLINE -void -CORBA_Object::set_parent(IUnknown *p) +ACE_INLINE void +CORBA_Object::set_parent (IUnknown *p) { this->parent_ = p; assert (this->parent_ != 0); } -ACE_INLINE -void -CORBA_Object::orb(CORBA_ORB_ptr orb) +ACE_INLINE void +CORBA_Object::orb (CORBA_ORB_ptr orb) { orb_ = orb; } -ACE_INLINE -CORBA_ORB_ptr -CORBA_Object::orb(void) const +ACE_INLINE CORBA_ORB_ptr +CORBA_Object::orb (void) const { return orb_; } ACE_INLINE -CORBA_Object::~CORBA_Object () +CORBA_Object::~CORBA_Object (void) { } - -// // DII hook to objref // -// The mapping for create_request is split into two forms, corresponding to -// the two usage styles described in CORBA section 6.2.1. -// -ACE_INLINE -void -__stdcall -CORBA_Object::_create_request ( - const CORBA_Char *operation, - CORBA_NVList_ptr arg_list, - CORBA_NamedValue_ptr result, - CORBA_Request_ptr &request, - CORBA_Flags req_flags, - CORBA_Environment &env -) +// The mapping for create_request is split into two forms, +// corresponding to the two usage styles described in CORBA section +// 6.2.1. + +ACE_INLINE void __stdcall +CORBA_Object::_create_request (const CORBA_Char *operation, + CORBA_NVList_ptr arg_list, + CORBA_NamedValue_ptr result, + CORBA_Request_ptr &request, + CORBA_Flags req_flags, + CORBA_Environment &env) { - env.clear (); - request = new CORBA_Request (this, operation, arg_list, result, req_flags); + env.clear (); + request = new CORBA_Request (this, operation, arg_list, result, req_flags); } - -ACE_INLINE -CORBA_Request_ptr -__stdcall -CORBA_Object::_request ( - const CORBA_Char *operation, - CORBA_Environment &env -) +ACE_INLINE CORBA_Request_ptr __stdcall +CORBA_Object::_request (const CORBA_Char *operation, + CORBA_Environment &env) { - env.clear (); - return new CORBA_Request (this, operation); + env.clear (); + return new CORBA_Request (this, operation); } -ACE_INLINE -ULONG -__stdcall -CORBA_Object::AddRef () +ACE_INLINE ULONG __stdcall +CORBA_Object::AddRef (void) { return parent_->AddRef (); } -ACE_INLINE -ULONG -__stdcall -CORBA_Object::Release () +ACE_INLINE ULONG __stdcall +CORBA_Object::Release (void) { return parent_->Release (); } -ACE_INLINE -HRESULT -__stdcall +ACE_INLINE HRESULT __stdcall CORBA_Object::QueryInterface (REFIID riid, void **ppv) { diff --git a/TAO/IIOP/lib/objtable.cpp b/TAO/IIOP/lib/objtable.cpp index a094685c9f0..0ca0a9ea65e 100644 --- a/TAO/IIOP/lib/objtable.cpp +++ b/TAO/IIOP/lib/objtable.cpp @@ -1,49 +1,52 @@ #include "objtable.h" -TAO_Dynamic_Hash_ObjTable::TAO_Dynamic_Hash_ObjTable(CORBA_ULong size) +TAO_Dynamic_Hash_ObjTable::TAO_Dynamic_Hash_ObjTable (CORBA_ULong size) { if (size > 0) - this->hash_.open(size); + this->hash_.open (size); // else we already have a default hash map } -TAO_Dynamic_Hash_ObjTable::~TAO_Dynamic_Hash_ObjTable() +TAO_Dynamic_Hash_ObjTable::~TAO_Dynamic_Hash_ObjTable (void) { - this->hash_.close(); + this->hash_.close (); } int -TAO_Dynamic_Hash_ObjTable::bind(const CORBA_OctetSeq &key, - CORBA_Object_ptr obj) +TAO_Dynamic_Hash_ObjTable::bind (const CORBA_OctetSeq &key, + CORBA_Object_ptr obj) { ACE_CString objkey ((char *)key.buffer); - return this->hash_.bind(objkey, obj); + return this->hash_.bind (objkey, obj); } int -TAO_Dynamic_Hash_ObjTable::find(const CORBA_OctetSeq &key, CORBA_Object_ptr &obj) +TAO_Dynamic_Hash_ObjTable::find (const CORBA_OctetSeq &key, + CORBA_Object_ptr &obj) { ACE_CString objkey ((char *)key.buffer); - return this->hash_.find(objkey, obj); + return this->hash_.find (objkey, obj); } -// Linear search strategy -TAO_Linear_ObjTable::TAO_Linear_ObjTable(CORBA_ULong size) - : next_(0), - tablesize_(size), - tbl_(new TAO_Linear_ObjTable_Entry[size]) +// Linear search strategy. +TAO_Linear_ObjTable::TAO_Linear_ObjTable (CORBA_ULong size) + : next_ (0), + tablesize_ (size), + tbl_ (new TAO_Linear_ObjTable_Entry[size]) { } -TAO_Linear_ObjTable::~TAO_Linear_ObjTable() +TAO_Linear_ObjTable::~TAO_Linear_ObjTable (void) { delete [] this->tbl_; } -// ****** we should really make sure that the same key doesn't exist ****** +// ****** we should really make sure that the same key doesn't exist +// ****** + int -TAO_Linear_ObjTable::bind(const CORBA_OctetSeq &key, - const CORBA_Object_ptr obj) +TAO_Linear_ObjTable::bind (const CORBA_OctetSeq &key, + const CORBA_Object_ptr obj) { CORBA_ULong i = this->next_; @@ -52,7 +55,7 @@ TAO_Linear_ObjTable::bind(const CORBA_OctetSeq &key, this->tbl_[i].obj = obj; this->tbl_[i].key.buffer = new CORBA_Octet [key.length]; this->tbl_[i].key.length = this->tbl_[i].key.maximum = key.length; - ACE_OS::memcpy(this->tbl_[i].key.buffer, key.buffer, key.length); + ACE_OS::memcpy (this->tbl_[i].key.buffer, key.buffer, key.length); this->next_++; return 0; @@ -61,57 +64,56 @@ TAO_Linear_ObjTable::bind(const CORBA_OctetSeq &key, } int -TAO_Linear_ObjTable::find(const CORBA_OctetSeq &key, - CORBA_Object_ptr &obj) +TAO_Linear_ObjTable::find (const CORBA_OctetSeq &key, + CORBA_Object_ptr &obj) { - CORBA_ULong i; - ACE_ASSERT(this->next_ <= this->tablesize_); - i=0; - while ( i < this->next_) + + ACE_ASSERT (this->next_ <= this->tablesize_); + + for (CORBA_ULong i = 0; + i < this->next_; + i++; { - if (!ACE_OS::memcmp(key.buffer, this->tbl_[i].key.buffer, key.length)) + if (!ACE_OS::memcmp (key.buffer, this->tbl_[i].key.buffer, key.length)) { obj = this->tbl_[i].obj; return 1; } - i++; - } return -1; // not found } -TAO_Linear_ObjTable_Entry::TAO_Linear_ObjTable_Entry() +TAO_Linear_ObjTable_Entry::TAO_Linear_ObjTable_Entry () { this->key.buffer = 0; this->key.length = this->key.maximum = 0; this->obj = 0; } -TAO_Linear_ObjTable_Entry::~TAO_Linear_ObjTable_Entry() +TAO_Linear_ObjTable_Entry::~TAO_Linear_ObjTable_Entry () { - if (this->key.buffer) - delete [] this->key.buffer; + delete [] this->key.buffer; this->key.length = this->key.maximum = 0; this->obj = 0; // cannot delete this as we do not own it } // Active Demux search strategy -TAO_Active_Demux_ObjTable::TAO_Active_Demux_ObjTable(CORBA_ULong size) - : next_(0), - tablesize_(size), - tbl_(new TAO_Active_Demux_ObjTable_Entry[size]) +TAO_Active_Demux_ObjTable::TAO_Active_Demux_ObjTable (CORBA_ULong size) + : next_ (0), + tablesize_ (size), + tbl_ (new TAO_Active_Demux_ObjTable_Entry[size]) { } -TAO_Active_Demux_ObjTable::~TAO_Active_Demux_ObjTable() +TAO_Active_Demux_ObjTable::~TAO_Active_Demux_ObjTable () { delete [] this->tbl_; } // ****** we should really make sure that the same key doesn't exist ****** int -TAO_Active_Demux_ObjTable::bind(const CORBA_OctetSeq &key, - CORBA_Object_ptr obj) +TAO_Active_Demux_ObjTable::bind (const CORBA_OctetSeq &key, + CORBA_Object_ptr obj) { CORBA_ULong i = this->next_; @@ -125,27 +127,27 @@ TAO_Active_Demux_ObjTable::bind(const CORBA_OctetSeq &key, } int -TAO_Active_Demux_ObjTable::find(const CORBA_OctetSeq &key, - CORBA_Object_ptr& obj) +TAO_Active_Demux_ObjTable::find (const CORBA_OctetSeq &key, + CORBA_Object_ptr& obj) { - CORBA_ULong i = ACE_OS::atoi((char *)key.buffer); + CORBA_ULong i = ACE_OS::atoi ((char *)key.buffer); - ACE_ASSERT(i <= this->tablesize_); + ACE_ASSERT (i <= this->tablesize_); obj = this->tbl_[i].obj; return 1; } -TAO_Active_Demux_ObjTable_Entry::TAO_Active_Demux_ObjTable_Entry() +TAO_Active_Demux_ObjTable_Entry::TAO_Active_Demux_ObjTable_Entry (void) { this->obj = 0; } -TAO_Active_Demux_ObjTable_Entry::~TAO_Active_Demux_ObjTable_Entry() +TAO_Active_Demux_ObjTable_Entry::~TAO_Active_Demux_ObjTable_Entry (void) { this->obj = 0; // cannot delete this as we do not own it } -#if defined(ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) template class ACE_Hash_Map_Manager<ACE_CString, CORBA_Object_ptr, ACE_SYNCH_RW_MUTEX>; template class ACE_Hash_Map_Entry<ACE_CString, CORBA_Object_ptr>; template class ACE_Guard<ACE_SYNCH_RW_MUTEX>; diff --git a/TAO/IIOP/lib/optable.cpp b/TAO/IIOP/lib/optable.cpp index de0335988f4..e2ef1d64d85 100644 --- a/TAO/IIOP/lib/optable.cpp +++ b/TAO/IIOP/lib/optable.cpp @@ -1,48 +1,54 @@ #include "optable.h" -TAO_Dynamic_Hash_OpTable::TAO_Dynamic_Hash_OpTable(CORBA_ULong size) +TAO_Dynamic_Hash_OpTable::TAO_Dynamic_Hash_OpTable (CORBA_ULong size) { if (size > 0) - this->hash_.open(size); + this->hash_.open (size); // else we already have a default hash map } -TAO_Dynamic_Hash_OpTable::~TAO_Dynamic_Hash_OpTable() +TAO_Dynamic_Hash_OpTable::~TAO_Dynamic_Hash_OpTable (void) { - this->hash_.close(); + this->hash_.close (); } -int TAO_Dynamic_Hash_OpTable::register_op(const CORBA_String &opname, skeleton - skel_ptr) +int +TAO_Dynamic_Hash_OpTable::register_op (const CORBA_String &opname, + skeleton + skel_ptr) { ACE_CString key (opname); - return this->hash_.bind(key, skel_ptr); + return this->hash_.bind (key, skel_ptr); } -skeleton TAO_Dynamic_Hash_OpTable::lookup(const CORBA_String &opname) +skeleton +TAO_Dynamic_Hash_OpTable::lookup (const CORBA_String &opname) { ACE_CString key (opname); skeleton skel_ptr = 0; - (void)this->hash_.find(key, skel_ptr); + (void) this->hash_.find (key, skel_ptr); return skel_ptr; } // Linear search strategy -TAO_Linear_OpTable::TAO_Linear_OpTable(CORBA_ULong size) - : next_(0), - tablesize_(size), - tbl_(new TAO_Linear_OpTable::Entry[size]) +TAO_Linear_OpTable::TAO_Linear_OpTable (CORBA_ULong size) + : next_ (0), + tablesize_ (size), + tbl_ (new TAO_Linear_OpTable::Entry[size]) { } -TAO_Linear_OpTable::~TAO_Linear_OpTable() +TAO_Linear_OpTable::~TAO_Linear_OpTable (void) { delete [] this->tbl_; } -// ****** we should really make sure that the same key doesn't exist ****** -int TAO_Linear_OpTable::register_op(const CORBA_String &opname, skeleton skel_ptr) +// ****** we should really make sure that the same key doesn't exist +// ****** +int +TAO_Linear_OpTable::register_op (const CORBA_String &opname, + skeleton skel_ptr) { CORBA_ULong i = this->next_; @@ -56,52 +62,53 @@ int TAO_Linear_OpTable::register_op(const CORBA_String &opname, skeleton skel_pt return -1; // error } -skeleton TAO_Linear_OpTable::lookup(const CORBA_String &opname) +skeleton +TAO_Linear_OpTable::lookup (const CORBA_String &opname) { - CORBA_ULong i; + ACE_ASSERT (this->next_ <= this->tablesize_); - ACE_ASSERT(this->next_ <= this->tablesize_); - i=0; - while ( i < this->next_) + for (CORBA_ULong i; + i < this->next_; + i++) { - if (!ACE_OS::strncmp(opname, this->tbl_[i].opname, ACE_OS::strlen(opname))) - { - return this->tbl_[i].skel_ptr; - } - i++; + if (!ACE_OS::strncmp (opname, + this->tbl_[i].opname, ACE_OS::strlen (opname))) + return this->tbl_[i].skel_ptr; } return 0; // not found } -TAO_Linear_OpTable::Entry::Entry() +TAO_Linear_OpTable::Entry::Entry (void) { this->opname = 0; this->skel_ptr = 0; } -TAO_Linear_OpTable::Entry::~Entry() +TAO_Linear_OpTable::Entry::~Entry (void) { this->opname = 0; this->skel_ptr = 0; // cannot delete this as we do not own it } // Active Demux search strategy -TAO_Active_Demux_OpTable::TAO_Active_Demux_OpTable(CORBA_ULong size) - : next_(0), - tablesize_(size), - tbl_(new TAO_Active_Demux_OpTable::Entry[size]) +TAO_Active_Demux_OpTable::TAO_Active_Demux_OpTable (CORBA_ULong size) + : next_ (0), + tablesize_ (size), + tbl_ (new TAO_Active_Demux_OpTable::Entry[size]) { } -TAO_Active_Demux_OpTable::~TAO_Active_Demux_OpTable() +TAO_Active_Demux_OpTable::~TAO_Active_Demux_OpTable (void) { delete [] this->tbl_; } // ****** we should really make sure that the same key doesn't exist ****** -int TAO_Active_Demux_OpTable::register_op(const CORBA_String &opname, skeleton skel_ptr) +int +TAO_Active_Demux_OpTable::register_op (const CORBA_String &opname, + skeleton skel_ptr) { - CORBA_ULong i = ACE_OS::atoi(opname); + CORBA_ULong i = ACE_OS::atoi (opname); if (i < this->tablesize_) { @@ -111,65 +118,69 @@ int TAO_Active_Demux_OpTable::register_op(const CORBA_String &opname, skeleton s return -1; // error } -skeleton TAO_Active_Demux_OpTable::lookup(const CORBA_String &opname) +skeleton +TAO_Active_Demux_OpTable::lookup (const CORBA_String &opname) { - CORBA_ULong i = ACE_OS::atoi(opname); + CORBA_ULong i = ACE_OS::atoi (opname); - ACE_ASSERT(i <= this->tablesize_); + ACE_ASSERT (i <= this->tablesize_); return this->tbl_[i].skel_ptr; } -TAO_Active_Demux_OpTable::Entry::Entry() +TAO_Active_Demux_OpTable::Entry::Entry (void) { this->skel_ptr = 0; } -TAO_Active_Demux_OpTable::Entry::~Entry() +TAO_Active_Demux_OpTable::Entry::~Entry (void) { this->skel_ptr = 0; // cannot delete this as we do not own it } -OpTable_Parameters::OpTable_Parameters() - : type_(OpTable_Parameters::TAO_DYNAMIC_HASH), - strategy_(0) +OpTable_Parameters::OpTable_Parameters (void) + : type_ (OpTable_Parameters::TAO_DYNAMIC_HASH), + strategy_ (0) { } -OpTable_Parameters::~OpTable_Parameters() +OpTable_Parameters::~OpTable_Parameters (void) { } -void OpTable_Parameters::lookup_strategy(OpTable_Parameters::DEMUX_STRATEGY s) +void +OpTable_Parameters::lookup_strategy (OpTable_Parameters::DEMUX_STRATEGY s) { this->type_ = s; } -OpTable_Parameters::DEMUX_STRATEGY OpTable_Parameters::lookup_strategy() const +OpTable_Parameters::DEMUX_STRATEGY OpTable_Parameters::lookup_strategy (void) const { return this->type_; } -void OpTable_Parameters::concrete_strategy(TAO_Operation_Table *ot) +void +OpTable_Parameters::concrete_strategy (TAO_Operation_Table *ot) { this->strategy_ = ot; } -TAO_Operation_Table* OpTable_Parameters::concrete_strategy() +TAO_Operation_Table* OpTable_Parameters::concrete_strategy (void) { return this->strategy_; } -OpTable_Factory::OpTable_Factory() +OpTable_Factory::OpTable_Factory (void) { } -OpTable_Factory::~OpTable_Factory() +OpTable_Factory::~OpTable_Factory (void) { } -TAO_Operation_Table* OpTable_Factory::opname_lookup_strategy() +TAO_Operation_Table * +OpTable_Factory::opname_lookup_strategy (void) { - OpTable_Parameters *p = TAO_OP_TABLE_PARAMETERS::instance(); + OpTable_Parameters *p = TAO_OP_TABLE_PARAMETERS::instance (); - return p->concrete_strategy(); + return p->concrete_strategy (); } diff --git a/TAO/IIOP/lib/orbobj.cpp b/TAO/IIOP/lib/orbobj.cpp index 3400c2f4cb5..93650b2ca07 100644 --- a/TAO/IIOP/lib/orbobj.cpp +++ b/TAO/IIOP/lib/orbobj.cpp @@ -1,13 +1,13 @@ -// @(#)orbobj.cpp 1.8 95/09/24 +// @ (#)orbobj.cpp 1.8 95/09/24 // Copyright 1994-1995 by Sun Microsystems Inc. // All Rights Reserved // // ORB: CORBA::ORB operations // -// XXX as with TOA, this has a strong coupling to the Internet ORB (IIOP) -// code. We should make it know less about that protocol component and -// have a loose table-driven coupling to ORB/protocol library components. -// +// XXX as with TAO, this has a strong coupling to the Internet ORB +// (IIOP) code. We should make it know less about that protocol +// component and have a loose table-driven coupling to ORB/protocol +// library components. #include <assert.h> #include <limits.h> @@ -24,17 +24,15 @@ #include "roa.h" #include <initguid.h> -extern void __TC_init_table (); +extern void __TC_init_table (void); extern void __TC_init_standard_exceptions (CORBA_Environment &env); #if defined (SIG_IGN_BROKEN) # undef SIG_IGN -# define SIG_IGN ((RETSIGTYPE (*)(int))1) +# define SIG_IGN ((RETSIGTYPE (*) (int))1) #endif // NeXT -// // COM's IUnknown support -// // {A201E4C6-F258-11ce-9598-0000C07CA898} DEFINE_GUID (IID_CORBA_ORB, @@ -46,32 +44,30 @@ DEFINE_GUID (IID_STUB_Object, 0xa201e4c7, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); #endif -ULONG -__stdcall -CORBA_ORB::Release () +ULONG __stdcall +CORBA_ORB::Release (void) { - ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); + ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, lock_, 0); assert (this != 0); if (--_refcount != 0) return _refcount; - guard.release(); + guard.release (); delete this; return 0; } - -// // ORB initialisation, per OMG document 94-9-46. // -// XXX in addition to the "built in" Internet ORB, there will be ORBs which -// are added separately, e.g. through a DLL listed in the registry. Registry -// will be used to assign orb names and to establish which is the default. -// -static CORBA_ORB_ptr the_orb; +// XXX in addition to the "built in" Internet ORB, there will be ORBs +// which are added separately, e.g. through a DLL listed in the +// registry. Registry will be used to assign orb names and to +// establish which is the default. + +static CORBA_ORB_ptr the_orb; CORBA_ORB_ptr CORBA_ORB_init (int &argc, @@ -80,17 +76,15 @@ CORBA_ORB_init (int &argc, CORBA_Environment &env) { static ACE_Thread_Mutex lock; - ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock, 0); + ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, lock, 0); env.clear (); - // // Verify some of the basic implementation requirements. This test // gets optimized away by a decent compiler (or else the rest of the // routine does). // // NOTE: we still "just" assume that native floating point is IEEE. - // if (sizeof (CORBA_Short) != 2 || sizeof (CORBA_Long) != 4 @@ -99,40 +93,36 @@ CORBA_ORB_init (int &argc, || sizeof (CORBA_Double) != 8 || sizeof (CORBA_LongDouble) != 16 || sizeof (CORBA_WChar) < 2 - || sizeof (void *) != SIZEOF_VOID_P - ) + || sizeof (void *) != SIZEOF_VOID_P) { env.exception (new CORBA_INITIALIZE (COMPLETED_NO)); return 0; } - // // ignoring argc, argv for now -- no arguments we care about // - // XXX should remove any of the "-ORB*" arguments that we know - // about ... and report errors for the rest. + // XXX should remove any of the "-ORB*" arguments that we know about + // ... and report errors for the rest. // // Parsing of these arguments should set values in a // TAO_ORB_Parameters instance, likely the one contained in the // newly-created ORB. #ifdef DEBUG - // // Make it a little easier to debug programs using this code. - // { - char *value = ACE_OS::getenv ("TAO_ORB_DEBUG"); - - if (value != 0) { - debug_level = ACE_OS::atoi (value); - if (debug_level <= 0) - debug_level = 1; - dmsg1 ("debug_level == %d", debug_level); - } + char *value = ACE_OS::getenv ("TAO_ORB_DEBUG"); + + if (value != 0) + { + debug_level = ACE_OS::atoi (value); + if (debug_level <= 0) + debug_level = 1; + dmsg1 ("debug_level == %d", debug_level); + } } -#endif // DEBUG +#endif /* DEBUG */ - // // On Win32, we should be collecting information from the Registry // such as what ORBs are configured, specific configuration details // like whether they generate IOR or URL style stringified objrefs @@ -146,7 +136,6 @@ CORBA_ORB_init (int &argc, // makes it always use URL-style stringified objrefs, where the // hostname and TCP port number are explicit (and the whole objref // is readable by mortals). - // CORBA_Boolean use_ior; if (orb_name != 0 && ACE_OS::strcmp (orb_name, "internet") == 0) @@ -159,27 +148,22 @@ CORBA_ORB_init (int &argc, // // Impractical to have each call to the ORB protect against the // implementation artifact of potential writes to dead connections, - // as it'd be way expensive. Do it here; who cares about SIGPIPE - // in these kinds of applications, anyway? - // - (void) ACE_OS::signal (SIGPIPE, SIG_IGN); + // as it'd be way expensive. Do it here; who cares about SIGPIPE in + // these kinds of applications, anyway? + (void) ACE_OS::signal (SIGPIPE, SIG_IGN); #endif // SIGPIPE - ACE_OS::socket_init(ACE_WSOCK_VERSION); + ACE_OS::socket_init (ACE_WSOCK_VERSION); - // // Call various internal initialization routines. - // __TC_init_table (); __TC_init_standard_exceptions (env); if (env.exception () != 0) return 0; - // // Inititalize the "ORB" pseudo-object now. - // - the_orb = TAO_ORB::instance(); - the_orb->use_omg_ior_format(use_ior); + the_orb = TAO_ORB::instance (); + the_orb->use_omg_ior_format (use_ior); return the_orb; } @@ -194,124 +178,111 @@ CORBA_ORB::create_list (CORBA_Long count, if (count != 0) { retval->_len = 0; - retval->_max = (unsigned) count; - retval->_values = (CORBA_NamedValue_ptr) calloc ((unsigned) count, - sizeof (CORBA_NamedValue)); + retval->_max = (u_int) count; + retval->_values = (CORBA_NamedValue_ptr) ACEO_OS::calloc ((u_int) count, + sizeof (CORBA_NamedValue)); } } - -// // This is a server-side internal routine; it's not available to any // portable code except method code, which moreover may not access the -// state variable directly since its implemention may differ between ORBs. +// state variable directly since its implemention may differ between +// ORBs. // // XXX it's server-side so should be OA-specific and not in this module -// + CORBA_ORB_ptr -_orb () +_orb (void) { return the_orb; } -CORBA_BOA_ptr CORBA_ORB::BOA_init(int &argc, char **argv, const char *boa_identifier) +CORBA_BOA_ptr CORBA_ORB::BOA_init (int &argc, + char **argv, + const char *boa_identifier) { // parse the arguments looking for options starting with -OA. After - // processing these options, move all these to the end of the argv list and - // decrement argc appropriately. + // processing these options, move all these to the end of the argv + // list and decrement argc appropriately. - TAO_OA_Parameters *params = TAO_OA_PARAMS::instance(); //should have been BOA_Parameters + TAO_OA_Parameters *params = TAO_OA_PARAMS::instance (); //should have been BOA_Parameters CORBA_BOA_ptr rp; CORBA_String_var id = boa_identifier; - CORBA_String_var host = CORBA_string_dup(""); - CORBA_String_var demux = CORBA_string_dup("dynamic_hash"); // default atleast for now + CORBA_String_var host = CORBA_string_dup (""); + CORBA_String_var demux = CORBA_string_dup ("dynamic_hash"); // default atleast for now CORBA_UShort port = 5001; // some default port -- needs to be a #defined value CORBA_ULong tablesize = 0; // default table size for lookup tables CORBA_Boolean numeric = CORBA_B_FALSE; CORBA_Boolean use_threads = CORBA_B_FALSE; - const char* ior = 0; - int i, j; + const char *ior = 0; ACE_INET_Addr rendezvous; CORBA_Environment env; - i = 0; - while(i < argc) + int i = 0; + + while (i < argc) { - if(strcmp(argv[i], "-OAid") == 0) + // @@ Can you please add comments describing each of these options? + if (ACE_OS::strcmp (argv[i], "-OAid") == 0) { - if(i + 1 < argc) - id = CORBA_string_dup(argv[i + 1]); - else - { - } + if (i + 1 < argc) + id = CORBA_string_dup (argv[i + 1]); - for(int j = i ; j + 2 < argc ; j++) + for (int j = i ; j + 2 < argc ; j++) argv[j] = argv[j + 2]; argc -= 2; } - else if (strcmp(argv[i], "-OAhost") == 0) + else if (ACE_OS::strcmp (argv[i], "-OAhost") == 0) { if (i + 1 < argc) - host = CORBA_string_dup(argv[i + 1]); - else - { - } + host = CORBA_string_dup (argv[i + 1]); - for(int j = i ; j + 2 < argc ; j++) + for (int j = i ; j + 2 < argc ; j++) argv[j] = argv[j + 2]; argc -= 2; } - else if (strcmp(argv[i], "-OAport") == 0) + else if (ACE_OS::strcmp (argv[i], "-OAport") == 0) { if (i + 1 < argc) - port = ACE_OS::atoi(argv[i + 1]); - else - { - } + port = ACE_OS::atoi (argv[i + 1]); - for(int j = i ; j + 2 < argc ; j++) + for (int j = i ; j + 2 < argc ; j++) argv[j] = argv[j + 2]; argc -= 2; } - else if (strcmp(argv[i], "-OAobjdemux") == 0) + else if (ACE_OS::strcmp (argv[i], "-OAobjdemux") == 0) { if (i + 1 < argc) - demux = CORBA_string_dup(argv[i+1]); - else - { - } + demux = CORBA_string_dup (argv[i+1]); - for(int j = i ; j + 2 < argc ; j++) + for (int j = i ; j + 2 < argc ; j++) argv[j] = argv[j + 2]; argc -= 2; } - else if (strcmp(argv[i], "-OAtablesize") == 0) + else if (ACE_OS::strcmp (argv[i], "-OAtablesize") == 0) { if (i + 1 < argc) - tablesize = ACE_OS::atoi(argv[i+1]); - else - { - } + tablesize = ACE_OS::atoi (argv[i+1]); - for(int j = i ; j + 2 < argc ; j++) + for (int j = i ; j + 2 < argc ; j++) argv[j] = argv[j + 2]; argc -= 2; } - else if (strcmp(argv[i], "-OArcvsock") == 0) + else if (ACE_OS::strcmp (argv[i], "-OArcvsock") == 0) { } - else if (strcmp(argv[i], "-OAsndsock") == 0) + else if (ACE_OS::strcmp (argv[i], "-OAsndsock") == 0) { } - else if (strcmp(argv[i], "-OAthread") == 0) + else if (ACE_OS::strcmp (argv[i], "-OAthread") == 0) { use_threads = CORBA_B_TRUE; - for(int j = i ; j + 1 < argc ; j++) + for (int j = i ; j + 1 < argc ; j++) argv[j] = argv[j + 1]; argc -= 1; @@ -321,36 +292,35 @@ CORBA_BOA_ptr CORBA_ORB::BOA_init(int &argc, char **argv, const char *boa_identi } // create a INET_Addr - if (ACE_OS::strlen(host) > 0){ - rendezvous.set(port, host); - } else { - rendezvous.set(port); - } + if (ACE_OS::strlen (host) > 0) + rendezvous.set (port, host); + else + rendezvous.set (port); - // ACE_MT(ACE_GUARD(ACE_Thread_Mutex, roa_mon, lock_)); + // ACE_MT (ACE_GUARD (ACE_Thread_Mutex, roa_mon, lock_)); - if (params->oa()) + if (params->oa ()) { env.exception (new CORBA_INITIALIZE (COMPLETED_NO)); return 0; } // set all parameters - params->using_threads(use_threads); - params->demux_strategy(demux); - params->addr(rendezvous); - params->upcall(CORBA_BOA::dispatch); - params->tablesize(tablesize); - -#if defined(ROA_NEED_REQ_KEY) - (void) ACE_Thread::keycreate(&req_key_); + params->using_threads (use_threads); + params->demux_strategy (demux); + params->addr (rendezvous); + params->upcall (CORBA_BOA::dispatch); + params->tablesize (tablesize); + +#if defined (ROA_NEED_REQ_KEY) + (void) ACE_Thread::keycreate (&req_key_); #endif - ACE_NEW_RETURN (rp, ROA(this, env), 0); + ACE_NEW_RETURN (rp, ROA (this, env), 0); return rp; } -#if !defined(__ACE_INLINE__) +#if !defined (__ACE_INLINE__) # include "orbobj.i" #endif diff --git a/TAO/IIOP/lib/orbobj.i b/TAO/IIOP/lib/orbobj.i index 5b0091c571b..d47a62708ea 100644 --- a/TAO/IIOP/lib/orbobj.i +++ b/TAO/IIOP/lib/orbobj.i @@ -1,31 +1,26 @@ -// // Constructor and destructor are accessible to subclasses -// ACE_INLINE -CORBA_ORB::CORBA_ORB () +CORBA_ORB::CORBA_ORB (void) { - _refcount = 1; + _refcount = 1; } ACE_INLINE -CORBA_ORB::~CORBA_ORB () +CORBA_ORB::~CORBA_ORB (void) { - assert (_refcount == 0); + assert (_refcount == 0); } -// // CORBA dup/release build on top of COM's (why not). -// -ACE_INLINE -void + +ACE_INLINE void CORBA_release (CORBA_ORB_ptr obj) { if (obj) obj->Release (); } -ACE_INLINE -CORBA_ORB_ptr +ACE_INLINE CORBA_ORB_ptr CORBA_ORB::_duplicate (CORBA_ORB_ptr obj) { if (obj) @@ -33,29 +28,24 @@ CORBA_ORB::_duplicate (CORBA_ORB_ptr obj) return obj; } -// // Null pointers represent nil objects. -// -ACE_INLINE -CORBA_ORB_ptr -CORBA_ORB::_nil () + +ACE_INLINE CORBA_ORB_ptr +CORBA_ORB::_nil (void) { return 0; } -ACE_INLINE -CORBA_Boolean +ACE_INLINE CORBA_Boolean CORBA_is_nil (CORBA_ORB_ptr obj) { return (CORBA_Boolean) (obj == 0); } -ACE_INLINE -ULONG -__stdcall -CORBA_ORB::AddRef () +ACE_INLINE ULONG __stdcall +CORBA_ORB::AddRef (void) { - ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); + ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, lock_, 0); return _refcount++; } diff --git a/TAO/IIOP/lib/params.i b/TAO/IIOP/lib/params.i index 1470b1ad002..ecf129839db 100644 --- a/TAO/IIOP/lib/params.i +++ b/TAO/IIOP/lib/params.i @@ -1,136 +1,121 @@ ACE_INLINE -TAO_OA_Parameters::TAO_OA_Parameters() - : using_threads_(0), - thread_flags_(THR_NEW_LWP), - context_p_(0), - upcall_(0), - forwarder_(0), - oa_(0) +TAO_OA_Parameters::TAO_OA_Parameters (void) + : using_threads_ (0), + thread_flags_ (THR_NEW_LWP), + context_p_ (0), + upcall_ (0), + forwarder_ (0), + oa_ (0) { } -ACE_INLINE -int -TAO_OA_Parameters::using_threads() +ACE_INLINE int +TAO_OA_Parameters::using_threads (void) { return using_threads_; } -ACE_INLINE -void -TAO_OA_Parameters::using_threads(int i) +ACE_INLINE void +TAO_OA_Parameters::using_threads (int i) { using_threads_ = i; } -ACE_INLINE -void* -TAO_OA_Parameters::context() +ACE_INLINE void * +TAO_OA_Parameters::context (void) { return context_p_; } -ACE_INLINE -void -TAO_OA_Parameters::context(void* p) +ACE_INLINE void +TAO_OA_Parameters::context (void* p) { context_p_ = p; } -ACE_INLINE -TAO_OA_Parameters::UpcallFunc -TAO_OA_Parameters::upcall() +ACE_INLINE TAO_OA_Parameters::UpcallFunc +TAO_OA_Parameters::upcall (void) { return upcall_; } -ACE_INLINE -void -TAO_OA_Parameters::upcall(TAO_OA_Parameters::UpcallFunc f) +ACE_INLINE void +TAO_OA_Parameters::upcall (TAO_OA_Parameters::UpcallFunc f) { upcall_ = f; } -ACE_INLINE -TAO_OA_Parameters::ForwardFunc -TAO_OA_Parameters::forwarder() +ACE_INLINE TAO_OA_Parameters::ForwardFunc +TAO_OA_Parameters::forwarder (void) { return forwarder_; } -ACE_INLINE -void -TAO_OA_Parameters::forwarder(TAO_OA_Parameters::ForwardFunc f) +ACE_INLINE void +TAO_OA_Parameters::forwarder (TAO_OA_Parameters::ForwardFunc f) { forwarder_ = f; } -ACE_INLINE -CORBA_BOA_ptr -TAO_OA_Parameters::oa() +ACE_INLINE CORBA_BOA_ptr +TAO_OA_Parameters::oa (void) { return oa_; } -ACE_INLINE -void -TAO_OA_Parameters::oa(CORBA_BOA_ptr anOA) +ACE_INLINE void +TAO_OA_Parameters::oa (CORBA_BOA_ptr anOA) { oa_ = anOA; } -ACE_INLINE -u_int -TAO_OA_Parameters::thread_flags() +ACE_INLINE u_int +TAO_OA_Parameters::thread_flags (void) { return thread_flags_; } -ACE_INLINE -void -TAO_OA_Parameters::thread_flags(u_int f) +ACE_INLINE void +TAO_OA_Parameters::thread_flags (u_int f) { thread_flags_ = f; } -ACE_INLINE -void -TAO_OA_Parameters::addr(ACE_INET_Addr &addr) +ACE_INLINE void +TAO_OA_Parameters::addr (ACE_INET_Addr &addr) { this->addr_ = addr; } -ACE_INLINE -ACE_INET_Addr -TAO_OA_Parameters::addr() +ACE_INLINE ACE_INET_Addr +TAO_OA_Parameters::addr (void) { return this->addr_; } -ACE_INLINE -void -TAO_OA_Parameters::demux_strategy(DEMUX_STRATEGY strategy) +ACE_INLINE void +TAO_OA_Parameters::demux_strategy (DEMUX_STRATEGY strategy) { this->demux_ = strategy; // Trust that the value is valid! } ACE_INLINE -void -TAO_OA_Parameters::demux_strategy(char* strategy) +void TAO_OA_Parameters::demux_strategy (char* strategy) { - if (!ACE_OS::strcmp(strategy, "linear")) + // @@ Can you please add a comment for this? + if (!ACE_OS::strcmp (strategy, "linear")) { this->demux_ = TAO_LINEAR; } - else if (!ACE_OS::strcmp(strategy, "dynamic_hash")) + else if (!ACE_OS::strcmp (strategy, "dynamic_hash")) { this->demux_ = TAO_DYNAMIC_HASH; } - else if (!ACE_OS::strcmp(strategy, "user_def")) + else if (!ACE_OS::strcmp (strategy, "user_def")) { this->demux_ = TAO_USER_DEFINED; } - else if (!ACE_OS::strcmp(strategy, "active_demux")) + else if (!ACE_OS::strcmp (strategy, "active_demux")) { this->demux_ = TAO_ACTIVE_DEMUX; } @@ -141,23 +126,20 @@ TAO_OA_Parameters::demux_strategy(char* strategy) } } -ACE_INLINE -TAO_OA_Parameters::DEMUX_STRATEGY -TAO_OA_Parameters::demux_strategy() +ACE_INLINE TAO_OA_Parameters::DEMUX_STRATEGY +TAO_OA_Parameters::demux_strategy (void) { return this->demux_; } -ACE_INLINE -void -TAO_OA_Parameters::tablesize(CORBA_ULong tblsize) +ACE_INLINE void +TAO_OA_Parameters::tablesize (CORBA_ULong tblsize) { this->tablesize_ = tblsize; } -ACE_INLINE -CORBA_ULong -TAO_OA_Parameters::tablesize() +ACE_INLINE CORBA_ULong +TAO_OA_Parameters::tablesize (void) { return this->tablesize_; } diff --git a/TAO/IIOP/lib/principa.cpp b/TAO/IIOP/lib/principa.cpp index a5113fa210c..6b6aaea4a3e 100644 --- a/TAO/IIOP/lib/principa.cpp +++ b/TAO/IIOP/lib/principa.cpp @@ -1,4 +1,4 @@ -// @(#)principa.cpp 1.4 95/11/04 +// @ (#)principa.cpp 1.4 95/11/04 // Copyright 1994-1995 by Sun Microsystems Inc. // All Rights Reserved // @@ -12,31 +12,29 @@ #include <initguid.h> - - void CORBA_release (CORBA_Principal_ptr principal) { - if (principal) - principal->Release (); + if (principal) + principal->Release (); } CORBA_Boolean CORBA_is_nil (CORBA_Principal_ptr principal) { - return (CORBA_Boolean)(principal == 0); + return (CORBA_Boolean) (principal == 0); } -CORBA_Principal::CORBA_Principal () +CORBA_Principal::CORBA_Principal (void) { } -CORBA_Principal::~CORBA_Principal () +CORBA_Principal::~CORBA_Principal (void) { - assert (_refcount == 0); + assert (_refcount == 0); - if (id.buffer) - delete id.buffer; + if (id.buffer) + delete id.buffer; } // @@ -48,45 +46,40 @@ DEFINE_GUID (IID_CORBA_Principal, 0xa201e4c0, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); -ULONG -__stdcall -CORBA_Principal::AddRef () +ULONG __stdcall +CORBA_Principal::AddRef (void) { - ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, principal_lock_, 0); + ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, principal_lock_, 0); return ++_refcount; } -ULONG -__stdcall -CORBA_Principal::Release () +ULONG __stdcall +CORBA_Principal::Release (void) { - ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, principal_lock_, 0); + ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, principal_lock_, 0); if (--_refcount != 0) return _refcount; - guard.release(); + guard.release (); delete this; return 0; } -HRESULT -__stdcall -CORBA_Principal::QueryInterface ( - REFIID riid, - void **ppv -) +HRESULT __stdcall +CORBA_Principal::QueryInterface (REFIID riid, + void **ppv) { - *ppv = 0; + *ppv = 0; - if (IID_CORBA_Principal == riid || IID_IUnknown == riid) - *ppv = this; + if (IID_CORBA_Principal == riid || IID_IUnknown == riid) + *ppv = this; - if (*ppv == 0) - return ResultFromScode (E_NOINTERFACE); + if (*ppv == 0) + return ResultFromScode (E_NOINTERFACE); - (void) AddRef (); - return NOERROR; + (void) AddRef (); + return NOERROR; } diff --git a/TAO/IIOP/lib/request.cpp b/TAO/IIOP/lib/request.cpp index 4eb16e2a115..c5aa1bbde9b 100644 --- a/TAO/IIOP/lib/request.cpp +++ b/TAO/IIOP/lib/request.cpp @@ -13,23 +13,20 @@ #include "cdr.h" #include "thread.h" - // {77420085-F276-11ce-9598-0000C07CA898} DEFINE_GUID (IID_CORBA_Request, 0x77420085, 0xf276, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); -ULONG -__stdcall -CORBA_Request::AddRef () +ULONG __stdcall +CORBA_Request::AddRef (void) { ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, lock_, 0); return _refcount++; } -ULONG -__stdcall -CORBA_Request::Release () +ULONG __stdcall +CORBA_Request::Release (void) { ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, lock_, 0); @@ -44,12 +41,9 @@ CORBA_Request::Release () return 0; } -HRESULT -__stdcall -CORBA_Request::QueryInterface ( - REFIID riid, - void **ppv -) +HRESULT __stdcall +CORBA_Request::QueryInterface (REFIID riid, + void **ppv) { *ppv = 0; @@ -63,9 +57,8 @@ CORBA_Request::QueryInterface ( return NOERROR; } -// // Reference counting for DII Request object -// + void CORBA_release (CORBA_Request_ptr req) { @@ -76,35 +69,30 @@ CORBA_release (CORBA_Request_ptr req) CORBA_Boolean CORBA_is_nil (CORBA_Request_ptr req) { - return (CORBA_Boolean)(req == 0); + return (CORBA_Boolean) req == 0; } -// + // DII Request class implementation -// -CORBA_Request::CORBA_Request ( - CORBA_Object_ptr obj, - const CORBA_Char *op, - CORBA_NVList_ptr args, - CORBA_NamedValue_ptr result, - CORBA_Flags flags -) : - _args (args), - _result (result), - _flags (flags), - _refcount (1) + +CORBA_Request::CORBA_Request (CORBA_Object_ptr obj, + const CORBA_Char *op, + CORBA_NVList_ptr args, + CORBA_NamedValue_ptr result, + CORBA_Flags flags) + : _args (args), + _result (result), + _flags (flags), + _refcount (1) { _target = CORBA_Object::_duplicate (obj); _opname = CORBA_string_copy (op); } - -CORBA_Request::CORBA_Request ( - CORBA_Object_ptr obj, - const CORBA_Char *op -) : - _flags (0), - _refcount (1) +CORBA_Request::CORBA_Request (CORBA_Object_ptr obj, + const CORBA_Char *op) + : _flags (0), + _refcount (1) { _target = CORBA_Object::_duplicate (obj); _opname = CORBA_string_copy (op); @@ -113,7 +101,7 @@ CORBA_Request::CORBA_Request ( _result = new CORBA_NamedValue; } -CORBA_Request::~CORBA_Request () +CORBA_Request::~CORBA_Request (void) { assert (_refcount == 0); @@ -123,39 +111,53 @@ CORBA_Request::~CORBA_Request () CORBA_release (_result); } -// // The public DII interfaces: normal and oneway calls. // // NOTE that using DII, programmers can get the special behaviour of // discarding the response for normal calls. This doesn't change the -// semantics of any OMG-IDL interface, it just streamlines control flow -// in some exotic situations. -// +// semantics of any OMG-IDL interface, it just streamlines control +// flow in some exotic situations. + void -CORBA_Request::invoke () +CORBA_Request::invoke (void) { - STUB_Object *stub; - - if (_target->QueryInterface (IID_STUB_Object, (void **) &stub) != NOERROR) { - _env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); - return; - } - - stub->do_dynamic_call ((char *)_opname, CORBA_B_TRUE, - _args, _result, _flags, _exceptions, _env); + STUB_Object *stub; + + if (_target->QueryInterface (IID_STUB_Object, + (void **) &stub) != NOERROR) + { + _env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); + return; + } + + stub->do_dynamic_call ((char *)_opname, + CORBA_B_TRUE, + _args, + _result, + _flags, + _exceptions, + _env); stub->Release (); } void -CORBA_Request::send_oneway () +CORBA_Request::send_oneway (void) { - STUB_Object *stub; - - if (_target->QueryInterface (IID_STUB_Object, (void **) &stub) != NOERROR) { - _env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); - return; - } - stub->do_dynamic_call ((char *)_opname, CORBA_B_TRUE, - _args, _result, _flags, _exceptions, _env); + STUB_Object *stub; + + if (_target->QueryInterface (IID_STUB_Object, + (void **) &stub) != NOERROR) + { + _env.exception (new CORBA_DATA_CONVERSION (COMPLETED_NO)); + return; + } + + stub->do_dynamic_call ((char *)_opname, + CORBA_B_TRUE, + _args, + _result, + _flags, + _exceptions, + _env); stub->Release (); } diff --git a/TAO/IIOP/lib/roa.cpp b/TAO/IIOP/lib/roa.cpp index 5bac00066ee..a3b00ed70a4 100644 --- a/TAO/IIOP/lib/roa.cpp +++ b/TAO/IIOP/lib/roa.cpp @@ -1,10 +1,3 @@ -// = LIB -// TAO -// = AUTHOR -// Chris Cleeland -// = FILENAME -// roa.cpp -// = VERSION // $Id$ #include "orb.h" @@ -21,176 +14,168 @@ #include <initguid.h> // Forward declarations... -static void request_dispatcher(GIOP::RequestHeader& req, - CDR& request_body, - CDR* reply, - TAO_Dispatch_Context* context, - CORBA_Environment& env); -static GIOP::LocateStatusType request_forwarder(opaque& target_key, - CORBA_Object_ptr& forward_reference, - TAO_Dispatch_Context* ctx); - +static void request_dispatcher (GIOP::RequestHeader &req, + CDR &request_body, + CDR *reply, + TAO_Dispatch_Context *context, + CORBA_Environment &env); + +static GIOP::LocateStatusType request_forwarder (opaque &target_key, + CORBA_Object_ptr &forward_reference, + TAO_Dispatch_Context *ctx); ROA_ptr ROA::init (CORBA_ORB_ptr parent, - ACE_INET_Addr& rendezvous, - CORBA_Environment& env) + ACE_INET_Addr &rendezvous, + CORBA_Environment &env) { env.clear (); - TAO_OA_Parameters* p = TAO_OA_PARAMS::instance(); + TAO_OA_Parameters *p = TAO_OA_PARAMS::instance (); - // ACE_MT(ACE_GUARD(ACE_Thread_Mutex, roa_mon, lock_)); + // ACE_MT (ACE_GUARD (ACE_Thread_Mutex, roa_mon, lock_)); - if (p->oa()) + if (p->oa ()) { env.exception (new CORBA_INITIALIZE (COMPLETED_NO)); return 0; } -#if defined(ROA_NEED_REQ_KEY) - (void) ACE_Thread::keycreate(&req_key_); +#if defined (ROA_NEED_REQ_KEY) + (void) ACE_Thread::keycreate (&req_key_); #endif ROA_ptr rp; - ACE_NEW_RETURN (rp, ROA(parent, env), 0); - p->oa(rp); + ACE_NEW_RETURN (rp, ROA (parent, env), 0); + p->oa (rp); return rp; } - ROA::ROA (CORBA_ORB_ptr owning_orb, CORBA_Environment &env) - : do_exit_(CORBA_B_FALSE), - orb_(owning_orb), - call_count_(0), - skeleton_(0) + : do_exit_ (CORBA_B_FALSE), + orb_ (owning_orb), + call_count_ (0), + skeleton_ (0) { - TAO_OA_Parameters* p = TAO_OA_PARAMS::instance(); - TAO_Server_Factory& f = owning_orb->server_factory(); + TAO_OA_Parameters *p = TAO_OA_PARAMS::instance (); + TAO_Server_Factory &f = owning_orb->server_factory (); - ACE_ASSERT(p->oa() == 0); + ACE_ASSERT (p->oa () == 0); - // // Initialize the endpoint ... or try! - // - if (client_acceptor_.open(p->addr(), - ACE_Service_Config::reactor(), - f.creation_strategy(), - f.accept_strategy(), - f.concurrency_strategy(), - f.scheduling_strategy()) == -1) + if (client_acceptor_.open (p->addr (), + ACE_Service_Config::reactor (), + fn.creation_strategy (), + f.accept_strategy (), + f.concurrency_strategy (), + f.scheduling_strategy ()) == -1) // XXXCJC Need to return an error somehow!! Maybe set do_exit? ; - client_acceptor_.acceptor().get_local_addr(addr_); - this->objtable_ = f.object_lookup_strategy(); + client_acceptor_.acceptor ().get_local_addr (addr_); + this->objtable_ = f.object_lookup_strategy (); + if (this->objtable_ != 0) - p->oa(this); + p->oa (this); } -ROA::~ROA () +ROA::~ROA (void) { } -// // Generic routine to handle a message. -// + int -ROA::handle_message (TAO_Dispatch_Context& ctx, CORBA_Environment& env) +ROA::handle_message (TAO_Dispatch_Context &ctx, + CORBA_Environment &env) { int result = GIOP::incoming_message (ctx.endpoint_, - GIOP::ForwardFunc(ctx.check_forward_ ? request_forwarder : 0), - GIOP::RequestHandler(request_dispatcher), &ctx, env); + GIOP::ForwardFunc (ctx.check_forward_ ? request_forwarder : 0), + GIOP::RequestHandler (request_dispatcher), + &ctx, + env); - ACE_MT(ACE_GUARD_RETURN(ACE_Thread_Mutex, roa_mon, lock_, -1)); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, roa_mon, lock_, -1)); call_count_--; return result; } -// // Create an objref -// + CORBA_Object_ptr -ROA::create (CORBA_OctetSeq& key, +ROA::create (CORBA_OctetSeq &key, CORBA_String type_id, - CORBA_Environment& env) + CORBA_Environment &env) { CORBA_String id; - IIOP_Object* data; + IIOP_Object *data; if (type_id) id = CORBA_string_copy (type_id); else id = 0; - IIOP::Version ver(IIOP::MY_MAJOR, IIOP::MY_MINOR); - CORBA_String h = addr_.get_host_name(); - data = new IIOP_Object (id, IIOP::ProfileBody(ver, + + IIOP::Version ver (IIOP::MY_MAJOR, IIOP::MY_MINOR); + CORBA_String h = addr_.get_host_name (); + + data = new IIOP_Object (id, IIOP::ProfileBody (ver, h, - addr_.get_port_number(), + addr_.get_port_number (), key)); - if (data != 0) - { - env.clear (); - } + env.clear (); else { env.exception (new CORBA_NO_MEMORY (COMPLETED_NO)); return 0; } - // // Return the CORBA_Object_ptr interface to this objref. - // CORBA_Object_ptr new_obj; - if (data->QueryInterface (IID_CORBA_Object, (void**)&new_obj) - != NOERROR) + if (data->QueryInterface (IID_CORBA_Object, + (void**)&new_obj) != NOERROR) env.exception (new CORBA_INTERNAL (COMPLETED_NO)); data->Release (); return new_obj; } - -// // Return the key fed into an object at creation time. -// + CORBA_OctetSeq * -ROA::get_key(CORBA_Object_ptr, CORBA_Environment& env) +ROA::get_key (CORBA_Object_ptr, + CORBA_Environment &env) { // XXX implement me ! ... must have been created by this OA. env.exception (new CORBA_IMP_LIMIT (COMPLETED_NO)); return 0; } -#if defined(ROA_NEED_REQ_KEY) -// +#if defined (ROA_NEED_REQ_KEY) // return the target's key // -// NOTE: as with all "in" parameters to a call, this memory is freed +// NOTE: as with all "in" parameters to a call, this memory is freed // by the ORB not by the object implementation. -// + CORBA_OctetSeq * -TCP_OA::get_target_key (CORBA_Environment& env) +TCP_OA::get_target_key (CORBA_Environment &env) { env.clear (); return &request_tsd->object_key; } - -// // return the caller's principal // -// NOTE: as with all "in" parameters to a call, this memory is freed +// NOTE: as with all "in" parameters to a call, this memory is freed // by the ORB not by the object implementation. -// + CORBA_Principal_ptr -ROA::get_client_principal (CORBA_Environment& env) +ROA::get_client_principal (CORBA_Environment &env) { env.clear (); @@ -198,25 +183,21 @@ ROA::get_client_principal (CORBA_Environment& env) } #endif -// // Used by method code to ask the OA to shut down. -// void -ROA::please_shutdown(CORBA_Environment& env) +ROA::please_shutdown (CORBA_Environment &env) { - ACE_MT(ACE_GUARD(ACE_Thread_Mutex, roa_mon, lock_)); + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, roa_mon, lock_)); env.clear (); do_exit_ = CORBA_B_TRUE; } -// // Used by non-method code to tell the OA to shut down. -// void -ROA::clean_shutdown(CORBA_Environment& env) +ROA::clean_shutdown (CORBA_Environment &env) { - ACE_MT(ACE_GUARD(ACE_Thread_Mutex, roa_mon, lock_)); + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, roa_mon, lock_)); env.clear (); @@ -230,12 +211,11 @@ ROA::clean_shutdown(CORBA_Environment& env) // Here we need to tell all the endpoints to shut down... } - -// // For BOA -- BOA operations for which we provide the vtable entry -// + void -ROA::register_dir (CORBA_BOA::dsi_handler handler, void* ctx, CORBA_Environment& env) +ROA::register_dir (CORBA_BOA::dsi_handler handler, + void *ctx, CORBA_Environment &env) { if (handler == 0) { @@ -251,62 +231,50 @@ ROA::register_dir (CORBA_BOA::dsi_handler handler, void* ctx, CORBA_Environment& // OBSOLETE!!! But for now I'm afraid to take it out. void -ROA::get_request(CORBA_Boolean use_threads, +ROA::get_request (CORBA_Boolean use_threads, struct timeval *tvp, - CORBA_Environment& env) + CORBA_Environment &env) { - // // API spec calls for the DIR to be registered and for this to // report an invocation order problem if this is called after // shutdown was started (app can always avoid the latter). - // if (skeleton_ == 0) { env.exception (new CORBA_INITIALIZE (COMPLETED_NO)); return; } - // // Just call the IIOP level dispatch code without allowing it to // ever forward requests to another ROA. - // get_request (skeleton_, 0, use_threads, context_, tvp, env); } // OBSOLETE!!! But stays in b/c the one above calls it. void -ROA::get_request ( - CORBA_BOA::dsi_handler handler, - void check_forward ( - CORBA_OctetSeq &key, - CORBA_Object_ptr &fwd_ref, - void *ctx, - CORBA_Environment &env - ), - CORBA_Boolean do_thr_create, - void *app_state, - timeval *timeout, - CORBA_Environment &env -) +ROA::get_request (CORBA_BOA::dsi_handler handler, + void check_forward (CORBA_OctetSeq &key, + CORBA_Object_ptr &fwd_ref, + void *ctx, + CORBA_Environment &env), + CORBA_Boolean do_thr_create, + void *app_state, + timeval *timeout, + CORBA_Environment &env) { #if 0 - server_endpoint *fd; + server_endpoint *fd; #endif env.clear (); - // // Two bits of OA-private state need to be guarded by a critical - // region: the "do_exit" flag, and the "call_count" flag. These - // are used in clean shutdown, and can be modified here. - // + // region: the "do_exit" flag, and the "call_count" flag. These are + // used in clean shutdown, and can be modified here. { - ACE_MT(ACE_GUARD(ACE_Thread_Mutex, ace_mon, lock_)); + ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, lock_)); - // - // Applications sometimes make mistakes: here, it'd be - // polling for a new request after initiating shutdown. - // + // Applications sometimes make mistakes: here, it'd be polling for + // a new request after initiating shutdown. if (do_exit_) { dmsg ("called get_request during OA shutdown"); @@ -314,9 +282,8 @@ ROA::get_request ( return; } - // // Here, some unthreaded app asked for thread support. Ooops! - // + if (do_thr_create) { env.exception (new CORBA_IMP_LIMIT (COMPLETED_NO)); @@ -324,7 +291,6 @@ ROA::get_request ( return; } - // // Get a request/message ... if no file descriptor is returned, // the application-specified timeout was reached, leading to a // clean shutdown. Otherwise we flag an incoming message (so @@ -332,20 +298,20 @@ ROA::get_request ( // section. Some other thread could now get a request on some // other connection, if one's ready. // - // THREADING NOTE: what block_for_connection() returns will not + // THREADING NOTE: what block_for_connection () returns will not // be read or written by any other thread until it's released ... // that is, until "fd" goes out of scope. At least, in the // current implementation, which doesn't let threads share a // connection. // // Also, note that the underlying constraint of only allowing a - // single thread to block_for_connection() call bubbles up here too. - // + // single thread to block_for_connection () call bubbles up here too. + #ifdef _POSIX_THREADS static int blocking; // = 0 if (blocking) { - dmsg ("concurrent TCP_OA::get_request() calls"); + dmsg ("concurrent TCP_OA::get_request () calls"); env.exception (new CORBA_IMP_LIMIT (COMPLETED_NO)); return; } else @@ -353,17 +319,16 @@ ROA::get_request ( #endif // _POSIX_THREADS - // // Get a connection and hand it to method code. // - // There are four "threading modes" currently possible with - // this software, though only two are exposed in the OA API. + // There are four "threading modes" currently possible with this + // software, though only two are exposed in the OA API. // // - Single-Threaded ... where either no threads are // used, or method code only sees one thread. // // - Simple MT ... like single threaded, except that - // (a) method code can see multiple threads, (b) a thread + // (a) method code can see multiple threads, (b) a thread // context switch happens before incoming methods get // processed, and (c) there's expensive handshaking re // connections when they're released. @@ -403,90 +368,77 @@ ROA::get_request ( blocking = 0; #endif // _POSIX_THREADS - if (env.exception () != 0) { - dexc (env, "TCP_OA, block for connection"); - return; - } -#if 0 - if (fd == 0) { - do_exit = CORBA_B_TRUE; - return; - } -#endif + if (env.exception () != 0) + { + dexc (env, "TCP_OA, block for connection"); + return; + } - // - // THREADING NOTE: This is the last of the need to have the OA + // THREADING NOTE: This is the last of the need to have the OA // locked ... next, let other threads in to access its state. - // + call_count_++; } - // // OK, now we've got a connection with a "live" IIOP message ready. // - // If we're "eager", there's not actually any data on that connection - // yet ... but we still hand it to some other thread as if it were - // all there. This gets all the setup out of the critical path so that - // when data does arrive, its latency is minimal: straight into the - // IIOP data buffer, in the best (zero copy) case, with no lingering in - // kernel read queues. + // If we're "eager", there's not actually any data on that + // connection yet ... but we still hand it to some other thread as + // if it were all there. This gets all the setup out of the + // critical path so that when data does arrive, its latency is + // minimal: straight into the IIOP data buffer, in the best (zero + // copy) case, with no lingering in kernel read queues. // - if (do_thr_create) { + if (do_thr_create) + { #ifdef _POSIX_THREADS - // - // Want to handle it in another thread. That means handing off a - // bunch of information to that thread and then having it do the - // work ... the simplest alternative is to heap-allocate the data - // and hand it over. That involves no handshaking with the thread - // we're about to create. Note that we're also handing off the - // connection resource too -- when this dispatch context gets - // destroyed, only then is the connection released. - // - TAO_Dispatch_Context* ctx; - - ctx = new TAO_Dispatch_Context; - ctx->skeleton_ = handler; - ctx->check_forward_ = check_forward; - ctx->context_ = app_state; - ctx->oa_ = this; + // Want to handle it in another thread. That means handing off + // a bunch of information to that thread and then having it do + // the work ... the simplest alternative is to heap-allocate the + // data and hand it over. That involves no handshaking with the + // thread we're about to create. Note that we're also handing + // off the connection resource too -- when this dispatch context + // gets destroyed, only then is the connection released. + + TAO_Dispatch_Context *ctx; + + ctx = new TAO_Dispatch_Context; + ctx->skeleton_ = handler; + ctx->check_forward_ = check_forward; + ctx->context_ = app_state; + ctx->oa_ = this; #if 0 // g++ didn't complain about this, but Sun C++ does - ctx->endpoint_ = fd; + ctx->endpoint_ = fd; #endif - // - // Actually create the thread. - // - int errcode; - pthread_t tid; - - // XXX Devpro bug at "-O3" + // Actually create the thread. + int errcode; + pthread_t tid; + // XXX Devpro bug at "-O3" - if (errcode == 0) - return; + if (errcode == 0) + return; - // - // Can't create a thread as requested. Rather than handling it - // in another thread, we must then handle it ourselves. It's bad - // news to drop requests, as would happen if we were to just - // report an exception. - // - // XXX this should be logged as some kind of system fault; - // an administrator would need to deal with these failures - // if they happen repatedly. - // - dmsg2 ("pthread_create error: %d (%s)", errcode, - strerror (errcode)); - delete context_; + // Can't create a thread as requested. Rather than handling it + // in another thread, we must then handle it ourselves. It's + // bad news to drop requests, as would happen if we were to just + // report an exception. + // + // XXX this should be logged as some kind of system fault; an + // administrator would need to deal with these failures if they + // happen repatedly. + dmsg2 ("pthread_create error: %d (%s)", errcode, + strerror (errcode)); + delete context_; #endif // _POSIX_THREADS - } + } - // - // Handle it in this thread. We can do it without any need - // to dynamically allocate memory. - // - TAO_Dispatch_Context ctx; + // Handle it in this thread. We can do it without any need to + // dynamically allocate memory. + + TAO_Dispatch_Context ctx; ctx.skeleton_ = handler; ctx.check_forward_ = check_forward; @@ -498,54 +450,48 @@ ROA::get_request ( handle_message (ctx, env); - // // Don't report any errors from the application/skeleton back to the // top level ... the application already has a variety of means to // pass whatever data needs passing, and we don't need to confuse // things by mixing ORB and application errors here. - // - if (env.exception () != 0) { - dexc (env, "TCP_OA, handle incoming message"); - env.clear (); - } + + if (env.exception () != 0) + { + dexc (env, "TCP_OA, handle incoming message"); + env.clear (); + } } -// // For COM -- IUnknown operations, we provide the vtable entry -// // {A201E4C4-F258-11ce-9598-0000C07CA898} DEFINE_GUID (IID_ROA, 0xa201e4c4, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); - -ULONG -__stdcall -ROA::AddRef () +ULONG __stdcall +ROA::AddRef (void) { - ACE_MT(ACE_GUARD_RETURN(ACE_Thread_Mutex, roa_mon, com_lock_, 0)); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, roa_mon, com_lock_, 0)); return ++refcount_; } -ULONG -__stdcall -ROA::Release () +ULONG __stdcall +ROA::Release (void) { { - ACE_MT(ACE_GUARD_RETURN(ACE_Thread_Mutex, roa_mon, com_lock_, 0)); + ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, roa_mon, com_lock_, 0)); if (--refcount_ != 0) return refcount_; - } delete this; return 0; } -HRESULT -__stdcall -ROA::QueryInterface (REFIID riid, void** ppv) +HRESULT __stdcall +ROA::QueryInterface (REFIID riid, + void **ppv) { *ppv = 0; @@ -557,71 +503,67 @@ ROA::QueryInterface (REFIID riid, void** ppv) if (*ppv == 0) return ResultFromScode (E_NOINTERFACE); - (void) AddRef (); + (void) AddRef (); return NOERROR; } // Dispatch routine that provides most of the IIOP glue ... constructs // a dynamic ServerRequest and any reply message that's needed. // -// Based on what this does, would it be make sense to move -// much of this functionality into a method on the OA that gets called -// by ROA_Handler::handle_input()? -// +// Based on what this does, would it be make sense to move much of +// this functionality into a method on the OA that gets called by +// ROA_Handler::handle_input ()? + static void -request_dispatcher (GIOP::RequestHeader& req, - CDR& request_body, - CDR* reply, - TAO_Dispatch_Context* helper, - CORBA_Environment& env) +request_dispatcher (GIOP::RequestHeader &req, + CDR &request_body, + CDR *reply, + TAO_Dispatch_Context *helper, + CORBA_Environment &env) { - TAO_OA_Parameters* p = TAO_OA_PARAMS::instance(); + TAO_OA_Parameters *p = TAO_OA_PARAMS::instance (); IIOP_ServerRequest svr_req (&request_body, - p->oa()->orb (), - p->oa()); + p->oa ()->orb (), + p->oa ()); - // // ServerRequest is what does the unmarshaling, driven by typecodes // that the DSI user provides. Create the ServerRequest, store away - // information that'll be needed by some methods, and call the dispatch - // routine that the user supplied. Then release the reference so it - // can be safely destroyed sometime later. + // information that'll be needed by some methods, and call the + // dispatch routine that the user supplied. Then release the + // reference so it can be safely destroyed sometime later. // svr_req._opname = req.operation; -#if defined(ROA_NEED_REQ_KEY) - (void) ACE_Thread::setspecific(p->oa().req_key_, &req); +#if defined (ROA_NEED_REQ_KEY) + (void) ACE_Thread::setspecific (p->oa ().req_key_, &req); #endif - CORBA_BOA_ptr oa = p->oa(); + CORBA_BOA_ptr oa = p->oa (); CORBA_BOA::dsi_handler ptmf = helper->skeleton_; - (oa->*ptmf)(req.object_key, svr_req, helper->context_, env); + (oa->*ptmf) (req.object_key, svr_req, helper->context_, env); // is this the correct way to do it? skeleton is a member function svr_req.release (); - // // If reply is null, this was a oneway request ... return! - // if (reply == 0) return; - // // Otherwise check for correct parameter handling, and reply as // appropriate. // - // NOTE: if "env" is set, it takes precedence over exceptions + // NOTE: if "env" is set, it takes precedence over exceptions // reported using the mechanism of the ServerRequest. Only system // exceptions are reported that way ... // - // XXX Exception reporting is ambiguous; it can be cleaner than + // XXX Exception reporting is ambiguous; it can be cleaner than // this. With both language-mapped and dynamic/explicit reporting // mechanisms, one of must be tested "first" ... so an exception // reported using the other mechanism could be "lost". Perhaps only // the language mapped one should be used for system exceptions. - // - CORBA_TypeCode_ptr tc; - const void *value; + + CORBA_TypeCode_ptr tc; + const void *value; if (!svr_req._params && env.exception () == 0) { @@ -632,44 +574,36 @@ request_dispatcher (GIOP::RequestHeader& req, if (env.exception () != 0) { // standard exceptions only CORBA_Environment env2; - CORBA_Exception *x = env.exception (); - CORBA_TypeCode_ptr except_tc = x->type (); + CORBA_Exception *x = env.exception (); + CORBA_TypeCode_ptr except_tc = x->type (); reply->put_ulong (GIOP::SYSTEM_EXCEPTION); (void) CDR::encoder (except_tc, x, 0, reply, env2); - } else if (svr_req._exception) { // any exception at all - CORBA_Exception *x; - CORBA_TypeCode_ptr except_tc; + CORBA_Exception *x; + CORBA_TypeCode_ptr except_tc; x = (CORBA_Exception *) svr_req._exception->value (); except_tc = svr_req._exception->type (); - // // Finish the GIOP Reply header, then marshal the exception. // - // XXX x->type() someday ... - // + // XXX x->type () someday ... if (svr_req._ex_type == SYSTEM_EXCEPTION) reply->put_ulong (GIOP::SYSTEM_EXCEPTION); else reply->put_ulong (GIOP::USER_EXCEPTION); (void) CDR::encoder (except_tc, x, 0, reply, env); - } else { // normal reply - // // First finish the GIOP header ... - // reply->put_ulong (GIOP::NO_EXCEPTION); - // // ... then send any return value ... - // if (svr_req._retval) { tc = svr_req._retval->type (); @@ -677,15 +611,11 @@ request_dispatcher (GIOP::RequestHeader& req, (void) CDR::encoder (tc, value, 0, reply, env); } - // // ... followed by "inout" and "out" parameters, left to right - // - unsigned i; - - for (i = 0; i < svr_req._params->count (); i++) + for (u_int i = 0; i < svr_req._params->count (); i++) { CORBA_NamedValue_ptr nv = svr_req._params->item (i); - CORBA_Any_ptr any; + CORBA_Any_ptr any; if (!(nv->flags () & (CORBA_ARG_INOUT|CORBA_ARG_OUT))) continue; @@ -698,16 +628,15 @@ request_dispatcher (GIOP::RequestHeader& req, } } -// -// Helper routine that provides IIOP glue for forwarding requests -// to specific objects from one process to another. -// +// Helper routine that provides IIOP glue for forwarding requests to +// specific objects from one process to another. + static GIOP::LocateStatusType -request_forwarder (opaque& target_key, - CORBA_Object_ptr& forward_reference, - TAO_Dispatch_Context* helper) +request_forwarder (opaque &target_key, + CORBA_Object_ptr &forward_reference, + TAO_Dispatch_Context *helper) { - CORBA_Environment env; + CORBA_Environment env; assert (helper->check_forward_ != 0); helper->check_forward_ (target_key, forward_reference, helper->context_, env); @@ -720,11 +649,11 @@ request_forwarder (opaque& target_key, return GIOP::OBJECT_FORWARD; } -#if ! defined(__ACE_INLINE__) +#if ! defined (__ACE_INLINE__) # include "roa.i" #endif -#if defined(ACE_TEMPLATES_REQUIRE_SPECIALIZATION) +#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION) // Direct template class ACE_Strategy_Acceptor<ROA_Handler, ACE_SOCK_ACCEPTOR>; // Indirect diff --git a/TAO/IIOP/lib/roa.i b/TAO/IIOP/lib/roa.i index 2dc71563fcc..49227ffea8f 100644 --- a/TAO/IIOP/lib/roa.i +++ b/TAO/IIOP/lib/roa.i @@ -1,20 +1,17 @@ -ACE_INLINE -CORBA_Boolean -ROA::shutting_down() +ACE_INLINE CORBA_Boolean +ROA::shutting_down (void) { return do_exit_; } -ACE_INLINE -CORBA_ORB_ptr -ROA::orb() const +ACE_INLINE CORBA_ORB_ptr +ROA::orb (void) const { return orb_; } -ACE_INLINE -ACE_INET_Addr -ROA::get_addr() const +ACE_INLINE ACE_INET_Addr +ROA::get_addr (void) const { return addr_; } diff --git a/TAO/IIOP/lib/svrrqst.cpp b/TAO/IIOP/lib/svrrqst.cpp index c4fec26c5e7..70603d80ab6 100644 --- a/TAO/IIOP/lib/svrrqst.cpp +++ b/TAO/IIOP/lib/svrrqst.cpp @@ -3,7 +3,7 @@ // All Rights Reserved // // Implementation of the Dynamic Server Skeleton Interface -// + #include <orb.h> #include <initguid.h> @@ -14,7 +14,6 @@ #include "svrrqst.h" - // {77420086-F276-11ce-9598-0000C07CA898} DEFINE_GUID (IID_IIOP_ServerRequest, 0x77420086, 0xf276, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); @@ -23,9 +22,7 @@ DEFINE_GUID (IID_IIOP_ServerRequest, DEFINE_GUID(IID_CORBA_ServerRequest, 0x4b48d881, 0xf7f0, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); - - -IIOP_ServerRequest::~IIOP_ServerRequest () +IIOP_ServerRequest::~IIOP_ServerRequest (void) { assert (_refcount == 0); if (_params) @@ -35,11 +32,9 @@ IIOP_ServerRequest::~IIOP_ServerRequest () if (_exception) delete _exception; } - -ULONG -__stdcall -IIOP_ServerRequest::AddRef () +ULONG __stdcall +IIOP_ServerRequest::AddRef (void) { ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); @@ -47,9 +42,8 @@ IIOP_ServerRequest::AddRef () return _refcount++; } -ULONG -__stdcall -IIOP_ServerRequest::Release () +ULONG __stdcall +IIOP_ServerRequest::Release (void) { ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); @@ -65,12 +59,9 @@ IIOP_ServerRequest::Release () return 0; } -HRESULT -__stdcall -IIOP_ServerRequest::QueryInterface ( - REFIID riid, - void **ppv -) +HRESULT __stdcall +IIOP_ServerRequest::QueryInterface (REFIID riid, + void **ppv) { assert (_refcount > 0); *ppv = 0; @@ -87,96 +78,78 @@ IIOP_ServerRequest::QueryInterface ( return NOERROR; } - -// // Unmarshal in/inout params, and set up to marshal the appropriate // inout/out/return values later on. -// -void -__stdcall -IIOP_ServerRequest::params ( - CORBA_NVList_ptr list, - CORBA_Environment &env -) -{ - unsigned i; +void __stdcall +IIOP_ServerRequest::params (CORBA_NVList_ptr list, + CORBA_Environment &env) +{ env.clear (); - // // Save params for later use when marshaling reply - // _params = list; - // // Then unmarshal each "in" and "inout" parameter - // - for (i = 0; i < list->count (); i++) { - CORBA_NamedValue_ptr nv; - CORBA_Any_ptr any; - CORBA_TypeCode_ptr tc; - void *value; - - nv = list->item (i); - if (!(nv->flags () & (CORBA_ARG_IN | CORBA_ARG_INOUT))) - continue; - - // - // First, make sure the memory into which we'll be unmarshaling - // exists, and is the right size. - // - // NOTE: desirable to have a way to let the dynamic implementation - // routine preallocate this data, for environments where DSI is - // just being used in lieu of a language mapped server side API - // and the size is really knowable in advance. - // - any = nv->value (); - tc = any->type (); - tc->AddRef (); - value = new char [tc->size (env)]; - any->replace (tc, value, CORBA_B_TRUE, env); - - // - // Decrement the refcount of "tc". - // - // The earlier AddRef is needed since Any::replace() releases - // the typecode inside the Any. Without the dup, the reference - // count can go to zero, and the typecode would then be deleted. - // - // This Release ensures that the reference count is correct so - // the typecode can be deleted some other time. - // - tc->Release (); - - // - // Then just unmarshal the value. - // - (void) CDR::decoder (tc, value, 0, _incoming, env); - } + for (u_int i = 0; i < list->count (); i++) + { + CORBA_NamedValue_ptr nv; + CORBA_Any_ptr any; + CORBA_TypeCode_ptr tc; + void *value; + + nv = list->item (i); + if (!(nv->flags () & (CORBA_ARG_IN | CORBA_ARG_INOUT))) + continue; + + // First, make sure the memory into which we'll be unmarshaling + // exists, and is the right size. + // + // NOTE: desirable to have a way to let the dynamic + // implementation routine preallocate this data, for + // environments where DSI is just being used in lieu of a + // language mapped server side API and the size is really + // knowable in advance. + + any = nv->value (); + tc = any->type (); + tc->AddRef (); + value = new char [tc->size (env)]; + any->replace (tc, value, CORBA_B_TRUE, env); + + // Decrement the refcount of "tc". + // + // The earlier AddRef is needed since Any::replace() releases + // the typecode inside the Any. Without the dup, the reference + // count can go to zero, and the typecode would then be deleted. + // + // This Release ensures that the reference count is correct so + // the typecode can be deleted some other time. + + tc->Release (); + + // Then just unmarshal the value. + (void) CDR::decoder (tc, value, 0, _incoming, env); + } - // // If any data is left over, it'd be context values ... else error. // We don't support context values, so it's always an error. - // - if (_incoming->bytes_remaining () != 0) { - dmsg1 ("params(), %d bytes remaining (error)", - _incoming->bytes_remaining ()); - env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); - } -} + if (_incoming->bytes_remaining () != 0) + { + dmsg1 ("params(), %d bytes remaining (error)", + _incoming->bytes_remaining ()); + env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); + } +} -// // Store the result value. There's either an exception, or a result, // but not both of them. Results (and exceptions) can be reported // only after the parameter list has been provided (maybe empty). -// -void -__stdcall -IIOP_ServerRequest::result ( - CORBA_Any_ptr value, - CORBA_Environment &env -) + +void __stdcall +IIOP_ServerRequest::result (CORBA_Any_ptr value, + CORBA_Environment &env) { env.clear (); @@ -188,17 +161,12 @@ IIOP_ServerRequest::result ( // XXX send the message now! } - -// // Store the exception value. -// -void -__stdcall -IIOP_ServerRequest::exception ( - CORBA_ExceptionType type, - CORBA_Any_ptr value, - CORBA_Environment &env -) + +void __stdcall +IIOP_ServerRequest::exception (CORBA_ExceptionType type, + CORBA_Any_ptr value, + CORBA_Environment &env) { if (!_params || _retval || _exception) env.exception (new CORBA_BAD_INV_ORDER (COMPLETED_NO)); @@ -211,43 +179,36 @@ IIOP_ServerRequest::exception ( // XXX send the message now! } - -// // Invocation attributes. -// -CORBA_String -__stdcall -IIOP_ServerRequest::op_name () + +CORBA_String __stdcall +IIOP_ServerRequest::op_name (void) { return _opname; } -CORBA_Object_ptr -__stdcall -IIOP_ServerRequest::target () +CORBA_Object_ptr __stdcall +IIOP_ServerRequest::target (void) { // XXX implement me!! Code from TCP_OA exists ... return 0; } -CORBA_Principal_ptr -__stdcall -IIOP_ServerRequest::caller () +CORBA_Principal_ptr __stdcall +IIOP_ServerRequest::caller (void) { // XXX ... return client's principal return 0; } -CORBA_ORB_ptr -__stdcall -IIOP_ServerRequest::orb () +CORBA_ORB_ptr __stdcall +IIOP_ServerRequest::orb (void) { return _orb; } -CORBA_BOA_ptr -__stdcall -IIOP_ServerRequest::oa () +CORBA_BOA_ptr __stdcall +IIOP_ServerRequest::oa (void) { return _boa; } diff --git a/TAO/IIOP/lib/t-sizes.cpp b/TAO/IIOP/lib/t-sizes.cpp index d12460d3bfc..8653ea4196d 100644 --- a/TAO/IIOP/lib/t-sizes.cpp +++ b/TAO/IIOP/lib/t-sizes.cpp @@ -6,10 +6,10 @@ int main(int argc, char* argv[]) { - SHOWSIZE(CORBA_Short); - SHOWSIZE(CORBA_Long); - SHOWSIZE(CORBA_LongLong); - SHOWSIZE(CORBA_Float); - SHOWSIZE(CORBA_Double); - SHOWSIZE(CORBA_LongDouble); + SHOWSIZE (CORBA_Short); + SHOWSIZE (CORBA_Long); + SHOWSIZE (CORBA_LongLong); + SHOWSIZE (CORBA_Float); + SHOWSIZE (CORBA_Double); + SHOWSIZE (CORBA_LongDouble); } diff --git a/TAO/IIOP/lib/t-xdr.cpp b/TAO/IIOP/lib/t-xdr.cpp index 4e5e31802e1..4729082975e 100644 --- a/TAO/IIOP/lib/t-xdr.cpp +++ b/TAO/IIOP/lib/t-xdr.cpp @@ -1,12 +1,11 @@ // XDR record stream ... test encode performance against CDR, using // normal kinds of inlining performance hacks // -// XXX as of 3-Nov-95 XDR_stream should only be relied on to marshal the -// simplest primitives ... not objrefs, typecodes, etc. Also, the +// XXX as of 3-Nov-95 XDR_stream should only be relied on to marshal +// the simplest primitives ... not objrefs, typecodes, etc. Also, the // handling of sequences of chars/octets/shorts/wchars is wrong. // // It's suitable only for a simple performance test just now ... -// #include <string.h> @@ -26,49 +25,48 @@ #include "xdr.h" - -// A structure that's somewhat representative of an IIOP message -// in terms of overall complexity, so that its encoding cost is +// A structure that's somewhat representative of an IIOP message in +// terms of overall complexity, so that its encoding cost is // "interesting" typedef CORBA_SEQUENCE <CORBA_Octet> opaque; -struct interesting { - -// A call that's mostly going to be "on the mark" for IIOP-ish -// messages with small numbers of parameters: - -// 4 chars magic -// 2 bytes version -// 1 byte byte-order -// 1 byte message type ---> 8 bytes "pure header" - CORBA_Char hdr_bytes [8]; -// 1 word message size --=> end of GIOP::MessageHeader - CORBA_ULong hdr_len; - -// Service Context (1 word min) - CORBA_ULong empty_ctx; -// 1 word request id - CORBA_ULong request_id; -// 1 byte response-expected flag - CORBA_Boolean response_expected; -// [ CDR: 3 bytes padding ] -// opaque object key (1 word min; typically less than 16 bytes) - opaque object_key; -// string operation name (non-empty ... often less than 10 bytes) - CORBA_String opname; -// Principal client (1 word min) - opaque client_id; - -// --=> END OF GIOP::RequestHeader - -// ... small number of parameters with any significance - -// 2 word parameters - CORBA_ULong param1; - CORBA_ULong param2; -// 1 string parameter - CORBA_String param3; +struct interesting +{ + // A call that's mostly going to be "on the mark" for IIOP-ish + // messages with small numbers of parameters: + + // 4 chars magic + // 2 bytes version + // 1 byte byte-order + // 1 byte message type ---> 8 bytes "pure header" + CORBA_Char hdr_bytes [8]; + // 1 word message size --=> end of GIOP::MessageHeader + CORBA_ULong hdr_len; + + // Service Context (1 word min) + CORBA_ULong empty_ctx; + // 1 word request id + CORBA_ULong request_id; + // 1 byte response-expected flag + CORBA_Boolean response_expected; + // [ CDR: 3 bytes padding ] + // opaque object key (1 word min; typically less than 16 bytes) + opaque object_key; + // string operation name (non-empty ... often less than 10 bytes) + CORBA_String opname; + // Principal client (1 word min) + opaque client_id; + + // --=> END OF GIOP::RequestHeader + + // ... small number of parameters with any significance + + // 2 word parameters + CORBA_ULong param1; + CORBA_ULong param2; + // 1 string parameter + CORBA_String param3; }; @@ -78,79 +76,78 @@ struct interesting { extern CORBA_TypeCode TC_opaque; static void -do_test ( - int use_XDR, - CORBA_TypeCode_ptr tc, - void *data -) +do_test (int use_XDR, + CORBA_TypeCode_ptr tc, + void *data) { - unsigned loopcount = 100 * 1000; - unsigned i; - unsigned error_count = 0; - ACE_Time_Value before, after; - CORBA_String opname = "kill_husband"; - opaque key; - CORBA_Boolean status; + unsigned loopcount = 100 * 1000; + unsigned i; + unsigned error_count = 0; + ACE_Time_Value before, after; + CORBA_String opname = "kill_husband"; + opaque key; + CORBA_Boolean status; key.buffer = (CORBA_Octet *) "jacqueline"; key.length = key.maximum = 10; before = ACE_OS::gettimeofday (); - if (use_XDR) { + if (use_XDR) + { - // Using XDR APIs and encoding rules ... - // encode the structure repeatedly + // Using XDR APIs and encoding rules ... encode the structure + // repeatedly - for (i = 0; i < loopcount; i++) { - CORBA_Environment env; - XDR_stream stream (-1); + for (i = 0; i < loopcount; i++) { + CORBA_Environment env; + XDR_stream stream (-1); - // GIOP header plus most of request header - status = status - && stream.put_long ('GIOP') // magic - && stream.put_long ('\01\01\01\01') // version etc - && stream.put_long (99) // msg len - && stream.put_long (0) // no svc ctx - && stream.put_long (42) // request ID - && stream.put_boolean (CORBA_B_TRUE)// response? - ; + // GIOP header plus most of request header + status = status + && stream.put_long ('GIOP') // magic + && stream.put_long ('\01\01\01\01') // version etc + && stream.put_long (99) // msg len + && stream.put_long (0) // no svc ctx + && stream.put_long (42) // request ID + && stream.put_boolean (CORBA_B_TRUE)// response? + ; - if (status) - status = XDR_stream::encoder (&TC_opaque, &key, 0, &stream, env) - == CORBA_TypeCode::TRAVERSE_CONTINUE; + if (status) + status = XDR_stream::encoder (&TC_opaque, &key, 0, &stream, env) + == CORBA_TypeCode::TRAVERSE_CONTINUE; - if (status) - status = XDR_stream::encoder (_tc_CORBA_String, &opname, - 0, &stream, env) + if (status) + status = XDR_stream::encoder (_tc_CORBA_String, &opname, + 0, &stream, env) + == CORBA_TypeCode::TRAVERSE_CONTINUE; + + /* + if (status) + status = XDR_stream::encoder (_tc_CORBA_Principal, &key, + 0, &stream, env) == CORBA_TypeCode::TRAVERSE_CONTINUE; + */ - /* + // Parameters: two longs, a string + status = status + && stream.put_long (99) + && stream.put_long (-3455); if (status) - status = XDR_stream::encoder (_tc_CORBA_Principal, &key, - 0, &stream, env) - == CORBA_TypeCode::TRAVERSE_CONTINUE; - */ + status = XDR_stream::encoder (_tc_CORBA_String, &opname, + 0, &stream, env) + == CORBA_TypeCode::TRAVERSE_CONTINUE; - // Parameters: two longs, a string - status = status - && stream.put_long (99) - && stream.put_long (-3455); - if (status) - status = XDR_stream::encoder (_tc_CORBA_String, &opname, - 0, &stream, env) + // Gratuitous extra "interesting" data + status = XDR_stream::encoder (tc, data, 0, &stream, env) == CORBA_TypeCode::TRAVERSE_CONTINUE; - // Gratuitous extra "interesting" data - status = XDR_stream::encoder (tc, data, 0, &stream, env) - == CORBA_TypeCode::TRAVERSE_CONTINUE; - - if (status != CORBA_B_TRUE) - error_count++; - } + if (status != CORBA_B_TRUE) + error_count++; + } - } else { + } else { // This branch is the same, but using CDR APIs and encoding ... // encode the structure repeatedly @@ -224,38 +221,36 @@ do_test ( } } - int -main ( - int argc, - char **argv -) +main (int argc, + char **argv) { - int c; - int use_XDR = 1; - CORBA_TypeCode_ptr tc = _tc_CORBA_TypeCode; - void *data = tc; - - while ((c = ACE_OS::getopt (argc, argv, "cx")) != EOF) { - switch (c) { - case 'c': - use_XDR = 0; - continue; - - case 'x': - use_XDR = 1; - continue; - - case '?': - default: - // usage: - ACE_OS::fprintf (stderr, "usage: %s" - , " [-cx]" - , "\n" - , argv [0] - ); + int c; + int use_XDR = 1; + CORBA_TypeCode_ptr tc = _tc_CORBA_TypeCode; + void *data = tc; + + while ((c = ACE_OS::getopt (argc, argv, "cx")) != EOF) + { + switch (c) + { + case 'c': + use_XDR = 0; + continue; + + case 'x': + use_XDR = 1; + continue; + + case '?': + default: + // usage: + ACE_OS::fprintf (stderr, "usage: %s" + , " [-cx]" + , "\n" + , argv [0]); + } } - } do_test (1, tc, data); // XDR-ish do_test (0, tc, data); // CDR diff --git a/TAO/IIOP/lib/tc_const.cpp b/TAO/IIOP/lib/tc_const.cpp index ec278502242..20b22c79508 100644 --- a/TAO/IIOP/lib/tc_const.cpp +++ b/TAO/IIOP/lib/tc_const.cpp @@ -19,14 +19,13 @@ #include <string.h> #include <orb.h> -// // Null and void -// + static CORBA_TypeCode tc_null (tk_null); const CORBA_TypeCode_ptr _tc_CORBA_Null = (CORBA_TypeCode_ptr) &tc_null; CORBA_TypeCode_ptr -CORBA_TypeCode::_nil () +CORBA_TypeCode::_nil (void) { return &tc_null; } @@ -34,9 +33,9 @@ CORBA_TypeCode::_nil () static CORBA_TypeCode tc_void (tk_void); const CORBA_TypeCode_ptr _tc_CORBA_Void = &tc_void; -// + // Basic numeric types: short, long, longlong, and unsigned variants -// + static CORBA_TypeCode tc_short (tk_short); const CORBA_TypeCode_ptr _tc_CORBA_Short = &tc_short; @@ -55,9 +54,8 @@ const CORBA_TypeCode_ptr _tc_CORBA_ULong = &tc_ulong; static CORBA_TypeCode tc_ulonglong (tk_ulonglong); const CORBA_TypeCode_ptr _tc_CORBA_ULongLong = &tc_ulonglong; -// // Floating point types: single, double, quad precision -// + static CORBA_TypeCode tc_float (tk_float); const CORBA_TypeCode_ptr _tc_CORBA_Float = &tc_float; @@ -67,20 +65,18 @@ const CORBA_TypeCode_ptr _tc_CORBA_Double = &tc_double; static CORBA_TypeCode tc_longdouble (tk_longdouble); const CORBA_TypeCode_ptr _tc_CORBA_LongDouble = &tc_longdouble; -// // Various simple quantities -// + static CORBA_TypeCode tc_boolean (tk_boolean); const CORBA_TypeCode_ptr _tc_CORBA_Boolean = &tc_boolean; static CORBA_TypeCode tc_octet (tk_octet); const CORBA_TypeCode_ptr _tc_CORBA_Octet = &tc_octet; -// -// Internationalization-related data types: ISO Latin/1 and "wide" +// Internationalization-related data types: ISO Latin/1 and "wide" // characters, and strings of each. "wchar" is probably Unicode 1.1, // "wstring" being null-terminated sets thereof. -// + static CORBA_TypeCode tc_char (tk_char); const CORBA_TypeCode_ptr _tc_CORBA_Char = &tc_char; @@ -106,28 +102,31 @@ const CORBA_TypeCode_ptr _tc_CORBA_TypeCode = &tc_typecode; static CORBA_TypeCode tc_principal (tk_Principal); const CORBA_TypeCode_ptr _tc_CORBA_Principal = &tc_principal; -// // typecode for objref is complex, has two string parameters // // NOTE: Must be four-byte aligned -// -static const unsigned char oc_objref [] = { - 0, 0, 0, 0, // big endian encoding (+ padding) - 0, 0, 0, 29, // 29 char string + 3 pad bytes - 'I', 'D', 'L', ':', - 'o', 'm', 'g', '.', - 'o', 'r', 'g', '/', - 'C', 'O', 'R', 'B', - 'A', '/', 'O', 'b', - 'j', 'e', 'c', 't', - ':', '1', '.', '0', - '\0', 0, 0, 0, - 0, 0, 0, 7, // 7 chars "Object" + 1 pad byte - 'O', 'b', 'j', 'e', - 'c', 't', '\0', 0, + +static const u_char oc_objref [] = +{ + 0, 0, 0, 0, // big endian encoding (+ padding) + 0, 0, 0, 29, // 29 char string + 3 pad bytes + 'I', 'D', 'L', ':', + 'o', 'm', 'g', '.', + 'o', 'r', 'g', '/', + 'C', 'O', 'R', 'B', + 'A', '/', 'O', 'b', + 'j', 'e', 'c', 't', + ':', '1', '.', '0', + '\0', 0, 0, 0, + 0, 0, 0, 7, // 7 chars "Object" + 1 pad byte + 'O', 'b', 'j', 'e', + 'c', 't', '\0', 0, }; -static CORBA_TypeCode - tc_objref (tk_objref, sizeof oc_objref, - (unsigned char *)&oc_objref, CORBA_B_FALSE); + +static CORBA_TypeCode tc_objref (tk_objref, + sizeof oc_objref, + (u_char *) &oc_objref, + CORBA_B_FALSE); + const CORBA_TypeCode_ptr _tc_CORBA_Object = &tc_objref; diff --git a/TAO/IIOP/lib/typecode.cpp b/TAO/IIOP/lib/typecode.cpp index 9e86e8b14aa..8185473e57a 100644 --- a/TAO/IIOP/lib/typecode.cpp +++ b/TAO/IIOP/lib/typecode.cpp @@ -1,20 +1,20 @@ -// @(#)typecode.cpp 1.4 95/09/19 +// @ (#)typecode.cpp 1.4 95/09/19 // Copyright 1994-1995 by Sun Microsystems Inc. // All Rights Reserved // // TYPECODE: basic implementation of TypeCodes // -// Typecodes essentially consist of just the CDR octets that get marshaled -// and unmarshaled, and this code knows how to parse those octets and answer -// questions CORBA's TypeCode APIs require. +// Typecodes essentially consist of just the CDR octets that get +// marshaled and unmarshaled, and this code knows how to parse those +// octets and answer questions CORBA's TypeCode APIs require. // -// NOTE: This isn't well tuned performance-wise. Given how much is variable -// (byte order, alignment) it's clear tuning has its limits with respect to -// CDR bytecode interpretation. -// -// THREADING NOTE: Typecodes are readonly data structures, and the only -// mutual exclusion relates to reference counting and construction. +// NOTE: This isn't well tuned performance-wise. Given how much is +// variable (byte order, alignment) it's clear tuning has its limits +// with respect to CDR bytecode interpretation. // +// THREADING NOTE: Typecodes are readonly data structures, and the +// only mutual exclusion relates to reference counting and +// construction. #include <assert.h> #include <limits.h> @@ -43,44 +43,36 @@ CORBA_release (CORBA_TypeCode_ptr tc) CORBA_Boolean CORBA_is_nil (CORBA_TypeCode_ptr tc) { - return (CORBA_Boolean) (tc == 0); + return (CORBA_Boolean) tc == 0; } -// // Constructor for CONSTANT typecodes with empty parameter lists. -// These are only created once, and those constants are shared. -// -CORBA_TypeCode::CORBA_TypeCode ( - CORBA_TCKind kind -) : - _length (0), - _buffer (0), - _kind (kind), - _parent (0), - _refcount (1), - _orb_owns (CORBA_B_FALSE) +// These are only created once, and those constants are shared. + +CORBA_TypeCode::CORBA_TypeCode (CORBA_TCKind kind) + : _length (0), + _buffer (0), + _kind (kind), + _parent (0), + _refcount (1), + _orb_owns (CORBA_B_FALSE) { } - -// -// Constructor for all other typecodes, including constants with non-empty -// parameter lists. See "corba.hh" for details. -// -CORBA_TypeCode::CORBA_TypeCode ( - CORBA_TCKind kind, - CORBA_ULong length, - CORBA_Octet *buffer, - CORBA_Boolean orb_owns_tc -) : - _length (length), - _buffer (buffer), - _kind (kind), - _parent (0), - _refcount (1), - _orb_owns (orb_owns_tc) +// Constructor for all other typecodes, including constants with +// non-empty parameter lists. See "corba.hh" for details. + +CORBA_TypeCode::CORBA_TypeCode (CORBA_TCKind kind, + CORBA_ULong length, + CORBA_Octet *buffer, + CORBA_Boolean orb_owns_tc) + : _length (length), + _buffer (buffer), + _kind (kind), + _parent (0), + _refcount (1), + _orb_owns (orb_owns_tc) { - // // The CDR code used to interpret TypeCodes requires in-memory // alignments to match the "on-the-wire" alignments, simplifying // algorithms used to marshal/unmarshal. @@ -88,33 +80,32 @@ CORBA_TypeCode::CORBA_TypeCode ( // However, it's often hard to get compilers (in particular) to // generate data that's so aligned, since C++ doesn't provide // primitives giving control at that low a level. Although there - // are ways to get that alignment which work in almost all cases, - // we need to ensure adequate alignment in _all_ cases. + // are ways to get that alignment which work in almost all cases, we + // need to ensure adequate alignment in _all_ cases. // // This code exists to ensure such alignment; since the constructor - // is intended only for use by an IDL compiler or ORB code, it's - // not currently a priority to ensure the allocated code is freed. - // - if ((((ptr_arith_t)buffer) & 0x03) != 0) { - ptr_arith_t temp; + // is intended only for use by an IDL compiler or ORB code, it's not + // currently a priority to ensure the allocated code is freed. + + if (( ((ptr_arith_t) buffer) & 0x03) != 0) + { + ptr_arith_t temp; - temp = (ptr_arith_t) ACE_OS::malloc (length + 4); - temp += 3; - temp &= ~0x03; - _buffer = (CORBA_Octet *) temp; + temp = (ptr_arith_t) ACE_OS::malloc (length + 4); + temp += 3; + temp &= ~0x03; + _buffer = (CORBA_Octet *) temp; - (void) ACE_OS::memcpy (_buffer, buffer, (size_t) length); - _orb_owns = CORBA_B_FALSE; // XXX may leak - } + (void) ACE_OS::memcpy (_buffer, buffer, (size_t) length); + _orb_owns = CORBA_B_FALSE; // XXX may leak + } } +// Destructor. For "indirected" typecodes, the typecode reuses the +// buffer owned by its parent, and so rather than deleting the buffer +// it just drops the parent's refcount. -// -// Destructor. For "indirected" typecodes, the typecode reuses the buffer -// owned by its parent, and so rather than deleting the buffer it just drops -// the parent's refcount. -// -CORBA_TypeCode::~CORBA_TypeCode () +CORBA_TypeCode::~CORBA_TypeCode (void) { if (_parent) _parent->Release (); @@ -122,31 +113,24 @@ CORBA_TypeCode::~CORBA_TypeCode () delete _buffer; } - -// // COM's IUnknown support -// -// // {A201E4C1-F258-11ce-9598-0000C07CA898} DEFINE_GUID (IID_CORBA_TypeCode, 0xa201e4c1, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98); - -ULONG -__stdcall -CORBA_TypeCode::AddRef () +ULONG __stdcall +CORBA_TypeCode::AddRef (void) { - ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); + ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, lock_, 0); return _refcount++; } -ULONG -__stdcall -CORBA_TypeCode::Release () +ULONG __stdcall +CORBA_TypeCode::Release (void) { - ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, lock_, 0); + ACE_GUARD_RETURN (ACE_Thread_Mutex, guard, lock_, 0); assert (this != 0); @@ -157,12 +141,9 @@ CORBA_TypeCode::Release () return 0; } -HRESULT -__stdcall -CORBA_TypeCode::QueryInterface ( - REFIID riid, - void **ppv -) +HRESULT __stdcall +CORBA_TypeCode::QueryInterface (REFIID riid, + void **ppv) { *ppv = 0; @@ -172,102 +153,81 @@ CORBA_TypeCode::QueryInterface ( if (*ppv == 0) return ResultFromScode (E_NOINTERFACE); - (void) AddRef (); + (void) AddRef (); return NOERROR; } - -// // just fetch the 'kind' field out of the typecode -// + CORBA_TCKind -CORBA_TypeCode::kind ( - CORBA_Environment &env -) const +CORBA_TypeCode::kind (CORBA_Environment &env) const { env.clear (); return _kind; } - -// // skip a typecode encoding in a given CDR stream -// + static CORBA_Boolean -skip_typecode( - CDR &stream -) +skip_typecode (CDR &stream) { - CORBA_ULong kind; - CORBA_ULong temp; + CORBA_ULong kind; + CORBA_ULong temp; - if (!stream.get_ulong (kind) - || kind >= TC_KIND_COUNT) + if (!stream.get_ulong (kind) || kind >= TC_KIND_COUNT) return CORBA_B_FALSE; - switch (kind) { - // - // Most TypeCodes have empty parameter lists, nothing to skip - // - default: - break; - - // - // Some have single integer parameters, easy to skip. - // - // have preallocated constants that could be used. - // - case tk_string: - case tk_wstring: - case ~0: - return stream.get_ulong (temp); - - // - // The rest have "complex" parameter lists that are - // encoded as bulk octets ... just skip them - // - case tk_objref: - case tk_struct: - case tk_union: - case tk_enum: - case tk_sequence: - case tk_array: - case tk_alias: - case tk_except: - return stream.get_ulong (temp) != CORBA_B_FALSE - && stream.skip_bytes (temp) != CORBA_B_FALSE; - } + switch (kind) + { + // Most TypeCodes have empty parameter lists, nothing to skip + default: + break; + + // Some have single integer parameters, easy to skip. Some have + // preallocated constants that could be used. + case tk_string: + case tk_wstring: + case ~0: + return stream.get_ulong (temp); + + // The rest have "complex" parameter lists that are + // encoded as bulk octets ... just skip them. + case tk_objref: + case tk_struct: + case tk_union: + case tk_enum: + case tk_sequence: + case tk_array: + case tk_alias: + case tk_except: + return stream.get_ulong (temp) != CORBA_B_FALSE + && stream.skip_bytes (temp) != CORBA_B_FALSE; + } return CORBA_B_TRUE; } -// // Return member labels for tk_union typecodes. -// + CORBA_Any_ptr -CORBA_TypeCode::member_label ( - CORBA_ULong n, - CORBA_Environment &env -) const +CORBA_TypeCode::member_label (CORBA_ULong n, + CORBA_Environment &env) const { env.clear (); - CDR stream; + CDR stream; - stream.setup_encapsulation(_buffer, (size_t)_length); + stream.setup_encapsulation (_buffer, (size_t)_length); - // // this function is only applicable to the tk_union TC - // - if (_kind != tk_union) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } + if (_kind != tk_union) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } - // // skip ID and name, and then get the discriminant TC - // CORBA_TypeCode_ptr tc = 0; if (!stream.skip_string () // type ID, hidden @@ -278,425 +238,420 @@ CORBA_TypeCode::member_label ( return 0; } - // // skip default used, and get member count - // - CORBA_ULong member_count; + CORBA_ULong member_count; if (!stream.get_ulong (member_count) // default used - || !stream.get_ulong (member_count) - ) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } + || !stream.get_ulong (member_count)) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } - // - // If caller asked for the label for a nonexistent member, they - // get an error report! - // - if (n >= member_count) { - env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); - return 0; - } + // If caller asked for the label for a nonexistent member, they get + // an error report! + if (n >= member_count) + { + env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); + return 0; + } - // - // Get the n-th member label; they're all the same size and have - // no nested pointers, so we just overwrite each one with the - // enxt parameter. - // - void *buf = new CORBA_Octet [tc->size (env)]; + // Get the n-th member label; they're all the same size and have no + // nested pointers, so we just overwrite each one with the enxt + // parameter. + + void *buf = new CORBA_Octet [tc->size (env)]; if (env.exception () != 0) return 0; - for (CORBA_ULong i = 0; i <= n; i++) { - if (CDR::decoder (tc, buf, this, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE - || !stream.skip_string () // member name - || !skip_typecode (stream)) { // member TC - delete buf; - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + for (CORBA_ULong i = 0; i <= n; i++) + { + if (CDR::decoder (tc, buf, this, &stream, env) + != CORBA_TypeCode::TRAVERSE_CONTINUE + || !stream.skip_string () // member name + || !skip_typecode (stream)) + { // member TC + delete [] buf; + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } } - } - // // return the member label as an any - // - CORBA_Any *retval; + CORBA_Any *retval; - retval = new CORBA_Any(tc, buf, CORBA_B_TRUE); + retval = new CORBA_Any (tc, buf, CORBA_B_TRUE); tc->Release (); return retval; } - -// -// say how many parameters this typecode has; normally a fixed number, some -// are variable length. -// -// NOTE: This refers to "real" parameters, not what shows up in the IFR -// spec !! That is, "hidden" parameters are counted here, this doesn't -// strictly comply with what CORBA says "param_count" provides. +// say how many parameters this typecode has; normally a fixed number, +// some are variable length. // +// NOTE: This refers to "real" parameters, not what shows up in the +// IFR spec !! That is, "hidden" parameters are counted here, this +// doesn't strictly comply with what CORBA says "param_count" +// provides. + CORBA_ULong -CORBA_TypeCode::param_count ( - CORBA_Environment &env -) const +CORBA_TypeCode::param_count (CORBA_Environment &env) const { env.clear (); - switch (_kind) { - default: - return 0; - - case tk_string: - case tk_wstring: - return 1; - - case tk_objref: - case tk_sequence: - case tk_array: - return 2; - - case tk_alias: - return 3; - - case tk_except: - case tk_struct: + switch (_kind) { - CORBA_ULong members; - CDR stream; - - stream.setup_encapsulation(_buffer, (size_t)_length); + default: + return 0; - // skip rest of header (type ID and name) and collect the - // number of struct members - if (!stream.skip_string () // ID - || !stream.skip_string () // struct name - || !stream.get_ulong (members)) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + case tk_string: + case tk_wstring: + return 1; + + case tk_objref: + case tk_sequence: + case tk_array: + return 2; + + case tk_alias: + return 3; + + case tk_except: + case tk_struct: + { + CORBA_ULong members; + CDR stream; + + stream.setup_encapsulation (_buffer, (size_t)_length); + + // skip rest of header (type ID and name) and collect the + // number of struct members + if (!stream.skip_string () // ID + || !stream.skip_string () // struct name + || !stream.get_ulong (members)) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } + + return 3 + 2 * members; } - - return 3 + 2 * members; - } - case tk_enum: - { - CORBA_ULong members; - CDR stream; - - stream.setup_encapsulation(_buffer, (size_t)_length); - - // skip rest of header (type ID and name) and collect the - // number of struct members - if (!stream.skip_string () // ID - || !stream.skip_string () // typedef name - || !stream.get_ulong (members)) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + case tk_enum: + { + CORBA_ULong members; + CDR stream; + + stream.setup_encapsulation (_buffer, (size_t)_length); + + // skip rest of header (type ID and name) and collect the + // number of struct members + if (!stream.skip_string () // ID + || !stream.skip_string () // typedef name + || !stream.get_ulong (members)) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } + + return 3 + members; } - - return 3 + members; - } - case tk_union: - { - CORBA_ULong members; - CDR stream; - - stream.setup_encapsulation(_buffer, (size_t)_length); - - // skip rest of header (type ID, name, etc...) and collect the - // number of struct members - if (!stream.skip_string () // ID - || !stream.skip_string () // struct name - || !skip_typecode (stream) // discriminant TC - || !stream.get_ulong (members) // default used - || !stream.get_ulong (members) // real member count - ) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + case tk_union: + { + CORBA_ULong members; + CDR stream; + + stream.setup_encapsulation (_buffer, (size_t) _length); + + // skip rest of header (type ID, name, etc...) and collect the + // number of struct members + if (!stream.skip_string () // ID + || !stream.skip_string () // struct name + || !skip_typecode (stream) // discriminant TC + || !stream.get_ulong (members) // default used + || !stream.get_ulong (members)) // real member count + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } + + return 5 + 3 * members; } - - return 5 + 3 * members; } - } } -// -// Internal hack, used until member_count() and length() are implemented. -// Doesn't support all the types that those routines support. -// +// Internal hack, used until member_count () and length () are +// implemented. Doesn't support all the types that those routines +// support. + CORBA_ULong -CORBA_TypeCode::ulong_param ( - CORBA_ULong n, - CORBA_Environment &env -) const +CORBA_TypeCode::ulong_param (CORBA_ULong n, + CORBA_Environment &env) const { - CORBA_ULong temp; + CORBA_ULong temp; temp = param_count (env); // clears env if (env.exception ()) return 0; - if (temp < n) { - env.exception (new CORBA_Bounds); - return 0; - } + if (temp < n) + { + env.exception (new CORBA_Bounds); + return 0; + } - // // Get parameters for non-empty typecodes; their parameter lists are // encapsulated CDR (for complex ones) or inlined (for simple ones). - // - switch (_kind) { - default: // most have no long params - break; - - // - // Array, sequence ... complex parameter lists - // - case tk_array: // param 1 is an integer - case tk_sequence: // ... identical content - { - if (n == 0) - break; - - // - // Build CDR stream for encapsulated params, and skip the - // typecode up front. - // - CDR stream; + switch (_kind) + { + default: // most have no long params + break; - stream.setup_encapsulation (_buffer, (size_t)_length); - if (!skip_typecode (stream)) { - env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); - return 0; + // Array, sequence ... complex parameter lists + case tk_array: // param 1 is an integer + case tk_sequence: // ... identical content + { + if (n == 0) + break; + + // Build CDR stream for encapsulated params, and skip the + // typecode up front. + CDR stream; + + stream.setup_encapsulation (_buffer, (size_t)_length); + if (!skip_typecode (stream)) + { + env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); + return 0; + } + + // Then comes the "bounds" parameter. + if (!stream.get_ulong (temp)) + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return temp; } - // - // Then comes the "bounds" parameter. - // - if (!stream.get_ulong (temp)) - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return temp; + // string, wstring ... simple parameter lists, containing just the + // string bounds (zero indicates unbounded). Stored specially + case tk_string: + case tk_wstring: + if (n != 0) + break; + return _length; } - - // - // string, wstring ... simple parameter lists, containing just - // the string bounds (zero indicates unbounded). Stored specially - // - case tk_string: - case tk_wstring: - if (n != 0) - break; - return _length; - } env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); return 0; } - -// -// Internal hack, used until member_type(), discriminator_type(), -// and content_type() are implemented. -// -// NOTE special calling convention for CDR::decoder() when we're -// potentially deencapsulating an indirected typecode: the "data2" -// value indicates that this typecode is the parent. See comments -// at CDR::decoder() for further details. +// Internal hack, used until member_type (), discriminator_type (), +// and content_type () are implemented. // +// NOTE special calling convention for CDR::decoder () when we're +// potentially deencapsulating an indirected typecode: the "data2" +// value indicates that this typecode is the parent. See comments at +// CDR::decoder () for further details. + CORBA_TypeCode_ptr -CORBA_TypeCode::typecode_param ( - CORBA_ULong n, - CORBA_Environment &env -) const +CORBA_TypeCode::typecode_param (CORBA_ULong n, + CORBA_Environment &env) const { - CORBA_ULong temp; + CORBA_ULong temp; temp = param_count (env); // clears env if (env.exception ()) return 0; - if (temp < n) { - env.exception (new CORBA_Bounds); - return 0; - } + if (temp < n) + { + env.exception (new CORBA_Bounds); + return 0; + } - // // Build the de-encapsulating CDR stream, bypassing the stringent - // alignment tests (we're a bit looser in what we need here, and - // we _know_ we're OK). Then skip the byte order code. - // - CDR stream; - CORBA_TypeCode_ptr tc = 0; + // alignment tests (we're a bit looser in what we need here, and we + // _know_ we're OK). Then skip the byte order code. - stream.setup_encapsulation (_buffer, (size_t)_length); + CDR stream; + CORBA_TypeCode_ptr tc = 0; - switch (_kind) { - default: // most have no tc params - break; - - case tk_sequence: // param 0 is a tc - case tk_array: - if (n != 0) - break; - if (CDR::decoder (_tc_CORBA_TypeCode, &tc, this, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } - return tc; + stream.setup_encapsulation (_buffer, (size_t)_length); - case tk_alias: // #1 is a tc - if (n != 2) + switch (_kind) + { + default: // most have no tc params break; - if (!stream.skip_string () // type ID, hidden - || !stream.skip_string () // typedef name - || CDR::decoder (_tc_CORBA_TypeCode, &tc, this, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } - return tc; - case tk_except: - case tk_struct: // #5 and up are tc, index from 0 - if ((n < 4) || (n & 0x1)) { // tc is at odd number of param list - env.exception (new CORBA_Bounds); - return 0; - } + case tk_sequence: // param 0 is a tc + case tk_array: + if (n != 0) + break; + if (CDR::decoder (_tc_CORBA_TypeCode, + &tc, this, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } + return tc; - if (!stream.skip_string () // type ID, hidden - || !stream.skip_string () // typedef name - || !stream.get_ulong (temp)) { // member count - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } else { - CORBA_ULong i; - temp = (n - 3) / 2; - - // skip member pairs to the one we want - for (i = 0; i < temp; i++) { - // skip to the member being asked - if (!stream.skip_string () // member name - || !skip_typecode (stream)) { + case tk_alias: // #1 is a tc + if (n != 2) + break; + if (!stream.skip_string () // type ID, hidden + || !stream.skip_string () // typedef name + || CDR::decoder (_tc_CORBA_TypeCode, &tc, this, &stream, env) + != CORBA_TypeCode::TRAVERSE_CONTINUE) + { env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); return 0; } - } + return tc; - if (!stream.skip_string () - || CDR::decoder (_tc_CORBA_TypeCode, &tc, this, &stream, - env)!= CORBA_TypeCode::TRAVERSE_CONTINUE) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + case tk_except: + case tk_struct: // #5 and up are tc, index from 0 + if ((n < 4) || (n & 0x1)) { // tc is at odd number of param list + env.exception (new CORBA_Bounds); return 0; } - return tc; - } - case tk_union: // #6 and up are tc, index from 0 - if (n != 2 && (n < 7 || (n - 7) % 3)) { - env.exception (new CORBA_Bounds); - return 0; - } + if (!stream.skip_string () // type ID, hidden + || !stream.skip_string () // typedef name + || !stream.get_ulong (temp)) + { // member count + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } + else + { + CORBA_ULong i; + temp = (n - 3) / 2; + + // skip member pairs to the one we want + for (i = 0; i < temp; i++) + { + // skip to the member being asked + if (!stream.skip_string () // member name + || !skip_typecode (stream)) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } + } + + if (!stream.skip_string () + || CDR::decoder (_tc_CORBA_TypeCode, &tc, this, &stream, + env)!= CORBA_TypeCode::TRAVERSE_CONTINUE) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } + return tc; + } - if (!stream.skip_string () // type ID, hidden - || !stream.skip_string () // typedef name - || CDR::decoder (_tc_CORBA_TypeCode, &tc, this, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE // TC - ) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } else if (!stream.get_ulong (temp) // default used - || !stream.get_ulong (temp) // member count - ) { - tc->Release (); - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } + case tk_union: // #6 and up are tc, index from 0 + if (n != 2 && (n < 7 || (n - 7) % 3)) + { + env.exception (new CORBA_Bounds); + return 0; + } - if (n == 2) - return tc; + if (!stream.skip_string () // type ID, hidden + || !stream.skip_string () // typedef name + || CDR::decoder (_tc_CORBA_TypeCode, + &tc, this, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) // TC + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } + else if (!stream.get_ulong (temp) // default used + || !stream.get_ulong (temp)) // member count + { + tc->Release (); + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } - temp = (n - 7) / 3; + if (n == 2) + return tc; - // - // skip to the member requested - // - CORBA_ULong i; - CORBA_Long scratch; // always big enough + temp = (n - 7) / 3; - for (i = 0; i < temp; i++) { + // skip to the member requested - if (CDR::decoder (tc, &scratch, this, &stream, env) // member label - != CORBA_TypeCode::TRAVERSE_CONTINUE - || !stream.skip_string () // member name - || !skip_typecode (stream)) { // member typecode - tc->Release (); - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } - } + CORBA_ULong i; + CORBA_Long scratch; // always big enough + + for (i = 0; i < temp; i++) + { + if (CDR::decoder (tc, &scratch, this, &stream, env) // member label + != CORBA_TypeCode::TRAVERSE_CONTINUE + || !stream.skip_string () // member name + || !skip_typecode (stream)) + { // member typecode + tc->Release (); + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } + } - if (CDR::decoder (tc, &scratch, this, &stream, env) // member label - != CORBA_TypeCode::TRAVERSE_CONTINUE - || !stream.skip_string () // member name - ) { + // member label + if (CDR::decoder (tc, + &scratch, this, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE + || !stream.skip_string ()) // member name + { + tc->Release (); + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } tc->Release (); - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; - } - tc->Release (); - if (CDR::decoder (_tc_CORBA_TypeCode, &tc, this, &stream, env) - != CORBA_TypeCode::TRAVERSE_CONTINUE) { - env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); - return 0; + if (CDR::decoder (_tc_CORBA_TypeCode, + &tc, this, + &stream, env) != CORBA_TypeCode::TRAVERSE_CONTINUE) + { + env.exception (new CORBA_BAD_TYPECODE (COMPLETED_NO)); + return 0; + } + return tc; } - return tc; - } env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); return 0; } - -// // Return the type ID (RepositoryId) for the TypeCode; it may be empty. // // NOTE the string returned here is owned by the typecode!! -// + CORBA_String -CORBA_TypeCode::id ( - CORBA_Environment &env -) const +CORBA_TypeCode::id (CORBA_Environment &env) const { env.clear (); - switch (_kind) { - // - // These are all complex typecodes, which have as their first parameter - // (number zero) a repository/type ID string encoded per CDR rules. - // That means we can just return a pointer to that string directly! - // - case tk_objref: - case tk_struct: - case tk_union: - case tk_enum: - case tk_alias: - case tk_except: - return (CORBA_String) (_buffer - + 4 // skip byte order flag and padding - + 4 // skip (strlen + 1) - ); - - // - // No other typecodes ever have type IDs - // - default: - env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); - return 0; - } + switch (_kind) + { + // These are all complex typecodes, which have as their first + // parameter (number zero) a repository/type ID string encoded + // per CDR rules. That means we can just return a pointer to + // that string directly! + + case tk_objref: + case tk_struct: + case tk_union: + case tk_enum: + case tk_alias: + case tk_except: + return (CORBA_String) (_buffer + + 4 // skip byte order flag and padding + + 4 // skip (strlen + 1) + ); + + // No other typecodes ever have type IDs + default: + env.exception (new CORBA_BAD_PARAM (COMPLETED_NO)); + return 0; + } } diff --git a/include/makeinclude/platform_osf1_4.0.GNU b/include/makeinclude/platform_osf1_4.0.GNU index 01db0c5d454..168850d052a 100644 --- a/include/makeinclude/platform_osf1_4.0.GNU +++ b/include/makeinclude/platform_osf1_4.0.GNU @@ -4,9 +4,9 @@ CC = cxx CXX = $(CC) CFLAGS += $(DCFLAGS) -pthread -ptr ptrepository CCFLAGS += $(CFLAGS) -w0 -DCFLAGS += -g -expect_unresolved '*' +DCFLAGS += -g DLD = $(CXX) -LD = $(CXX) +LDFLAGS += -shared -expect_unresolved '*' LIBS += -pthread -ltli -lrt -ptr ptrepository PIC = ARFLAGS = ruvZ |