TAO_IIOP_Profile Class Reference

This class defines the protocol specific attributes required for locating ORBs over a TCP/IP network. More...

#include <IIOP_Profile.h>

Inheritance diagram for TAO_IIOP_Profile:

Inheritance graph
[legend]
Collaboration diagram for TAO_IIOP_Profile:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 TAO_IIOP_Profile (const ACE_INET_Addr &addr, const TAO::ObjectKey &object_key, const TAO_GIOP_Message_Version &version, TAO_ORB_Core *orb_core)
 TAO_IIOP_Profile (const char *host, CORBA::UShort port, const TAO::ObjectKey &object_key, const ACE_INET_Addr &addr, const TAO_GIOP_Message_Version &version, TAO_ORB_Core *orb_core)
 TAO_IIOP_Profile (TAO_ORB_Core *orb_core)
 Profile constructor, default.
void add_endpoint (TAO_IIOP_Endpoint *endp)
void remove_endpoint (TAO_IIOP_Endpoint *endp)
virtual void remove_generic_endpoint (TAO_Endpoint *ep)
virtual void add_generic_endpoint (TAO_Endpoint *ep)
 Add an endpoint when the specific endpoint type is unknown.
virtual char object_key_delimiter (void) const
 The object key delimiter that IIOP uses or expects.
virtual char * to_string (void)
 Template methods. Please see Profile.h for documentation.
virtual int encode_endpoints (void)
virtual int encode_alternate_endpoints (void)
virtual TAO_Endpointendpoint (void)
virtual TAO_Endpointbase_endpoint (void)
virtual CORBA::ULong endpoint_count (void) const
 Return how many endpoints this profile contains.
virtual CORBA::ULong hash (CORBA::ULong max)
 Return a hash value for this object.

Static Public Member Functions

static const char * prefix (void)
 Return the char string prefix.

Static Public Attributes

static const char object_key_delimiter_ = '/'

Protected Member Functions

 ~TAO_IIOP_Profile (void)
 Destructor is to be called only through <_decr_refcnt>.
int encode_endpoints_for_rt (void)
virtual int decode_profile (TAO_InputCDR &cdr)
 Template methods. Please see Profile.h for the documentation.
virtual int decode_endpoints (void)
virtual void parse_string_i (const char *string)
 Protocol specific implementation of parse_string ().
virtual void create_profile_body (TAO_OutputCDR &cdr) const
 Creates an encapsulation of the ProfileBody struct in the cdr.
virtual CORBA::Boolean do_is_equivalent (const TAO_Profile *other_profile)
 Profile equivalence template method invoked on subclasses.

Protected Attributes

TAO_IIOP_Endpoint endpoint_
CORBA::ULong count_
 Number of endpoints in the list headed by <endpoint_>.

Detailed Description

This class defines the protocol specific attributes required for locating ORBs over a TCP/IP network.

This class defines the IIOP profile as specified in the CORBA specification.

Definition at line 44 of file IIOP_Profile.h.


Constructor & Destructor Documentation

TAO_IIOP_Profile::TAO_IIOP_Profile ( const ACE_INET_Addr addr,
const TAO::ObjectKey &  object_key,
const TAO_GIOP_Message_Version version,
TAO_ORB_Core orb_core 
)

Profile constructor, same as above except the object_key has already been marshaled.

Definition at line 51 of file IIOP_Profile.cpp.

00055   : TAO_Profile (IOP::TAG_INTERNET_IOP,
00056                  orb_core,
00057                  object_key,
00058                  version),
00059     endpoint_ (addr,
00060                orb_core->orb_params ()->use_dotted_decimal_addresses ()),
00061     count_ (1)
00062 {
00063 }

TAO_IIOP_Profile::TAO_IIOP_Profile ( const char *  host,
CORBA::UShort  port,
const TAO::ObjectKey &  object_key,
const ACE_INET_Addr addr,
const TAO_GIOP_Message_Version version,
TAO_ORB_Core orb_core 
)

Profile constructor, this is the most efficient since it doesn't require any address resolution processing.

Definition at line 65 of file IIOP_Profile.cpp.

00071   : TAO_Profile (IOP::TAG_INTERNET_IOP,
00072                  orb_core,
00073                  object_key,
00074                  version),
00075     endpoint_ (host, port, addr),
00076     count_ (1)
00077 {
00078 }

TAO_IIOP_Profile::TAO_IIOP_Profile ( TAO_ORB_Core orb_core  ) 

Profile constructor, default.

Definition at line 80 of file IIOP_Profile.cpp.

00081   : TAO_Profile (IOP::TAG_INTERNET_IOP,
00082                  orb_core,
00083                  TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR,
00084                                            TAO_DEF_GIOP_MINOR)),
00085     endpoint_ (),
00086     count_ (1)
00087 {
00088 }

TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_IIOP_Profile::~TAO_IIOP_Profile ( void   )  [protected]

Destructor is to be called only through <_decr_refcnt>.

Definition at line 24 of file IIOP_Profile.cpp.

References TAO_Endpoint::next().

00025 {
00026   // Clean up the list of endpoints since we own it.
00027   // Skip the head, since it is not dynamically allocated.
00028   TAO_Endpoint *tmp = 0;
00029 
00030   for (TAO_Endpoint *next = this->endpoint ()->next ();
00031        next != 0;
00032        next = tmp)
00033     {
00034       tmp = next->next ();
00035       delete next;
00036     }
00037 }


