#include "tao/Connector_Registry.h" #include "tao/ORB_Core.h" #include "tao/Profile.h" #include "tao/Transport_Connector.h" #include "tao/Protocol_Factory.h" #include "tao/debug.h" #include "tao/ORB_Constants.h" #include "tao/CDR.h" #include "tao/SystemException.h" #include "ace/Auto_Ptr.h" #if !defined(__ACE_INLINE__) #include "tao/Connector_Registry.inl" #endif /* __ACE_INLINE__ */ TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_Connector_Registry::TAO_Connector_Registry () : connectors_ (nullptr), size_ (0) { } TAO_Connector_Registry::~TAO_Connector_Registry () { this->close_all (); delete [] this->connectors_; } TAO_Connector * TAO_Connector_Registry::get_connector (CORBA::ULong tag) const { const TAO_ConnectorSetIterator end = this->end (); for (TAO_ConnectorSetIterator connector = this->begin (); connector != end; ++connector) { if ((*connector)->tag () == tag) return *connector; } return nullptr; } int TAO_Connector_Registry::open (TAO_ORB_Core *orb_core) { TAO_ProtocolFactorySet * const pfs = orb_core->protocol_factories (); // The array containing the TAO_Connectors will never contain more // than the number of loaded protocols in the ORB core. if (this->connectors_ == nullptr) ACE_NEW_RETURN (this->connectors_, TAO_Connector *[pfs->size ()], -1); // Open one connector for each loaded protocol! const TAO_ProtocolFactorySetItor end = pfs->end (); for (TAO_ProtocolFactorySetItor factory = pfs->begin (); factory != end; ++factory) { std::unique_ptr connector ((*factory)->factory ()->make_connector ()); if (connector.get ()) { if (connector->open (orb_core) != 0) { TAOLIB_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - TAO_Connector_Registry") ACE_TEXT ("::open: unable to open connector for ") ACE_TEXT ("<%C>.\n"), (*factory)->protocol_name ().c_str ()), -1); } this->connectors_[this->size_++] = connector.release (); } else return -1; } return 0; } int TAO_Connector_Registry::close_all () { const TAO_ConnectorSetIterator end = this->end (); for (TAO_ConnectorSetIterator i = this->begin (); i != end; ++i) { if (*i == nullptr) continue; (*i)->close (); delete *i; } this->size_ = 0; return 0; } int TAO_Connector_Registry::make_mprofile (const char *ior, TAO_MProfile &mprofile) { if (!ior) // Failure: Null IOR string pointer throw ::CORBA::INV_OBJREF ( CORBA::SystemException::_tao_minor_code ( 0, EINVAL), CORBA::COMPLETED_NO); const TAO_ConnectorSetIterator first_connector = this->begin (); const TAO_ConnectorSetIterator last_connector = this->end (); for (TAO_ConnectorSetIterator connector = first_connector; connector != last_connector; ++connector) { if (*connector) { const int mp_result = (*connector)->make_mprofile (ior, mprofile); if (mp_result == 0) return 0; // Success } else // Failure: Null pointer to connector in connector registry. throw ::CORBA::INV_OBJREF ( CORBA::SystemException::_tao_minor_code ( 0, EINVAL), CORBA::COMPLETED_NO); } // Failure: None of the connectors were able to parse the URL style // IOR into an MProfile. throw ::CORBA::INV_OBJREF ( CORBA::SystemException::_tao_minor_code ( TAO_CONNECTOR_REGISTRY_NO_USABLE_PROTOCOL, 0), CORBA::COMPLETED_NO); } TAO_Profile * TAO_Connector_Registry::create_profile (TAO_InputCDR &cdr) { CORBA::ULong tag = 0; // If there is an error we abort. if (!(cdr >> tag)) { TAOLIB_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - TAO_Connector_Registry::") ACE_TEXT ("create_profile: Unable to extract tag from CDR stream\n"))); return nullptr; } TAO_Connector *connector = this->get_connector (tag); if (connector == nullptr) { if (TAO_debug_level > 0) { TAOLIB_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - TAO_Connector_Registry::") ACE_TEXT ("create_profile: Unknown profile tag <0x%x>\n"), tag)); } TAO_ORB_Core *orb_core = cdr.orb_core (); if (orb_core == nullptr) { orb_core = TAO_ORB_Core_instance (); if (TAO_debug_level > 0) { TAOLIB_DEBUG ((LM_WARNING, ACE_TEXT ("TAO (%P|%t) - TAO_Connector_Registry") ACE_TEXT ("::create_profile: ") ACE_TEXT ("WARNING: extracting object from ") ACE_TEXT ("default ORB_Core\n"))); } } TAO_Profile *pfile = nullptr; ACE_NEW_RETURN (pfile, TAO_Unknown_Profile (tag, orb_core), nullptr); if (pfile->decode (cdr) == -1) { TAOLIB_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - TAO_Connector_Registry::") ACE_TEXT ("create_profile: Unable to decode unknown profile from CDR stream\n"))); pfile->_decr_refcnt (); pfile = nullptr; } return pfile; } // OK, we've got a known profile. It's going to be encapsulated // ProfileData. Create a new decoding stream and context for it, // and skip the data in the parent stream // ProfileData is encoded as a sequence of octet. So first get the // length of the sequence. CORBA::ULong encap_len = 0; if (!(cdr >> encap_len)) { TAOLIB_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - TAO_Connector_Registry::") ACE_TEXT ("create_profile: Unable to extract encapsulated length from CDR stream\n"))); return nullptr; } // Create the decoding stream from the encapsulation in the buffer, // and skip the encapsulation. TAO_InputCDR str (cdr, encap_len); if (!str.good_bit () || !cdr.skip_bytes (encap_len)) { TAOLIB_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - TAO_Connector_Registry::") ACE_TEXT ("create_profile: Unable to skip encapsulated stream from CDR stream\n"))); return nullptr; } TAO_Profile* profile = connector->create_profile (str); if (!profile) { TAOLIB_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - TAO_Connector_Registry::") ACE_TEXT ("create_profile: Connector returned null profile for tag <0x%x>\n"), tag)); } return profile; } char TAO_Connector_Registry::object_key_delimiter (const char *ior) { if (!ior) { errno = EINVAL; return 0; // Failure: Null IOR string pointer } const TAO_ConnectorSetIterator first_connector = this->begin (); const TAO_ConnectorSetIterator last_connector = this->end (); for (TAO_ConnectorSetIterator connector = first_connector; connector != last_connector; ++connector) { if (*connector) { if ((*connector)->check_prefix (ior) == 0) return (*connector)->object_key_delimiter (); } } // Failure: None of the connectors were able to match their protocol // against the provided string. return 0; } TAO_END_VERSIONED_NAMESPACE_DECL