TAO_TypeCodeFactory_i. More...
#include <TypeCodeFactory_i.h>
Public Member Functions | |
TAO_TypeCodeFactory_i (void) | |
ctor | |
~TAO_TypeCodeFactory_i (void) | |
dtor | |
virtual CORBA::TypeCode_ptr | create_struct_tc (const char *id, const char *name, const CORBA::StructMemberSeq &members) |
virtual CORBA::TypeCode_ptr | create_union_tc (const char *id, const char *name, CORBA::TypeCode_ptr discriminator_type, const CORBA::UnionMemberSeq &members) |
virtual CORBA::TypeCode_ptr | create_enum_tc (const char *id, const char *name, const CORBA::EnumMemberSeq &members) |
virtual CORBA::TypeCode_ptr | create_alias_tc (const char *id, const char *name, CORBA::TypeCode_ptr original_type) |
virtual CORBA::TypeCode_ptr | create_exception_tc (const char *id, const char *name, const CORBA::StructMemberSeq &members) |
virtual CORBA::TypeCode_ptr | create_interface_tc (const char *id, const char *name) |
virtual CORBA::TypeCode_ptr | create_string_tc (CORBA::ULong bound) |
virtual CORBA::TypeCode_ptr | create_wstring_tc (CORBA::ULong bound) |
virtual CORBA::TypeCode_ptr | create_fixed_tc (CORBA::UShort digits, CORBA::UShort scale) |
virtual CORBA::TypeCode_ptr | create_sequence_tc (CORBA::ULong bound, CORBA::TypeCode_ptr element_type) |
virtual CORBA::TypeCode_ptr | create_array_tc (CORBA::ULong length, CORBA::TypeCode_ptr element_type) |
virtual CORBA::TypeCode_ptr | create_value_tc (const char *id, const char *name, CORBA::ValueModifier type_modifier, CORBA::TypeCode_ptr concrete_base, const CORBA::ValueMemberSeq &members) |
virtual CORBA::TypeCode_ptr | create_value_box_tc (const char *id, const char *name, CORBA::TypeCode_ptr boxed_type) |
virtual CORBA::TypeCode_ptr | create_native_tc (const char *id, const char *name) |
virtual CORBA::TypeCode_ptr | create_recursive_tc (const char *id) |
virtual CORBA::TypeCode_ptr | create_abstract_interface_tc (const char *id, const char *name) |
virtual CORBA::TypeCode_ptr | create_local_interface_tc (const char *id, const char *name) |
virtual CORBA::TypeCode_ptr | create_component_tc (const char *id, const char *name) |
virtual CORBA::TypeCode_ptr | create_home_tc (const char *id, const char *name) |
virtual CORBA::TypeCode_ptr | create_event_tc (const char *id, const char *name, CORBA::ValueModifier type_modifier, CORBA::TypeCode_ptr concrete_base, const CORBA::ValueMemberSeq &members) |
Static Public Member Functions | |
static TAO_TypeCodeFactory_i * | _narrow (CORBA::Object_ptr obj) |
= LocalObject methods | |
Private Member Functions | |
void | compute_default_label (CORBA::TCKind kind, CORBA::ULong skip_slot, const CORBA::UnionMemberSeq &members, TAO::TypeCode::Case_Dynamic *&the_case) |
Finds a legal default label value. | |
CORBA::TypeCode_ptr | create_tc_common (const char *id, const char *name, CORBA::TCKind kind) |
Called for all types that take just an id and a name. | |
CORBA::TypeCode_ptr | string_wstring_tc_common (CORBA::ULong bound, CORBA::TCKind kind) |
Code for strings and wstrings is identical except for TCKind. | |
CORBA::TypeCode_ptr | sequence_array_tc_common (CORBA::ULong bound, CORBA::TypeCode_ptr element_type, CORBA::TCKind kind) |
Code for arrays and sequences is identical except for TCKind. | |
CORBA::TypeCode_ptr | struct_except_tc_common (const char *id, const char *name, const CORBA::StructMemberSeq &members, CORBA::TCKind kind) |
Code for structs and unions is identical except for TCKind. | |
CORBA::TypeCode_ptr | alias_value_box_tc_common (const char *id, const char *name, CORBA::TypeCode_ptr underlying_type, CORBA::TCKind kind) |
Code for aliases and boxed valuetypes is identical except for TCKind. | |
CORBA::TypeCode_ptr | value_event_tc_common (const char *id, const char *name, CORBA::ValueModifier type_modifier, CORBA::TypeCode_ptr concrete_base, const CORBA::ValueMemberSeq &members, CORBA::TCKind kind) |
CORBA::Boolean | valid_name (const char *name) |
CORBA::Boolean | valid_id (const char *id) |
CORBA::Boolean | valid_content_type (CORBA::TypeCode_ptr tc) |
CORBA::Boolean | unique_label_values (const CORBA::UnionMemberSeq &members, CORBA::TypeCode_ptr disc_tc, CORBA::ULong default_index_slot) |
CORBA::Boolean | valid_disc_type (CORBA::TypeCode_ptr tc) |
bool | check_recursion (CORBA::TCKind kind, char const *id, CORBA::TypeCode_ptr member, CORBA::TypeCode_ptr &recursive_tc, char const *working_id) |
Check member for recursive TypeCode . | |
CORBA::TypeCode_ptr | make_recursive_tc (CORBA::TCKind kind, char const *id) |
Make a recursive TypeCode with the given kind and repository ID. | |
TAO_TypeCodeFactory_i (const TAO_TypeCodeFactory_i &src) | |
Prohibited. | |
TAO_TypeCodeFactory_i & | operator= (const TAO_TypeCodeFactory_i &src) |
Implementation of the CORBA::TypeCodeFactory interface
Definition at line 43 of file TypeCodeFactory_i.h.
TAO_TypeCodeFactory_i::TAO_TypeCodeFactory_i | ( | void | ) |
TAO_TypeCodeFactory_i::~TAO_TypeCodeFactory_i | ( | void | ) |
TAO_TypeCodeFactory_i::TAO_TypeCodeFactory_i | ( | const TAO_TypeCodeFactory_i & | src | ) | [private] |
Prohibited.
TAO_TypeCodeFactory_i * TAO_TypeCodeFactory_i::_narrow | ( | CORBA::Object_ptr | obj | ) | [static] |
= LocalObject methods
Reimplemented from CORBA::LocalObject.
Definition at line 111 of file TypeCodeFactory_i.cpp.
{ if (CORBA::is_nil (_tao_objref)) { return 0; } return dynamic_cast<TAO_TypeCodeFactory_i *> (_tao_objref); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::alias_value_box_tc_common | ( | const char * | id, | |
const char * | name, | |||
CORBA::TypeCode_ptr | underlying_type, | |||
CORBA::TCKind | kind | |||
) | [private] |
Code for aliases and boxed valuetypes is identical except for TCKind.
Definition at line 1309 of file TypeCodeFactory_i.cpp.
{ CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr (); if (name == 0 || !this->valid_name (name)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO); } if (id == 0 || !this->valid_id (id)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO); } CORBA::Boolean const valid_content = this->valid_content_type (underlying_type); if (!valid_content) { throw ::CORBA::BAD_TYPECODE (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO); } CORBA::TypeCode_var tmp (CORBA::TypeCode::_duplicate (underlying_type)); typedef TAO::TypeCode::Alias<CORBA::String_var, CORBA::TypeCode_var, TAO::True_RefCount_Policy> typecode_type; ACE_NEW_THROW_EX (tc, typecode_type (kind, id, name, tmp), CORBA::NO_MEMORY ()); return tc; }
bool TAO_TypeCodeFactory_i::check_recursion | ( | CORBA::TCKind | kind, | |
char const * | id, | |||
CORBA::TypeCode_ptr | member, | |||
CORBA::TypeCode_ptr & | recursive_tc, | |||
char const * | working_id | |||
) | [private] |
Check member for recursive TypeCode
.
true
if member contains a recursive TypeCode
, and set recursive_tc to the actual recursive TypeCode
that was represented by the recursive TypeCode
placeholder. Definition at line 1726 of file TypeCodeFactory_i.cpp.
{ if (kind != CORBA::tk_struct && kind != CORBA::tk_union && kind != CORBA::tk_value && kind != CORBA::tk_event) return false; CORBA::TypeCode_var unaliased_member = TAO::unaliased_typecode (member); CORBA::TCKind const unaliased_member_kind = unaliased_member->kind (); // Recursively iterate through the member and content types until // we've exhausted all TypeCodes capable of containing other // TypeCodes. switch (unaliased_member_kind) { case CORBA::tk_struct: case CORBA::tk_union: case CORBA::tk_value: case CORBA::tk_event: { CORBA::ULong const nfields = unaliased_member->member_count (); for (CORBA::ULong i = 0; i < nfields; ++i) { CORBA::TypeCode_var member_tc = unaliased_member->member_type (i); CORBA::TCKind const member_tc_kind = member_tc->kind (); if (member_tc_kind == CORBA::TAO_TC_KIND_COUNT) { // Valuetypes can directly contain a recursive member // (e.g. valuetype V { public V member; };). Check if // the member TypeCode is the recursive TypeCode // placeholder. if (kind == CORBA::tk_value || kind == CORBA::tk_event) { char const * member_tc_id = member_tc->id (); if (ACE_OS::strcmp (id, member_tc_id) == 0) { TAO::TypeCodeFactory::Recursive_TypeCode * const rtc = dynamic_cast< TAO::TypeCodeFactory::Recursive_TypeCode *> ( member_tc.in ()); if (!rtc) { throw CORBA::INTERNAL (); } if (CORBA::is_nil (recursive_tc)) { recursive_tc = this->make_recursive_tc (kind, id); } // Set the actual recursive TypeCode. rtc->the_typecode (recursive_tc); return true; } // Different recursive TypeCode. Let it be. } else { // @@ structs and unions may not directly contain // recursive members. They must be indirectly // recursive through a member sequence (which // itself may be contained inside a nested // struct, union, etc). throw ::CORBA::BAD_TYPECODE (); } } else { if (member_tc_kind == CORBA::tk_value || member_tc_kind == CORBA::tk_event) { char const * member_tc_id = member_tc->id (); if (working_id != 0 && ACE_OS::strcmp (working_id, member_tc_id) == 0) { // We've found a recursion at a lower level but // not the one we're looking for, so we must end // the recursion, which would otherwise never return. break; } // Update working_id to catch non-top-level recursion // of valuetype or eventtype. Other case caught below. working_id = member_tc_id; } bool const recursion_detected = this->check_recursion (kind, id, member_tc.in (), recursive_tc, working_id); if (recursion_detected) { return true; } } // Not recursive or not the recursive TypeCode we want. // Try the next member. } } break; case CORBA::tk_sequence: case CORBA::tk_array: { CORBA::TypeCode_var content_tc = unaliased_member->content_type (); CORBA::TCKind const content_tc_kind = content_tc->kind (); char const * content_tc_id = 0; if (content_tc_kind == CORBA::tk_struct || content_tc_kind == CORBA::tk_union || content_tc_kind == CORBA::TAO_TC_KIND_COUNT) { content_tc_id = content_tc->id (); } if (working_id != 0 && content_tc_id != 0 && ACE_OS::strcmp (working_id, content_tc_id) == 0) { // We've found a recursion at a lower level but // not the one we're looking for, so we must // end the recursion, which would otherwise never return. break; } if (content_tc_kind == CORBA::TAO_TC_KIND_COUNT) { if (ACE_OS::strcmp (id, content_tc_id) == 0) { TAO::TypeCodeFactory::Recursive_TypeCode * const rtc = dynamic_cast<TAO::TypeCodeFactory::Recursive_TypeCode *> (content_tc.in ()); if (!rtc) { throw CORBA::INTERNAL (); } if (CORBA::is_nil (recursive_tc)) { recursive_tc = this->make_recursive_tc (kind, id); } // Set the actual recursive TypeCode. rtc->the_typecode (recursive_tc); return true; } // Different recursive TypeCode. Let it be. } return this->check_recursion ( kind, id, content_tc.in (), recursive_tc, content_tc_id != 0 ? content_tc_id : working_id); } default: break; // Not a recursion-capable TypeCode. } return false; }
void TAO_TypeCodeFactory_i::compute_default_label | ( | CORBA::TCKind | kind, | |
CORBA::ULong | skip_slot, | |||
const CORBA::UnionMemberSeq & | members, | |||
TAO::TypeCode::Case_Dynamic *& | the_case | |||
) | [private] |
Finds a legal default label value.
Definition at line 864 of file TypeCodeFactory_i.cpp.
{ // One to hold the current default value, one to // hold the curent label's extracted value. struct disc_types { CORBA::Char char_val; CORBA::Boolean bool_val; CORBA::Short short_val; CORBA::UShort ushort_val; CORBA::Long long_val; CORBA::ULong ulong_val; #if !defined (ACE_LACKS_LONGLONG_T) CORBA::ULongLong ulonglong_val; #endif /* ACE_LACKS_LONGLONG_T */ CORBA::ULong enum_val; // TODO - handle (u)longlong types } dv, u; dv.char_val = 0; dv.bool_val = 0; dv.short_val = ACE_INT16_MIN; dv.ushort_val = 0; dv.long_val = ACE_INT32_MIN; dv.ulong_val = 0; #if !defined (ACE_LACKS_LONGLONG_T) dv.ulonglong_val = 0; #endif /* ACE_LACKS_LONGLONG_T */ dv.enum_val = 0; CORBA::ULong const len = members.length (); bool success = false; // A collision forces us to start over, because the label // values need not be in sorted order. while (!success) { success = true; for (CORBA::ULong i = 0; i < len; ++i) { // This is the one we're trying to find a legal value for. if (i == skip_slot) { continue; } // If there's a collision, we increment the default value. switch (kind) { case CORBA::tk_char: members[i].label >>= CORBA::Any::to_char (u.char_val); if (u.char_val == dv.char_val) { dv.char_val++; success = false; } break; case CORBA::tk_boolean: members[i].label >>= CORBA::Any::to_boolean (u.bool_val); if (u.bool_val == dv.bool_val) { dv.bool_val = !dv.bool_val; success = false; } break; case CORBA::tk_short: members[i].label >>= u.short_val; if (u.short_val == dv.short_val) { dv.short_val++; success = false; } break; case CORBA::tk_ushort: members[i].label >>= u.ushort_val; if (u.ushort_val == dv.ushort_val) { dv.ushort_val++; success = false; } break; case CORBA::tk_long: members[i].label >>= u.long_val; if (u.long_val == dv.long_val) { dv.long_val++; success = false; } break; case CORBA::tk_ulong: members[i].label >>= u.ulong_val; if (u.ulong_val == dv.ulong_val) { dv.ulong_val++; success = false; } break; #if !defined (ACE_LACKS_LONGLONG_T) case CORBA::tk_ulonglong: members[i].label >>= u.ulonglong_val; if (u.ulonglong_val == dv.ulonglong_val) { dv.ulonglong_val++; success = false; } break; #endif /* ACE_LACKS_LONGLONG_T */ case CORBA::tk_enum: { TAO::Any_Impl *impl = members[i].label.impl (); TAO_InputCDR for_reading (static_cast<ACE_Message_Block *> (0)); if (impl->encoded ()) { TAO::Unknown_IDL_Type *unk = dynamic_cast<TAO::Unknown_IDL_Type *> (impl); if (!unk) throw CORBA::INTERNAL (); // We don't want unk's rd_ptr to move, in case // we are shared by another Any, so we use this // to copy the state, not the buffer. for_reading = unk->_tao_get_cdr (); } else { TAO_OutputCDR out; impl->marshal_value (out); TAO_InputCDR tmp (out); for_reading = tmp; } for_reading.read_ulong (u.enum_val); if (u.enum_val == dv.enum_val) { dv.enum_val++; success = false; } break; } default: break; } // If there's been a collision, we should start over right away. if (!success) { break; } } } // Add the default value to the encapsulation. switch (kind) { case CORBA::tk_char: { typedef TAO::TypeCode::Case_T<CORBA::Char, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW (the_case, case_type (dv.char_val)); } break; case CORBA::tk_boolean: { typedef TAO::TypeCode::Case_T<CORBA::Boolean, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW (the_case, case_type (dv.bool_val)); } break; case CORBA::tk_short: { typedef TAO::TypeCode::Case_T<CORBA::Short, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW (the_case, case_type (dv.short_val)); } break; case CORBA::tk_ushort: { typedef TAO::TypeCode::Case_T<CORBA::UShort, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW (the_case, case_type (dv.ushort_val)); } break; case CORBA::tk_long: { typedef TAO::TypeCode::Case_T<CORBA::Long, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW (the_case, case_type (dv.long_val)); } break; case CORBA::tk_ulong: { typedef TAO::TypeCode::Case_T<CORBA::ULong, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW (the_case, case_type (dv.ulong_val)); } break; #if !defined (ACE_LACKS_LONGLONG_T) case CORBA::tk_ulonglong: { typedef TAO::TypeCode::Case_T<CORBA::ULongLong, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW (the_case, case_type (dv.ulonglong_val)); } break; #endif /* ACE_LACKS_LONGLONG_T */ case CORBA::tk_enum: { // Enumerators are encoded as CORBA::ULong. typedef TAO::TypeCode::Case_T<CORBA::ULong, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW (the_case, case_type (dv.enum_val)); } break; default: break; } }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_abstract_interface_tc | ( | const char * | id, | |
const char * | name | |||
) | [virtual] |
Definition at line 803 of file TypeCodeFactory_i.cpp.
{ return this->create_tc_common (id, name, CORBA::tk_abstract_interface ); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_alias_tc | ( | const char * | id, | |
const char * | name, | |||
CORBA::TypeCode_ptr | original_type | |||
) | [virtual] |
Definition at line 664 of file TypeCodeFactory_i.cpp.
{ return this->alias_value_box_tc_common (id, name, original_type, CORBA::tk_alias); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_array_tc | ( | CORBA::ULong | length, | |
CORBA::TypeCode_ptr | element_type | |||
) | [virtual] |
Definition at line 736 of file TypeCodeFactory_i.cpp.
{ return sequence_array_tc_common (length, element_type, CORBA::tk_array); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_component_tc | ( | const char * | id, | |
const char * | name | |||
) | [virtual] |
Definition at line 827 of file TypeCodeFactory_i.cpp.
{ return this->create_tc_common (id, name, CORBA::tk_component); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_enum_tc | ( | const char * | id, | |
const char * | name, | |||
const CORBA::EnumMemberSeq & | members | |||
) | [virtual] |
Definition at line 611 of file TypeCodeFactory_i.cpp.
{ CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr (); if (name == 0 || !this->valid_name (name)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO); } if (id == 0 || !this->valid_id (id)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO); } CORBA::ULong const len = members.length (); ACE_Hash_Map_Manager<ACE_CString, int, ACE_Null_Mutex> map; ACE_Array_Base<CORBA::String_var> enumerators (len); for (CORBA::ULong index = 0; index < len; ++index) { ACE_CString ext_id (members[index]); int int_id = 0; // Is there a duplicate member name? if (map.trybind (ext_id, int_id) != 0) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 17, CORBA::COMPLETED_NO); } enumerators[index] = members[index]; } typedef TAO::TypeCode::Enum< CORBA::String_var, ACE_Array_Base<CORBA::String_var>, TAO::True_RefCount_Policy> typecode_type; ACE_NEW_THROW_EX (tc, typecode_type (id, name, enumerators, len), CORBA::NO_MEMORY ()); return tc; }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_event_tc | ( | const char * | id, | |
const char * | name, | |||
CORBA::ValueModifier | type_modifier, | |||
CORBA::TypeCode_ptr | concrete_base, | |||
const CORBA::ValueMemberSeq & | members | |||
) | [virtual] |
Definition at line 846 of file TypeCodeFactory_i.cpp.
{ return this->value_event_tc_common (id, name, type_modifier, concrete_base, members, CORBA::tk_event); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_exception_tc | ( | const char * | id, | |
const char * | name, | |||
const CORBA::StructMemberSeq & | members | |||
) | [virtual] |
Definition at line 676 of file TypeCodeFactory_i.cpp.
{ return this->struct_except_tc_common (id, name, members, CORBA::tk_except); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_fixed_tc | ( | CORBA::UShort | digits, | |
CORBA::UShort | scale | |||
) | [virtual] |
Definition at line 712 of file TypeCodeFactory_i.cpp.
{ CORBA::TypeCode_ptr tc; ACE_NEW_THROW_EX (tc, TAO::TypeCode::Fixed<TAO::True_RefCount_Policy> (digits, scale), CORBA::NO_MEMORY ()); return tc; }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_home_tc | ( | const char * | id, | |
const char * | name | |||
) | [virtual] |
Definition at line 838 of file TypeCodeFactory_i.cpp.
{ return this->create_tc_common (id, name, CORBA::tk_home); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_interface_tc | ( | const char * | id, | |
const char * | name | |||
) | [virtual] |
Definition at line 688 of file TypeCodeFactory_i.cpp.
{ return this->create_tc_common (id, name, CORBA::tk_objref); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_local_interface_tc | ( | const char * | id, | |
const char * | name | |||
) | [virtual] |
Definition at line 815 of file TypeCodeFactory_i.cpp.
{ return this->create_tc_common (id, name, CORBA::tk_local_interface ); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_native_tc | ( | const char * | id, | |
const char * | name | |||
) | [virtual] |
Definition at line 775 of file TypeCodeFactory_i.cpp.
{ return this->create_tc_common (id, name, CORBA::tk_native); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_recursive_tc | ( | const char * | id | ) | [virtual] |
Definition at line 786 of file TypeCodeFactory_i.cpp.
{ CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr (); if (id == 0 || !this->valid_id (id)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO); } ACE_NEW_THROW_EX (tc, TAO::TypeCodeFactory::Recursive_TypeCode (id), CORBA::NO_MEMORY ()); return tc; }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_sequence_tc | ( | CORBA::ULong | bound, | |
CORBA::TypeCode_ptr | element_type | |||
) | [virtual] |
Definition at line 726 of file TypeCodeFactory_i.cpp.
{ return sequence_array_tc_common (bound, element_type, CORBA::tk_sequence); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_string_tc | ( | CORBA::ULong | bound | ) | [virtual] |
Definition at line 698 of file TypeCodeFactory_i.cpp.
{ return this->string_wstring_tc_common (bound, CORBA::tk_string); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_struct_tc | ( | const char * | id, | |
const char * | name, | |||
const CORBA::StructMemberSeq & | members | |||
) | [virtual] |
Definition at line 122 of file TypeCodeFactory_i.cpp.
{ return this->struct_except_tc_common (id, name, members, CORBA::tk_struct); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_tc_common | ( | const char * | id, | |
const char * | name, | |||
CORBA::TCKind | kind | |||
) | [private] |
Called for all types that take just an id and a name.
Definition at line 1122 of file TypeCodeFactory_i.cpp.
{ if (name == 0 || !this->valid_name (name)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO); } // Repo id may not be null for object or native type. if (id == 0 || !this->valid_id (id)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO); } CORBA::TypeCode_ptr tc; typedef TAO::TypeCode::Objref<CORBA::String_var, TAO::True_RefCount_Policy> typecode_type; ACE_NEW_THROW_EX (tc, typecode_type (kind, id, name), CORBA::NO_MEMORY ()); return tc; }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_union_tc | ( | const char * | id, | |
const char * | name, | |||
CORBA::TypeCode_ptr | discriminator_type, | |||
const CORBA::UnionMemberSeq & | members | |||
) | [virtual] |
Definition at line 134 of file TypeCodeFactory_i.cpp.
{ CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr (); if (name == 0 || !this->valid_name (name)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO); } if (id == 0 || !this->valid_id (id)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO); } CORBA::Boolean const good_disc_type = this->valid_disc_type (discriminator_type); if (!good_disc_type) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 20, CORBA::COMPLETED_NO); } CORBA::ULong const len = members.length (); CORBA::ULong dups = 0; CORBA::ULong raw_default_index = ACE_UINT32_MAX; CORBA::Long default_index = -1; CORBA::Octet value = ACE_OCTET_MAX; ACE_Hash_Map_Manager<ACE_CString, int, ACE_Null_Mutex> map; // No getting around iterating over the members twice. We have // to do it once *before* the overall length is written to the // CDR stream, to know by how much, if any, the number of members // differs from the number of labels. // // @@ Now that the TypeCode implementation has been rewritten, do we // still need to iterate over the members twice? for (CORBA::ULong i = 0; i < len; ++i) { CORBA::UnionMember const & member = members[i]; char const * const member_name = member.name; int trybind_status = 0; if (i > 0) { // Is this a duplicate case label? If so, we have to adjust // the 'length' we encode - a member gets encoded only once. if (ACE_OS::strcmp (member_name, members[i - 1].name) == 0) { CORBA::Boolean const equiv = member.type.in ()->equivalent (members[i - 1].type.in ()); // If adjacent names are the same and their types are // equivalent, then they are duplicate case labels. If // the types are not equivalent, then they are separate // members with the same name, which is not allowed. if (equiv) { ++dups; } else { throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 17, CORBA::COMPLETED_NO); } } else { // Only if we do not have a duplicate case label do we // check for a duplicate member name. ACE_CString ext_id (member_name); int int_id = 0; trybind_status = map.trybind (ext_id, int_id); } } else { ACE_CString ext_id (member_name); int int_id = 0; trybind_status = map.trybind (ext_id, int_id); } // Duplicate member name? if (trybind_status != 0) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 17, CORBA::COMPLETED_NO); } CORBA::TypeCode_ptr const tc_holder = member.type.in (); // Valid member type? CORBA::Boolean const valid_member = this->valid_content_type (tc_holder); if (!valid_member) { throw ::CORBA::BAD_TYPECODE ( CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO); } // Reset the default index, if we have a default case label. if ((member.label >>= CORBA::Any::to_octet (value)) == 1) { if (value == 0) { raw_default_index = i; // Only the multiple labels that come before the // default label affect its adjusted value. default_index = static_cast<CORBA::Long> (i - dups); } } else { // Else check that the label type is equivalent to the // given discriminator type. CORBA::TypeCode_var const tmp = member.label.type (); CORBA::Boolean const equiv = discriminator_type->equivalent (tmp.in () ); if (!equiv) { throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 19, CORBA::COMPLETED_NO); } } } CORBA::Boolean const unique_labels = this->unique_label_values (members, discriminator_type, raw_default_index ); if (!unique_labels) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 18, CORBA::COMPLETED_NO); } using namespace TCF::Union; case_array_type cases (len - dups); CORBA::TCKind const kind = discriminator_type->kind (); CORBA::ULong ci = 0; // Case array index. bool is_recursive = false; CORBA::TypeCode_var recursive_tc; for (CORBA::ULong index = 0; index < len; ++index) { CORBA::UnionMember const & member = members[index]; if (index > 0) { // Is this a duplicate case label? If so, skip it - a member // goes into the TypeCode only once. if (ACE_OS::strcmp (member.name, members[index - 1].name) == 0) { continue; } } // Check if recursive. bool const recursion_detected = this->check_recursion (CORBA::tk_union, id, member.type.in (), recursive_tc.inout (), 0); // Do not clobber previous positive detection. if (recursion_detected) { is_recursive = true; } elem_type & element = cases[ci]; TAO::TypeCode::Case_Dynamic * the_case = 0; if (index == raw_default_index) { // This is the default label - we have to find a legal value. this->compute_default_label (kind, index, members, the_case); if (the_case == 0) { // Should never throw since label kind was // verified earlier. throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 19, CORBA::COMPLETED_NO); } } else { // Ugly. *sigh* switch (kind) { case CORBA::tk_enum: { TAO::Any_Impl * const impl = member.label.impl (); TAO_InputCDR for_reading ( static_cast<ACE_Message_Block *> (0)); if (impl->encoded ()) { TAO::Unknown_IDL_Type * const unk = dynamic_cast<TAO::Unknown_IDL_Type *> (impl); if (!unk) throw CORBA::INTERNAL (); // We don't want unk's rd_ptr to move, in case we // are shared by another Any, so we use this to // copy the state, not the buffer. for_reading = unk->_tao_get_cdr (); } else { TAO_OutputCDR out; impl->marshal_value (out); TAO_InputCDR tmp (out); for_reading = tmp; } CORBA::ULong label; for_reading.read_ulong (label); typedef TAO::TypeCode::Case_T<CORBA::ULong, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW_THROW_EX (the_case, case_type (label), CORBA::NO_MEMORY ()); } break; case CORBA::tk_ulong: { CORBA::ULong label; if (!(member.label >>= label)) { // Should never throw since label kind was // verified earlier. throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 19, CORBA::COMPLETED_NO); } typedef TAO::TypeCode::Case_T<CORBA::ULong, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW_THROW_EX (the_case, case_type (label), CORBA::NO_MEMORY ()); } break; case CORBA::tk_long: { CORBA::Long label; if (!(member.label >>= label)) { // Should never throw since label kind was // verified earlier. throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 19, CORBA::COMPLETED_NO); } typedef TAO::TypeCode::Case_T<CORBA::Long, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW_THROW_EX (the_case, case_type (label), CORBA::NO_MEMORY ()); } break; case CORBA::tk_ushort: { CORBA::UShort label; if (!(member.label >>= label)) { // Should never throw since label kind was // verified earlier. throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 19, CORBA::COMPLETED_NO); } typedef TAO::TypeCode::Case_T<CORBA::UShort, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW_THROW_EX (the_case, case_type (label), CORBA::NO_MEMORY ()); } break; case CORBA::tk_short: { CORBA::Short label; if (!(member.label >>= label)) { // Should never throw since label kind was // verified earlier. throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 19, CORBA::COMPLETED_NO); } typedef TAO::TypeCode::Case_T<CORBA::Short, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW_THROW_EX (the_case, case_type (label), CORBA::NO_MEMORY ()); } break; case CORBA::tk_char: { CORBA::Char label; if (!(member.label >>= CORBA::Any::to_char (label))) { // Should never throw since label kind was // verified earlier. throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 19, CORBA::COMPLETED_NO); } typedef TAO::TypeCode::Case_T<CORBA::Char, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW_THROW_EX (the_case, case_type (label), CORBA::NO_MEMORY ()); } break; case CORBA::tk_boolean: { CORBA::Boolean label; if (!(member.label >>= CORBA::Any::to_boolean (label))) { // Should never throw since label kind was // verified earlier. throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 19, CORBA::COMPLETED_NO); } typedef TAO::TypeCode::Case_T<CORBA::Boolean, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW_THROW_EX (the_case, case_type (label), CORBA::NO_MEMORY ()); } break; case CORBA::tk_longlong: { CORBA::LongLong label; if (!(member.label >>= label)) { // Should never throw since label kind was // verified earlier. throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 19, CORBA::COMPLETED_NO); } typedef TAO::TypeCode::Case_T<CORBA::LongLong, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW_THROW_EX (the_case, case_type (label), CORBA::NO_MEMORY ()); } break; #if !defined (ACE_LACKS_LONGLONG_T) case CORBA::tk_ulonglong: { CORBA::ULongLong label; if (!(member.label >>= label)) { // Should never throw since label kind was // verified earlier. throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 19, CORBA::COMPLETED_NO); } typedef TAO::TypeCode::Case_T<CORBA::ULongLong, CORBA::String_var, CORBA::TypeCode_var> case_type; ACE_NEW_THROW_EX (the_case, case_type (label), CORBA::NO_MEMORY ()); } break; #endif /* !ACE_LACKS_LONGLONG_T */ default: throw ::CORBA::BAD_PARAM ( CORBA::OMGVMCID | 20, CORBA::COMPLETED_NO); } } ++ci; elem_type case_value (the_case); element.swap (case_value); // Exception-safe element->name (member.name.in ()); element->type (member.type.in ()); } // @@ Blame this on MSVC++ 6 workarounds. *sigh* CORBA::TypeCode_var duped_disc_type ( CORBA::TypeCode::_duplicate (discriminator_type)); if (is_recursive) { recursive_typecode_type * const rtc = dynamic_cast<recursive_typecode_type *> (recursive_tc.in ()); if (!rtc) { throw CORBA::INTERNAL (); } rtc->union_parameters (name, duped_disc_type, cases, // Will be copied. cases.size (), default_index); return recursive_tc._retn (); } ACE_NEW_THROW_EX (tc, typecode_type (id, name, duped_disc_type, cases, // Will be copied. cases.size (), default_index), CORBA::NO_MEMORY ()); return tc; }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_value_box_tc | ( | const char * | id, | |
const char * | name, | |||
CORBA::TypeCode_ptr | boxed_type | |||
) | [virtual] |
Definition at line 762 of file TypeCodeFactory_i.cpp.
{ return this->alias_value_box_tc_common (id, name, boxed_type, CORBA::tk_value_box); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_value_tc | ( | const char * | id, | |
const char * | name, | |||
CORBA::ValueModifier | type_modifier, | |||
CORBA::TypeCode_ptr | concrete_base, | |||
const CORBA::ValueMemberSeq & | members | |||
) | [virtual] |
Definition at line 744 of file TypeCodeFactory_i.cpp.
{ return this->value_event_tc_common (id, name, type_modifier, concrete_base, members, CORBA::tk_value ); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::create_wstring_tc | ( | CORBA::ULong | bound | ) | [virtual] |
Definition at line 705 of file TypeCodeFactory_i.cpp.
{ return this->string_wstring_tc_common (bound, CORBA::tk_wstring); }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::make_recursive_tc | ( | CORBA::TCKind | kind, | |
char const * | id | |||
) | [private] |
Make a recursive TypeCode with the given kind and repository ID.
Definition at line 1923 of file TypeCodeFactory_i.cpp.
{ CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr (); switch (kind) { case CORBA::tk_struct: ACE_NEW_THROW_EX (tc, TCF::Struct::recursive_typecode_type (kind, id), CORBA::NO_MEMORY ()); break; case CORBA::tk_union: ACE_NEW_THROW_EX (tc, TCF::Union::recursive_typecode_type (kind, id), CORBA::NO_MEMORY ()); break; case CORBA::tk_value: case CORBA::tk_event: ACE_NEW_THROW_EX (tc, TCF::Value::recursive_typecode_type (kind, id), CORBA::NO_MEMORY ()); break; default: // Should never hit this case. throw ::CORBA::INTERNAL (); } return tc; }
TAO_TypeCodeFactory_i& TAO_TypeCodeFactory_i::operator= | ( | const TAO_TypeCodeFactory_i & | src | ) | [private] |
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::sequence_array_tc_common | ( | CORBA::ULong | bound, | |
CORBA::TypeCode_ptr | element_type, | |||
CORBA::TCKind | kind | |||
) | [private] |
Code for arrays and sequences is identical except for TCKind.
Definition at line 1169 of file TypeCodeFactory_i.cpp.
{ CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr (); CORBA::Boolean const valid_element = this->valid_content_type (element_type); if (!valid_element) { throw ::CORBA::BAD_TYPECODE (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO); } CORBA::TypeCode_var tmp (CORBA::TypeCode::_duplicate (element_type)); typedef TAO::TypeCode::Sequence<CORBA::TypeCode_var, TAO::True_RefCount_Policy> typecode_type; ACE_NEW_THROW_EX (tc, typecode_type (kind, tmp, bound), CORBA::NO_MEMORY ()); return tc; }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::string_wstring_tc_common | ( | CORBA::ULong | bound, | |
CORBA::TCKind | kind | |||
) | [private] |
Code for strings and wstrings is identical except for TCKind.
Definition at line 1153 of file TypeCodeFactory_i.cpp.
{ CORBA::TypeCode_ptr tc; ACE_NEW_THROW_EX (tc, TAO::TypeCode::String<TAO::True_RefCount_Policy> (kind, bound), CORBA::NO_MEMORY ()); return tc; }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::struct_except_tc_common | ( | const char * | id, | |
const char * | name, | |||
const CORBA::StructMemberSeq & | members, | |||
CORBA::TCKind | kind | |||
) | [private] |
Code for structs and unions is identical except for TCKind.
Definition at line 1197 of file TypeCodeFactory_i.cpp.
{ CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr (); if (name == 0 || !this->valid_name (name)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO); } if (id == 0 || !this->valid_id (id)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO); } CORBA::ULong const len = members.length (); ACE_Hash_Map_Manager<ACE_CString, int, ACE_Null_Mutex> map; using namespace TCF::Struct; field_array_type fields (len); bool is_recursive = false; CORBA::TypeCode_var recursive_tc; for (CORBA::ULong index = 0; index < len; ++index) { // Valid member type? CORBA::TypeCode_ptr const member_tc = members[index].type.in (); CORBA::Boolean const valid_member = this->valid_content_type (member_tc ); if (!valid_member) { throw ::CORBA::BAD_TYPECODE ( CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO); } char const * const member_name = members[index].name; if (member_name == 0 || !this->valid_name (member_name)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO); } ACE_CString ext_id (member_name); int int_id = 0; // Is there a duplicate member name? if (map.trybind (ext_id, int_id) != 0) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 17, CORBA::COMPLETED_NO); } TAO::TypeCode::Struct_Field<CORBA::String_var, CORBA::TypeCode_var> & field = fields[index]; // Check if recursive. bool const recursion_detected = this->check_recursion (kind, id, member_tc, recursive_tc.inout (), 0); // Do not clobber previous positive detection. if (recursion_detected) { is_recursive = true; } field.name = member_name; field.type = CORBA::TypeCode::_duplicate (member_tc); } if (is_recursive) { recursive_typecode_type * const rtc = dynamic_cast<recursive_typecode_type *> (recursive_tc.in ()); if (!rtc) { throw CORBA::INTERNAL (); } rtc->struct_parameters (name, fields, len); return recursive_tc._retn (); } ACE_NEW_THROW_EX (tc, typecode_type (kind, id, name, fields, len), CORBA::NO_MEMORY ()); return tc; }
CORBA::Boolean TAO_TypeCodeFactory_i::unique_label_values | ( | const CORBA::UnionMemberSeq & | members, | |
CORBA::TypeCode_ptr | disc_tc, | |||
CORBA::ULong | default_index_slot | |||
) | [private] |
Definition at line 1550 of file TypeCodeFactory_i.cpp.
{ CORBA::TCKind disc_kind = disc_tc->kind (); CORBA::ULong length = members.length (); // We have already checked for valid discriminator type // and valid label types, so we won't check for any of that here. struct label_types { CORBA::Char char_val; CORBA::Boolean bool_val; CORBA::Short short_val; CORBA::UShort ushort_val; CORBA::Long long_val; CORBA::ULong ulong_val; CORBA::ULong enum_val; CORBA::ULongLong ulonglong_val; CORBA::LongLong longlong_val; } s = {0, 0, 0, 0, 0, 0, 0, 0, ACE_CDR_LONGLONG_INITIALIZER }; // Two cases - one for signed and one for unsigned discriminator types. if (disc_kind == CORBA::tk_long || disc_kind == CORBA::tk_short) { ACE_Bounded_Set<CORBA::Long> checker (length); for (CORBA::ULong i = 0; i < length; ++i) { if (i == default_index_slot) { continue; } switch (disc_kind) { case CORBA::tk_long: members[i].label >>= s.long_val; if (checker.insert (s.long_val) != 0) { return false; } break; case CORBA::tk_short: members[i].label >>= s.short_val; if (checker.insert (s.short_val) != 0) { return false; } break; default: break; } } } else { ACE_Bounded_Set<CORBA::ULong> checker (length); for (CORBA::ULong i = 0; i < length; ++i) { if (i == default_index_slot) { continue; } switch (disc_kind) { case CORBA::tk_boolean: members[i].label >>= CORBA::Any::to_boolean (s.bool_val); if (checker.insert (s.bool_val) != 0) { return false; } break; case CORBA::tk_char: members[i].label >>= CORBA::Any::to_char (s.char_val); if (checker.insert (s.char_val) != 0) { return false; } break; case CORBA::tk_ushort: members[i].label >>= s.ushort_val; if (checker.insert (s.ushort_val) != 0) { return false; } break; case CORBA::tk_ulong: members[i].label >>= s.ulong_val; if (checker.insert (s.ulong_val) != 0) { return false; } break; case CORBA::tk_enum: { TAO::Any_Impl *impl = members[i].label.impl (); TAO_InputCDR for_reading (static_cast<ACE_Message_Block *> (0)); if (impl->encoded ()) { TAO::Unknown_IDL_Type *unk = dynamic_cast<TAO::Unknown_IDL_Type *> (impl); if (!unk) throw CORBA::INTERNAL (); // We don't want unk's rd_ptr to move, in case // we are shared by another Any, so we use this // to copy the state, not the buffer. for_reading = unk->_tao_get_cdr (); } else { TAO_OutputCDR out; impl->marshal_value (out); TAO_InputCDR tmp (out); for_reading = tmp; } for_reading.read_ulong (s.enum_val); if (checker.insert (s.enum_val) != 0) { return false; } break; } default: break; } } } return true; }
CORBA::Boolean TAO_TypeCodeFactory_i::valid_content_type | ( | CORBA::TypeCode_ptr | tc | ) | [private] |
Definition at line 1532 of file TypeCodeFactory_i.cpp.
{ CORBA::TCKind const kind = TAO::unaliased_kind (tc); switch (kind) { case CORBA::TAO_TC_KIND_COUNT: return true; // Recursive TypeCode. case CORBA::tk_void: case CORBA::tk_except: return false; default: return true; } }
CORBA::Boolean TAO_TypeCodeFactory_i::valid_disc_type | ( | CORBA::TypeCode_ptr | tc | ) | [private] |
Definition at line 1708 of file TypeCodeFactory_i.cpp.
{ CORBA::TCKind const kind = tc->kind (); return (kind == CORBA::tk_enum || kind == CORBA::tk_ulong || kind == CORBA::tk_long || kind == CORBA::tk_ushort || kind == CORBA::tk_short || kind == CORBA::tk_char || kind == CORBA::tk_boolean || kind == CORBA::tk_longlong || kind == CORBA::tk_ulonglong); }
CORBA::Boolean TAO_TypeCodeFactory_i::valid_id | ( | const char * | id | ) | [private] |
Definition at line 1505 of file TypeCodeFactory_i.cpp.
{ ACE_CString safety (id, 0, false); ACE_CString::size_type const pos = safety.find (':'); if (pos == ACE_CString::npos) { return 0; } ACE_CString format (safety.substr (0, pos)); if (format == "IDL" || format == "RMI" || format == "DCE" || format == "LOCAL") { return true; } return false; }
CORBA::Boolean TAO_TypeCodeFactory_i::valid_name | ( | const char * | name | ) | [private] |
If any of these fail, we raise a spec-defined minor code of BAD_PARAM or BAD_TYPECODE.
Definition at line 1474 of file TypeCodeFactory_i.cpp.
{ // Empty string is valid for name. if (*name == '\0') { return true; } if (!ACE_OS::ace_isalpha (*name)) { return false; } const char *tmp = name + 1; for (; *tmp; ++tmp) { if (ACE_OS::ace_isalnum (*tmp) || *tmp == '_') { continue; } else { return false; } } return true; }
CORBA::TypeCode_ptr TAO_TypeCodeFactory_i::value_event_tc_common | ( | const char * | id, | |
const char * | name, | |||
CORBA::ValueModifier | type_modifier, | |||
CORBA::TypeCode_ptr | concrete_base, | |||
const CORBA::ValueMemberSeq & | members, | |||
CORBA::TCKind | kind | |||
) | [private] |
Definition at line 1350 of file TypeCodeFactory_i.cpp.
{ CORBA::TypeCode_ptr tc = CORBA::TypeCode_ptr (); if (name == 0 || !this->valid_name (name)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO); } if (id == 0 || !this->valid_id (id)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 16, CORBA::COMPLETED_NO); } CORBA::ULong const len = members.length (); using namespace TCF::Value; field_array_type fields (len); ACE_Hash_Map_Manager<ACE_CString, int, ACE_Null_Mutex> map; bool is_recursive = false; CORBA::TypeCode_var recursive_tc; for (CORBA::ULong index = 0; index < len; ++index) { // Valid member type? CORBA::TypeCode_ptr const member_tc = members[index].type.in (); CORBA::Boolean const valid_member = this->valid_content_type (member_tc); if (!valid_member) { throw ::CORBA::BAD_TYPECODE ( CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO); } const char * const member_name = members[index].name; if (member_name == 0 || !this->valid_name (member_name)) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 15, CORBA::COMPLETED_NO); } ACE_CString ext_id (member_name); int int_id = 0; // Is there a duplicate member name? if (map.trybind (ext_id, int_id) != 0) { throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 17, CORBA::COMPLETED_NO); } // Check if recursive. bool const recursion_detected = this->check_recursion (kind, id, member_tc, recursive_tc.inout (), 0); // Do not clobber previous positive detection. if (recursion_detected) { is_recursive = true; } TAO::TypeCode::Value_Field<CORBA::String_var, CORBA::TypeCode_var> & field = fields[index]; field.name = member_name; field.type = CORBA::TypeCode::_duplicate (member_tc); field.visibility = members[index].access; } CORBA::TypeCode_var tmp ( CORBA::TypeCode::_duplicate (CORBA::is_nil (concrete_base) ? CORBA::_tc_null : concrete_base)); if (is_recursive) { recursive_typecode_type * const rtc = dynamic_cast<recursive_typecode_type *> (recursive_tc.in ()); if (!rtc) { throw CORBA::INTERNAL (); } rtc->valuetype_parameters (name, type_modifier, tmp, fields, len); return recursive_tc._retn (); } ACE_NEW_THROW_EX (tc, typecode_type (kind, id, name, type_modifier, tmp, fields, len), CORBA::NO_MEMORY ()); return tc; }