Member Function Documentation

void TAO_IIOP_Profile::add_endpoint ( TAO_IIOP_Endpoint endp  ) 

Add endp to this profile's list of endpoints (it is inserted next to the head of the list). This profiles takes ownership of endp.

Definition at line 395 of file IIOP_Profile.cpp.

References count_, endpoint_, and TAO_IIOP_Endpoint::next_.

Referenced by add_generic_endpoint(), TAO_IIOP_Acceptor::create_shared_profile(), and decode_endpoints().

00396 {
00397   endp->next_ = this->endpoint_.next_;
00398   this->endpoint_.next_ = endp;
00399 
00400   ++this->count_;
00401 }

void TAO_IIOP_Profile::add_generic_endpoint ( TAO_Endpoint ep  )  [virtual]

Add an endpoint when the specific endpoint type is unknown.

Reimplemented from TAO_Profile.

Definition at line 451 of file IIOP_Profile.cpp.

References ACE_NEW, and add_endpoint().

00452 {
00453   TAO_IIOP_Endpoint *iep = dynamic_cast<TAO_IIOP_Endpoint *>(endp);
00454   if (iep != 0)
00455     {
00456       TAO_IIOP_Endpoint *clone;
00457       ACE_NEW (clone, TAO_IIOP_Endpoint(*iep));
00458       this->add_endpoint(clone);
00459     }
00460 }

TAO_Endpoint * TAO_IIOP_Profile::base_endpoint ( void   )  [virtual]

Since SSLIOP_Profile derives from IIOP_Profile, but SSLIOP_Endpoint does not derive from IIOP_Endpoint, it is necessary to have a way of always getting the IIOP_Endpoint using a generic interface regardless of the final type of the profile.

Reimplemented from TAO_Profile.

Definition at line 381 of file IIOP_Profile.cpp.

References endpoint_.

00382 {
00383   // do not call endpoint(), return the value directly. This is to
00384   // avoid calling a derived implementation of endpoint().
00385   return &this->endpoint_;
00386 }

void TAO_IIOP_Profile::create_profile_body ( TAO_OutputCDR cdr  )  const [protected, virtual]

Creates an encapsulation of the ProfileBody struct in the cdr.

Implements TAO_Profile.

Definition at line 555 of file IIOP_Profile.cpp.

References ACE_ERROR, TAO_Tagged_Components::encode(), LM_ERROR, TAO_Profile::ref_object_key_, ACE_OS::strchr(), TAO_Profile::tagged_components(), TAO_ENCAP_BYTE_ORDER, ACE_OutputCDR::write_octet(), ACE_OutputCDR::write_string(), and ACE_OutputCDR::write_ushort().

00556 {
00557   encap.write_octet (TAO_ENCAP_BYTE_ORDER);
00558 
00559   // The GIOP version
00560   encap.write_octet (this->version_.major);
00561   encap.write_octet (this->version_.minor);
00562 
00563   // STRING hostname from profile
00564 #if defined (ACE_HAS_IPV6)
00565   // For IPv6 decimal addresses make sure the possibly included scopeid
00566   // is not published as this has only local meaning.
00567   const char* host = 0;
00568   const char* pos = 0;
00569   if (this->endpoint_.is_ipv6_decimal_ &&
00570       (pos = ACE_OS::strchr (host = this->endpoint_.host (), '%')) != 0)
00571     {
00572       ACE_CString tmp;
00573       size_t len = pos - host;
00574       tmp.set (this->endpoint_.host (), len, 1);
00575       encap.write_string (tmp.c_str ());
00576     }
00577   else
00578 #endif /* ACE_HAS_IPV6 */
00579   encap.write_string (this->endpoint_.host ());
00580 
00581 
00582   // UNSIGNED SHORT port number
00583   encap.write_ushort (this->endpoint_.port ());
00584 
00585   // OCTET SEQUENCE for object key
00586   if (this->ref_object_key_)
00587     encap << this->ref_object_key_->object_key ();
00588   else
00589     {
00590       ACE_ERROR ((LM_ERROR,
00591                   "(%P|%t) TAO - IIOP_Profile::create_profile_body "
00592                   "no object key marshalled \n"));
00593     }
00594 
00595   if (this->version_.major > 1
00596       || this->version_.minor > 0)
00597     this->tagged_components ().encode (encap);
00598 }

int TAO_IIOP_Profile::decode_endpoints ( void   )  [protected, virtual]

Helper for decode(). Decodes endpoints from a tagged component. Decode only if RTCORBA is enabled. Furthermore, we may not find TAO_TAG_ENDPOINTS component, e.g., if we are talking to nonRT version of TAO or some other ORB. This is not an error, and we must proceed. Return 0 on success and -1 on failure.

Implements TAO_Profile.

Definition at line 747 of file IIOP_Profile.cpp.

References ACE_NEW_RETURN, add_endpoint(), TAO_Tagged_Components::components(), endpoint(), endpoint_, TAO_Endpoint::priority(), TAO_Profile::tag(), TAO_Profile::tagged_components_, TAO_INVALID_PRIORITY, and TAO_TAG_ENDPOINTS.

