summaryrefslogtreecommitdiff
path: root/TAO/tao/Profile.cpp
diff options
context:
space:
mode:
authorWilliam R. Otte <wotte@dre.vanderbilt.edu>2006-07-24 15:50:21 +0000
committerWilliam R. Otte <wotte@dre.vanderbilt.edu>2006-07-24 15:50:21 +0000
commit3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c (patch)
tree197c810e5f5bce17b1233a7cb8d7b50c0bcd25e2 /TAO/tao/Profile.cpp
parent6b846cf03c0bcbd8c276cb0af61a181e5f98eaae (diff)
downloadATCD-3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c.tar.gz
Repo restructuring
Diffstat (limited to 'TAO/tao/Profile.cpp')
-rw-r--r--TAO/tao/Profile.cpp977
1 files changed, 977 insertions, 0 deletions
diff --git a/TAO/tao/Profile.cpp b/TAO/tao/Profile.cpp
new file mode 100644
index 00000000000..4485d84c13d
--- /dev/null
+++ b/TAO/tao/Profile.cpp
@@ -0,0 +1,977 @@
+// $Id$
+
+#include "tao/Profile.h"
+#include "tao/Messaging_PolicyValueC.h"
+#include "tao/Stub.h"
+#include "tao/debug.h"
+#include "tao/target_specification.h"
+#include "tao/ORB_Core.h"
+#include "tao/Client_Strategy_Factory.h"
+#include "tao/CDR.h"
+#include "tao/SystemException.h"
+#include "tao/PolicyC.h"
+#include "tao/Endpoint.h"
+
+#include "ace/ACE.h"
+#include "ace/OS_NS_string.h"
+#include "ace/os_include/os_ctype.h"
+
+#if !defined (__ACE_INLINE__)
+#include "tao/Profile.i"
+#endif /* __ACE_INLINE__ */
+
+
+ACE_RCSID (tao,
+ Profile,
+ "$Id$")
+
+// ****************************************************************
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_Profile::TAO_Profile (CORBA::ULong tag,
+ TAO_ORB_Core *orb_core,
+ const TAO::ObjectKey &obj_key,
+ const TAO_GIOP_Message_Version &version)
+ : version_ (version)
+ , are_policies_parsed_ (false)
+ , addressing_mode_ (0)
+ , tagged_profile_ (0)
+ , ref_object_key_ (0)
+ , tag_ (tag)
+ , orb_core_ (orb_core)
+ , forward_to_ (0)
+ , refcount_ (this->orb_core_->
+ client_factory ()->create_profile_refcount ())
+{
+ (void) this->orb_core_->object_key_table ().bind (obj_key,
+ this->ref_object_key_);
+}
+
+TAO_Profile::TAO_Profile (CORBA::ULong tag,
+ TAO_ORB_Core *orb_core,
+ const TAO_GIOP_Message_Version &version)
+ : version_ (version)
+ , are_policies_parsed_ (false)
+ , addressing_mode_ (0)
+ , tagged_profile_ (0)
+ , ref_object_key_ (0)
+ , tag_ (tag)
+ , orb_core_ (orb_core)
+ , forward_to_ (0)
+ , refcount_ (this->orb_core_->
+ client_factory ()->create_profile_refcount ())
+{
+}
+
+TAO_Profile::~TAO_Profile (void)
+{
+ if (this->tagged_profile_)
+ {
+ delete this->tagged_profile_;
+ }
+
+ this->orb_core_->object_key_table ().unbind (this->ref_object_key_);
+
+ //@@ TAO_PROFILE_SPL_DESTRUCTOR_ADD_HOOK
+}
+
+unsigned long
+TAO_Profile::_incr_refcnt (void)
+{
+ return this->refcount_.increment ();
+}
+
+unsigned long
+TAO_Profile::_decr_refcnt (void)
+{
+ unsigned long count = this->refcount_.decrement ();
+ if (count != 0)
+ return count;
+
+ // refcount is 0, so delete us!
+ // delete will call our ~ destructor which in turn deletes stuff.
+ delete this;
+ return 0;
+}
+
+void
+TAO_Profile::add_tagged_component (const IOP::TaggedComponent &component
+ ACE_ENV_ARG_DECL)
+{
+ // Sanity checks.
+ this->verify_orb_configuration (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ this->verify_profile_version (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // ----------------------------------------------------------------
+
+ // Add the given tagged component to this profile.
+ //
+ // Note that multiple tagged profiles with the same tag value may be
+ // added, unless the tagged component is known to be unique by TAO.
+ this->tagged_components_.set_component (component);
+}
+
+TAO::ObjectKey *
+TAO_Profile::_key (void) const
+{
+ TAO::ObjectKey *key = 0;
+
+ if (this->ref_object_key_)
+ {
+ ACE_NEW_RETURN (key,
+ TAO::ObjectKey (this->ref_object_key_->object_key ()),
+ 0);
+ }
+ return key;
+}
+
+
+int
+TAO_Profile::encode (TAO_OutputCDR &stream) const
+{
+ // UNSIGNED LONG, protocol tag
+ stream.write_ulong (this->tag_);
+
+ // Create the encapsulation....
+ TAO_OutputCDR encap (ACE_CDR::DEFAULT_BUFSIZE,
+ TAO_ENCAP_BYTE_ORDER,
+ this->orb_core ()->output_cdr_buffer_allocator (),
+ this->orb_core ()->output_cdr_dblock_allocator (),
+ this->orb_core ()->output_cdr_msgblock_allocator (),
+ this->orb_core ()->orb_params ()->cdr_memcpy_tradeoff (),
+ TAO_DEF_GIOP_MAJOR,
+ TAO_DEF_GIOP_MINOR);
+
+ // Create the profile body
+ this->create_profile_body (encap);
+
+ // write the encapsulation as an octet sequence...
+ stream << CORBA::ULong (encap.total_length ());
+ stream.write_octet_array_mb (encap.begin ());
+
+ return 1;
+}
+
+int
+TAO_Profile::decode (TAO_InputCDR& cdr)
+{
+ size_t const encap_len = cdr.length ();
+
+ // Read and verify major, minor versions, ignoring profiles
+ // whose versions we don't understand.
+ if (!(cdr.read_octet (this->version_.major)
+ && this->version_.major == TAO_DEF_GIOP_MAJOR
+ && cdr.read_octet (this->version_.minor)
+ && this->version_.minor <= TAO_DEF_GIOP_MINOR))
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO (%P|%t) - Profile::decode - v%d.%d\n"),
+ this->version_.major,
+ this->version_.minor));
+ }
+
+ return -1;
+ }
+
+ // Transport specific details
+ if (this->decode_profile (cdr) < 0)
+ {
+ return -1;
+ }
+
+ // @@NOTE: This place *may* need strategizing. Here are the
+ // issues. Placing the ObjectKey in the table adds an allocation and
+ // a lock while decoding. This is bad for some cases especially if
+ // the application is marshalling object references across to the
+ // server end. But the server could use "lazy" evaluation and avoid
+ // this during marshalling.
+ //
+ // The only place this will get important is when a thead tries to
+ // use the object reference to create a CORBA object to make an
+ // invocation. Since creation of a CORBA object itself is expensive,
+ // it looks like we may not need to worry much.
+ //
+ // Remember strategizing needs reconciliation of forces imposed
+ // by runtime memory growth. Doing a random strategization would
+ // destroy the wins in runtime memory growth got by using this
+ // table scheme.
+ TAO::ObjectKey ok;
+
+ // ... and object key.
+ if (TAO::ObjectKey::demarshal_key (ok,
+ cdr) == 0)
+ {
+ return -1;
+ }
+
+ TAO::ObjectKey_Table &okt = this->orb_core ()->object_key_table ();
+
+ if (okt.bind (ok, this->ref_object_key_) == -1)
+ {
+ return -1;
+ }
+
+ // Tagged Components *only* exist after version 1.0!
+ // For GIOP 1.2, IIOP and GIOP have same version numbers!
+ if (this->version_.major > 1
+ || this->version_.minor > 0)
+ {
+ if (this->tagged_components_.decode (cdr) == 0)
+ {
+ return -1;
+ }
+ }
+
+ if (cdr.length () != 0 && TAO_debug_level)
+ {
+ // If there is extra data in the profile we are supposed to
+ // ignore it, but print a warning just in case...
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("%d bytes out of %d left after profile data\n"),
+ cdr.length (),
+ encap_len));
+ }
+
+ // Decode any additional endpoints per profile. This is used by RTCORBA
+ // and by IIOP when TAG_ALTERNATE_IIOP_ADDRESS components are present.
+ if (this->decode_endpoints () == -1)
+ {
+ return -1;
+ }
+
+ return 1;
+}
+
+IOP::TaggedProfile *
+TAO_Profile::create_tagged_profile (void)
+{
+ if (this->tagged_profile_ == 0)
+ {
+ ACE_NEW_RETURN (this->tagged_profile_,
+ IOP::TaggedProfile,
+ 0);
+
+ // As we have not created we will now create the TaggedProfile
+ this->tagged_profile_->tag = this->tag_;
+
+ // Create the encapsulation....
+ TAO_OutputCDR encap (ACE_DEFAULT_CDR_BUFSIZE,
+ TAO_ENCAP_BYTE_ORDER,
+ this->orb_core ()->output_cdr_buffer_allocator (),
+ this->orb_core ()->output_cdr_dblock_allocator (),
+ this->orb_core ()->output_cdr_msgblock_allocator (),
+ this->orb_core ()->orb_params ()->cdr_memcpy_tradeoff (),
+ TAO_DEF_GIOP_MAJOR,
+ TAO_DEF_GIOP_MINOR);
+
+ // Create the profile body
+ this->create_profile_body (encap);
+
+ CORBA::ULong const length =
+ static_cast <CORBA::ULong> (encap.total_length ());
+
+#if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
+ // Place the message block in to the Sequence of Octets that we
+ // have
+ this->tagged_profile_->profile_data.replace (length,
+ encap.begin ());
+#else
+ this->tagged_profile_->profile_data.length (length);
+ CORBA::Octet *buffer =
+ this->tagged_profile_->profile_data.get_buffer ();
+
+ for (const ACE_Message_Block *i = encap.begin ();
+ i != encap.end ();
+ i = i->next ())
+ {
+ ACE_OS::memcpy (buffer, i->rd_ptr (), i->length ());
+ buffer += i->length ();
+ }
+#endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
+ }
+
+ return this->tagged_profile_;
+}
+
+void
+TAO_Profile::set_tagged_components (TAO_OutputCDR &out_cdr)
+{
+ CORBA::ULong const length = static_cast <CORBA::ULong> (out_cdr.total_length ());
+
+ IOP::TaggedComponent tagged_component;
+ tagged_component.tag = TAO_TAG_ENDPOINTS;
+ tagged_component.component_data.length (length);
+ CORBA::Octet *buf =
+ tagged_component.component_data.get_buffer ();
+
+ for (const ACE_Message_Block *iterator = out_cdr.begin ();
+ iterator != 0;
+ iterator = iterator->cont ())
+ {
+ size_t const i_length = iterator->length ();
+ ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
+
+ buf += i_length;
+ }
+
+ // Add component with encoded endpoint data to this profile's
+ // TaggedComponents.
+ tagged_components_.set_component (tagged_component);
+}
+
+
+void
+TAO_Profile::policies (CORBA::PolicyList *policy_list
+ ACE_ENV_ARG_DECL)
+{
+#if (TAO_HAS_CORBA_MESSAGING == 1)
+
+ if (policy_list == 0)
+ {
+ if (TAO_debug_level)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("TAO_Profile::policies: ")
+ ACE_TEXT ("Null Policy List!\n")));
+ }
+
+ return;
+ }
+
+ Messaging::PolicyValue pv;
+ Messaging::PolicyValueSeq policy_value_seq;
+
+ size_t length;
+ CORBA::Octet *buf = 0;
+
+ policy_value_seq.length (policy_list->length ());
+
+ // This loop iterates through CORBA::PolicyList to convert
+ // each CORBA::Policy into a CORBA::PolicyValue
+ const size_t plen = policy_list->length ();
+
+ for (CORBA::ULong i = 0; i < plen; ++i)
+ {
+ TAO_OutputCDR out_CDR;
+ policy_value_seq[i].ptype =
+ (*policy_list)[i]->policy_type (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ out_CDR << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER);
+ (*policy_list)[i]->_tao_encode (out_CDR);
+
+ length = out_CDR.total_length ();
+ policy_value_seq[i].pvalue.length (static_cast <CORBA::ULong>(length));
+
+ buf = policy_value_seq[i].pvalue.get_buffer ();
+
+ // Copy the CDR buffer data into the octet sequence buffer.
+
+ for (const ACE_Message_Block *iterator = out_CDR.begin ();
+ iterator != 0;
+ iterator = iterator->cont ())
+ {
+ ACE_OS::memcpy (buf, iterator->rd_ptr (), iterator->length ());
+ buf += iterator->length ();
+ }
+ }
+
+ TAO_OutputCDR out_cdr;
+ // Now we have to embed the Messaging::PolicyValueSeq into
+ // a TaggedComponent.
+
+ IOP::TaggedComponent tagged_component;
+ tagged_component.tag = Messaging::TAG_POLICIES;
+
+ out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER);
+ out_cdr << policy_value_seq;
+
+ length = out_cdr.total_length ();
+
+ tagged_component.component_data.length (static_cast <CORBA::ULong>(length));
+ buf = tagged_component.component_data.get_buffer ();
+
+ for (const ACE_Message_Block *iterator = out_cdr.begin ();
+ iterator != 0;
+ iterator = iterator->cont ())
+ {
+ size_t const i_length = iterator->length ();
+ ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
+
+ buf += i_length;
+ }
+
+ // Eventually we add the TaggedComponent to the TAO_TaggedComponents
+ // member variable.
+ tagged_components_.set_component (tagged_component);
+ this->are_policies_parsed_ = true;
+
+#else /* TAO_HAS_CORBA_MESSAGING == 1 */
+
+ ACE_UNUSED_ARG (policy_list);
+ ACE_ENV_ARG_NOT_USED; // FUZZ: ignore check_for_ace_check
+
+#endif /* TAO_HAS_CORBA_MESSAGING == 1 */
+}
+
+
+
+void
+TAO_Profile::get_policies (CORBA::PolicyList& pl
+ ACE_ENV_ARG_DECL)
+{
+#if (TAO_HAS_CORBA_MESSAGING == 1) && !defined (CORBA_E_MICRO)
+
+ if (!this->are_policies_parsed_)
+ // None has already parsed the policies.
+ {
+ IOP::TaggedComponent tagged_component;
+ tagged_component.tag = Messaging::TAG_POLICIES;
+
+ // This gets a component with the proper "tag" field
+ // if it exists.
+ if (this->tagged_components_.get_component (tagged_component))
+ {
+ const CORBA::Octet *buf =
+ tagged_component.component_data.get_buffer ();
+
+ TAO_InputCDR in_cdr (reinterpret_cast <const char *> (buf),
+ tagged_component.component_data.length ());
+
+ // Extract the Byte Order
+ CORBA::Boolean byte_order;
+
+ if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
+ {
+ return ;
+ }
+
+ in_cdr.reset_byte_order (static_cast <int> (byte_order));
+
+ // Now we take out the Messaging::PolicyValueSeq out from the
+ // CDR.
+ Messaging::PolicyValueSeq policy_value_seq;
+
+ if (!(in_cdr >> policy_value_seq))
+ {
+ ACE_THROW (CORBA::INV_OBJREF ());
+ }
+
+ // Here we extract the Messaging::PolicyValue out of the sequence
+ // and we convert those into the proper CORBA::Policy
+
+ CORBA::Policy_var policy;
+ CORBA::ULong const length = policy_value_seq.length ();
+
+ // Set the policy list length.
+ pl.length (length);
+
+ for (CORBA::ULong i = 0; i < length; ++i)
+ {
+ ACE_TRY_NEW_ENV
+ {
+ policy =
+ this->orb_core_->orb ()->_create_policy (
+ policy_value_seq[i].ptype
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ if (!CORBA::is_nil (policy.in ()))
+ {
+ buf = policy_value_seq[i].pvalue.get_buffer ();
+
+ TAO_InputCDR in_cdr (
+ reinterpret_cast <const char*> (buf),
+ policy_value_seq[i].pvalue.length ());
+
+ if (!(in_cdr >> ACE_InputCDR::to_boolean (byte_order)))
+ ACE_TRY_THROW (CORBA::INV_OBJREF ());
+
+ in_cdr.reset_byte_order (static_cast <int> (byte_order));
+
+ policy->_tao_decode (in_cdr);
+ pl[i] = policy._retn ();
+ }
+ else
+ {
+ // This case should occure when in the IOR are
+ // embedded policies that TAO doesn't support,
+ // so as specified by the RT-CORBA
+ // spec. ptc/99-05-03 we just ignore these
+ // un-understood policies.
+
+ if (TAO_debug_level >= 5)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("The IOR contains unsupported ")
+ ACE_TEXT ("policies.\n")));
+ }
+ }
+ ACE_CATCHANY
+ {
+ // This case should occur when in the IOR are
+ // embedded policies that TAO doesn't support, so as
+ // specified by the RT-CORBA spec. ptc/99-05-03 we
+ // just ignore these un-understood policies.
+
+ if (TAO_debug_level >= 5)
+ ACE_PRINT_EXCEPTION(ACE_ANY_EXCEPTION,
+ ACE_TEXT ("IOR contains ")
+ ACE_TEXT ("unsupported policies."));
+ }
+ ACE_ENDTRY;
+ }
+ }
+ }
+
+#else
+ ACE_UNUSED_ARG (pl);
+ ACE_ENV_ARG_NOT_USED; // FUZZ: ignore check_for_ace_check
+#endif /* (TAO_HAS_CORBA_MESSAGING == 1) */
+
+}
+
+
+void
+TAO_Profile::verify_orb_configuration (ACE_ENV_SINGLE_ARG_DECL)
+{
+ // If the ORB isn't configured to support tagged components, then
+ // throw an exception.
+ if (this->orb_core_->orb_params ()->std_profile_components () == 0
+ || !this->orb_core_->orb ()->_use_omg_ior_format ())
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Cannot add ")
+ ACE_TEXT ("IOP::TaggedComponent to profile.\n")
+ ACE_TEXT ("(%P|%t) Standard profile components ")
+ ACE_TEXT ("have been disabled or URL style IORs\n")
+ ACE_TEXT ("(%P|%t) are in use. Try ")
+ ACE_TEXT ("\"-ORBStdProfileComponents 1\" and/or\n")
+ ACE_TEXT ("(%P|%t) \"-ORBObjRefStyle IOR\".\n")));
+ }
+
+ // According to the Portable Interceptor specification, we're
+ // supposed to throw a CORBA::BAD_PARAM exception if it isn't
+ // possible to add components to the profile.
+ // @todo: We need the proper minor code as soon as the spec is
+ // updated.
+ ACE_THROW (CORBA::BAD_PARAM (
+ CORBA::SystemException::_tao_minor_code (
+ 0,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+}
+
+void
+TAO_Profile::verify_profile_version (ACE_ENV_SINGLE_ARG_DECL)
+{
+ // GIOP 1.0 does not support tagged components. Throw an exception
+ // if the profile is a GIOP 1.0 profile.
+
+ if (this->version_.major == 1 && this->version_.minor == 0)
+ {
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("(%P|%t) Cannot add ")
+ ACE_TEXT ("IOP::TaggedComponent to GIOP 1.0")
+ ACE_TEXT ("IOR profile.\n")
+ ACE_TEXT ("(%P|%t) Try using a GIOP 1.1 or ")
+ ACE_TEXT ("greater endpoint.\n")));
+ }
+
+ // According to the Portable Interceptor specification, we're
+ // supposed to throw a CORBA::BAD_PARAM exception if it isn't
+ // possible to add components to the profile.
+ // @todo: We need the proper minor code as soon as the spec is
+ // updated.
+ ACE_THROW (CORBA::BAD_PARAM (
+ CORBA::SystemException::_tao_minor_code (
+ 0,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+}
+
+int
+TAO_Profile::supports_multicast (void) const
+{
+ // Most profiles do not support multicast endpoints.
+ return 0;
+}
+
+bool
+TAO_Profile::supports_non_blocking_oneways (void) const
+{
+ return !(this->version_.major == 1 && this->version_.minor == 0);
+}
+
+void
+TAO_Profile::addressing_mode (CORBA::Short addr
+ ACE_ENV_ARG_DECL)
+{
+ // ** See race condition note about addressing mode in Profile.h **
+ switch (addr)
+ {
+ case TAO_Target_Specification::Key_Addr:
+ case TAO_Target_Specification::Profile_Addr:
+ case TAO_Target_Specification::Reference_Addr:
+ this->addressing_mode_ = addr;
+ break;
+
+ default:
+ ACE_THROW (CORBA::BAD_PARAM (
+ CORBA::SystemException::_tao_minor_code (
+ 0,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+}
+
+void
+TAO_Profile::parse_string (const char *ior
+ ACE_ENV_ARG_DECL)
+{
+ if (!ior || !*ior)
+ {
+ ACE_THROW (CORBA::INV_OBJREF (
+ CORBA::SystemException::_tao_minor_code (
+ 0,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+
+ // Remove the "N.n@" version prefix, if it exists, and verify the
+ // version is one that we accept.
+
+ // Check for version
+ if (isdigit (ior [0]) &&
+ ior[1] == '.' &&
+ isdigit (ior [2]) &&
+ ior[3] == '@')
+ {
+ // @@ This may fail for non-ascii character sets [but take that
+ // with a grain of salt]
+ this->version_.set_version ((char) (ior[0] - '0'),
+ (char) (ior[2] - '0'));
+ ior += 4;
+ // Skip over the "N.n@"
+ }
+ else
+ {
+ // CORBA spec requires 1.0 if a version isn't specified.
+ this->version_.set_version (1, 0);
+ }
+
+ if (this->version_.major != TAO_DEF_GIOP_MAJOR ||
+ this->version_.minor > TAO_DEF_GIOP_MINOR)
+ {
+ ACE_THROW (CORBA::INV_OBJREF (
+ CORBA::SystemException::_tao_minor_code (
+ 0,
+ EINVAL),
+ CORBA::COMPLETED_NO));
+ }
+
+ this->parse_string_i (ior
+ ACE_ENV_ARG_PARAMETER);
+}
+
+CORBA::Boolean
+TAO_Profile::is_equivalent (const TAO_Profile *other)
+{
+ CORBA::Boolean result = false;
+ if (other)
+ {
+ TAO_Service_Callbacks::Profile_Equivalence callback
+ = this->is_equivalent_hook (other);
+ switch (callback)
+ {
+ case TAO_Service_Callbacks::DONT_KNOW:
+ return this->tag () == other->tag ()
+ && this->version_ == other->version ()
+ && this->endpoint_count () == other->endpoint_count ()
+ && this->object_key () == other->object_key ()
+ && this->do_is_equivalent (other);
+ case TAO_Service_Callbacks::EQUIVALENT:
+ result = true;
+ break;
+ case TAO_Service_Callbacks::NOT_EQUIVALENT:
+ break;
+ }
+ }
+ return result;
+}
+
+CORBA::Boolean
+TAO_Profile::compare_key (const TAO_Profile *other) const
+{
+ return (this->ref_object_key_ == other->ref_object_key_) ||
+ ((this->ref_object_key_ != 0 &&
+ other->ref_object_key_ != 0 &&
+ this->ref_object_key_->object_key() ==
+ other->ref_object_key_->object_key()));
+}
+
+TAO_Endpoint *
+TAO_Profile::first_filtered_endpoint (void)
+{
+ TAO_Endpoint *ep = this->endpoint();
+ return ep == 0 ? 0 : ep->next_filtered(this->orb_core_,0);
+}
+
+TAO_Endpoint *
+TAO_Profile::next_filtered_endpoint (TAO_Endpoint *source)
+{
+ if (source == 0)
+ return this->first_filtered_endpoint();
+ return source->next_filtered(this->orb_core_,this->endpoint());
+}
+
+void
+TAO_Profile::add_generic_endpoint (TAO_Endpoint *)
+{
+ // noop for the base type
+}
+
+TAO_Service_Callbacks::Profile_Equivalence
+TAO_Profile::is_equivalent_hook (const TAO_Profile *other)
+{
+ // Allow services to apply their own definition of "equivalence."
+ return this->orb_core_->is_profile_equivalent (this, other);
+}
+
+CORBA::ULong
+TAO_Profile::hash_service_i (CORBA::ULong m)
+{
+ return this->orb_core_->hash_service (this, m);
+}
+
+/*
+ * Hook to comment out no op method
+ * in the base class that is specialized in the
+ * derived class.
+ */
+//@@ TAO_PROFILE_SPL_COMMENT_HOOK_START
+
+int
+TAO_Profile::encode_alternate_endpoints(void)
+{
+ // this should be a pure virtual, but there are many
+ // existing specializations that would need to be
+ // modified. This maintains the existing behavior, since
+ // the previous version of the POA did not gather alternate
+ // endpoints.
+
+ return 0;
+}
+
+void
+TAO_Profile::remove_generic_endpoint (TAO_Endpoint *)
+{
+ // default for virtual methods, thus a no-op
+}
+
+//@@ TAO_PROFILE_SPL_COMMENT_HOOK_END
+
+//@@ TAO_PROFILE_SPL_METHODS_ADD_HOOK
+
+// ****************************************************************
+
+TAO_Unknown_Profile::TAO_Unknown_Profile (CORBA::ULong tag,
+ TAO_ORB_Core *orb_core)
+ : TAO_Profile (tag,
+ orb_core,
+ TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR,
+ TAO_DEF_GIOP_MINOR))
+{
+}
+
+TAO_Endpoint*
+TAO_Unknown_Profile::endpoint (void)
+{
+ return 0;
+}
+
+CORBA::ULong
+TAO_Unknown_Profile::endpoint_count (void) const
+{
+ return 0;
+}
+
+void
+TAO_Unknown_Profile::parse_string (const char *
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+ // @@ THROW something????
+}
+
+void
+TAO_Unknown_Profile::parse_string_i (const char *
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+ // @@ THROW something????
+}
+
+char
+TAO_Unknown_Profile::object_key_delimiter (void) const
+{
+ return 0;
+}
+
+char *
+TAO_Unknown_Profile::to_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+{
+ // @@ THROW something?
+ return 0;
+}
+
+int
+TAO_Unknown_Profile::decode (TAO_InputCDR& cdr)
+{
+ if ((cdr >> this->body_) == 0)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+TAO_Unknown_Profile::decode_profile (TAO_InputCDR &)
+{
+ return 0;
+}
+
+int
+TAO_Unknown_Profile::decode_endpoints (void)
+{
+ return 0;
+}
+
+int
+TAO_Unknown_Profile::encode (TAO_OutputCDR &stream) const
+{
+ stream.write_ulong (this->tag ());
+ return (stream << this->body_);
+}
+
+int
+TAO_Unknown_Profile::encode_endpoints (void)
+{
+ return 0;
+}
+
+const TAO::ObjectKey &
+TAO_Unknown_Profile::object_key (void) const
+{
+ // @@ TODO this is wrong, but the function is deprecated anyway....
+ static TAO::ObjectKey empty_key;
+ return empty_key;
+}
+
+TAO::ObjectKey *
+TAO_Unknown_Profile::_key (void) const
+{
+ return 0;
+}
+
+CORBA::Boolean
+TAO_Unknown_Profile::do_is_equivalent (const TAO_Profile* other_profile)
+{
+ const TAO_Unknown_Profile * op =
+ dynamic_cast <const TAO_Unknown_Profile *> (other_profile);
+
+ return (CORBA::Boolean) (op == 0 ? 0 : this->body_ == op->body_);
+}
+
+TAO_Service_Callbacks::Profile_Equivalence
+TAO_Unknown_Profile::is_equivalent_hook (const TAO_Profile * /* other */)
+{
+ // Override the default implementation since we don't need the
+ // additional checks it performs.
+
+ return TAO_Service_Callbacks::DONT_KNOW;
+}
+
+CORBA::ULong
+TAO_Unknown_Profile::hash (CORBA::ULong max
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+ return (ACE::hash_pjw (reinterpret_cast <const char*>
+ (this->body_.get_buffer ()),
+ this->body_.length ()) % max);
+}
+
+void
+TAO_Unknown_Profile::create_profile_body (TAO_OutputCDR &) const
+{
+ // No idea about the profile body! Just return
+ return;
+}
+
+
+
+// *************************************************************
+// Operators for TAO_opaque encoding and decoding
+// *************************************************************
+
+CORBA::Boolean
+operator<< (TAO_OutputCDR& cdr, const TAO_opaque& x)
+{
+ CORBA::ULong const length = x.length ();
+ cdr.write_ulong (length);
+
+#if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
+ if (x.mb () != 0)
+ {
+ cdr.write_octet_array_mb (x.mb ());
+ }
+ else
+#endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
+ {
+ cdr.write_octet_array (x.get_buffer (), length);
+ }
+
+ return (CORBA::Boolean) cdr.good_bit ();
+}
+
+CORBA::Boolean
+operator>>(TAO_InputCDR& cdr, TAO_opaque& x)
+{
+ CORBA::ULong length;
+ cdr.read_ulong (length);
+
+#if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
+ if(ACE_BIT_DISABLED(cdr.start()->flags(),
+ ACE_Message_Block::DONT_DELETE)
+ && (cdr.orb_core() == 0
+ || 1 == cdr.orb_core()->
+ resource_factory()->
+ input_cdr_allocator_type_locked()
+ )
+ )
+ {
+ x.replace (length, cdr.start ());
+ x.mb ()->wr_ptr (x.mb ()->rd_ptr () + length);
+ cdr.skip_bytes (length);
+ }
+ else
+#endif /* TAO_NO_COPY_OCTET_SEQUENCES == 0 */
+ {
+ x.length (length);
+ cdr.read_octet_array (x.get_buffer (), length);
+ }
+
+ return (CORBA::Boolean) cdr.good_bit ();
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL