Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / IIOP_Profile.cpp
blobfd9528b3c6b5edc2cd05fbfc53cc8e8155b7e825
1 // -*- C++ -*-
2 #include "tao/IIOP_Profile.h"
4 #if defined (TAO_HAS_IIOP) && (TAO_HAS_IIOP != 0)
6 #include "tao/ORB_Core.h"
7 #include "tao/debug.h"
8 #include "tao/IIOP_EndpointsC.h"
9 #include "tao/CDR.h"
10 #include "tao/SystemException.h"
11 #include "ace/OS_NS_string.h"
12 #include "ace/OS_NS_stdio.h"
13 #include "ace/Truncate.h"
14 #include "ace/os_include/os_netdb.h"
15 #include <cstring>
17 static const char the_prefix[] = "iiop";
19 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
21 TAO_IIOP_Profile::~TAO_IIOP_Profile ()
23 // Clean up the list of endpoints since we own it.
24 // Skip the head, since it is not dynamically allocated.
25 TAO_Endpoint *tmp = nullptr;
27 for (TAO_Endpoint *next = this->endpoint ()->next ();
28 next != nullptr;
29 next = tmp)
31 tmp = next->next ();
32 delete next;
36 const char TAO_IIOP_Profile::object_key_delimiter_ = '/';
38 char
39 TAO_IIOP_Profile::object_key_delimiter () const
41 return TAO_IIOP_Profile::object_key_delimiter_;
44 TAO_IIOP_Profile::TAO_IIOP_Profile (const ACE_INET_Addr &addr,
45 const TAO::ObjectKey &object_key,
46 const TAO_GIOP_Message_Version &version,
47 TAO_ORB_Core *orb_core)
48 : TAO_Profile (IOP::TAG_INTERNET_IOP,
49 orb_core,
50 object_key,
51 version),
52 endpoint_ (addr,
53 orb_core->orb_params ()->use_dotted_decimal_addresses ()),
54 last_endpoint_ (&this->endpoint_),
55 count_ (1)
59 TAO_IIOP_Profile::TAO_IIOP_Profile (const char* host,
60 CORBA::UShort port,
61 const TAO::ObjectKey &object_key,
62 const ACE_INET_Addr &addr,
63 const TAO_GIOP_Message_Version &version,
64 TAO_ORB_Core *orb_core)
65 : TAO_Profile (IOP::TAG_INTERNET_IOP,
66 orb_core,
67 object_key,
68 version),
69 endpoint_ (host, port, addr),
70 last_endpoint_ (&this->endpoint_),
71 count_ (1)
75 TAO_IIOP_Profile::TAO_IIOP_Profile (TAO_ORB_Core *orb_core)
76 : TAO_Profile (IOP::TAG_INTERNET_IOP,
77 orb_core,
78 TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR,
79 TAO_DEF_GIOP_MINOR)),
80 endpoint_ (),
81 last_endpoint_ (&this->endpoint_),
82 count_ (1)
86 int
87 TAO_IIOP_Profile::decode_profile (TAO_InputCDR& cdr)
89 // Decode host and port into the <endpoint_>.
90 // it is necessary to do it indirectly so that IPv6 host addresses
91 // can be evaluated correctly.
92 CORBA::String_var host;
93 CORBA::UShort port;
95 if (cdr.read_string(host.out()) == 0 ||
96 cdr.read_ushort (port) == 0)
98 if (TAO_debug_level > 0)
99 TAOLIB_DEBUG ((LM_DEBUG,
100 ACE_TEXT ("TAO (%P|%t) IIOP_Profile::decode - ")
101 ACE_TEXT ("error while decoding host/port\n")));
102 return -1;
105 this->endpoint_.host(host.in());
106 this->endpoint_.port(port);
108 if (cdr.good_bit ())
110 // Invalidate the object_addr_ until first access.
111 this->endpoint_.object_addr_.set_type (-1);
113 const char* csv = this->orb_core()->orb_params()->preferred_interfaces();
114 if (csv != nullptr && *csv != '\0')
116 bool const enforce =
117 this->orb_core()->orb_params()->enforce_pref_interfaces();
118 this->count_ += this->endpoint_.preferred_interfaces(csv, enforce, *this);
120 return 1;
123 return -1;
126 void
127 TAO_IIOP_Profile::parse_string_i (const char *ior)
129 // Pull off the "hostname:port/" part of the objref
130 // Copy the string because we are going to modify it...
132 const char *okd = std::strchr (ior, this->object_key_delimiter_);
134 if (okd == nullptr || okd == ior)
136 // No object key delimiter or no hostname specified.
137 throw ::CORBA::INV_OBJREF (
138 CORBA::SystemException::_tao_minor_code (
140 EINVAL),
141 CORBA::COMPLETED_NO);
144 // Length of host string.
145 CORBA::ULong length_host = 0;
147 const char *cp_pos_overrun = std::strchr (ior, ':'); // Look for a port
148 const char *cp_pos = (cp_pos_overrun < okd) ? cp_pos_overrun : nullptr; // but before object key
149 #if defined (ACE_HAS_IPV6)
150 // IPv6 numeric address in host string?
151 bool ipv6_in_host = false;
153 // Check if this is a (possibly) IPv6 supporting profile containing a
154 // decimal IPv6 address representation.
155 if ((this->version().major > TAO_MIN_IPV6_IIOP_MAJOR ||
156 this->version().minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
157 ior[0] == '[')
159 // In this case we have to find the end of the numeric address and
160 // start looking for the port separator from there.
161 const char *cp_pos_a_overrun = std::strchr(ior, ']');
162 const char *cp_pos_a = (cp_pos_a_overrun < okd) ? cp_pos_a_overrun : 0; // before object key
163 if (cp_pos_a == 0)
165 // No valid IPv6 address specified.
166 if (TAO_debug_level > 0)
168 TAOLIB_ERROR ((LM_ERROR,
169 ACE_TEXT ("\nTAO (%P|%t) IIOP_Profile: ")
170 ACE_TEXT ("Invalid IPv6 decimal address specified.\n")));
173 throw ::CORBA::INV_OBJREF (
174 CORBA::SystemException::_tao_minor_code (
176 EINVAL),
177 CORBA::COMPLETED_NO);
179 else
181 if (cp_pos_a[1] == ':') // Look for a port
182 cp_pos = cp_pos_a + 1;
183 else
184 cp_pos = 0;
185 ipv6_in_host = true; // host string contains full IPv6 numeric address
188 #endif /* ACE_HAS_IPV6 */
190 if (cp_pos == ior)
192 // No hostname, however one is required by the spec when specifying a port.
193 // See formal-04-03-01, section 13.6.10.3
194 if (TAO_debug_level > 0)
196 TAOLIB_ERROR ((LM_ERROR,
197 ACE_TEXT ("\nTAO (%P|%t) IIOP_Profile: ")
198 ACE_TEXT ("Host address may be omited only when no port has been specified.\n")));
201 throw ::CORBA::INV_OBJREF (
202 CORBA::SystemException::_tao_minor_code (
204 EINVAL),
205 CORBA::COMPLETED_NO);
207 else if (cp_pos != nullptr)
209 // A port number or port name was specified.
210 CORBA::ULong length_port = ACE_Utils::truncate_cast<CORBA::ULong> (okd - cp_pos - 1);
211 CORBA::String_var tmp = CORBA::string_alloc (length_port);
213 if (tmp.in() != nullptr)
215 ACE_OS::strncpy (tmp.inout (), cp_pos + 1, length_port);
216 tmp[length_port] = '\0';
219 if (length_port == 0)
221 this->endpoint_.port_ = 2809; // default IIOP port for
222 // parsing corbaloc strings
224 else if (tmp.in () != nullptr && ACE_OS::strspn (tmp.in (), "1234567890") == length_port)
226 this->endpoint_.port_ =
227 static_cast<CORBA::UShort> (ACE_OS::atoi (tmp.in ()));
229 else
231 ACE_INET_Addr ia;
232 if (tmp.in () == nullptr || ia.string_to_addr (tmp.in ()) == -1)
234 throw ::CORBA::INV_OBJREF (
235 CORBA::SystemException::_tao_minor_code (
237 EINVAL),
238 CORBA::COMPLETED_NO);
240 else
242 this->endpoint_.port_ = ia.get_port_number ();
245 length_host = ACE_Utils::truncate_cast<CORBA::ULong> (cp_pos - ior);
247 else
248 length_host = ACE_Utils::truncate_cast<CORBA::ULong> (okd - ior);
250 #if defined (ACE_HAS_IPV6)
251 if (ipv6_in_host)
252 length_host -= 2; // don't store '[' and ']'
253 #endif /* ACE_HAS_IPV6 */
255 CORBA::String_var tmp = CORBA::string_alloc (length_host);
257 #if defined (ACE_HAS_IPV6)
258 if (ipv6_in_host)
259 ACE_OS::strncpy (tmp.inout (), ior + 1, length_host);
260 else
261 #endif /* ACE_HAS_IPV6 */
262 // Skip the trailing '/'
263 ACE_OS::strncpy (tmp.inout (), ior, length_host);
264 tmp[length_host] = '\0';
266 this->endpoint_.host_ = tmp._retn ();
267 #if defined (ACE_HAS_IPV6)
268 this->endpoint_.is_ipv6_decimal_ = ipv6_in_host;
269 #endif /* ACE_HAS_IPV6 */
271 if (ACE_OS::strcmp (this->endpoint_.host_.in (), "") == 0)
273 ACE_INET_Addr host_addr;
275 char tmp_host [MAXHOSTNAMELEN + 1];
277 // If no host is specified: assign the default host, i.e. the
278 // local host.
279 if (host_addr.get_host_name (tmp_host,
280 sizeof (tmp_host)) != 0)
282 // Can't get the IP address since the INET_Addr wasn't
283 // initialized. Just throw an exception.
285 if (TAO_debug_level > 0)
286 TAOLIB_DEBUG ((LM_DEBUG,
287 ACE_TEXT ("\n\nTAO (%P|%t) ")
288 ACE_TEXT ("IIOP_Profile::parse_string ")
289 ACE_TEXT ("- %p\n\n"),
290 ACE_TEXT ("cannot determine hostname")));
292 // @@ What's the right exception to throw here?
293 throw ::CORBA::INV_OBJREF (
294 CORBA::SystemException::_tao_minor_code (
296 EINVAL),
297 CORBA::COMPLETED_NO);
300 this->endpoint_.host_ = CORBA::string_dup (tmp_host);
301 const char* csv = this->orb_core()->orb_params()->preferred_interfaces();
302 bool const enforce =
303 this->orb_core()->orb_params()->enforce_pref_interfaces();
304 this->endpoint_.preferred_interfaces (csv, enforce, *this);
307 TAO::ObjectKey ok;
309 TAO::ObjectKey::decode_string_to_sequence (ok,
310 okd + 1);
312 (void) this->orb_core ()->object_key_table ().bind (ok,
313 this->ref_object_key_);
316 CORBA::Boolean
317 TAO_IIOP_Profile::do_is_equivalent (const TAO_Profile *other_profile)
319 if (other_profile == this)
320 return true;
322 const TAO_IIOP_Profile *op =
323 dynamic_cast<const TAO_IIOP_Profile *> (other_profile);
325 // Make sure we have a TAO_IIOP_Profile.
326 if (op == nullptr)
327 return false;
329 if (this->count_ == 0 && op->count_ == 0)
330 return true;
331 if (this->count_ != op->count_)
332 return false;
333 // Check endpoints equivalence.
334 const TAO_IIOP_Endpoint *other_endp = &op->endpoint_;
335 for (TAO_IIOP_Endpoint *endp = &this->endpoint_;
336 endp != nullptr;
337 endp = endp->next_)
339 if (endp->is_equivalent (other_endp))
340 other_endp = other_endp->next_;
341 else
342 return false;
345 return true;
348 CORBA::ULong
349 TAO_IIOP_Profile::hash (CORBA::ULong max)
351 // Get the hash value for all endpoints.
352 CORBA::ULong hashval = 0;
353 for (TAO_IIOP_Endpoint *endp = &this->endpoint_;
354 endp != nullptr;
355 endp = endp->next_)
357 hashval += endp->hash ();
360 hashval += this->version_.minor;
361 hashval += this->tag ();
363 const TAO::ObjectKey &ok =
364 this->ref_object_key_->object_key ();
366 if (ok.length () >= 4)
368 hashval += ok[1];
369 hashval += ok[3];
372 hashval += TAO_Profile::hash_service_i (max);
374 return hashval % max;
377 TAO_Endpoint*
378 TAO_IIOP_Profile::endpoint ()
380 return &this->endpoint_;
383 TAO_Endpoint *
384 TAO_IIOP_Profile::base_endpoint ()
386 // do not call endpoint(), return the value directly. This is to
387 // avoid calling a derived implementation of endpoint().
388 return &this->endpoint_;
391 CORBA::ULong
392 TAO_IIOP_Profile::endpoint_count () const
394 return this->count_;
397 void
398 TAO_IIOP_Profile::add_endpoint (TAO_IIOP_Endpoint *endp)
400 this->last_endpoint_->next_ = endp;
401 this->last_endpoint_ = endp;
403 ++this->count_;
406 void
407 TAO_IIOP_Profile::remove_endpoint (TAO_IIOP_Endpoint *endp)
409 if (endp == nullptr)
410 return;
412 // special handling for the target matching the base endpoint
413 if (endp == &this->endpoint_)
415 if (--this->count_ > 0)
417 TAO_IIOP_Endpoint* n = this->endpoint_.next_;
418 this->endpoint_ = *n;
419 // since the assignment operator does not copy the next_
420 // pointer, we must do it by hand
421 this->endpoint_.next_ = n->next_;
422 if (this->last_endpoint_ == n)
424 this->last_endpoint_ = &this->endpoint_;
426 delete n;
428 return;
431 TAO_IIOP_Endpoint* prev = &this->endpoint_;
432 TAO_IIOP_Endpoint* cur = this->endpoint_.next_;
434 while (cur != nullptr)
436 if (cur == endp)
437 break;
438 prev = cur;
439 cur = cur->next_;
442 if (cur != nullptr)
444 prev->next_ = cur->next_;
445 cur->next_ = nullptr;
446 --this->count_;
447 if (this->last_endpoint_ == cur)
449 this->last_endpoint_ = prev;
451 delete cur;
455 void
456 TAO_IIOP_Profile::remove_generic_endpoint (TAO_Endpoint *ep)
458 this->remove_endpoint(dynamic_cast<TAO_IIOP_Endpoint *>(ep));
461 void
462 TAO_IIOP_Profile::add_generic_endpoint (TAO_Endpoint *endp)
464 TAO_IIOP_Endpoint *iep = dynamic_cast<TAO_IIOP_Endpoint *>(endp);
465 if (iep != nullptr)
467 TAO_IIOP_Endpoint *clone;
468 ACE_NEW (clone, TAO_IIOP_Endpoint(*iep));
469 this->add_endpoint(clone);
473 char *
474 TAO_IIOP_Profile::to_string () const
476 // corbaloc:iiop:1.2@host:port,iiop:1.2@host:port,.../key
478 CORBA::String_var key;
479 TAO::ObjectKey::encode_sequence_to_string (key.inout(),
480 this->ref_object_key_->object_key ());
482 size_t buflen = (
483 8 /* "corbaloc" */ +
484 1 /* colon separator */ +
485 1 /* object key separator */ +
486 std::strlen (key.in ()));
487 size_t const pfx_len = (
488 std::strlen (::the_prefix) /* "iiop" */ +
489 1 /* colon separator */);
491 const TAO_IIOP_Endpoint *endp = nullptr;
492 for (endp = &this->endpoint_; endp != nullptr; endp = endp->next_)
494 buflen += (
495 pfx_len +
496 1 /* major version */ +
497 1 /* decimal point */ +
498 1 /* minor version */ +
499 1 /* `@' character */ +
500 std::strlen (endp->host ()) +
501 1 /* colon separator */ +
502 5 /* port number */ +
503 1 /* comma */);
504 #if defined (ACE_HAS_IPV6)
505 if (endp->is_ipv6_decimal_)
506 buflen += 2; // room for '[' and ']'
507 #endif /* ACE_HAS_IPV6 */
510 static const char digits [] = "0123456789";
512 char * buf = CORBA::string_alloc (static_cast<CORBA::ULong> (buflen));
514 ACE_OS::strcpy(buf, "corbaloc:");
516 for (endp = &this->endpoint_; endp != nullptr; endp = endp->next_)
518 if(&this->endpoint_ != endp)
519 ACE_OS::strcat(buf, ",");
521 #if defined (ACE_HAS_IPV6)
522 if (endp->is_ipv6_decimal_)
524 // Don't publish scopeid if included.
525 ACE_CString tmp(endp->host ());
526 ACE_CString::size_type pos = tmp.find('%');
527 if (pos != ACE_CString::npos)
529 tmp = tmp.substr(0, pos + 1);
530 tmp[pos] = '\0';
532 ACE_OS::sprintf (buf + std::strlen(buf),
533 "%s:%c.%c@[%s]:%d",
534 ::the_prefix,
535 digits [this->version_.major],
536 digits [this->version_.minor],
537 tmp.c_str (),
538 endp->port () );
540 else
541 #endif
542 ACE_OS::sprintf (buf + std::strlen(buf),
543 "%s:%c.%c@%s:%d",
544 ::the_prefix,
545 digits [this->version_.major],
546 digits [this->version_.minor],
547 endp->host (),
548 endp->port () );
550 ACE_OS::sprintf (buf + std::strlen(buf),
551 "%c%s",
552 this->object_key_delimiter_,
553 key.in ());
555 return buf;
558 const char *
559 TAO_IIOP_Profile::prefix ()
561 return ::the_prefix;
564 void
565 TAO_IIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
567 encap.write_octet (TAO_ENCAP_BYTE_ORDER);
569 // The GIOP version
570 encap.write_octet (this->version_.major);
571 encap.write_octet (this->version_.minor);
573 // STRING hostname from profile
574 #if defined (ACE_HAS_IPV6)
575 // For IPv6 decimal addresses make sure the possibly included scopeid
576 // is not published as this has only local meaning.
577 const char* host = 0;
578 const char* pos = 0;
579 if (this->endpoint_.is_ipv6_decimal_ &&
580 (pos = std::strchr (host = this->endpoint_.host (), '%')) != 0)
582 ACE_CString tmp;
583 size_t len = pos - host;
584 tmp.set (this->endpoint_.host (), len, 1);
585 encap.write_string (tmp.c_str ());
587 else
588 #endif /* ACE_HAS_IPV6 */
589 encap.write_string (this->endpoint_.host ());
591 // UNSIGNED SHORT port number
592 encap.write_ushort (this->endpoint_.port ());
594 // OCTET SEQUENCE for object key
595 if (this->ref_object_key_)
596 encap << this->ref_object_key_->object_key ();
597 else
599 TAOLIB_ERROR ((LM_ERROR,
600 "(%P|%t) TAO - IIOP_Profile::create_profile_body "
601 "no object key marshalled\n"));
604 if (this->version_.major > 1 || this->version_.minor > 0)
605 this->tagged_components ().encode (encap);
609 TAO_IIOP_Profile::encode_alternate_endpoints ()
611 // encode IOP::TAG_ALTERNATE_IIOP_ADDRESS tags if there are more
612 // than one endpoints to listen to.
613 const TAO_IIOP_Endpoint *endpoint = &this->endpoint_;
614 for (CORBA::ULong i = 1;
615 i < this->count_;
616 ++i)
618 // The first endpoint is the actual endpoint. The rest of the
619 // endpoints are the alternate endpoints. So, neglect the first
620 // endpoint for TAG_ALTERNATE_IIOP_ADDRESS
621 endpoint = endpoint->next_;
623 if (!endpoint->is_encodable_)
624 continue;
626 // Encode the data structure. - The CORBA specification does not
627 // mandate a particular container for the endpoints, only that
628 // it is encoded as host first, then port.
629 TAO_OutputCDR out_cdr;
631 #if defined (ACE_HAS_IPV6)
632 // For IPv6 decimal addresses make sure the possibly included scopeid
633 // is not published as this has only local meaning.
634 const char* host = 0;
635 const char* pos = 0;
636 if (endpoint->is_ipv6_decimal_ &&
637 (pos = std::strchr (host = endpoint->host (), '%')) != 0)
639 ACE_CString tmp;
640 size_t len = pos - host;
641 tmp.set (endpoint->host (), len, 1);
642 if (!(out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER))
643 || !(out_cdr << tmp.c_str ())
644 || !(out_cdr << endpoint->port ()))
645 return -1;
646 out_cdr.write_string (len, endpoint->host ());
648 else
649 #endif /* ACE_HAS_IPV6 */
650 if (!(out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER))
651 || !(out_cdr << endpoint->host ())
652 || !(out_cdr << endpoint->port ()))
653 return -1;
655 IOP::TaggedComponent tagged_component;
656 tagged_component.tag = IOP::TAG_ALTERNATE_IIOP_ADDRESS;
658 size_t length = out_cdr.total_length ();
659 tagged_component.component_data.length
660 (static_cast<CORBA::ULong>(length));
661 CORBA::Octet *buf =
662 tagged_component.component_data.get_buffer ();
664 for (const ACE_Message_Block *iterator = out_cdr.begin ();
665 iterator != nullptr;
666 iterator = iterator->cont ())
668 size_t i_length = iterator->length ();
669 ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
671 buf += i_length;
674 // Add component with encoded endpoint data to this profile's
675 // TaggedComponents.
676 tagged_components_.set_component (tagged_component);
678 return 0;
682 TAO_IIOP_Profile::encode_endpoints ()
684 CORBA::ULong actual_count = 0;
686 const TAO_IIOP_Endpoint *endpoint = &this->endpoint_;
688 // Count the number of endpoints that needs to be encoded
689 for (CORBA::ULong c = 0;
690 c != this->count_;
691 ++c)
693 if (endpoint->is_encodable_)
694 ++actual_count;
696 endpoint = endpoint->next_;
699 // Create a data structure and fill it with endpoint info for wire
700 // transfer.
701 // We include information for the head of the list
702 // together with other endpoints because even though its addressing
703 // info is transmitted using standard ProfileBody components, its
704 // priority is not!
706 TAO::IIOPEndpointSequence endpoints;
707 endpoints.length (actual_count);
709 endpoint = &this->endpoint_;
711 for (CORBA::ULong i = 0;
712 i < actual_count;
713 ++i)
715 if (endpoint->is_encodable_)
717 #if defined (ACE_HAS_IPV6)
718 if (endpoint->is_ipv6_decimal_)
720 // Don't publish scopeid if included.
721 ACE_CString tmp(endpoint->host ());
722 ACE_CString::size_type pos = tmp.find('%');
723 if (pos != ACE_CString::npos)
725 tmp = tmp.substr (0, pos + 1);
726 tmp[pos] = '\0';
727 endpoints[i].host = tmp.c_str();
729 else
730 endpoints[i].host = tmp.c_str();
732 else
733 #endif /* ACE_HAS_IPV6 */
734 endpoints[i].host = endpoint->host ();
735 endpoints[i].port = endpoint->port ();
736 endpoints[i].priority = endpoint->priority ();
738 endpoint = endpoint->next_;
741 // Encode the data structure.
742 TAO_OutputCDR out_cdr;
743 if (!(out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER))
744 || !(out_cdr << endpoints))
745 return -1;
747 this->set_tagged_components (out_cdr);
749 return 0;
754 TAO_IIOP_Profile::decode_endpoints ()
756 IOP::TaggedComponent tagged_component;
757 tagged_component.tag = TAO_TAG_ENDPOINTS;
759 if (this->tagged_components_.get_component (tagged_component))
761 const CORBA::Octet *buf =
762 tagged_component.component_data.get_buffer ();
764 TAO_InputCDR in_cdr (reinterpret_cast<const char *> (buf),
765 tagged_component.component_data.length ());
767 // Extract the Byte Order.
768 CORBA::Boolean byte_order;
769 if (!(in_cdr >> ACE_InputCDR::to_boolean (byte_order)))
770 return -1;
771 in_cdr.reset_byte_order (static_cast<int> (byte_order));
773 // Extract endpoints sequence.
774 TAO::IIOPEndpointSequence endpoints;
776 if (!(in_cdr >> endpoints))
777 return -1;
779 // Get the priority of the first endpoint (head of the list.
780 // It's other data is extracted as part of the standard profile
781 // decoding.
782 this->endpoint_.priority (endpoints[0].priority);
784 // Use information extracted from the tagged component to
785 // populate the profile. Skip the first endpoint, since it is
786 // always extracted through standard profile body. Also, begin
787 // from the end of the sequence to preserve endpoint order,
788 // since <add_endpoint> method reverses the order of endpoints
789 // in the list.
790 for (CORBA::ULong i = endpoints.length () - 1;
791 i > 0;
792 --i)
794 TAO_IIOP_Endpoint *endpoint = nullptr;
795 ACE_NEW_RETURN (endpoint,
796 TAO_IIOP_Endpoint (endpoints[i].host,
797 endpoints[i].port,
798 endpoints[i].priority),
799 -1);
801 this->add_endpoint (endpoint);
805 // Now decode if there are any TAG_ALTERNATE_IIOP_ADDRESS
806 // components.
808 IOP::MultipleComponentProfile& tc = this->tagged_components_.components();
809 for (CORBA::ULong index = 0; index < tc.length(); index++)
811 if (tc[index].tag != IOP::TAG_ALTERNATE_IIOP_ADDRESS)
812 continue;
813 const CORBA::Octet *buf =
814 tc[index].component_data.get_buffer ();
816 TAO_InputCDR in_cdr (reinterpret_cast<const char*>(buf),
817 tc[index].component_data.length ());
819 // Extract the Byte Order.
820 CORBA::Boolean byte_order;
821 if (!(in_cdr >> ACE_InputCDR::to_boolean (byte_order)))
822 return -1;
824 in_cdr.reset_byte_order (static_cast<int>(byte_order));
826 CORBA::String_var host;
827 CORBA::Short port;
829 if (!(in_cdr >> host.out()) || !(in_cdr >> port))
830 return -1;
832 TAO_IIOP_Endpoint *endpoint = nullptr;
833 ACE_NEW_RETURN (endpoint,
834 TAO_IIOP_Endpoint (host.in(),
835 port,
836 TAO_INVALID_PRIORITY),
837 -1);
839 this->add_endpoint (endpoint);
842 return 0;
845 TAO_END_VERSIONED_NAMESPACE_DECL
847 #endif /* TAO_HAS_IIOP && TAO_HAS_IIOP != 0 */