00748 {
00749   IOP::TaggedComponent tagged_component;
00750   tagged_component.tag = TAO_TAG_ENDPOINTS;
00751 
00752   if (this->tagged_components_.get_component (tagged_component))
00753     {
00754       const CORBA::Octet *buf =
00755         tagged_component.component_data.get_buffer ();
00756 
00757       TAO_InputCDR in_cdr (reinterpret_cast<const char *> (buf),
00758                            tagged_component.component_data.length ());
00759 
00760       // Extract the Byte Order.
00761       CORBA::Boolean byte_order;
00762       if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00763         return -1;
00764       in_cdr.reset_byte_order (static_cast<int> (byte_order));
00765 
00766       // Extract endpoints sequence.
00767       TAO::IIOPEndpointSequence endpoints;
00768 
00769       if ((in_cdr >> endpoints) == 0)
00770         return -1;
00771 
00772       // Get the priority of the first endpoint (head of the list.
00773       // It's other data is extracted as part of the standard profile
00774       // decoding.
00775       this->endpoint_.priority (endpoints[0].priority);
00776 
00777       // Use information extracted from the tagged component to
00778       // populate the profile.  Skip the first endpoint, since it is
00779       // always extracted through standard profile body.  Also, begin
00780       // from the end of the sequence to preserve endpoint order,
00781       // since <add_endpoint> method reverses the order of endpoints
00782       // in the list.
00783       for (CORBA::ULong i = endpoints.length () - 1;
00784            i > 0;
00785            --i)
00786         {
00787           TAO_IIOP_Endpoint *endpoint = 0;
00788           ACE_NEW_RETURN (endpoint,
00789                           TAO_IIOP_Endpoint (endpoints[i].host,
00790                                              endpoints[i].port,
00791                                              endpoints[i].priority),
00792                           -1);
00793 
00794           this->add_endpoint (endpoint);
00795         }
00796     }
00797 
00798   // Now decode if there are any TAG_ALTERNATE_IIOP_ADDRESS
00799   // components.
00800 
00801   IOP::MultipleComponentProfile& tc = this->tagged_components_.components();
00802   for (CORBA::ULong index = 0; index < tc.length(); index++)
00803     {
00804       if (tc[index].tag != IOP::TAG_ALTERNATE_IIOP_ADDRESS)
00805         continue;
00806       const CORBA::Octet *buf =
00807         tc[index].component_data.get_buffer ();
00808 
00809       TAO_InputCDR in_cdr (reinterpret_cast<const char*>(buf),
00810                            tc[index].component_data.length ());
00811 
00812       // Extract the Byte Order.
00813       CORBA::Boolean byte_order;
00814       if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00815         return -1;
00816 
00817       in_cdr.reset_byte_order (static_cast<int>(byte_order));
00818 
00819       CORBA::String_var host;
00820       CORBA::Short port;
00821 
00822       if ((in_cdr >> host.out()) == 0 ||
00823           (in_cdr >> port) == 0)
00824         return -1;
00825 
00826       TAO_IIOP_Endpoint *endpoint = 0;
00827       ACE_NEW_RETURN (endpoint,
00828                       TAO_IIOP_Endpoint (host.in(),
00829                                          port,
00830                                          TAO_INVALID_PRIORITY),
00831                       -1);
00832 
00833       this->add_endpoint (endpoint);
00834     }
00835 
00836   return 0;
00837 }

int TAO_IIOP_Profile::decode_profile ( TAO_InputCDR cdr  )  [protected, virtual]

Template methods. Please see Profile.h for the documentation.

Implements TAO_Profile.

Definition at line 92 of file IIOP_Profile.cpp.

References ACE_DEBUG, ACE_TEXT, count_, endpoint_, TAO_ORB_Parameters::enforce_pref_interfaces(), ACE_InputCDR::good_bit(), TAO_IIOP_Endpoint::host(), LM_DEBUG, TAO_Profile::orb_core(), TAO_ORB_Core::orb_params(), TAO_IIOP_Endpoint::port(), TAO_IIOP_Endpoint::preferred_interfaces(), TAO_ORB_Parameters::preferred_interfaces(), ACE_InputCDR::read_string(), ACE_InputCDR::read_ushort(), and TAO_debug_level.

00093 {
00094   // Decode host and port into the <endpoint_>.
00095   // it is necessary to do it indirectly so that IPv6 host addresses
00096   // can be evaluated correctly.
00097   CORBA::String_var host;
00098   CORBA::UShort port;
00099 
00100   if (cdr.read_string(host.out()) == 0 ||
00101       cdr.read_ushort (port) == 0)
00102     {
00103       if (TAO_debug_level > 0)
00104         ACE_DEBUG ((LM_DEBUG,
00105                     ACE_TEXT ("TAO (%P|%t) IIOP_Profile::decode - ")
00106                     ACE_TEXT ("error while decoding host/port\n")));
00107       return -1;
00108     }
00109 
00110   this->endpoint_.host(host.in());
00111   this->endpoint_.port(port);
00112 
00113   if (cdr.good_bit ())
00114     {
00115       // Invalidate the object_addr_ until first access.
00116       this->endpoint_.object_addr_.set_type (-1);
00117 
00118       const char* csv = this->orb_core()->orb_params()->preferred_interfaces();
00119       bool const enforce =
00120         this->orb_core()->orb_params()->enforce_pref_interfaces();
00121       this->count_ += this->endpoint_.preferred_interfaces(csv, enforce);
00122 
00123       return 1;
00124     }
00125 
00126   return -1;
00127 }

CORBA::Boolean TAO_IIOP_Profile::do_is_equivalent ( const TAO_Profile other_profile  )  [protected, virtual]

