diff options
Diffstat (limited to 'TAO/tao/IIOP_Interpreter.cpp')
-rw-r--r-- | TAO/tao/IIOP_Interpreter.cpp | 1211 |
1 files changed, 0 insertions, 1211 deletions
diff --git a/TAO/tao/IIOP_Interpreter.cpp b/TAO/tao/IIOP_Interpreter.cpp deleted file mode 100644 index 3f0b3c24858..00000000000 --- a/TAO/tao/IIOP_Interpreter.cpp +++ /dev/null @@ -1,1211 +0,0 @@ -// $Id$ - -// @(#)interp.cpp 1.4 95/11/04 -// Copyright 1994-1995 by Sun Microsystems Inc. -// All Rights Reserved - -// We need to include Sequence.h and Sequence_T.h before the -// IIOP_Interpreter to workaround a Greenhills (1.8.8 and 1.8.9) -// compiler bug. -#include "tao/Sequence.h" -#include "tao/Sequence_T.h" -#include "tao/IIOP_Interpreter.h" -#include "tao/Any.h" -#include "tao/varout.h" -#include "tao/CDR.h" -#include "tao/Typecode.h" -#include "tao/Environment.h" -#include "tao/Union.h" - -ACE_RCSID(tao, IIOP_Interpreter, "$Id$") - -TAO_IIOP_Interpreter::Table_Element -TAO_IIOP_Interpreter::table_[CORBA::TC_KIND_COUNT] = -{ - { 0, 1, 0 }, // CORBA::tk_null - { 0, 1, 0 }, // CORBA::tk_void - - { 0, 1, 0, 0 }, // CORBA::tk_short - { 0, 1, 0, 0 }, // CORBA::tk_long - { 0, 1, 0, 0 }, // CORBA::tk_ushort - { 0, 1, 0, 0 }, // CORBA::tk_ulong - - { 0, 1, 0, 0 }, // CORBA::tk_float - { 0, 1, 0, 0 }, // CORBA::tk_double - - { 0, 1, 0, 0 }, // CORBA::tk_boolean - { 0, 1, 0, 0 }, // CORBA::tk_char - { 0, 1, 0, 0 }, // CORBA::tk_octet - { 0, 1, 0, 0 }, // CORBA::tk_any - - { 0, 1, 0, 0 }, // CORBA::tk_TypeCode - { 0, 1, 0, 0 }, // CORBA::tk_Principal - { 0, 1, 0, skip_encapsulation }, // CORBA::tk_objref - - { 0, 1, calc_struct_attributes, 0 }, // CORBA::tk_struct - { 0, 1, calc_union_attributes, 0 }, // CORBA::tk_union - - { 0, 1, 0, skip_encapsulation }, // CORBA::tk_enum - { 0, 1, 0, skip_long }, // CORBA::tk_string -#if defined (TAO_NO_COPY_OCTET_SEQUENCES) - { 0, 1, calc_seq_attributes, 0 }, // CORBA::tk_sequence -#else - { 0, 1, 0, skip_encapsulation }, // CORBA::tk_sequence -#endif - { 0, 1, calc_array_attributes, 0 }, // CORBA::tk_array - - // = Two TCKind values added in 94-11-7 - { 0, 1, calc_alias_attributes, 0 }, // CORBA::tk_alias - { 0, 1, calc_exception_attributes, 0 }, // CORBA::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 }, // CORBA::tk_longlong - { 0, 1, 0, 0 }, // CORBA::tk_ulonglong - { 0, 1, 0, 0 }, // CORBA::tk_longdouble - { 0, 1, 0, 0 }, // CORBA::tk_wchar - { 0, 1, 0, skip_long } // CORBA::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). - - enum TCKIND - { - tk_null = 0, - tk_void = 1, - tk_short = 2, - tk_long = 3, - tk_ushort = 4, - tk_ulong = 5, - tk_float = 6, - tk_double = 7, - tk_boolean = 8, - tk_char = 9, - tk_octet = 10, - tk_any = 11, - tk_TypeCode = 12, - tk_Principal = 13, - tk_objref = 14, - tk_struct = 15, - tk_union = 16, - tk_enum = 17, - tk_string = 18, - tk_sequence = 19, - tk_array = 20, - tk_alias = 21, // 94-11-7 - tk_except = 22, // 94-11-7 - - // these five are OMG-IDL data type extensions - tk_longlong = 23, // 94-9-32 Appendix A (+ 2) - tk_ulonglong = 24, // 94-9-32 Appendix A (+ 2) - tk_longdouble = 25, // 94-9-32 Appendix A (+ 2) - tk_wchar = 26, // 94-9-32 Appendix A (+ 2) - tk_wstring = 27, // 94-9-32 Appendix A (+ 2) - - // This symbol is not defined by CORBA 2.0. It's used to speed up - // dispatch based on TCKind values, and lets many important ones - // just be table lookups. It must always be the last enum value!! - - TC_KIND_COUNT - }; - -#if defined (TAO_HAS_FIXED_BYTE_ALIGNMENT) - // Have a bogus one - #define declare_entry(x,t) struct align_struct_ ## t { } - - #define setup_entry(x,t) \ - { \ - TAO_IIOP_Interpreter::table_ [t].size_ = sizeof (x); \ - TAO_IIOP_Interpreter::table_ [t].alignment_ = 1; \ - } -#else /* ! TAO_HAS_FIXED_BYTE_ALIGNMENT */ - // unix, ACE_WIN32, VXWORKS, __Lynx__, at least - #define declare_entry(x,t) \ - struct align_struct_ ## t \ - { \ - x one; \ - char dummy [TAO_MAXIMUM_NATIVE_TYPE_SIZE + 1 - sizeof(x)]; \ - x two; \ - } - - #define setup_entry(x,t) \ - { \ - align_struct_ ## t align; \ - TAO_IIOP_Interpreter::table_ [t].size_ = sizeof (x); \ - TAO_IIOP_Interpreter::table_ [t].alignment_ = \ - (char *) &align.two - (char *) &align.one - TAO_MAXIMUM_NATIVE_TYPE_SIZE; \ - } -#endif /* ! TAO_HAS_FIXED_BYTE_ALIGNMENT */ - -// Fills in fixed size and alignment values. - -declare_entry (CORBA::Short, tk_short); -declare_entry (CORBA::Long, tk_long); -declare_entry (CORBA::UShort, tk_ushort); -declare_entry (CORBA::ULong, tk_ulong); - -declare_entry (CORBA::Float, tk_float); -declare_entry (CORBA::Double, tk_double); - -declare_entry (CORBA::Boolean, tk_boolean); -declare_entry (CORBA::Char, tk_char); -declare_entry (CORBA::Octet, tk_octet); -declare_entry (CORBA::Any, tk_any); - -declare_entry (CORBA::TypeCode_ptr, tk_TypeCode); -declare_entry (CORBA::Principal_ptr, tk_Principal); -declare_entry (TAO_Object_Field_T<CORBA_Object>, tk_objref); - -declare_entry (CORBA::String, tk_string); -#if !defined (TAO_NO_COPY_OCTET_SEQUENCES) -declare_entry (TAO_opaque, tk_sequence); -#endif - -declare_entry (CORBA::LongLong, tk_longlong); -declare_entry (CORBA::ULongLong, tk_ulonglong); -declare_entry (CORBA::LongDouble, tk_longdouble); -declare_entry (CORBA::WChar, tk_wchar); -declare_entry (CORBA::WString, tk_wstring); - -void -TAO_IIOP_Interpreter::init (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, CORBA::tk_enum); - TAO_IIOP_Interpreter::table_ [CORBA::tk_enum].size_ = - sizeof (generic_enum); - TAO_IIOP_Interpreter::table_ [CORBA::tk_enum].alignment_ = - sizeof (generic_enum); - - setup_entry (CORBA::String, tk_string); -#if !defined (TAO_NO_COPY_OCTET_SEQUENCES) - setup_entry (TAO_opaque, tk_sequence); -#endif /* defined (TAO_NO_COPY_OCTET_SEQUENCES) */ - - 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 - -CORBA::Boolean -TAO_IIOP_Interpreter::skip_encapsulation (TAO_InputCDR *stream) -{ - return stream->skip_string (); -} - -CORBA::Boolean -TAO_IIOP_Interpreter::skip_long (TAO_InputCDR *stream) -{ - CORBA::ULong scratch; - - return stream->read_ulong (scratch); -} - -// 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; -// - The whole typecode (including TCKind enum) is in the stream -// -// 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_t -TAO_IIOP_Interpreter::calc_nested_size_and_alignment_i (CORBA::TypeCode_ptr tc, - TAO_InputCDR* stream, - CORBA::TCKind kind, - size_t &alignment, - CORBA::Environment &env) -{ - CORBA::ULong temp; - // Just a temporary to retrieve CORBA::TCKind variables as ULong's - - // 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 >= CORBA::TC_KIND_COUNT - || kind <= CORBA::tk_void - || kind == CORBA::tk_except) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::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 (TAO_IIOP_Interpreter::table_[kind].calc_ != 0) - { - assert (TAO_IIOP_Interpreter::table_[kind].size_ == 0); - - // Pull encapsulation length out of the stream. - if (stream->read_ulong (temp) == 0) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - - // Initialize the TypeCode if requested - if (tc) - { - tc->kind_ = kind; - tc->buffer_ = stream->rd_ptr (); - 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. - - assert (temp <= UINT_MAX); - - TAO_InputCDR nested (*stream, temp); - - if (nested.good_bit () == 0) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - - size_t size = TAO_IIOP_Interpreter::table_[kind].calc_ (&nested, - alignment, - env); - if (env.exception () != 0) - { - return 0; - } - - // 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 (temp); - - if (stream->rd_ptr () != nested.rd_ptr ()) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - return size; - } - assert (TAO_IIOP_Interpreter::table_[kind].size_ != 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: CORBA::tk_string, CORBA::tk_wstring, - // CORBA::tk_objref, CORBA::tk_enum, and CORBA::tk_sequence. - - if (tc) - { - CORBA::ULong len; - - tc->kind_ = kind; - switch (kind) - { - default: - assert (TAO_IIOP_Interpreter::table_[kind].skipper_ == 0); - break; - - case CORBA::tk_string: - case CORBA::tk_wstring: - if (stream->read_ulong (len) == 0) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - tc->length_ = len; - break; - - case CORBA::tk_enum: - case CORBA::tk_objref: - case CORBA::tk_sequence: - if (stream->read_ulong (len) == 0) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - tc->length_ = len; - - assert (len < UINT_MAX); - tc->buffer_ = stream->rd_ptr (); - stream->skip_bytes (len); - break; - } - - // Otherwise, consume any parameters without stuffing them into - // a temporary TypeCode. - } - else if (TAO_IIOP_Interpreter::table_[kind].skipper_ != 0 - && TAO_IIOP_Interpreter::table_[kind].skipper_ (stream) == 0) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - - // Return statically known values. - alignment = TAO_IIOP_Interpreter::table_[kind].alignment_; - return TAO_IIOP_Interpreter::table_[kind].size_; -} - -size_t -TAO_IIOP_Interpreter::calc_nested_size_and_alignment (CORBA::TypeCode_ptr tc, - TAO_InputCDR *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; - if (stream->read_ulong (temp) == 0) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - - env.clear (); - - CORBA::TCKind kind = (CORBA::TCKind) temp; - - if (kind != (CORBA::TCKind) ~0u) - { - return TAO_IIOP_Interpreter::calc_nested_size_and_alignment_i - (tc, - stream, - kind, - alignment, - env); - } - - // 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! - - // @@ ASG @@ - comparison with -8 or -4. I think the spec says it must be - // larger than -4 (absolute value) - // 09/04/98 - check this - // - - CORBA::Long offset; - if (!stream->read_long (offset) - || offset >= -8 - || ((-offset) & 0x03) != 0) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - - // Notice how we change the sign of the offset to estimate the - // maximum size. - TAO_InputCDR indirected_stream (*stream, -offset, offset); - - // Fetch indirected-to TCKind. - if (!indirected_stream.read_ulong (temp)) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - kind = (CORBA::TCKind) temp; - - return TAO_IIOP_Interpreter::calc_nested_size_and_alignment_i (tc, - &indirected_stream, - kind, - alignment, - env); -} - -// Given typecode bytes for a structure (or exception), figure out its -// alignment and size; return size, alignment is an 'out' parameter. -// Only "CORBA::tk_struct" (or "CORBA::tk_except") has been taken out of the stream -// parameter holding the bytes. -// -// We use a one-pass algorithm, calculating size and inter-element -// padding while recording the strongest alignment restriction. Then -// we correct the size to account for tail-padding. -// -// 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. - -size_t -TAO_IIOP_Interpreter::calc_struct_and_except_attributes (TAO_InputCDR *stream, - size_t &alignment, - CORBA::Boolean is_exception, - CORBA::Environment &env) -{ - 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 = TAO_IIOP_Interpreter::table_[CORBA::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->read_ulong (members)) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::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; - size_t member_alignment; - - // Skip name of the member. - if (!stream->skip_string ()) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - 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. - - 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; - }; - - // 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. - -size_t -TAO_IIOP_Interpreter::calc_struct_attributes (TAO_InputCDR *stream, - size_t &alignment, - CORBA::Environment &env) -{ - return calc_struct_and_except_attributes (stream, - alignment, - 0, - env); -} - -// Calculate size and alignment for an exception. - -size_t -TAO_IIOP_Interpreter::calc_exception_attributes (TAO_InputCDR *stream, - size_t &alignment, - CORBA::Environment &env) -{ - return calc_struct_and_except_attributes (stream, - alignment, - 1, - 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 -// the strictest alignment required by _any_ arm of the union. - -size_t -TAO_IIOP_Interpreter::calc_key_union_attributes (TAO_InputCDR *stream, - size_t &overall_alignment, - size_t &discrim_size_with_pad, - CORBA::Environment &env) -{ - CORBA::ULong members; - CORBA::ULong temp; - size_t discrim_and_base_size; - size_t discrim_and_base_size_with_pad; - size_t value_alignment; - size_t value_size; - // define a dummy structure to compute alignment of pointer type - struct align_ptr - { - void *one; - char dummy [TAO_MAXIMUM_NATIVE_TYPE_SIZE + 1 - sizeof (void*)]; - void *two; - }; - align_ptr ap; - - // the first member of the union internal representation is the VPTR - // since every union inherits from TAO_Base_Union - overall_alignment = (char *) &ap.two - (char *) &ap.one - - TAO_MAXIMUM_NATIVE_TYPE_SIZE; - - 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 (CORBA::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 (CORBA::tk_void); - - discrim_and_base_size = sizeof (TAO_Base_Union) + - calc_nested_size_and_alignment (&discrim_tc, - stream, - value_alignment, - env); - if (env.exception () != 0) - return 0; - - if (value_alignment > overall_alignment) - overall_alignment = value_alignment; - - - // skip "default used" indicator, and save "member count" - - if (!stream->read_ulong (temp) // default used - || !stream->read_ulong (members)) - { // member count - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - 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. - - value_alignment = 1; - 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. - // - // NOTE: This modifies 94-9-32 Appendix A to stipulate that - // "long long" values are not legal as discriminants. - - switch (discrim_tc.kind_) - { - case CORBA::tk_short: - case CORBA::tk_ushort: - case CORBA::tk_wchar: - { - CORBA::Short s; - - if (!stream->read_short (s)) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - } - break; - - case CORBA::tk_long: - case CORBA::tk_ulong: - case CORBA::tk_enum: - { - CORBA::Long l; - - if (!stream->read_long (l)) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - } - break; - - case CORBA::tk_boolean: - case CORBA::tk_char: - { - CORBA::Char c; - - if (!stream->read_char (c)) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - } - break; - - default: - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - - // We also don't care about any member name. - - if (!stream->skip_string ()) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - - // Get the member size and alignment. - // However, for variable sized member types and types that have - // constructors, these become members of the pointer types. We need to - // determine if we are dealing with such a member and accordingly adjust - // the size and alignment - CORBA::Boolean var_sized_member = 0; - TAO_InputCDR temp (*stream); - if (calc_union_attr_is_var_sized_member (&temp, var_sized_member) == -1) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - - if (var_sized_member) - { - member_size = sizeof (void*); - member_alignment = (char *) &ap.two - (char *) &ap.one - - TAO_MAXIMUM_NATIVE_TYPE_SIZE; - (void) CORBA::TypeCode::skip_typecode (*stream); - } - else - { - // proceed with the normal way of computing the size and 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_and_base_size_with_pad = - (size_t) align_binary (discrim_and_base_size, value_alignment); - discrim_size_with_pad = discrim_and_base_size_with_pad - - sizeof (TAO_Base_Union); - // 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_and_base_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). - -size_t -TAO_IIOP_Interpreter::calc_union_attributes (TAO_InputCDR *stream, - size_t &alignment, - CORBA::Environment &env) -{ - size_t scratch; - - return calc_key_union_attributes (stream, alignment, scratch, env); -} - -// Calculate size and alignment for a typedeffed type. - -size_t -TAO_IIOP_Interpreter::calc_alias_attributes (TAO_InputCDR *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 (CORBA::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); -} - -// 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.) - -size_t -TAO_IIOP_Interpreter::calc_array_attributes (TAO_InputCDR *stream, - size_t &alignment, - CORBA::Environment &env) -{ - 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 and check count of members. - - if (stream->read_ulong (member_count) == 0 - || member_count > UINT_MAX) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - - // Array size is a function only of member number and count - return member_size * (size_t) member_count; -} - -#if defined (TAO_NO_COPY_OCTET_SEQUENCES) -// Calculate size and alignment of a sequence. -// If octet sequence optimizations are enabled the size of octet -// sequences differ from the size of a regular sequence. - -size_t -TAO_IIOP_Interpreter::calc_seq_attributes (TAO_InputCDR *stream, - size_t &alignment, - CORBA::Environment &env) -{ - CORBA::TCKind kind; - - // Get the "kind" ... if this is an indirection, this is a guess - // which will soon be updated. - CORBA::ULong temp; - if (stream->read_ulong (temp) == 0) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - - if (temp == ~0u) - { - // 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! - CORBA::Long offset; - if (!stream->read_long (offset) - || offset >= -8 - || ((-offset) & 0x03) != 0) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - // Notice how we change the sign of the offset to estimate the - // maximum size. - TAO_InputCDR indirected_stream (*stream, -offset, offset); - - // Fetch indirected-to TCKind; this *cannot* be an indirection - // again because multiple indirections are non-complaint. - if (indirected_stream.read_ulong (temp) == 0 - || temp == ~0u) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - } - - kind = ACE_static_cast(CORBA::TCKind, temp); - - // Skip the rest of the stream because we don't use it. - if (stream->skip_bytes (stream->length ()) == 0) - { - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - return 0; - } - - size_t size; - if (kind == CORBA::tk_octet) - { - declare_entry (TAO_opaque, tk_sequence); - align_struct_tk_sequence align; - size = sizeof (TAO_opaque); -#if defined (TAO_HAS_FIXED_BYTE_ALIGNMENT) - alignment = 1; -#else - alignment = - (char*)&align.two - (char*)&align.one - TAO_MAXIMUM_NATIVE_TYPE_SIZE; -#endif /* TAO_HAS_FIXED_BYTE_ALIGNMENT */ - } - else - { - // Note: GHS can't handle TAO_Unbounded_Sequence<CORBA::Long> below. - // Instead, use TAO_Unbounded_String_Sequence. - declare_entry (TAO_Unbounded_String_Sequence, tk_sequence); - size = sizeof (TAO_Unbounded_String_Sequence); - align_struct_tk_sequence align; -#if defined (TAO_HAS_FIXED_BYTE_ALIGNMENT) - alignment = 1; -#else - alignment = - (char*)&align.two - (char*)&align.one - TAO_MAXIMUM_NATIVE_TYPE_SIZE; -#endif /* TAO_HAS_FIXED_BYTE_ALIGNMENT */ - } - return size; -} -#endif /* defined (TAO_NO_COPY_OCTET_SEQUENCES) */ - -// Cast the discriminant values to the right type and compare them. - -CORBA::Boolean -TAO_IIOP_Interpreter::match_value (CORBA::TCKind kind, - TAO_InputCDR *tc_stream, - const void *value, - CORBA::Environment &env) -{ - CORBA::Boolean retval = 0; - - switch (kind) - { - case CORBA::tk_short: - case CORBA::tk_ushort: - { - CORBA::UShort discrim; - - if (tc_stream->read_ushort (discrim) != 0) - retval = (discrim == *(CORBA::UShort *)value); - else - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - } - break; - - case CORBA::tk_long: - case CORBA::tk_ulong: - { - CORBA::ULong discrim; - - if (tc_stream->read_ulong (discrim) != 0) - retval = (discrim == *(CORBA::ULong *)value); - else - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - } - break; - - case CORBA::tk_enum: - { - CORBA::ULong discrim; - - if (tc_stream->read_ulong (discrim) != 0) - retval = (discrim == *(unsigned *)value); - else - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - } - break; - - case CORBA::tk_boolean: - { - CORBA::Boolean discrim; - - if (tc_stream->read_boolean (discrim) != 0) - retval = (discrim == *(CORBA::Boolean *)value); - else - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - } - break; - - case CORBA::tk_char: - { - CORBA::Char discrim; - - if (tc_stream->read_char (discrim) != 0) - retval = (discrim == *(CORBA::Char *)value); - else - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - } - break; - - case CORBA::tk_wchar: - { - CORBA::WChar discrim; - - if (tc_stream->read_wchar (discrim) != 0) - retval = (discrim == *(CORBA::WChar *)value); - else - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - } - break; - - default: - env.exception (new CORBA::BAD_TYPECODE (CORBA::COMPLETED_NO)); - } - - return retval; -} - -int -TAO_IIOP_Interpreter -::calc_union_attr_is_var_sized_member (TAO_InputCDR *stream, - CORBA::Boolean &flag) -{ - CORBA::Environment env; - CORBA::ULong temp; - flag = 0; - - // Get the tk_ "kind" field - if (stream->read_ulong (temp) == 0) - { - // error - return -1; - } - - env.clear (); - - CORBA::TCKind kind = (CORBA::TCKind) temp; - - switch (kind) - { - case CORBA::tk_null: - case CORBA::tk_void: - // error - return -1; - case CORBA::tk_short: - case CORBA::tk_ushort: - case CORBA::tk_long: - case CORBA::tk_ulong: - case CORBA::tk_longlong: - case CORBA::tk_ulonglong: - case CORBA::tk_float: - case CORBA::tk_double: - case CORBA::tk_longdouble: - case CORBA::tk_boolean: - case CORBA::tk_char: - case CORBA::tk_wchar: - case CORBA::tk_octet: - case CORBA::tk_enum: - case CORBA::tk_Principal: - // not variable sized - return 0; - case CORBA::tk_any: - case CORBA::tk_TypeCode: - case CORBA::tk_objref: - case CORBA::tk_union: - case CORBA::tk_string: - case CORBA::tk_wstring: - case CORBA::tk_sequence: - case CORBA::tk_array: - case CORBA::tk_except: - // always variable sized - flag = 1; - return 0; - case CORBA::tk_alias: - // find out what its base says - { - CORBA::ULong encap; - - // Pull encapsulation length out of the stream. - if (stream->read_ulong (encap) == 0) - { - return -1; - } - - assert (encap <= UINT_MAX); - - TAO_InputCDR nested (*stream, temp); - - if (nested.good_bit () == 0) - { - return -1; - } - - // Skip type ID and name in the parameter stream - if (!nested.skip_string () // type ID - || !nested.skip_string ()) // typedef name - { - return -1; - } - - // stream->skip_bytes (encap); - return calc_union_attr_is_var_sized_member (&nested, flag); - } - ACE_NOTREACHED (break); - case CORBA::tk_struct: - // explore further based on members - { - CORBA::ULong encap; - - // Pull encapsulation length out of the stream. - if (stream->read_ulong (encap) == 0) - { - return -1; - } - - assert (encap <= UINT_MAX); - - TAO_InputCDR nested (*stream, temp); - - if (nested.good_bit () == 0) - { - return -1; - } - - // stream.skip_bytes (encap); - // Skip type ID and name in the parameter stream - if (!nested.skip_string () // type ID - || !nested.skip_string ()) // typedef name - { - return -1; - } - - CORBA::ULong member_count; - if (nested.read_ulong (member_count) == 0) - { - return -1; - } - for (CORBA::ULong i = 0; i < member_count && !flag; i++) - { - // stop this loop the moment we discover that a member is variable - // in size - - // skip the name - if (nested.skip_string () == 0) - { - return -1; - } - TAO_InputCDR member_tc (nested); - if (calc_union_attr_is_var_sized_member (&member_tc, flag) == -1) - { - return -1; - } - CORBA::TypeCode::skip_typecode (nested); - } - } - return flag; - ACE_NOTREACHED (break); - case ~0: - // TO-DO - return 0; - default: - // error - return -1; - } - // cannot reach here - ACE_NOTREACHED (return -1); -} - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class TAO_Unbounded_Sequence<CORBA::Long>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate TAO_Unbounded_Sequence<CORBA::Long> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ |