Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / Profile.cpp
blob6465f4ef0a2f2b1346eda5397aaea53747a59c01
1 #include "tao/Profile.h"
2 #include "tao/Messaging_PolicyValueC.h"
3 #include "tao/Stub.h"
4 #include "tao/debug.h"
5 #include "tao/target_specification.h"
6 #include "tao/ORB_Core.h"
7 #include "tao/Client_Strategy_Factory.h"
8 #include "tao/CDR.h"
9 #include "tao/SystemException.h"
10 #include "tao/PolicyC.h"
11 #include "tao/Endpoint.h"
13 #include "ace/ACE.h"
14 #include "ace/OS_NS_string.h"
15 #include "ace/OS_NS_ctype.h"
17 #if !defined (__ACE_INLINE__)
18 #include "tao/Profile.inl"
19 #endif /* __ACE_INLINE__ */
21 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
23 TAO_Profile::TAO_Profile (CORBA::ULong tag,
24 TAO_ORB_Core *orb_core,
25 const TAO::ObjectKey &obj_key,
26 const TAO_GIOP_Message_Version &version)
27 : version_ (version)
28 , are_policies_parsed_ (false)
29 , addressing_mode_ (0)
30 , tagged_profile_ (nullptr)
31 , ref_object_key_ (nullptr)
32 , tag_ (tag)
33 , orb_core_ (orb_core)
34 , forward_to_ (nullptr)
35 , refcount_ (1)
36 , tagged_profile_lock_ ()
37 , tagged_profile_created_ (false)
39 (void) this->orb_core_->object_key_table ().bind (obj_key,
40 this->ref_object_key_);
43 TAO_Profile::TAO_Profile (CORBA::ULong tag,
44 TAO_ORB_Core *orb_core,
45 const TAO_GIOP_Message_Version &version)
46 : version_ (version)
47 , are_policies_parsed_ (false)
48 , addressing_mode_ (0)
49 , tagged_profile_ (nullptr)
50 , ref_object_key_ (nullptr)
51 , tag_ (tag)
52 , orb_core_ (orb_core)
53 , forward_to_ (nullptr)
54 , refcount_ (1)
55 , tagged_profile_lock_ ()
56 , tagged_profile_created_ (false)
60 TAO_Profile::~TAO_Profile ()
62 if (this->tagged_profile_)
64 delete this->tagged_profile_;
67 this->orb_core_->object_key_table ().unbind (this->ref_object_key_);
70 void
71 TAO_Profile::add_tagged_component (const IOP::TaggedComponent &component)
73 // Sanity checks.
74 this->verify_orb_configuration ();
76 this->verify_profile_version ();
78 // ----------------------------------------------------------------
80 // Add the given tagged component to this profile.
82 // Note that multiple tagged profiles with the same tag value may be
83 // added, unless the tagged component is known to be unique by TAO.
84 this->tagged_components_.set_component (component);
88 TAO_Endpoint *
89 TAO_Profile::base_endpoint ()
91 return this->endpoint();
94 TAO::ObjectKey *
95 TAO_Profile::_key () const
97 TAO::ObjectKey *key = nullptr;
99 if (this->ref_object_key_)
101 ACE_NEW_RETURN (key,
102 TAO::ObjectKey (this->ref_object_key_->object_key ()),
103 nullptr);
105 return key;
110 TAO_Profile::encode (TAO_OutputCDR &stream) const
112 // UNSIGNED LONG, protocol tag
113 stream.write_ulong (this->tag_);
115 // Create the encapsulation....
116 TAO_OutputCDR encap (ACE_CDR::DEFAULT_BUFSIZE,
117 TAO_ENCAP_BYTE_ORDER,
118 this->orb_core ()->output_cdr_buffer_allocator (),
119 this->orb_core ()->output_cdr_dblock_allocator (),
120 this->orb_core ()->output_cdr_msgblock_allocator (),
121 this->orb_core ()->orb_params ()->cdr_memcpy_tradeoff (),
122 TAO_DEF_GIOP_MAJOR,
123 TAO_DEF_GIOP_MINOR);
125 #if defined (TAO_ZERO_TAO_OUTPUTCDR_ALLOCATED_BUFFERS)
126 // Support limited oref ACE_OS::strcmp
127 (void) ACE_OS::memset (encap.current()->wr_ptr (),
129 encap.current()->space ());
130 #endif /* TAO_ZERO_TAO_OUTPUTCDR_ALLOCATED_BUFFERS */
132 // Create the profile body
133 this->create_profile_body (encap);
135 // write the encapsulation as an octet sequence...
136 stream << CORBA::ULong (encap.total_length ());
137 stream.write_octet_array_mb (encap.begin ());
139 return 1;
143 TAO_Profile::decode (TAO_InputCDR& cdr)
145 #if !defined (ACE_NLOGGING)
146 size_t const encap_len = cdr.length ();
147 #endif
149 // Read and verify major, minor versions, ignoring profiles
150 // whose versions we don't understand.
151 if (!(cdr.read_octet (this->version_.major)
152 && this->version_.major == TAO_DEF_GIOP_MAJOR
153 && cdr.read_octet (this->version_.minor)
154 && this->version_.minor <= TAO_DEF_GIOP_MINOR))
156 if (TAO_debug_level > 0)
158 TAOLIB_DEBUG ((LM_DEBUG,
159 ACE_TEXT ("TAO (%P|%t) - Profile::decode - v%d.%d\n"),
160 this->version_.major,
161 this->version_.minor));
164 return -1;
167 // Transport specific details
168 if (this->decode_profile (cdr) < 0)
170 return -1;
173 // @@NOTE: This place *may* need strategizing. Here are the
174 // issues. Placing the ObjectKey in the table adds an allocation and
175 // a lock while decoding. This is bad for some cases especially if
176 // the application is marshalling object references across to the
177 // server end. But the server could use "lazy" evaluation and avoid
178 // this during marshalling.
180 // The only place this will get important is when a thead tries to
181 // use the object reference to create a CORBA object to make an
182 // invocation. Since creation of a CORBA object itself is expensive,
183 // it looks like we may not need to worry much.
185 // Remember strategizing needs reconciliation of forces imposed
186 // by runtime memory growth. Doing a random strategization would
187 // destroy the wins in runtime memory growth got by using this
188 // table scheme.
189 TAO::ObjectKey ok;
191 // ... and object key.
192 if (TAO::ObjectKey::demarshal_key (ok, cdr) == 0)
194 return -1;
197 TAO::ObjectKey_Table &okt = this->orb_core ()->object_key_table ();
199 if (okt.bind (ok, this->ref_object_key_) == -1)
201 return -1;
204 // Tagged Components *only* exist after version 1.0!
205 // For GIOP 1.2, IIOP and GIOP have same version numbers!
206 if (this->version_.major > 1 || this->version_.minor > 0)
208 if (this->tagged_components_.decode (cdr) == 0)
210 return -1;
214 if (cdr.length () != 0 && TAO_debug_level)
216 // If there is extra data in the profile we are supposed to
217 // ignore it, but print a warning just in case...
218 TAOLIB_DEBUG ((LM_DEBUG,
219 ACE_TEXT ("%d bytes out of %d left after profile data\n"),
220 cdr.length (),
221 encap_len));
224 // Decode any additional endpoints per profile. This is used by RTCORBA
225 // and by IIOP when TAG_ALTERNATE_IIOP_ADDRESS components are present.
226 if (this->decode_endpoints () == -1)
228 return -1;
231 return 1;
234 IOP::TaggedProfile *
235 TAO_Profile::create_tagged_profile ()
237 if (this->tagged_profile_created_)
238 return this->tagged_profile_;
240 ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
241 guard,
242 this->tagged_profile_lock_,
243 this->tagged_profile_);
245 // .. DCL
246 if (!this->tagged_profile_created_)
248 ACE_NEW_RETURN (this->tagged_profile_,
249 IOP::TaggedProfile,
250 nullptr);
252 // As we have not created we will now create the TaggedProfile
253 this->tagged_profile_->tag = this->tag_;
255 // Create the encapsulation....
256 TAO_OutputCDR encap (ACE_DEFAULT_CDR_BUFSIZE,
257 TAO_ENCAP_BYTE_ORDER,
258 this->orb_core ()->output_cdr_buffer_allocator (),
259 this->orb_core ()->output_cdr_dblock_allocator (),
260 this->orb_core ()->output_cdr_msgblock_allocator (),
261 this->orb_core ()->orb_params ()->cdr_memcpy_tradeoff (),
262 TAO_DEF_GIOP_MAJOR,
263 TAO_DEF_GIOP_MINOR);
265 // Create the profile body
266 this->create_profile_body (encap);
268 CORBA::ULong const length =
269 static_cast <CORBA::ULong> (encap.total_length ());
271 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
272 // Place the message block in to the Sequence of Octets that we
273 // have
274 this->tagged_profile_->profile_data.replace (length, encap.begin ());
275 #else
276 this->tagged_profile_->profile_data.length (length);
277 CORBA::Octet *buffer =
278 this->tagged_profile_->profile_data.get_buffer ();
280 for (const ACE_Message_Block *i = encap.begin ();
281 i != encap.end ();
282 i = i->next ())
284 ACE_OS::memcpy (buffer, i->rd_ptr (), i->length ());
285 buffer += i->length ();
287 #endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
289 this->tagged_profile_created_ = true;
292 return this->tagged_profile_;
295 void
296 TAO_Profile::set_tagged_components (TAO_OutputCDR &out_cdr)
298 CORBA::ULong const length = static_cast <CORBA::ULong> (out_cdr.total_length ());
300 IOP::TaggedComponent tagged_component;
301 tagged_component.tag = TAO_TAG_ENDPOINTS;
302 tagged_component.component_data.length (length);
303 CORBA::Octet *buf = tagged_component.component_data.get_buffer ();
305 for (const ACE_Message_Block *iterator = out_cdr.begin ();
306 iterator != nullptr;
307 iterator = iterator->cont ())
309 size_t const i_length = iterator->length ();
310 ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
312 buf += i_length;
315 // Add component with encoded endpoint data to this profile's
316 // TaggedComponents.
317 tagged_components_.set_component (tagged_component);
321 void
322 TAO_Profile::policies (CORBA::PolicyList *policy_list)
324 if (policy_list == nullptr)
326 if (TAO_debug_level)
328 TAOLIB_DEBUG ((LM_DEBUG,
329 ACE_TEXT ("TAO_Profile::policies: ")
330 ACE_TEXT ("Null Policy List!\n")));
333 return;
336 Messaging::PolicyValueSeq policy_value_seq;
338 size_t length = 0;
339 CORBA::Octet *buf = nullptr;
341 // This loop iterates through CORBA::PolicyList to convert
342 // each CORBA::Policy into a CORBA::PolicyValue
343 CORBA::ULong const plen = policy_list->length ();
345 policy_value_seq.length (plen);
347 for (CORBA::ULong i = 0; i < plen; ++i)
349 TAO_OutputCDR out_CDR;
350 policy_value_seq[i].ptype = (*policy_list)[i]->policy_type ();
352 if (!(out_CDR << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)))
353 return;
355 if (!((*policy_list)[i]->_tao_encode (out_CDR)))
356 return;
358 length = out_CDR.total_length ();
359 policy_value_seq[i].pvalue.length (static_cast <CORBA::ULong>(length));
361 buf = policy_value_seq[i].pvalue.get_buffer ();
363 // Copy the CDR buffer data into the octet sequence buffer.
365 for (const ACE_Message_Block *iterator = out_CDR.begin ();
366 iterator != nullptr;
367 iterator = iterator->cont ())
369 ACE_OS::memcpy (buf, iterator->rd_ptr (), iterator->length ());
370 buf += iterator->length ();
374 TAO_OutputCDR out_cdr;
375 // Now we have to embed the Messaging::PolicyValueSeq into
376 // a TaggedComponent.
378 IOP::TaggedComponent tagged_component;
379 tagged_component.tag = Messaging::TAG_POLICIES;
381 if (!(out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)))
382 return;
384 if (!(out_cdr << policy_value_seq))
385 return;
387 length = out_cdr.total_length ();
389 tagged_component.component_data.length (static_cast <CORBA::ULong>(length));
390 buf = tagged_component.component_data.get_buffer ();
392 for (const ACE_Message_Block *iterator = out_cdr.begin ();
393 iterator != nullptr;
394 iterator = iterator->cont ())
396 size_t const i_length = iterator->length ();
397 ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
399 buf += i_length;
402 // Eventually we add the TaggedComponent to the TAO_TaggedComponents
403 // member variable.
404 tagged_components_.set_component (tagged_component);
405 this->are_policies_parsed_ = true;
408 void
409 TAO_Profile::get_policies (CORBA::PolicyList& pl)
411 #if !defined(CORBA_E_MICRO)
412 // None has already parsed the policies.
413 if (!this->are_policies_parsed_)
415 IOP::TaggedComponent tagged_component;
416 tagged_component.tag = Messaging::TAG_POLICIES;
418 // This gets a component with the proper "tag" field
419 // if it exists.
420 if (this->tagged_components_.get_component (tagged_component))
422 const CORBA::Octet *buf =
423 tagged_component.component_data.get_buffer ();
425 TAO_InputCDR in_cdr (reinterpret_cast <const char *> (buf),
426 tagged_component.component_data.length ());
428 // Extract the Byte Order
429 CORBA::Boolean byte_order;
431 if (!(in_cdr >> ACE_InputCDR::to_boolean (byte_order)))
433 return;
436 in_cdr.reset_byte_order (static_cast <int> (byte_order));
438 // Now we take out the Messaging::PolicyValueSeq out from the
439 // CDR.
440 Messaging::PolicyValueSeq policy_value_seq;
442 if (!(in_cdr >> policy_value_seq))
444 throw ::CORBA::INV_OBJREF ();
447 // Here we extract the Messaging::PolicyValue out of the sequence
448 // and we convert those into the proper CORBA::Policy
449 CORBA::ULong const length = policy_value_seq.length ();
451 for (CORBA::ULong i = 0; i < length; ++i)
455 CORBA::Policy_var policy =
456 this->orb_core_->orb ()->_create_policy (
457 policy_value_seq[i].ptype);
459 if (!CORBA::is_nil (policy.in ()))
461 buf = policy_value_seq[i].pvalue.get_buffer ();
463 TAO_InputCDR in_cdr (
464 reinterpret_cast <const char*> (buf),
465 policy_value_seq[i].pvalue.length ());
467 if (!(in_cdr >> ACE_InputCDR::to_boolean (byte_order)))
468 throw ::CORBA::INV_OBJREF ();
470 in_cdr.reset_byte_order (static_cast <int> (byte_order));
472 if (!policy->_tao_decode (in_cdr))
473 throw ::CORBA::INV_OBJREF ();
475 // Increase the policy length with 1 when we know we support
476 // this policy, this way we don't get nil values in the list
477 pl.length (pl.length () + 1);
479 pl[i] = policy._retn ();
481 else
483 // This case should occur when in the IOR are
484 // embedded policies that TAO doesn't support,
485 // so as specified by the RT-CORBA
486 // spec. ptc/99-05-03 we just ignore these
487 // un-understood policies.
488 if (TAO_debug_level >= 5)
489 TAOLIB_DEBUG ((LM_DEBUG,
490 ACE_TEXT ("The IOR contains unsupported ")
491 ACE_TEXT ("policies.\n")));
494 catch (const ::CORBA::Exception& ex)
496 // This case should occur when in the IOR are
497 // embedded policies that TAO doesn't support, so as
498 // specified by the RT-CORBA spec. ptc/99-05-03 we
499 // just ignore these un-understood policies.
501 if (TAO_debug_level >= 5)
502 ex._tao_print_exception (
503 ACE_TEXT ("IOR contains ")
504 ACE_TEXT ("unsupported policies."));
509 #else
510 ACE_UNUSED_ARG (pl);
511 #endif
514 void
515 TAO_Profile::verify_orb_configuration ()
517 // If the ORB isn't configured to support tagged components, then
518 // throw an exception.
519 if (!this->orb_core_->orb_params ()->std_profile_components ()
520 || !this->orb_core_->orb ()->_use_omg_ior_format ())
522 if (TAO_debug_level > 0)
524 TAOLIB_ERROR ((LM_ERROR,
525 ACE_TEXT ("(%P|%t) Cannot add ")
526 ACE_TEXT ("IOP::TaggedComponent to profile.\n")
527 ACE_TEXT ("(%P|%t) Standard profile components ")
528 ACE_TEXT ("have been disabled or URL style IORs\n")
529 ACE_TEXT ("(%P|%t) are in use. Try ")
530 ACE_TEXT ("\"-ORBStdProfileComponents 1\" and/or\n")
531 ACE_TEXT ("(%P|%t) \"-ORBObjRefStyle IOR\".\n")));
534 // According to the Portable Interceptor specification, we're
535 // supposed to throw a CORBA::BAD_PARAM exception if it isn't
536 // possible to add components to the profile.
537 // @todo: We need the proper minor code as soon as the spec is
538 // updated.
539 throw ::CORBA::BAD_PARAM (
540 CORBA::SystemException::_tao_minor_code (
542 EINVAL),
543 CORBA::COMPLETED_NO);
547 void
548 TAO_Profile::verify_profile_version ()
550 // GIOP 1.0 does not support tagged components. Throw an exception
551 // if the profile is a GIOP 1.0 profile.
553 if (this->version_.major == 1 && this->version_.minor == 0)
555 if (TAO_debug_level > 0)
557 TAOLIB_ERROR ((LM_ERROR,
558 ACE_TEXT ("(%P|%t) Cannot add ")
559 ACE_TEXT ("IOP::TaggedComponent to GIOP 1.0")
560 ACE_TEXT ("IOR profile.\n")
561 ACE_TEXT ("(%P|%t) Try using a GIOP 1.1 or ")
562 ACE_TEXT ("greater endpoint.\n")));
565 // According to the Portable Interceptor specification, we're
566 // supposed to throw a CORBA::BAD_PARAM exception if it isn't
567 // possible to add components to the profile.
568 // @todo: We need the proper minor code as soon as the spec is
569 // updated.
570 throw ::CORBA::BAD_PARAM (
571 CORBA::SystemException::_tao_minor_code (
573 EINVAL),
574 CORBA::COMPLETED_NO);
579 TAO_Profile::supports_multicast () const
581 // Most profiles do not support multicast endpoints.
582 return 0;
585 bool
586 TAO_Profile::supports_non_blocking_oneways () const
588 return !(this->version_.major == 1 && this->version_.minor == 0);
591 void
592 TAO_Profile::addressing_mode (CORBA::Short addr)
594 // ** See race condition note about addressing mode in Profile.h **
595 switch (addr)
597 case TAO_Target_Specification::Key_Addr:
598 case TAO_Target_Specification::Profile_Addr:
599 case TAO_Target_Specification::Reference_Addr:
600 this->addressing_mode_ = addr;
601 break;
603 default:
604 throw ::CORBA::BAD_PARAM (
605 CORBA::SystemException::_tao_minor_code (
607 EINVAL),
608 CORBA::COMPLETED_NO);
612 void
613 TAO_Profile::parse_string (const char *ior)
615 if (!ior || !*ior)
617 throw ::CORBA::INV_OBJREF (
618 CORBA::SystemException::_tao_minor_code (
620 EINVAL),
621 CORBA::COMPLETED_NO);
624 // Remove the "N.n@" version prefix, if it exists, and verify the
625 // version is one that we accept.
627 // Check for version
628 if (ACE_OS::ace_isdigit (ior [0]) &&
629 ior[1] == '.' &&
630 ACE_OS::ace_isdigit (ior [2]) &&
631 ior[3] == '@')
633 // @@ This may fail for non-ascii character sets [but take that
634 // with a grain of salt]
635 this->version_.set_version ((char) (ior[0] - '0'),
636 (char) (ior[2] - '0'));
637 ior += 4;
638 // Skip over the "N.n@"
640 else
642 // CORBA spec requires 1.0 if a version isn't specified.
643 this->version_.set_version (1, 0);
646 if (this->version_.major != TAO_DEF_GIOP_MAJOR ||
647 this->version_.minor > TAO_DEF_GIOP_MINOR)
649 throw ::CORBA::INV_OBJREF (
650 CORBA::SystemException::_tao_minor_code (
652 EINVAL),
653 CORBA::COMPLETED_NO);
656 this->parse_string_i (ior);
659 CORBA::Boolean
660 TAO_Profile::is_equivalent (const TAO_Profile *other)
662 CORBA::Boolean result = false;
663 if (other)
665 TAO_Service_Callbacks::Profile_Equivalence callback
666 = this->is_equivalent_hook (other);
667 switch (callback)
669 case TAO_Service_Callbacks::DONT_KNOW:
670 return this->tag () == other->tag ()
671 && this->version_ == other->version ()
672 && this->endpoint_count () == other->endpoint_count ()
673 && this->object_key () == other->object_key ()
674 && this->do_is_equivalent (other);
675 case TAO_Service_Callbacks::EQUIVALENT:
676 result = true;
677 break;
678 case TAO_Service_Callbacks::NOT_EQUIVALENT:
679 break;
682 return result;
685 CORBA::Boolean
686 TAO_Profile::compare_key (const TAO_Profile *other) const
688 return (this->ref_object_key_ == other->ref_object_key_) ||
689 ((this->ref_object_key_ != nullptr &&
690 other->ref_object_key_ != nullptr &&
691 this->ref_object_key_->object_key() ==
692 other->ref_object_key_->object_key()));
695 TAO_Endpoint *
696 TAO_Profile::first_filtered_endpoint ()
698 TAO_Endpoint *ep = this->endpoint();
699 return ep == nullptr ? nullptr : ep->next_filtered(this->orb_core_,nullptr);
702 TAO_Endpoint *
703 TAO_Profile::next_filtered_endpoint (TAO_Endpoint *source)
705 if (source == nullptr)
706 return this->first_filtered_endpoint();
707 return source->next_filtered(this->orb_core_,this->endpoint());
710 void
711 TAO_Profile::add_generic_endpoint (TAO_Endpoint *)
713 // noop for the base type
716 TAO_Service_Callbacks::Profile_Equivalence
717 TAO_Profile::is_equivalent_hook (const TAO_Profile *other)
719 // Allow services to apply their own definition of "equivalence."
720 return this->orb_core_->is_profile_equivalent (this, other);
723 CORBA::ULong
724 TAO_Profile::hash_service_i (CORBA::ULong m)
726 return this->orb_core_->hash_service (this, m);
730 TAO_Profile::encode_alternate_endpoints()
732 // this should be a pure virtual, but there are many
733 // existing specializations that would need to be
734 // modified. This maintains the existing behavior, since
735 // the previous version of the POA did not gather alternate
736 // endpoints.
738 return 0;
741 void
742 TAO_Profile::remove_generic_endpoint (TAO_Endpoint *)
744 // default for virtual methods, thus a no-op
747 // ****************************************************************
749 TAO_Unknown_Profile::TAO_Unknown_Profile (CORBA::ULong tag,
750 TAO_ORB_Core *orb_core)
751 : TAO_Profile (tag,
752 orb_core,
753 TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR,
754 TAO_DEF_GIOP_MINOR))
758 TAO_Endpoint*
759 TAO_Unknown_Profile::endpoint ()
761 return nullptr;
764 CORBA::ULong
765 TAO_Unknown_Profile::endpoint_count () const
767 return 0;
770 void
771 TAO_Unknown_Profile::parse_string (const char *)
773 // @@ THROW something????
776 void
777 TAO_Unknown_Profile::parse_string_i (const char *)
779 // @@ THROW something????
782 char
783 TAO_Unknown_Profile::object_key_delimiter () const
785 return 0;
788 char *
789 TAO_Unknown_Profile::to_string () const
791 // @@ THROW something?
792 return nullptr;
796 TAO_Unknown_Profile::decode (TAO_InputCDR& cdr)
798 if (!(cdr >> this->body_))
800 return -1;
803 return 0;
807 TAO_Unknown_Profile::decode_profile (TAO_InputCDR &)
809 return 0;
813 TAO_Unknown_Profile::decode_endpoints ()
815 return 0;
819 TAO_Unknown_Profile::encode (TAO_OutputCDR &stream) const
821 stream.write_ulong (this->tag ());
822 return (stream << this->body_);
826 TAO_Unknown_Profile::encode_endpoints ()
828 return 0;
831 TAO::ObjectKey *
832 TAO_Unknown_Profile::_key () const
834 return nullptr;
837 CORBA::Boolean
838 TAO_Unknown_Profile::do_is_equivalent (const TAO_Profile* other_profile)
840 const TAO_Unknown_Profile * op =
841 dynamic_cast <const TAO_Unknown_Profile *> (other_profile);
843 return (CORBA::Boolean) (op == nullptr ? 0 : this->body_ == op->body_);
846 TAO_Service_Callbacks::Profile_Equivalence
847 TAO_Unknown_Profile::is_equivalent_hook (const TAO_Profile * /* other */)
849 // Override the default implementation since we don't need the
850 // additional checks it performs.
852 return TAO_Service_Callbacks::DONT_KNOW;
855 CORBA::ULong
856 TAO_Unknown_Profile::hash (CORBA::ULong max)
858 return (ACE::hash_pjw (reinterpret_cast <const char*>
859 (this->body_.get_buffer ()),
860 this->body_.length ()) % max);
863 void
864 TAO_Unknown_Profile::create_profile_body (TAO_OutputCDR &) const
866 // No idea about the profile body! Just return
867 return;
871 // *************************************************************
872 // Operators for TAO_opaque encoding and decoding
873 // *************************************************************
875 CORBA::Boolean
876 operator<< (TAO_OutputCDR& cdr, const TAO_opaque& x)
878 CORBA::ULong const length = x.length ();
879 cdr.write_ulong (length);
881 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
882 if (x.mb () != nullptr)
884 cdr.write_octet_array_mb (x.mb ());
886 else
887 #endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
889 cdr.write_octet_array (x.get_buffer (), length);
892 return cdr.good_bit ();
895 CORBA::Boolean
896 operator>>(TAO_InputCDR& cdr, TAO_opaque& x)
898 CORBA::ULong length;
899 cdr.read_ulong (length);
901 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
902 if(ACE_BIT_DISABLED(cdr.start()->flags(),
903 ACE_Message_Block::DONT_DELETE)
904 && (cdr.orb_core() == nullptr
905 || 1 == cdr.orb_core()->
906 resource_factory()->
907 input_cdr_allocator_type_locked()))
909 x.replace (length, cdr.start ());
910 x.mb ()->wr_ptr (x.mb ()->rd_ptr () + length);
911 cdr.skip_bytes (length);
913 else
914 #endif /* TAO_NO_COPY_OCTET_SEQUENCES == 0 */
916 x.length (length);
917 cdr.read_octet_array (x.get_buffer (), length);
920 return cdr.good_bit ();
923 TAO_END_VERSIONED_NAMESPACE_DECL