Profile equivalence template method invoked on subclasses.

TAO_Profile subclasses must implement this template method so that they can apply their own definition of profile equivalence.

Implements TAO_Profile.

Definition at line 314 of file IIOP_Profile.cpp.

References count_, endpoint_, and TAO_IIOP_Endpoint::next_.

00315 {
00316   if (other_profile == this)
00317     return true;
00318 
00319   const TAO_IIOP_Profile *op =
00320     dynamic_cast<const TAO_IIOP_Profile *> (other_profile);
00321 
00322   // Make sure we have a TAO_IIOP_Profile.
00323   if (op == 0)
00324     return false;
00325 
00326   if (this->count_ == 0 && op->count_ == 0)
00327     return true;
00328   if (this->count_ != op->count_)
00329     return false;
00330   // Check endpoints equivalence.
00331   const TAO_IIOP_Endpoint *other_endp = &op->endpoint_;
00332   for (TAO_IIOP_Endpoint *endp = &this->endpoint_;
00333        endp != 0;
00334        endp = endp->next_)
00335     {
00336       if (endp->is_equivalent (other_endp))
00337         other_endp = other_endp->next_;
00338       else
00339         return false;
00340     }
00341 
00342   return true;
00343 }

int TAO_IIOP_Profile::encode_alternate_endpoints ( void   )  [virtual]

Encode alternate endpoints for non-RT profiles, using multiple TAG_ALTERNATE_IIOP_ADDRESS components, one endpoint per component

Reimplemented from TAO_Profile.

Definition at line 601 of file IIOP_Profile.cpp.

References count_, endpoint(), endpoint_, ACE_OS::memcpy(), TAO_Tagged_Components::set_component(), ACE_OS::strchr(), TAO_Endpoint::tag(), TAO_Profile::tagged_components_, and TAO_ENCAP_BYTE_ORDER.

00602 {
00603   // encode IOP::TAG_ALTERNATE_IIOP_ADDRESS tags if there are more
00604   // than one endpoints to listen to.
00605   const TAO_IIOP_Endpoint *endpoint = &this->endpoint_;
00606   for (CORBA::ULong i = 1;
00607        i < this->count_;
00608        ++i)
00609     {
00610       // The first endpoint is the actual endpoint. The rest of the
00611       // endpoints are the alternate endpoints. So, neglect the first
00612       // endpoint for TAG_ALTERNATE_IIOP_ADDRESS
00613       endpoint = endpoint->next_;
00614 
00615       if (!endpoint->is_encodable_)
00616         continue;
00617 
00618       // Encode the data structure. - The CORBA specification does not
00619       // mandate a particular container for the endpoints, only that
00620       // it is encoded as host first, then port.
00621       TAO_OutputCDR out_cdr;
00622 
00623 #if defined (ACE_HAS_IPV6)
00624       // For IPv6 decimal addresses make sure the possibly included scopeid
00625       // is not published as this has only local meaning.
00626       const char* host = 0;
00627       const char* pos = 0;
00628       if (endpoint->is_ipv6_decimal_ &&
00629           (pos = ACE_OS::strchr (host = endpoint->host (), '%')) != 0)
00630         {
00631           ACE_CString tmp;
00632           size_t len = pos - host;
00633           tmp.set (endpoint->host (), len, 1);
00634           if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER) == 0)
00635               || (out_cdr << tmp.c_str () == 0)
00636               || (out_cdr << endpoint->port () == 0))
00637             return -1;
00638           out_cdr.write_string (len, endpoint->host ());
00639         }
00640       else
00641 #endif /* ACE_HAS_IPV6 */
00642       if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER) == 0)
00643                 || (out_cdr << endpoint->host () == 0)
00644           || (out_cdr << endpoint->port () == 0))
00645         return -1;
00646 
00647       IOP::TaggedComponent tagged_component;
00648       tagged_component.tag = IOP::TAG_ALTERNATE_IIOP_ADDRESS;
00649 
00650       size_t length = out_cdr.total_length ();
00651       tagged_component.component_data.length
00652         (static_cast<CORBA::ULong>(length));
00653       CORBA::Octet *buf =
00654         tagged_component.component_data.get_buffer ();
00655 
00656       for (const ACE_Message_Block *iterator = out_cdr.begin ();
00657                  iterator != 0;
00658            iterator = iterator->cont ())
00659         {
00660           size_t i_length = iterator->length ();
00661           ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
00662 
00663           buf += i_length;
00664         }
00665 
00666       // Add component with encoded endpoint data to this profile's
00667       // TaggedComponents.
00668       tagged_components_.set_component (tagged_component);
00669     }
00670   return  0;
00671 }

int TAO_IIOP_Profile::encode_endpoints ( void   )  [virtual]

Encode endpoints for RT profiles, using a single TAO_TAG_ENDPOINT component.

Implements TAO_Profile.

Definition at line 674 of file IIOP_Profile.cpp.

References count_, endpoint(), endpoint_, ACE_String_Base_Const::npos, and TAO_Endpoint::priority().

