s/Uint/UInt/g
[ACE_TAO.git] / TAO / tao / IIOP_Profile.cpp
blob64358da1313de38a474cff0ecaacd70d73a44e41
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 () );
551 ACE_OS::sprintf (buf + std::strlen(buf),
552 "%c%s",
553 this->object_key_delimiter_,
554 key.in ());
556 return buf;
559 const char *
560 TAO_IIOP_Profile::prefix ()
562 return ::the_prefix;
565 void
566 TAO_IIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
568 encap.write_octet (TAO_ENCAP_BYTE_ORDER);
570 // The GIOP version
571 encap.write_octet (this->version_.major);
572 encap.write_octet (this->version_.minor);
574 // STRING hostname from profile
575 #if defined (ACE_HAS_IPV6)
576 // For IPv6 decimal addresses make sure the possibly included scopeid
577 // is not published as this has only local meaning.
578 const char* host = 0;
579 const char* pos = 0;
580 if (this->endpoint_.is_ipv6_decimal_ &&
581 (pos = std::strchr (host = this->endpoint_.host (), '%')) != 0)
583 ACE_CString tmp;
584 size_t len = pos - host;
585 tmp.set (this->endpoint_.host (), len, 1);
586 encap.write_string (tmp.c_str ());
588 else
589 #endif /* ACE_HAS_IPV6 */
590 encap.write_string (this->endpoint_.host ());
592 // UNSIGNED SHORT port number
593 encap.write_ushort (this->endpoint_.port ());
595 // OCTET SEQUENCE for object key
596 if (this->ref_object_key_)
597 encap << this->ref_object_key_->object_key ();
598 else
600 TAOLIB_ERROR ((LM_ERROR,
601 "(%P|%t) TAO - IIOP_Profile::create_profile_body "
602 "no object key marshalled\n"));
605 if (this->version_.major > 1 || this->version_.minor > 0)
606 this->tagged_components ().encode (encap);
610 TAO_IIOP_Profile::encode_alternate_endpoints ()
612 // encode IOP::TAG_ALTERNATE_IIOP_ADDRESS tags if there are more
613 // than one endpoints to listen to.
614 const TAO_IIOP_Endpoint *endpoint = &this->endpoint_;
615 for (CORBA::ULong i = 1;
616 i < this->count_;
617 ++i)
619 // The first endpoint is the actual endpoint. The rest of the
620 // endpoints are the alternate endpoints. So, neglect the first
621 // endpoint for TAG_ALTERNATE_IIOP_ADDRESS
622 endpoint = endpoint->next_;
624 if (!endpoint->is_encodable_)
625 continue;
627 // Encode the data structure. - The CORBA specification does not
628 // mandate a particular container for the endpoints, only that
629 // it is encoded as host first, then port.
630 TAO_OutputCDR out_cdr;
632 #if defined (ACE_HAS_IPV6)
633 // For IPv6 decimal addresses make sure the possibly included scopeid
634 // is not published as this has only local meaning.
635 const char* host = 0;
636 const char* pos = 0;
637 if (endpoint->is_ipv6_decimal_ &&
638 (pos = std::strchr (host = endpoint->host (), '%')) != 0)
640 ACE_CString tmp;
641 size_t len = pos - host;
642 tmp.set (endpoint->host (), len, 1);
643 if (!(out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER))
644 || !(out_cdr << tmp.c_str ())
645 || !(out_cdr << endpoint->port ()))
646 return -1;
647 out_cdr.write_string (len, endpoint->host ());
649 else
650 #endif /* ACE_HAS_IPV6 */
651 if (!(out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER))
652 || !(out_cdr << endpoint->host ())
653 || !(out_cdr << endpoint->port ()))
654 return -1;
656 IOP::TaggedComponent tagged_component;
657 tagged_component.tag = IOP::TAG_ALTERNATE_IIOP_ADDRESS;
659 size_t length = out_cdr.total_length ();
660 tagged_component.component_data.length
661 (static_cast<CORBA::ULong>(length));
662 CORBA::Octet *buf =
663 tagged_component.component_data.get_buffer ();
665 for (const ACE_Message_Block *iterator = out_cdr.begin ();
666 iterator != nullptr;
667 iterator = iterator->cont ())
669 size_t i_length = iterator->length ();
670 ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
672 buf += i_length;
675 // Add component with encoded endpoint data to this profile's
676 // TaggedComponents.
677 tagged_components_.set_component (tagged_component);
679 return 0;
683 TAO_IIOP_Profile::encode_endpoints ()
685 CORBA::ULong actual_count = 0;
687 const TAO_IIOP_Endpoint *endpoint = &this->endpoint_;
689 // Count the number of endpoints that needs to be encoded
690 for (CORBA::ULong c = 0;
691 c != this->count_;
692 ++c)
694 if (endpoint->is_encodable_)
695 ++actual_count;
697 endpoint = endpoint->next_;
700 // Create a data structure and fill it with endpoint info for wire
701 // transfer.
702 // We include information for the head of the list
703 // together with other endpoints because even though its addressing
704 // info is transmitted using standard ProfileBody components, its
705 // priority is not!
707 TAO::IIOPEndpointSequence endpoints;
708 endpoints.length (actual_count);
710 endpoint = &this->endpoint_;
712 for (CORBA::ULong i = 0;
713 i < actual_count;
714 ++i)
716 if (endpoint->is_encodable_)
718 #if defined (ACE_HAS_IPV6)
719 if (endpoint->is_ipv6_decimal_)
721 // Don't publish scopeid if included.
722 ACE_CString tmp(endpoint->host ());
723 ACE_CString::size_type pos = tmp.find('%');
724 if (pos != ACE_CString::npos)
726 tmp = tmp.substr (0, pos + 1);
727 tmp[pos] = '\0';
728 endpoints[i].host = tmp.c_str();
730 else
731 endpoints[i].host = tmp.c_str();
733 else
734 #endif /* ACE_HAS_IPV6 */
735 endpoints[i].host = endpoint->host ();
736 endpoints[i].port = endpoint->port ();
737 endpoints[i].priority = endpoint->priority ();
739 endpoint = endpoint->next_;
742 // Encode the data structure.
743 TAO_OutputCDR out_cdr;
744 if (!(out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER))
745 || !(out_cdr << endpoints))
746 return -1;
748 this->set_tagged_components (out_cdr);
750 return 0;
755 TAO_IIOP_Profile::decode_endpoints ()
757 IOP::TaggedComponent tagged_component;
758 tagged_component.tag = TAO_TAG_ENDPOINTS;
760 if (this->tagged_components_.get_component (tagged_component))
762 const CORBA::Octet *buf =
763 tagged_component.component_data.get_buffer ();
765 TAO_InputCDR in_cdr (reinterpret_cast<const char *> (buf),
766 tagged_component.component_data.length ());
768 // Extract the Byte Order.
769 CORBA::Boolean byte_order;
770 if (!(in_cdr >> ACE_InputCDR::to_boolean (byte_order)))
771 return -1;
772 in_cdr.reset_byte_order (static_cast<int> (byte_order));
774 // Extract endpoints sequence.
775 TAO::IIOPEndpointSequence endpoints;
777 if (!(in_cdr >> endpoints))
778 return -1;
780 // Get the priority of the first endpoint (head of the list.
781 // It's other data is extracted as part of the standard profile
782 // decoding.
783 this->endpoint_.priority (endpoints[0].priority);
785 // Use information extracted from the tagged component to
786 // populate the profile. Skip the first endpoint, since it is
787 // always extracted through standard profile body. Also, begin
788 // from the end of the sequence to preserve endpoint order,
789 // since <add_endpoint> method reverses the order of endpoints
790 // in the list.
791 for (CORBA::ULong i = endpoints.length () - 1;
792 i > 0;
793 --i)
795 TAO_IIOP_Endpoint *endpoint = nullptr;
796 ACE_NEW_RETURN (endpoint,
797 TAO_IIOP_Endpoint (endpoints[i].host,
798 endpoints[i].port,
799 endpoints[i].priority),
800 -1);
802 this->add_endpoint (endpoint);
806 // Now decode if there are any TAG_ALTERNATE_IIOP_ADDRESS
807 // components.
809 IOP::MultipleComponentProfile& tc = this->tagged_components_.components();
810 for (CORBA::ULong index = 0; index < tc.length(); index++)
812 if (tc[index].tag != IOP::TAG_ALTERNATE_IIOP_ADDRESS)
813 continue;
814 const CORBA::Octet *buf =
815 tc[index].component_data.get_buffer ();
817 TAO_InputCDR in_cdr (reinterpret_cast<const char*>(buf),
818 tc[index].component_data.length ());
820 // Extract the Byte Order.
821 CORBA::Boolean byte_order;
822 if (!(in_cdr >> ACE_InputCDR::to_boolean (byte_order)))
823 return -1;
825 in_cdr.reset_byte_order (static_cast<int>(byte_order));
827 CORBA::String_var host;
828 CORBA::Short port;
830 if (!(in_cdr >> host.out()) || !(in_cdr >> port))
831 return -1;
833 TAO_IIOP_Endpoint *endpoint = nullptr;
834 ACE_NEW_RETURN (endpoint,
835 TAO_IIOP_Endpoint (host.in(),
836 port,
837 TAO_INVALID_PRIORITY),
838 -1);
840 this->add_endpoint (endpoint);
843 return 0;
846 TAO_END_VERSIONED_NAMESPACE_DECL
848 #endif /* TAO_HAS_IIOP && TAO_HAS_IIOP != 0 */