#include <IIOP_Profile.h>
Inheritance diagram for TAO_IIOP_Profile:
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_Endpoint * | endpoint (void) |
virtual TAO_Endpoint * | base_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_>. |
This class defines the IIOP profile as specified in the CORBA specification.
Definition at line 44 of file IIOP_Profile.h.
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 }
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 }
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().