IIOP_Profile.cpp

Go to the documentation of this file.
00001 #include "tao/IIOP_Profile.h"
00002 
00003 #if defined (TAO_HAS_IIOP) && (TAO_HAS_IIOP != 0)
00004 
00005 #include "tao/Environment.h"
00006 #include "tao/ORB_Core.h"
00007 #include "tao/debug.h"
00008 #include "tao/IIOP_EndpointsC.h"
00009 #include "tao/CDR.h"
00010 #include "tao/SystemException.h"
00011 
00012 #include "ace/OS_NS_string.h"
00013 #include "ace/OS_NS_stdio.h"
00014 
00015 ACE_RCSID (tao,
00016            IIOP_Profile,
00017            "IIOP_Profile.cpp,v 1.125 2006/05/16 12:33:29 jwillemsen Exp")
00018 
00019 #include "ace/os_include/os_netdb.h"
00020 
00021 static const char the_prefix[] = "iiop";
00022 
00023 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00024 
00025 TAO_IIOP_Profile::~TAO_IIOP_Profile (void)
00026 {
00027   // Clean up the list of endpoints since we own it.
00028   // Skip the head, since it is not dynamically allocated.
00029   TAO_Endpoint *tmp = 0;
00030 
00031   for (TAO_Endpoint *next = this->endpoint ()->next ();
00032        next != 0;
00033        next = tmp)
00034     {
00035       tmp = next->next ();
00036       delete next;
00037     }
00038 }
00039 
00040 //@@ TAO_PROFILE_SPL_COPY_HOOK_START
00041 
00042 const char TAO_IIOP_Profile::object_key_delimiter_ = '/';
00043 
00044 char
00045 TAO_IIOP_Profile::object_key_delimiter (void) const
00046 {
00047   return TAO_IIOP_Profile::object_key_delimiter_;
00048 }
00049 
00050 //@@ TAO_PROFILE_SPL_COPY_HOOK_END
00051 
00052 TAO_IIOP_Profile::TAO_IIOP_Profile (const ACE_INET_Addr &addr,
00053                                     const TAO::ObjectKey &object_key,
00054                                     const TAO_GIOP_Message_Version &version,
00055                                     TAO_ORB_Core *orb_core)
00056   : TAO_Profile (IOP::TAG_INTERNET_IOP,
00057                  orb_core,
00058                  object_key,
00059                  version),
00060     endpoint_ (addr,
00061                orb_core->orb_params ()->use_dotted_decimal_addresses ()),
00062     count_ (1)
00063 {
00064 }
00065 
00066 TAO_IIOP_Profile::TAO_IIOP_Profile (const char* host,
00067                                     CORBA::UShort port,
00068                                     const TAO::ObjectKey &object_key,
00069                                     const ACE_INET_Addr &addr,
00070                                     const TAO_GIOP_Message_Version &version,
00071                                     TAO_ORB_Core *orb_core)
00072   : TAO_Profile (IOP::TAG_INTERNET_IOP,
00073                  orb_core,
00074                  object_key,
00075                  version),
00076     endpoint_ (host, port, addr),
00077     count_ (1)
00078 {
00079 }
00080 
00081 TAO_IIOP_Profile::TAO_IIOP_Profile (TAO_ORB_Core *orb_core)
00082   : TAO_Profile (IOP::TAG_INTERNET_IOP,
00083                  orb_core,
00084                  TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR,
00085                                            TAO_DEF_GIOP_MINOR)),
00086     endpoint_ (),
00087     count_ (1)
00088 {
00089 }
00090 
00091 //@@ TAO_PROFILE_SPL_COPY_HOOK_START
00092 int
00093 TAO_IIOP_Profile::decode_profile (TAO_InputCDR& cdr)
00094 {
00095   // Decode host and port into the <endpoint_>.
00096   if (cdr.read_string (this->endpoint_.host_.out ()) == 0
00097       || cdr.read_ushort (this->endpoint_.port_) == 0)
00098     {
00099       if (TAO_debug_level > 0)
00100         ACE_DEBUG ((LM_DEBUG,
00101                     ACE_TEXT ("TAO (%P|%t) IIOP_Profile::decode - ")
00102                     ACE_TEXT ("error while decoding host/port\n")));
00103       return -1;
00104     }
00105 
00106   if (cdr.good_bit ())
00107     {
00108       // Invalidate the object_addr_ until first access.
00109       this->endpoint_.object_addr_.set_type (-1);
00110 
00111       const char* csv = this->orb_core()->orb_params()->preferred_interfaces();
00112       bool const enforce =
00113         this->orb_core()->orb_params()->enforce_pref_interfaces();
00114       this->count_ += this->endpoint_.preferred_interfaces(csv, enforce);
00115 
00116       return 1;
00117     }
00118 
00119   return -1;
00120 }
00121 
00122 void
00123 TAO_IIOP_Profile::parse_string_i (const char *ior
00124                                   ACE_ENV_ARG_DECL)
00125 {
00126   // Pull off the "hostname:port/" part of the objref
00127   // Copy the string because we are going to modify it...
00128 
00129   const char *okd = ACE_OS::strchr (ior, this->object_key_delimiter_);
00130 
00131   if (okd == 0 || okd == ior)
00132     {
00133       // No object key delimiter or no hostname specified.
00134       ACE_THROW (CORBA::INV_OBJREF (
00135                    CORBA::SystemException::_tao_minor_code (
00136                      0,
00137                      EINVAL),
00138                    CORBA::COMPLETED_NO));
00139     }
00140 
00141   // Length of host string.
00142   CORBA::ULong length_host = 0;
00143 
00144   const char *cp_pos = ACE_OS::strchr (ior, ':');  // Look for a port
00145 #if defined (ACE_HAS_IPV6)
00146   // IPv6 numeric address in host string?
00147   bool ipv6_in_host = false;
00148 
00149   // Check if this is a (possibly) IPv6 supporting profile containing a
00150   // decimal IPv6 address representation.
00151   if ((this->version().major > TAO_MIN_IPV6_IIOP_MAJOR ||
00152         this->version().minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
00153       ior[0] == '[')
00154     {
00155       // In this case we have to find the end of the numeric address and
00156       // start looking for the port separator from there.
00157       const char *cp_pos_a = ACE_OS::strchr(ior, ']');
00158       if (cp_pos_a == 0)
00159         {
00160           // No valid IPv6 address specified.
00161           if (TAO_debug_level > 0)
00162             {
00163               ACE_DEBUG ((LM_ERROR,
00164                        ACE_TEXT ("\nTAO (%P|%t) IIOP_Profile: ")
00165                        ACE_TEXT ("Invalid IPv6 decimal address specified.\n")));
00166             }
00167 
00168           ACE_THROW (CORBA::INV_OBJREF (
00169                        CORBA::SystemException::_tao_minor_code (
00170                          0,
00171                          EINVAL),
00172                        CORBA::COMPLETED_NO));
00173         }
00174       else
00175         {
00176           if (cp_pos_a[1] == ':')    // Look for a port
00177             cp_pos = cp_pos_a + 1;
00178           else
00179             cp_pos = 0;
00180           ipv6_in_host = true; // host string contains full IPv6 numeric address
00181         }
00182     }
00183 #endif /* ACE_HAS_IPV6 */
00184 
00185   if (cp_pos == ior)
00186     {
00187       // No hostname, however one is required by the spec when specifying a port.
00188       // See formal-04-03-01, section 13.6.10.3
00189       if (TAO_debug_level > 0)
00190         {
00191           ACE_DEBUG ((LM_ERROR,
00192                    ACE_TEXT ("\nTAO (%P|%t) IIOP_Profile: ")
00193                    ACE_TEXT ("Host address may be omited only when no port has been specified.\n")));
00194         }
00195 
00196       ACE_THROW (CORBA::INV_OBJREF (
00197                    CORBA::SystemException::_tao_minor_code (
00198                      0,
00199                      EINVAL),
00200                    CORBA::COMPLETED_NO));
00201     }
00202   else if (cp_pos != 0)
00203     {
00204       // A port number or port name was specified.
00205       CORBA::ULong length_port = okd - cp_pos - 1;
00206       CORBA::String_var tmp = CORBA::string_alloc (length_port);
00207 
00208       ACE_OS::strncpy (tmp.inout (), cp_pos + 1, length_port);
00209       tmp[length_port] = '\0';
00210       if (length_port == 0)
00211         {
00212           this->endpoint_.port_ = 2809; // default IIOP port for
00213           // parsing corbaloc strings
00214         }
00215       else if (ACE_OS::strspn (tmp.in (), "1234567890") == length_port)
00216         {
00217           this->endpoint_.port_ =
00218             static_cast<CORBA::UShort> (ACE_OS::atoi (tmp.in ()));
00219         }
00220       else
00221         {
00222           ACE_INET_Addr ia;
00223           if (ia.string_to_addr (tmp.in ()) == -1)
00224             {
00225               ACE_THROW (CORBA::INV_OBJREF (
00226                              CORBA::SystemException::_tao_minor_code (
00227                                0,
00228                                EINVAL),
00229                              CORBA::COMPLETED_NO));
00230             }
00231           else
00232             {
00233               this->endpoint_.port_ = ia.get_port_number ();
00234             }
00235         }
00236       length_host = cp_pos - ior;
00237     }
00238   else
00239     length_host = okd - ior;
00240 
00241 #if defined (ACE_HAS_IPV6)
00242   if (ipv6_in_host)
00243     length_host -= 2; // don't store '[' and ']'
00244 #endif /* ACE_HAS_IPV6 */
00245 
00246   CORBA::String_var tmp = CORBA::string_alloc (length_host);
00247 
00248 #if defined (ACE_HAS_IPV6)
00249   if (ipv6_in_host)
00250     ACE_OS::strncpy (tmp.inout (), ior + 1, length_host);
00251   else
00252 #endif /* ACE_HAS_IPV6 */
00253   // Skip the trailing '/'
00254   ACE_OS::strncpy (tmp.inout (), ior, length_host);
00255   tmp[length_host] = '\0';
00256 
00257   this->endpoint_.host_ = tmp._retn ();
00258 #if defined (ACE_HAS_IPV6)
00259   this->endpoint_.is_ipv6_decimal_ = ipv6_in_host;
00260 #endif /* ACE_HAS_IPV6 */
00261 
00262   if (ACE_OS::strcmp (this->endpoint_.host_.in (), "") == 0)
00263     {
00264       ACE_INET_Addr host_addr;
00265 
00266       char tmp_host [MAXHOSTNAMELEN + 1];
00267 
00268       // If no host is specified: assign the default host, i.e. the
00269       // local host.
00270       if (host_addr.get_host_name (tmp_host,
00271                                    sizeof (tmp_host)) != 0)
00272         {
00273           // Can't get the IP address since the INET_Addr wasn't
00274           // initialized.  Just throw an exception.
00275 
00276           if (TAO_debug_level > 0)
00277             ACE_DEBUG ((LM_DEBUG,
00278                         ACE_TEXT ("\n\nTAO (%P|%t) ")
00279                         ACE_TEXT ("IIOP_Profile::parse_string ")
00280                         ACE_TEXT ("- %p\n\n"),
00281                         ACE_TEXT ("cannot determine hostname")));
00282 
00283           // @@ What's the right exception to throw here?
00284           ACE_THROW (CORBA::INV_OBJREF (
00285                        CORBA::SystemException::_tao_minor_code (
00286                          0,
00287                          EINVAL),
00288                        CORBA::COMPLETED_NO));
00289         }
00290       else
00291         this->endpoint_.host_ = CORBA::string_dup (tmp_host);
00292     }
00293 
00294   TAO::ObjectKey ok;
00295 
00296   TAO::ObjectKey::decode_string_to_sequence (ok,
00297                                              okd + 1);
00298 
00299   (void) this->orb_core ()->object_key_table ().bind (ok,
00300                                                       this->ref_object_key_);
00301 }
00302 
00303 CORBA::Boolean
00304 TAO_IIOP_Profile::do_is_equivalent (const TAO_Profile *other_profile)
00305 {
00306   if (other_profile == this)
00307     return 1;
00308 
00309   const TAO_IIOP_Profile *op =
00310     dynamic_cast<const TAO_IIOP_Profile *> (other_profile);
00311 
00312   // Make sure we have a TAO_IIOP_Profile.
00313   if (op == 0)
00314     return 0;
00315 
00316   if (this->count_ == 0 && op->count_ == 0)
00317     return 1;
00318   if (this->count_ != op->count_)
00319     return 0;
00320   // Check endpoints equivalence.
00321   const TAO_IIOP_Endpoint *other_endp = &op->endpoint_;
00322   for (TAO_IIOP_Endpoint *endp = &this->endpoint_;
00323        endp != 0;
00324        endp = endp->next_)
00325     {
00326       if (endp->is_equivalent (other_endp))
00327         other_endp = other_endp->next_;
00328       else
00329         return 0;
00330     }
00331 
00332   return 1;
00333 }
00334 
00335 CORBA::ULong
00336 TAO_IIOP_Profile::hash (CORBA::ULong max
00337                         ACE_ENV_ARG_DECL_NOT_USED)
00338 {
00339   // Get the hash value for all endpoints.
00340   CORBA::ULong hashval = 0;
00341   for (TAO_IIOP_Endpoint *endp = &this->endpoint_;
00342        endp != 0;
00343        endp = endp->next_)
00344     {
00345       hashval += endp->hash ();
00346     }
00347 
00348   hashval += this->version_.minor;
00349   hashval += this->tag ();
00350 
00351   const TAO::ObjectKey &ok =
00352     this->ref_object_key_->object_key ();
00353 
00354   if (ok.length () >= 4)
00355     {
00356       hashval += ok[1];
00357       hashval += ok[3];
00358     }
00359 
00360   hashval += TAO_Profile::hash_service_i (max);
00361 
00362   return hashval % max;
00363 }
00364 
00365 TAO_Endpoint*
00366 TAO_IIOP_Profile::endpoint (void)
00367 {
00368   return &this->endpoint_;
00369 }
00370 
00371 CORBA::ULong
00372 TAO_IIOP_Profile::endpoint_count (void) const
00373 {
00374   return this->count_;
00375 }
00376 
00377 void
00378 TAO_IIOP_Profile::add_endpoint (TAO_IIOP_Endpoint *endp)
00379 {
00380   endp->next_ = this->endpoint_.next_;
00381   this->endpoint_.next_ = endp;
00382 
00383   ++this->count_;
00384 }
00385 
00386 void
00387 TAO_IIOP_Profile::remove_endpoint (TAO_IIOP_Endpoint *endp)
00388 {
00389   if (endp == 0)
00390     return;
00391 
00392   // special handling for the target matching the base endpoint
00393   if (endp == &this->endpoint_)
00394     {
00395       if (--this->count_ > 0)
00396         {
00397           TAO_IIOP_Endpoint* n = this->endpoint_.next_;
00398           this->endpoint_ = *n;
00399           // since the assignment operator does not copy the next_
00400           // pointer, we must do it by hand
00401           this->endpoint_.next_ = n->next_;
00402           delete n;
00403         }
00404       return;
00405     }
00406 
00407   TAO_IIOP_Endpoint* last = &this->endpoint_;
00408   TAO_IIOP_Endpoint* cur = this->endpoint_.next_;
00409 
00410   while (cur != 0)
00411   {
00412     if (cur == endp)
00413       break;
00414     last = cur;
00415     cur = cur->next_;
00416   }
00417 
00418   if (cur != 0)
00419   {
00420     last->next_ = cur->next_;
00421     cur->next_ = 0;
00422     --this->count_;
00423     delete cur;
00424   }
00425 }
00426 
00427 void
00428 TAO_IIOP_Profile::remove_generic_endpoint (TAO_Endpoint *ep)
00429 {
00430   this->remove_endpoint(dynamic_cast<TAO_IIOP_Endpoint *>(ep));
00431 }
00432 
00433 void
00434 TAO_IIOP_Profile::add_generic_endpoint (TAO_Endpoint *endp)
00435 {
00436   TAO_IIOP_Endpoint *iep = dynamic_cast<TAO_IIOP_Endpoint *>(endp);
00437   if (iep != 0)
00438     {
00439       TAO_IIOP_Endpoint *clone;
00440       ACE_NEW (clone, TAO_IIOP_Endpoint(*iep));
00441       this->add_endpoint(clone);
00442     }
00443 }
00444 
00445 char *
00446 TAO_IIOP_Profile::to_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00447 {
00448   // corbaloc:iiop:1.2@host:port,iiop:1.2@host:port,.../key
00449 
00450   CORBA::String_var key;
00451   TAO::ObjectKey::encode_sequence_to_string (key.inout(),
00452                                              this->ref_object_key_->object_key ());
00453 
00454   size_t buflen = (
00455        8 /* "corbaloc" */ +
00456        1 /* colon separator */ +
00457        1 /* object key separator */ +
00458        ACE_OS::strlen (key.in ()));
00459   size_t pfx_len = (
00460        ACE_OS::strlen (::the_prefix) /* "iiop" */ +
00461        1 /* colon separator */);
00462 
00463  const TAO_IIOP_Endpoint *endp = 0;
00464  for (endp = &this->endpoint_; endp != 0; endp = endp->next_)
00465    {
00466       buflen += (
00467           pfx_len +
00468           1 /* major version */ +
00469           1 /* decimal point */ +
00470           1 /* minor version */ +
00471           1 /* `@' character */ +
00472           ACE_OS::strlen (endp->host ()) +
00473           1 /* colon separator */ +
00474           5 /* port number */ +
00475           1 /* comma */);
00476 #if defined (ACE_HAS_IPV6)
00477       if (endp->is_ipv6_decimal_)
00478         buflen += 2; // room for '[' and ']'
00479 #endif /* ACE_HAS_IPV6 */
00480    }
00481 
00482   static const char digits [] = "0123456789";
00483 
00484   char * buf = CORBA::string_alloc (static_cast<CORBA::ULong> (buflen));
00485 
00486   ACE_OS::strcpy(buf, "corbaloc:");
00487 
00488   for (endp = &this->endpoint_; endp != 0; endp = endp->next_)
00489     {
00490       if(&this->endpoint_ != endp)
00491       ACE_OS::strcat(buf, ",");
00492 
00493 #if defined (ACE_HAS_IPV6)
00494       if (endp->is_ipv6_decimal_)
00495         {
00496           // Don't publish scopeid if included.
00497           ACE_CString tmp(endp->host ());
00498           ssize_t pos = tmp.find('%');
00499           if (pos != ACE_CString::npos)
00500             {
00501               tmp = tmp.substr(0, pos + 1);
00502               tmp[pos] = '\0';
00503             }
00504           ACE_OS::sprintf (buf + ACE_OS::strlen(buf),
00505                   "%s:%c.%c@[%s]:%d",
00506                   ::the_prefix,
00507                   digits [this->version_.major],
00508                   digits [this->version_.minor],
00509                   tmp.c_str (),
00510                   endp->port () );
00511         }
00512       else
00513 #endif
00514       ACE_OS::sprintf (buf + ACE_OS::strlen(buf),
00515               "%s:%c.%c@%s:%d",
00516               ::the_prefix,
00517               digits [this->version_.major],
00518               digits [this->version_.minor],
00519               endp->host (),
00520               endp->port () );
00521 
00522   }
00523   ACE_OS::sprintf (buf + ACE_OS::strlen(buf),
00524           "%c%s",
00525           this->object_key_delimiter_,
00526           key.in ());
00527 
00528   return buf;
00529 }
00530 
00531 const char *
00532 TAO_IIOP_Profile::prefix (void)
00533 {
00534   return ::the_prefix;
00535 }
00536 
00537 void
00538 TAO_IIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
00539 {
00540   encap.write_octet (TAO_ENCAP_BYTE_ORDER);
00541 
00542   // The GIOP version
00543   encap.write_octet (this->version_.major);
00544   encap.write_octet (this->version_.minor);
00545 
00546   // STRING hostname from profile
00547 #if defined (ACE_HAS_IPV6)
00548   // For IPv6 decimal addresses make sure the possibly included scopeid
00549   // is not published as this has only local meaning.
00550   const char* host;
00551   const char* pos;
00552   if (this->endpoint_.is_ipv6_decimal_ &&
00553       (pos = ACE_OS::strchr (host = this->endpoint_.host (), '%')) != 0)
00554     {
00555       ACE_CString tmp;
00556       size_t len = pos - host;
00557       tmp.set (this->endpoint_.host (), len, 1);
00558       encap.write_string (tmp.c_str ());
00559     }
00560   else
00561 #endif /* ACE_HAS_IPV6 */
00562   encap.write_string (this->endpoint_.host ());
00563 
00564 
00565   // UNSIGNED SHORT port number
00566   encap.write_ushort (this->endpoint_.port ());
00567 
00568   // OCTET SEQUENCE for object key
00569   if (this->ref_object_key_)
00570     encap << this->ref_object_key_->object_key ();
00571   else
00572     {
00573       ACE_ERROR ((LM_ERROR,
00574                   "(%P|%t) TAO - IIOP_Profile::create_profile_body "
00575                   "no object key marshalled \n"));
00576     }
00577 
00578   if (this->version_.major > 1
00579       || this->version_.minor > 0)
00580     this->tagged_components ().encode (encap);
00581 }
00582 
00583 int
00584 TAO_IIOP_Profile::encode_alternate_endpoints (void)
00585 {
00586   // encode IOP::TAG_ALTERNATE_IIOP_ADDRESS tags if there are more
00587   // than one endpoints to listen to.
00588   const TAO_IIOP_Endpoint *endpoint = &this->endpoint_;
00589   for (CORBA::ULong i = 1;
00590        i < this->count_;
00591        ++i)
00592     {
00593       // The first endpoint is the actual endpoint. The rest of the
00594       // endpoints are the alternate endpoints. So, neglect the first
00595       // endpoint for TAG_ALTERNATE_IIOP_ADDRESS
00596       endpoint = endpoint->next_;
00597 
00598       if (!endpoint->is_encodable_)
00599         continue;
00600 
00601       // Encode the data structure. - The CORBA specification does not
00602       // mandate a particular container for the endpoints, only that
00603       // it is encoded as host first, then port.
00604       TAO_OutputCDR out_cdr;
00605 
00606 #if defined (ACE_HAS_IPV6)
00607       // For IPv6 decimal addresses make sure the possibly included scopeid
00608       // is not published as this has only local meaning.
00609       const char* host;
00610       const char* pos;
00611       if (endpoint->is_ipv6_decimal_ &&
00612           (pos = ACE_OS::strchr (host = endpoint->host (), '%')) != 0)
00613         {
00614           ACE_CString tmp;
00615           size_t len = pos - host;
00616           tmp.set (endpoint->host (), len, 1);
00617           if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER) == 0)
00618               || (out_cdr << tmp.c_str () == 0)
00619               || (out_cdr << endpoint->port () == 0))
00620             return -1;
00621           out_cdr.write_string (len, endpoint->host ());
00622         }
00623       else
00624 #endif /* ACE_HAS_IPV6 */
00625       if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER) == 0)
00626                 || (out_cdr << endpoint->host () == 0)
00627           || (out_cdr << endpoint->port () == 0))
00628         return -1;
00629 
00630       IOP::TaggedComponent tagged_component;
00631       tagged_component.tag = IOP::TAG_ALTERNATE_IIOP_ADDRESS;
00632 
00633       size_t length = out_cdr.total_length ();
00634       tagged_component.component_data.length
00635         (static_cast<CORBA::ULong>(length));
00636       CORBA::Octet *buf =
00637         tagged_component.component_data.get_buffer ();
00638 
00639       for (const ACE_Message_Block *iterator = out_cdr.begin ();
00640                  iterator != 0;
00641            iterator = iterator->cont ())
00642         {
00643           size_t i_length = iterator->length ();
00644           ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
00645 
00646           buf += i_length;
00647         }
00648 
00649       // Add component with encoded endpoint data to this profile's
00650       // TaggedComponents.
00651       tagged_components_.set_component (tagged_component);
00652     }
00653   return  0;
00654 }
00655 
00656 int
00657 TAO_IIOP_Profile::encode_endpoints (void)
00658 {
00659   CORBA::ULong actual_count = 0;
00660 
00661   const TAO_IIOP_Endpoint *endpoint = &this->endpoint_;
00662 
00663   // Count the number of endpoints that needs to be encoded
00664   for (CORBA::ULong c = 0;
00665        c != this->count_;
00666        ++c)
00667     {
00668       if (endpoint->is_encodable_)
00669         ++actual_count;
00670 
00671       endpoint = endpoint->next_;
00672     }
00673 
00674   // Create a data structure and fill it with endpoint info for wire
00675   // transfer.
00676   // We include information for the head of the list
00677   // together with other endpoints because even though its addressing
00678   // info is transmitted using standard ProfileBody components, its
00679   // priority is not!
00680 
00681   TAO::IIOPEndpointSequence endpoints;
00682   endpoints.length (actual_count);
00683 
00684   endpoint = &this->endpoint_;
00685 
00686   for (CORBA::ULong i = 0;
00687        i < actual_count;
00688        ++i)
00689     {
00690       if (endpoint->is_encodable_)
00691         {
00692 #if defined (ACE_HAS_IPV6)
00693           if (endpoint->is_ipv6_decimal_)
00694             {
00695               // Don't publish scopeid if included.
00696               ACE_CString tmp(endpoint->host ());
00697               ssize_t pos = tmp.find('%');
00698               if (pos != ACE_CString::npos)
00699                 {
00700                   tmp = tmp.substr (0, pos + 1);
00701                   tmp[pos] = '\0';
00702                   endpoints[i].host = tmp.c_str();
00703                 }
00704               else
00705                 endpoints[i].host = tmp.c_str();
00706             }
00707           else
00708 #endif /* ACE_HAS_IPV6 */
00709           endpoints[i].host = endpoint->host ();
00710           endpoints[i].port = endpoint->port ();
00711           endpoints[i].priority = endpoint->priority ();
00712         }
00713       endpoint = endpoint->next_;
00714     }
00715 
00716   // Encode the data structure.
00717   TAO_OutputCDR out_cdr;
00718   if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)
00719        == 0)
00720       || (out_cdr << endpoints) == 0)
00721     return -1;
00722 
00723   this->set_tagged_components (out_cdr);
00724 
00725   return  0;
00726 }
00727 
00728 
00729 int
00730 TAO_IIOP_Profile::decode_endpoints (void)
00731 {
00732   IOP::TaggedComponent tagged_component;
00733   tagged_component.tag = TAO_TAG_ENDPOINTS;
00734 
00735   if (this->tagged_components_.get_component (tagged_component))
00736     {
00737       const CORBA::Octet *buf =
00738         tagged_component.component_data.get_buffer ();
00739 
00740       TAO_InputCDR in_cdr (reinterpret_cast<const char *> (buf),
00741                            tagged_component.component_data.length ());
00742 
00743       // Extract the Byte Order.
00744       CORBA::Boolean byte_order;
00745       if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00746         return -1;
00747       in_cdr.reset_byte_order (static_cast<int> (byte_order));
00748 
00749       // Extract endpoints sequence.
00750       TAO::IIOPEndpointSequence endpoints;
00751 
00752       if ((in_cdr >> endpoints) == 0)
00753         return -1;
00754 
00755       // Get the priority of the first endpoint (head of the list.
00756       // It's other data is extracted as part of the standard profile
00757       // decoding.
00758       this->endpoint_.priority (endpoints[0].priority);
00759 
00760       // Use information extracted from the tagged component to
00761       // populate the profile.  Skip the first endpoint, since it is
00762       // always extracted through standard profile body.  Also, begin
00763       // from the end of the sequence to preserve endpoint order,
00764       // since <add_endpoint> method reverses the order of endpoints
00765       // in the list.
00766       for (CORBA::ULong i = endpoints.length () - 1;
00767            i > 0;
00768            --i)
00769         {
00770           TAO_IIOP_Endpoint *endpoint = 0;
00771           ACE_NEW_RETURN (endpoint,
00772                           TAO_IIOP_Endpoint (endpoints[i].host,
00773                                              endpoints[i].port,
00774                                              endpoints[i].priority),
00775                           -1);
00776 
00777           this->add_endpoint (endpoint);
00778         }
00779     }
00780 
00781   // Now decode if there are any TAG_ALTERNATE_IIOP_ADDRESS
00782   // components.
00783 
00784   IOP::MultipleComponentProfile& tc = this->tagged_components_.components();
00785   for (CORBA::ULong index = 0; index < tc.length(); index++)
00786     {
00787       if (tc[index].tag != IOP::TAG_ALTERNATE_IIOP_ADDRESS)
00788         continue;
00789       const CORBA::Octet *buf =
00790         tc[index].component_data.get_buffer ();
00791 
00792       TAO_InputCDR in_cdr (reinterpret_cast<const char*>(buf),
00793                            tc[index].component_data.length ());
00794 
00795       // Extract the Byte Order.
00796       CORBA::Boolean byte_order;
00797       if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00798         return -1;
00799 
00800       in_cdr.reset_byte_order (static_cast<int>(byte_order));
00801 
00802       CORBA::String_var host;
00803       CORBA::Short port;
00804 
00805       if ((in_cdr >> host.out()) == 0 ||
00806           (in_cdr >> port) == 0)
00807         return -1;
00808 
00809       TAO_IIOP_Endpoint *endpoint = 0;
00810       ACE_NEW_RETURN (endpoint,
00811                       TAO_IIOP_Endpoint (host.in(),
00812                                          port,
00813                                          TAO_INVALID_PRIORITY),
00814                       -1);
00815 
00816       this->add_endpoint (endpoint);
00817     }
00818 
00819   return 0;
00820 }
00821 //@@ TAO_PROFILE_SPL_COPY_HOOK_END
00822 
00823 TAO_END_VERSIONED_NAMESPACE_DECL
00824 
00825 #endif /* TAO_HAS_IIOP && TAO_HAS_IIOP != 0 */

Generated on Thu Nov 9 11:54:13 2006 for TAO by doxygen 1.3.6