00675 {
00676   CORBA::ULong actual_count = 0;
00677 
00678   const TAO_IIOP_Endpoint *endpoint = &this->endpoint_;
00679 
00680   // Count the number of endpoints that needs to be encoded
00681   for (CORBA::ULong c = 0;
00682        c != this->count_;
00683        ++c)
00684     {
00685       if (endpoint->is_encodable_)
00686         ++actual_count;
00687 
00688       endpoint = endpoint->next_;
00689     }
00690 
00691   // Create a data structure and fill it with endpoint info for wire
00692   // transfer.
00693   // We include information for the head of the list
00694   // together with other endpoints because even though its addressing
00695   // info is transmitted using standard ProfileBody components, its
00696   // priority is not!
00697 
00698   TAO::IIOPEndpointSequence endpoints;
00699   endpoints.length (actual_count);
00700 
00701   endpoint = &this->endpoint_;
00702 
00703   for (CORBA::ULong i = 0;
00704        i < actual_count;
00705        ++i)
00706     {
00707       if (endpoint->is_encodable_)
00708         {
00709 #if defined (ACE_HAS_IPV6)
00710           if (endpoint->is_ipv6_decimal_)
00711             {
00712               // Don't publish scopeid if included.
00713               ACE_CString tmp(endpoint->host ());
00714               ACE_CString::size_type pos = tmp.find('%');
00715               if (pos != ACE_CString::npos)
00716                 {
00717                   tmp = tmp.substr (0, pos + 1);
00718                   tmp[pos] = '\0';
00719                   endpoints[i].host = tmp.c_str();
00720                 }
00721               else
00722                 endpoints[i].host = tmp.c_str();
00723             }
00724           else
00725 #endif /* ACE_HAS_IPV6 */
00726           endpoints[i].host = endpoint->host ();
00727           endpoints[i].port = endpoint->port ();
00728           endpoints[i].priority = endpoint->priority ();
00729         }
00730       endpoint = endpoint->next_;
00731     }
00732 
00733   // Encode the data structure.
00734   TAO_OutputCDR out_cdr;
00735   if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)
00736        == 0)
00737       || (out_cdr << endpoints) == 0)
00738     return -1;
00739 
00740   this->set_tagged_components (out_cdr);
00741 
00742   return  0;
00743 }

int TAO_IIOP_Profile::encode_endpoints_for_rt ( void   )  [protected]

Helper method for encode_endpoints to deal with RT requests.

Encodes this profile's endpoints into a tagged component. This is done only if RTCORBA is enabled, since currently this is the only case when we have more than one endpoint per profile. Returns 0 on success and -1 on failure.

Endpoints are transmitted using TAO-proprietory tagged component. Component tag is TAO_TAG_ENDPOINTS and component data is an encapsulation of a sequence of structs, each representing a single endpoint. Data format is specified in iiop_endpoins.pidl.

TAO_Endpoint * TAO_IIOP_Profile::endpoint ( void   )  [virtual]

Return a pointer to this profile's endpoint. If the profile contains more than one endpoint, i.e., a list, the method returns the head of the list.

Implements TAO_Profile.

Definition at line 375 of file IIOP_Profile.cpp.

References endpoint_.

Referenced by TAO_IIOP_Acceptor::create_new_profile(), TAO_IIOP_Acceptor::create_shared_profile(), decode_endpoints(), encode_alternate_endpoints(), and encode_endpoints().

00376 {
00377   return &this->endpoint_;
00378 }

CORBA::ULong TAO_IIOP_Profile::endpoint_count ( void   )  const [virtual]

Return how many endpoints this profile contains.

Implements TAO_Profile.

Definition at line 389 of file IIOP_Profile.cpp.

References count_.

00390 {
00391   return this->count_;
00392 }

CORBA::ULong TAO_IIOP_Profile::hash ( CORBA::ULong  max  )  [virtual]

Return a hash value for this object.

Implements TAO_Profile.

Definition at line 346 of file IIOP_Profile.cpp.

References TAO_Profile::hash_service_i(), TAO_GIOP_Message_Version::minor, TAO_Profile::ref_object_key_, TAO_Profile::tag(), and TAO_Profile::version_.

00347 {
00348   // Get the hash value for all endpoints.
00349   CORBA::ULong hashval = 0;
00350   for (TAO_IIOP_Endpoint *endp = &this->endpoint_;
00351        endp != 0;
00352        endp = endp->next_)
00353     {
00354       hashval += endp->hash ();
00355     }
00356 
00357   hashval += this->version_.minor;
00358   hashval += this->tag ();
00359 
00360   const TAO::ObjectKey &ok =
00361     this->ref_object_key_->object_key ();
00362 
00363   if (ok.length () >= 4)
00364     {
00365       hashval += ok[1];
00366       hashval += ok[3];
00367     }
00368 
00369   hashval += TAO_Profile::hash_service_i (max);
00370 
00371   return hashval % max;
00372 }

char TAO_IIOP_Profile::object_key_delimiter ( void   )  const [virtual]

The object key delimiter that IIOP uses or expects.

Implements TAO_Profile.

Definition at line 44 of file IIOP_Profile.cpp.

00045 {
00046   return TAO_IIOP_Profile::object_key_delimiter_;
00047 }

void TAO_IIOP_Profile::parse_string_i ( const char *  string  )  [protected, virtual]

Protocol specific implementation of parse_string ().

Implements TAO_Profile.

Definition at line 130 of file IIOP_Profile.cpp.

References CORBA::SystemException::_tao_minor_code(), ACE_DEBUG, ACE_ERROR, ACE_TEXT, ACE_OS::atoi(), CORBA::COMPLETED_NO, endpoint_, ACE_INET_Addr::get_host_name(), ACE_INET_Addr::get_port_number(), TAO_IIOP_Endpoint::host_, LM_DEBUG, LM_ERROR, MAXHOSTNAMELEN, TAO_GIOP_Message_Version::minor, TAO_IIOP_Endpoint::port_, ACE_OS::strchr(), ACE_OS::strcmp(), CORBA::string_alloc(), CORBA::string_dup(), ACE_INET_Addr::string_to_addr(), ACE_OS::strncpy(), ACE_OS::strspn(), TAO_debug_level, and TAO_Profile::version().

00131 {
00132   // Pull off the "hostname:port/" part of the objref
00133   // Copy the string because we are going to modify it...
00134 
00135   const char *okd = ACE_OS::strchr (ior, this->object_key_delimiter_);
00136 
00137   if (okd == 0 || okd == ior)
00138     {
00139       // No object key delimiter or no hostname specified.
00140       throw ::CORBA::INV_OBJREF (
00141                    CORBA::SystemException::_tao_minor_code (
00142                      0,
00143                      EINVAL),
00144                    CORBA::COMPLETED_NO);
00145     }
00146 
00147   // Length of host string.
00148   CORBA::ULong length_host = 0;
00149 
00150   const char *cp_pos = ACE_OS::strchr (ior, ':');  // Look for a port
00151 #if defined (ACE_HAS_IPV6)
00152   // IPv6 numeric address in host string?
00153   bool ipv6_in_host = false;
00154 
00155   // Check if this is a (possibly) IPv6 supporting profile containing a
00156   // decimal IPv6 address representation.
00157   if ((this->version().major > TAO_MIN_IPV6_IIOP_MAJOR ||
00158         this->version().minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
00159       ior[0] == '[')
00160     {
00161       // In this case we have to find the end of the numeric address and
00162       // start looking for the port separator from there.
00163       const char *cp_pos_a = ACE_OS::strchr(ior, ']');
00164       if (cp_pos_a == 0)
00165         {
00166           // No valid IPv6 address specified.
00167           if (TAO_debug_level > 0)
00168             {
00169               ACE_ERROR ((LM_ERROR,
00170                        ACE_TEXT ("\nTAO (%P|%t) IIOP_Profile: ")
00171                        ACE_TEXT ("Invalid IPv6 decimal address specified.\n")));
00172             }
00173 
00174           throw ::CORBA::INV_OBJREF (
00175                        CORBA::SystemException::_tao_minor_code (
00176                          0,
00177                          EINVAL),
00178                        CORBA::COMPLETED_NO);
00179         }
00180       else
00181         {
00182           if (cp_pos_a[1] == ':')    // Look for a port
00183             cp_pos = cp_pos_a + 1;
00184           else
00185             cp_pos = 0;
00186           ipv6_in_host = true; // host string contains full IPv6 numeric address
00187         }
00188     }
00189 #endif /* ACE_HAS_IPV6 */
00190 
00191   if (cp_pos == ior)
00192     {
00193       // No hostname, however one is required by the spec when specifying a port.
00194       // See formal-04-03-01, section 13.6.10.3
00195       if (TAO_debug_level > 0)
00196         {
00197           ACE_ERROR ((LM_ERROR,
00198                    ACE_TEXT ("\nTAO (%P|%t) IIOP_Profile: ")
00199                    ACE_TEXT ("Host address may be omited only when no port has been specified.\n")));
00200         }
00201 
00202       throw ::CORBA::INV_OBJREF (
00203                    CORBA::SystemException::_tao_minor_code (
00204                      0,
00205                      EINVAL),
00206                    CORBA::COMPLETED_NO);
00207     }
00208   else if (cp_pos != 0)
00209     {
00210       // A port number or port name was specified.
00211       CORBA::ULong length_port = okd - cp_pos - 1;
00212       CORBA::String_var tmp = CORBA::string_alloc (length_port);
00213 
00214       if (tmp.in() != 0)
00215         {
00216           ACE_OS::strncpy (tmp.inout (), cp_pos + 1, length_port);
00217           tmp[length_port] = '\0';
00218         }
00219 
00220       if (length_port == 0)
00221         {
00222           this->endpoint_.port_ = 2809; // default IIOP port for
00223           // parsing corbaloc strings
00224         }
00225       else if (tmp.in () != 0 && ACE_OS::strspn (tmp.in (), "1234567890") == length_port)
00226         {
00227           this->endpoint_.port_ =
00228             static_cast<CORBA::UShort> (ACE_OS::atoi (tmp.in ()));
00229         }
00230       else
00231         {
00232           ACE_INET_Addr ia;
00233           if (tmp.in () == 0 || ia.string_to_addr (tmp.in ()) == -1)
00234             {
00235               throw ::CORBA::INV_OBJREF (
00236                              CORBA::SystemException::_tao_minor_code (
00237                                0,
00238                                EINVAL),
00239                              CORBA::COMPLETED_NO);
00240             }
00241           else
00242             {
00243               this->endpoint_.port_ = ia.get_port_number ();
00244             }
00245         }
00246       length_host = cp_pos - ior;
00247     }
00248   else
00249     length_host = okd - ior;
00250 
00251 #if defined (ACE_HAS_IPV6)
00252   if (ipv6_in_host)
00253     length_host -= 2; // don't store '[' and ']'
00254 #endif /* ACE_HAS_IPV6 */
00255 
00256   CORBA::String_var tmp = CORBA::string_alloc (length_host);
00257 
00258 #if defined (ACE_HAS_IPV6)
00259   if (ipv6_in_host)
00260     ACE_OS::strncpy (tmp.inout (), ior + 1, length_host);
00261   else
00262 #endif /* ACE_HAS_IPV6 */
00263   // Skip the trailing '/'
00264   ACE_OS::strncpy (tmp.inout (), ior, length_host);
00265   tmp[length_host] = '\0';
00266 
00267   this->endpoint_.host_ = tmp._retn ();
00268 #if defined (ACE_HAS_IPV6)
00269   this->endpoint_.is_ipv6_decimal_ = ipv6_in_host;
00270 #endif /* ACE_HAS_IPV6 */
00271 
00272   if (ACE_OS::strcmp (this->endpoint_.host_.in (), "") == 0)
00273     {
00274       ACE_INET_Addr host_addr;
00275 
00276       char tmp_host [MAXHOSTNAMELEN + 1];
00277 
00278       // If no host is specified: assign the default host, i.e. the
00279       // local host.
00280       if (host_addr.get_host_name (tmp_host,
00281                                    sizeof (tmp_host)) != 0)
00282         {
00283           // Can't get the IP address since the INET_Addr wasn't
00284           // initialized.  Just throw an exception.
00285 
00286           if (TAO_debug_level > 0)
00287             ACE_DEBUG ((LM_DEBUG,
00288                         ACE_TEXT ("\n\nTAO (%P|%t) ")
00289                         ACE_TEXT ("IIOP_Profile::parse_string ")
00290                         ACE_TEXT ("- %p\n\n"),
00291                         ACE_TEXT ("cannot determine hostname")));
00292 
00293           // @@ What's the right exception to throw here?
00294           throw ::CORBA::INV_OBJREF (
00295                        CORBA::SystemException::_tao_minor_code (
00296                          0,
00297                          EINVAL),
00298                        CORBA::COMPLETED_NO);
00299         }
00300       else
00301         this->endpoint_.host_ = CORBA::string_dup (tmp_host);
00302     }
00303 
00304   TAO::ObjectKey ok;
00305 
00306   TAO::ObjectKey::decode_string_to_sequence (ok,
00307                                              okd + 1);
00308 
00309   (void) this->orb_core ()->object_key_table ().bind (ok,
00310                                                       this->ref_object_key_);
00311 }

const char * TAO_IIOP_Profile::prefix ( void   )  [static]

Return the char string prefix.

Definition at line 549 of file IIOP_Profile.cpp.

References the_prefix.

00550 {
00551   return ::the_prefix;
00552 }

void TAO_IIOP_Profile::remove_endpoint ( TAO_IIOP_Endpoint endp  ) 

Remove endp from this profile's list of endpoints and free the endp memory. This method assumes endp is in this profile's endpoint list.

Definition at line 404 of file IIOP_Profile.cpp.

References count_, endpoint_, and TAO_IIOP_Endpoint::next_.

Referenced by remove_generic_endpoint().

00405 {
00406   if (endp == 0)
00407     return;
00408 
00409   // special handling for the target matching the base endpoint
00410   if (endp == &this->endpoint_)
00411     {
00412       if (--this->count_ > 0)
00413         {
00414           TAO_IIOP_Endpoint* n = this->endpoint_.next_;
00415           this->endpoint_ = *n;
00416           // since the assignment operator does not copy the next_
00417           // pointer, we must do it by hand
00418           this->endpoint_.next_ = n->next_;
00419           delete n;
00420         }
00421       return;
00422     }
00423 
00424   TAO_IIOP_Endpoint* last = &this->endpoint_;
00425   TAO_IIOP_Endpoint* cur = this->endpoint_.next_;
00426 
00427   while (cur != 0)
00428   {
00429     if (cur == endp)
00430       break;
00431     last = cur;
00432     cur = cur->next_;
00433   }
00434 
00435   if (cur != 0)
00436   {
00437     last->next_ = cur->next_;
00438     cur->next_ = 0;
00439     --this->count_;
00440     delete cur;
00441   }
00442 }

void TAO_IIOP_Profile::remove_generic_endpoint ( TAO_Endpoint ep  )  [virtual]

Remove the provided endpoint from the profile. Some subclasses of TAO_Profile already have a protocol-specific version of remove_endpoint, but this generic interface is required. The default implementation is a no-op. Protocol maintainers wishing to add support for the EndpointPolicy must implement remove_generic_endpoint to call their protocol-specific version of remove_endpoint

Reimplemented from TAO_Profile.

Definition at line 445 of file IIOP_Profile.cpp.

References remove_endpoint().

00446 {
00447   this->remove_endpoint(dynamic_cast<TAO_IIOP_Endpoint *>(ep));
00448 }

char * TAO_IIOP_Profile::to_string ( void   )  [virtual]

Template methods. Please see Profile.h for documentation.

Implements TAO_Profile.

Definition at line 463 of file IIOP_Profile.cpp.

References TAO_IIOP_Endpoint::host(), TAO_IIOP_Endpoint::next_, ACE_String_Base_Const::npos, TAO_IIOP_Endpoint::port(), TAO_Profile::ref_object_key_, ACE_OS::sprintf(), ACE_OS::strcat(), ACE_OS::strcpy(), CORBA::string_alloc(), and ACE_OS::strlen().

00464 {
00465   // corbaloc:iiop:1.2@host:port,iiop:1.2@host:port,.../key
00466 
00467   CORBA::String_var key;
00468   TAO::ObjectKey::encode_sequence_to_string (key.inout(),
00469                                              this->ref_object_key_->object_key ());
00470 
00471   size_t buflen = (
00472        8 /* "corbaloc" */ +
00473        1 /* colon separator */ +
00474        1 /* object key separator */ +
00475        ACE_OS::strlen (key.in ()));
00476   size_t const pfx_len = (
00477        ACE_OS::strlen (::the_prefix) /* "iiop" */ +
00478        1 /* colon separator */);
00479 
00480  const TAO_IIOP_Endpoint *endp = 0;
00481  for (endp = &this->endpoint_; endp != 0; endp = endp->next_)
00482    {
00483       buflen += (
00484           pfx_len +
00485           1 /* major version */ +
00486           1 /* decimal point */ +
00487           1 /* minor version */ +
00488           1 /* `@' character */ +
00489           ACE_OS::strlen (endp->host ()) +
00490           1 /* colon separator */ +
00491           5 /* port number */ +
00492           1 /* comma */);
00493 #if defined (ACE_HAS_IPV6)
00494       if (endp->is_ipv6_decimal_)
00495         buflen += 2; // room for '[' and ']'
00496 #endif /* ACE_HAS_IPV6 */
00497    }
00498 
00499   static const char digits [] = "0123456789";
00500 
00501   char * buf = CORBA::string_alloc (static_cast<CORBA::ULong> (buflen));
00502 
00503   ACE_OS::strcpy(buf, "corbaloc:");
00504 
00505   for (endp = &this->endpoint_; endp != 0; endp = endp->next_)
00506     {
00507       if(&this->endpoint_ != endp)
00508       ACE_OS::strcat(buf, ",");
00509 
00510 #if defined (ACE_HAS_IPV6)
00511       if (endp->is_ipv6_decimal_)
00512         {
00513           // Don't publish scopeid if included.
00514           ACE_CString tmp(endp->host ());
00515           ACE_CString::size_type pos = tmp.find('%');
00516           if (pos != ACE_CString::npos)
00517             {
00518               tmp = tmp.substr(0, pos + 1);
00519               tmp[pos] = '\0';
00520             }
00521           ACE_OS::sprintf (buf + ACE_OS::strlen(buf),
00522                   "%s:%c.%c@[%s]:%d",
00523                   ::the_prefix,
00524                   digits [this->version_.major],
00525                   digits [this->version_.minor],
00526                   tmp.c_str (),
00527                   endp->port () );
00528         }
00529       else
00530 #endif
00531       ACE_OS::sprintf (buf + ACE_OS::strlen(buf),
00532               "%s:%c.%c@%s:%d",
00533               ::the_prefix,
00534               digits [this->version_.major],
00535               digits [this->version_.minor],
00536               endp->host (),
00537               endp->port () );
00538 
00539   }
00540   ACE_OS::sprintf (buf + ACE_OS::strlen(buf),
00541           "%c%s",
00542           this->object_key_delimiter_,
00543           key.in ());
00544 
00545   return buf;
00546 }


Member Data Documentation

CORBA::ULong TAO_IIOP_Profile::count_ [protected]

Number of endpoints in the list headed by <endpoint_>.

Definition at line 188 of file IIOP_Profile.h.

Referenced by add_endpoint(), decode_profile(), do_is_equivalent(), encode_alternate_endpoints(), encode_endpoints(), endpoint_count(), and remove_endpoint().

TAO_IIOP_Endpoint TAO_IIOP_Profile::endpoint_ [protected]

Head of this profile's list of endpoints. This endpoint is not dynamically allocated because a profile always contains at least one endpoint.

Currently, a profile contains more than one endpoint, i.e., list contains more than just the head, only for two cases (1) when RTCORBA is enabled and (2) the ORB is initialized with -ORBPreferredInterfaces option. However, in the near future, this will be used in for mode as well, e.g., to support TAG_ALTERNATE_IIOP_ADDRESS feature.

This is probably as good a place to discuss how the list of endpoints is used for #2. If the ORB is configured to use preferred interfaces for invocation, TAO creates an endpoint per preferred interface. To be clear, every tuple <destination:target> will have an endpoint. What TAO essentially does is that creates it multiple endpoints so that the invocation code path can use existing iterating techniques to try one preferred interface after another (if the first did not work). If the ORB is configured with -ORBEnforcePreferredInterface set to false in addition to the ORBPreferredInterfaces option , TAO creates another endpoint with the preferred bit set to null, so that the invocation code can fall back to a TCP stack returned local address. Addressing info of the default endpoint, i.e., head of the list, is transmitted using standard IIOP ProfileBody components. See <encode_endpoints> method documentation above for how the rest of the endpoint list is transmitted.

Definition at line 185 of file IIOP_Profile.h.

Referenced by add_endpoint(), base_endpoint(), decode_endpoints(), decode_profile(), do_is_equivalent(), encode_alternate_endpoints(), encode_endpoints(), endpoint(), parse_string_i(), and remove_endpoint().

const char TAO_IIOP_Profile::object_key_delimiter_ = '/' [static]

Definition at line 49 of file IIOP_Profile.h.

Referenced by TAO_IIOP_Connector::object_key_delimiter().


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:39:32 2010 for TAO by  doxygen 1.4.7