// $Id$ #ifndef TAO_STRUCT_TYPECODE_CPP #define TAO_STRUCT_TYPECODE_CPP #include "tao/AnyTypeCode/Struct_TypeCode.h" #include "tao/AnyTypeCode/TypeCode_Struct_Field.h" #include "tao/AnyTypeCode/TypeCode_Traits.h" #include "tao/ORB_Core.h" #include "tao/TypeCodeFactory_Adapter.h" #include "tao/CDR.h" #ifndef __ACE_INLINE__ # include "tao/AnyTypeCode/Struct_TypeCode.inl" #endif /* !__ACE_INLINE__ */ #include "ace/Dynamic_Service.h" TAO_BEGIN_VERSIONED_NAMESPACE_DECL template bool TAO::TypeCode::Struct::tao_marshal (TAO_OutputCDR & cdr, CORBA::ULong offset) const { // A tk_struct TypeCode has a "complex" parameter list type (see // Table 15-2 in Section 15.3.5.1 "TypeCode" in the CDR section of // the CORBA specification), meaning that it must be marshaled into // a CDR encapsulation. // Create a CDR encapsulation. TAO_OutputCDR enc; // Account for the encoded CDR encapsulation length and byte order. // // Aligning on an octet since the next value after the CDR // encapsulation length will always be the byte order octet/boolean // in this case. offset = ACE_align_binary (offset + 4, ACE_CDR::OCTET_ALIGN); bool const success = (enc << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) && (enc << TAO_OutputCDR::from_string (this->base_attributes_.id (), 0)) && (enc << TAO_OutputCDR::from_string (this->base_attributes_.name (), 0)) && (enc << this->nfields_); if (!success) return false; Struct_Field const * const begin = &this->fields_[0]; Struct_Field const * const end = begin + this->nfields_; for (Struct_Field const * i = begin; i != end; ++i) { Struct_Field const & field = *i; if (!(enc << TAO_OutputCDR::from_string ( Traits::get_string (field.name), 0)) || !marshal (enc, Traits::get_typecode (field.type), offset + enc.total_length ())) return false; } return cdr << static_cast (enc.total_length ()) && cdr.write_octet_array_mb (enc.begin ()); } template void TAO::TypeCode::Struct::tao_duplicate (void) { this->RefCountPolicy::add_ref (); } template void TAO::TypeCode::Struct::tao_release (void) { this->RefCountPolicy::remove_ref (); } template CORBA::Boolean TAO::TypeCode::Struct::equal_i ( CORBA::TypeCode_ptr tc ) const { // This call shouldn't throw since CORBA::TypeCode::equal() verified // that the TCKind is the same as our's prior to invoking this // method, meaning that member_count() is supported. CORBA::ULong const tc_nfields = tc->member_count (); if (tc_nfields != this->nfields_) return false; for (CORBA::ULong i = 0; i < this->nfields_; ++i) { Struct_Field const & lhs_field = this->fields_[i]; char const * const lhs_name = Traits::get_string (lhs_field.name); char const * const rhs_name = tc->member_name (i ); if (ACE_OS::strcmp (lhs_name, rhs_name) != 0) return false; CORBA::TypeCode_ptr const lhs_tc = Traits::get_typecode (lhs_field.type); CORBA::TypeCode_var const rhs_tc = tc->member_type (i ); CORBA::Boolean const equal_members = lhs_tc->equal (rhs_tc.in () ); if (!equal_members) return false; } return true; } template CORBA::Boolean TAO::TypeCode::Struct::equivalent_i ( CORBA::TypeCode_ptr tc ) const { // Perform a structural comparison, excluding the name() and // member_name() operations. CORBA::ULong const tc_nfields = tc->member_count (); if (tc_nfields != this->nfields_) return false; for (CORBA::ULong i = 0; i < this->nfields_; ++i) { CORBA::TypeCode_ptr const lhs = Traits::get_typecode (this->fields_[i].type); CORBA::TypeCode_var const rhs = tc->member_type (i ); CORBA::Boolean const equiv_members = lhs->equivalent (rhs.in () ); if (!equiv_members) return false; } return true; } template CORBA::TypeCode_ptr TAO::TypeCode::Struct::get_compact_typecode_i ( void) const { ACE_Array_Base > tc_fields (this->nfields_); if (this->nfields_ > 0) { // Dynamically construct a new array of fields stripped of // member names. static char const empty_name[] = ""; for (CORBA::ULong i = 0; i < this->nfields_; ++i) { // Member names will be stripped, i.e. not embedded within // the compact TypeCode. tc_fields[i].name = empty_name; tc_fields[i].type = Traits::get_typecode ( this->fields_[i].type)->get_compact_typecode ( ); } } TAO_TypeCodeFactory_Adapter * const adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { ACE_THROW_RETURN (CORBA::INTERNAL (), CORBA::TypeCode::_nil ()); } return adapter->create_struct_except_tc (this->kind_, this->base_attributes_.id (), "" /* empty name */, tc_fields, this->nfields_ ); } template char const * TAO::TypeCode::Struct::id_i ( void) const { // Ownership is retained by the TypeCode, as required by the C++ // mapping. return this->base_attributes_.id (); } template char const * TAO::TypeCode::Struct::name_i ( void) const { // Ownership is retained by the TypeCode, as required by the C++ // mapping. return this->base_attributes_.name (); } template CORBA::ULong TAO::TypeCode::Struct::member_count_i ( void) const { return this->nfields_; } template char const * TAO::TypeCode::Struct::member_name_i ( CORBA::ULong index ) const { // Ownership is retained by the TypeCode, as required by the C++ // mapping. if (index >= this->nfields_) ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), 0); return Traits::get_string (this->fields_[index].name); } template CORBA::TypeCode_ptr TAO::TypeCode::Struct::member_type_i ( CORBA::ULong index ) const { if (index >= this->nfields_) ACE_THROW_RETURN (CORBA::TypeCode::Bounds (), CORBA::TypeCode::_nil ()); return CORBA::TypeCode::_duplicate ( Traits::get_typecode (this->fields_[index].type)); } TAO_END_VERSIONED_NAMESPACE_DECL #endif /* TAO_STRUCT_TYPECODE_CPP */