UIOP_Profile.cpp

Go to the documentation of this file.
00001 #include "tao/Strategies/UIOP_Profile.h"
00002 
00003 #if TAO_HAS_UIOP == 1
00004 
00005 #include "tao/Strategies/uiop_endpointsC.h"
00006 
00007 #include "tao/CDR.h"
00008 #include "tao/Environment.h"
00009 #include "tao/ORB.h"
00010 #include "tao/ORB_Core.h"
00011 #include "tao/debug.h"
00012 
00013 #include "ace/OS_NS_stdio.h"
00014 #include "ace/OS_NS_string.h"
00015 #include "ace/os_include/os_ctype.h"
00016 
00017 ACE_RCSID (Strategies,
00018            UIOP_Profile,
00019            "UIOP_Profile.cpp,v 1.32 2006/03/10 07:19:19 jtc Exp")
00020 
00021 static const char prefix_[] = "uiop";
00022 
00023 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00024 
00025 const char TAO_UIOP_Profile::object_key_delimiter_ = '|';
00026 
00027 char
00028 TAO_UIOP_Profile::object_key_delimiter (void) const
00029 {
00030   return TAO_UIOP_Profile::object_key_delimiter_;
00031 }
00032 
00033 TAO_UIOP_Profile::TAO_UIOP_Profile (const ACE_UNIX_Addr &addr,
00034                                     const TAO::ObjectKey &object_key,
00035                                     const TAO_GIOP_Message_Version &version,
00036                                     TAO_ORB_Core *orb_core)
00037   : TAO_Profile (TAO_TAG_UIOP_PROFILE,
00038                  orb_core,
00039                  object_key,
00040                  version),
00041     endpoint_ (addr),
00042     count_ (1)
00043 {
00044 }
00045 
00046 TAO_UIOP_Profile::TAO_UIOP_Profile (const char *,
00047                                     const TAO::ObjectKey &object_key,
00048                                     const ACE_UNIX_Addr &addr,
00049                                     const TAO_GIOP_Message_Version &version,
00050                                     TAO_ORB_Core *orb_core)
00051   : TAO_Profile (TAO_TAG_UIOP_PROFILE,
00052                  orb_core,
00053                  object_key,
00054                  version),
00055     endpoint_ (addr),
00056     count_ (1)
00057 {
00058 }
00059 
00060 TAO_UIOP_Profile::TAO_UIOP_Profile (TAO_ORB_Core *orb_core)
00061   : TAO_Profile (TAO_TAG_UIOP_PROFILE,
00062                  orb_core,
00063                  TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR,
00064                                            TAO_DEF_GIOP_MINOR)),
00065     endpoint_ (),
00066     count_ (1)
00067 {
00068 }
00069 
00070 TAO_UIOP_Profile::~TAO_UIOP_Profile (void)
00071 {
00072   // Clean up the list of endpoints since we own it.
00073   // Skip the head, since it is not dynamically allocated.
00074   TAO_Endpoint *tmp = 0;
00075 
00076   for (TAO_Endpoint *next = this->endpoint ()->next ();
00077        next != 0;
00078        next = tmp)
00079     {
00080       tmp = next->next ();
00081       delete next;
00082     }
00083 }
00084 
00085 TAO_Endpoint*
00086 TAO_UIOP_Profile::endpoint (void)
00087 {
00088   return &this->endpoint_;
00089 }
00090 
00091 CORBA::ULong
00092 TAO_UIOP_Profile::endpoint_count (void) const
00093 {
00094   return this->count_;
00095 }
00096 
00097 void
00098 TAO_UIOP_Profile::parse_string_i (const char *string
00099                                   ACE_ENV_ARG_DECL)
00100 {
00101   if (!string || !*string)
00102     {
00103       ACE_THROW (CORBA::INV_OBJREF (
00104                    CORBA::SystemException::_tao_minor_code (
00105                      0,
00106                      EINVAL),
00107                    CORBA::COMPLETED_NO));
00108     }
00109 
00110   // Remove the "N.n@" version prefix, if it exists, and verify the
00111   // version is one that we accept.
00112 
00113   // Check for version
00114   if (isdigit (string [0]) &&
00115       string[1] == '.' &&
00116       isdigit (string [2]) &&
00117       string[3] == '@')
00118     {
00119       // @@ This may fail for non-ascii character sets [but take that
00120       // with a grain of salt]
00121       this->version_.set_version ((char) (string [0] - '0'),
00122                                   (char) (string [2] - '0'));
00123       string += 4;
00124       // Skip over the "N.n@"
00125     }
00126 
00127   if (this->version_.major != TAO_DEF_GIOP_MAJOR ||
00128       this->version_.minor  > TAO_DEF_GIOP_MINOR)
00129     {
00130       ACE_THROW (CORBA::INV_OBJREF (
00131                    CORBA::SystemException::_tao_minor_code (
00132                      0,
00133                      EINVAL),
00134                    CORBA::COMPLETED_NO));
00135     }
00136 
00137 
00138   // Pull off the "rendezvous point" part of the objref
00139   // Copy the string because we are going to modify it...
00140   CORBA::String_var copy (string);
00141 
00142   char *start = copy.inout ();
00143   char *cp = ACE_OS::strchr (start, this->object_key_delimiter_);
00144 
00145   if (cp == 0)
00146     {
00147       ACE_THROW (CORBA::INV_OBJREF (
00148                    CORBA::SystemException::_tao_minor_code (
00149                      TAO::VMCID,
00150                      EINVAL),
00151                    CORBA::COMPLETED_NO));
00152       // No rendezvous point specified
00153     }
00154 
00155   CORBA::ULong length = cp - start;
00156 
00157   CORBA::String_var rendezvous = CORBA::string_alloc (length);
00158 
00159   ACE_OS::strncpy (rendezvous.inout (), start, length);
00160   rendezvous[length] = '\0';
00161 
00162   if (this->endpoint_.object_addr_.set (rendezvous.in ()) != 0)
00163     {
00164       ACE_THROW (CORBA::INV_OBJREF (
00165                    CORBA::SystemException::_tao_minor_code (
00166                      TAO::VMCID,
00167                      EINVAL),
00168                    CORBA::COMPLETED_NO));
00169     }
00170 
00171   start = ++cp;  // increment past the object key separator
00172 
00173   TAO::ObjectKey ok;
00174   TAO::ObjectKey::decode_string_to_sequence (ok,
00175                                              start);
00176 
00177   (void) this->orb_core ()->object_key_table ().bind (ok,
00178                                                       this->ref_object_key_);
00179 }
00180 
00181 CORBA::Boolean
00182 TAO_UIOP_Profile::do_is_equivalent (const TAO_Profile *other_profile)
00183 {
00184   const TAO_UIOP_Profile *op =
00185     dynamic_cast <const TAO_UIOP_Profile *> (other_profile);
00186 
00187   if (op == 0)
00188     return 0;
00189 
00190   // Check endpoints equivalence.
00191   const TAO_UIOP_Endpoint *other_endp = &op->endpoint_;
00192   for (TAO_UIOP_Endpoint *endp = &this->endpoint_;
00193        endp != 0;
00194        endp = endp->next_)
00195     {
00196       if (endp->is_equivalent (other_endp))
00197         other_endp = other_endp->next_;
00198       else
00199         return 0;
00200     }
00201 
00202   return 1;
00203 }
00204 
00205 CORBA::ULong
00206 TAO_UIOP_Profile::hash (CORBA::ULong max
00207                         ACE_ENV_ARG_DECL_NOT_USED)
00208 {
00209   // Get the hashvalue for all endpoints.
00210   CORBA::ULong hashval = 0;
00211   for (TAO_UIOP_Endpoint *endp = &this->endpoint_;
00212        endp != 0;
00213        endp = endp->next_)
00214     {
00215       hashval += endp->hash ();
00216     }
00217 
00218   hashval += this->version_.minor;
00219   hashval += this->tag ();
00220 
00221   const TAO::ObjectKey &ok =
00222     this->ref_object_key_->object_key ();
00223 
00224   if (ok.length () >= 4)
00225     {
00226       hashval += ok[1];
00227       hashval += ok[3];
00228     }
00229 
00230   hashval += this->hash_service_i (max);
00231 
00232   return hashval % max;
00233 }
00234 
00235 void
00236 TAO_UIOP_Profile::add_endpoint (TAO_UIOP_Endpoint *endp)
00237 {
00238   endp->next_ = this->endpoint_.next_;
00239   this->endpoint_.next_ = endp;
00240 
00241   this->count_++;
00242 }
00243 
00244 
00245 char *
00246 TAO_UIOP_Profile::to_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00247 {
00248   CORBA::String_var key;
00249   TAO::ObjectKey::encode_sequence_to_string (key.inout(),
00250                                             this->ref_object_key_->object_key ());
00251 
00252   u_int buflen = (8 /* "corbaloc" */ +
00253                   1 /* colon separator */ +
00254                   ACE_OS::strlen (::prefix_) +
00255                   1 /* colon separator */ +
00256                   1 /* major version */ +
00257                   1 /* decimal point */ +
00258                   1 /* minor version */ +
00259                   1 /* `@' character */ +
00260                   ACE_OS::strlen (this->endpoint_.rendezvous_point ()) +
00261                   1 /* object key separator */ +
00262                   ACE_OS::strlen (key.in ()));
00263 
00264   char * buf = CORBA::string_alloc (buflen);
00265 
00266   static const char digits [] = "0123456789";
00267 
00268   ACE_OS::sprintf (buf,
00269                    "corbaloc:%s:%c.%c@%s%c%s",
00270                    ::prefix_,
00271                    digits [this->version_.major],
00272                    digits [this->version_.minor],
00273                    this->endpoint_.rendezvous_point (),
00274                    this->object_key_delimiter_,
00275                    key.in ());
00276   return buf;
00277 }
00278 
00279 const char *
00280 TAO_UIOP_Profile::prefix (void)
00281 {
00282   return ::prefix_;
00283 }
00284 
00285 int
00286 TAO_UIOP_Profile::decode_profile (TAO_InputCDR& cdr)
00287 {
00288   char *rendezvous = 0;
00289 
00290   // Get rendezvous_point
00291   if (cdr.read_string (rendezvous) == 0)
00292     {
00293       ACE_DEBUG ((LM_DEBUG, "error decoding UIOP rendezvous_point"));
00294       return -1;
00295     }
00296 
00297   if (this->endpoint_.object_addr_.set (rendezvous) == -1)
00298     {
00299       // In the case of an ACE_UNIX_Addr, this should call should
00300       // never fail!
00301       //
00302       // If the call fails, allow the profile to be created, and rely
00303       // on TAO's connection handling to throw the appropriate
00304       // exception.
00305       if (TAO_debug_level > 0)
00306         {
00307           ACE_DEBUG ((LM_DEBUG,
00308                       ACE_TEXT ("TAO (%P|%t) UIOP_Profile::decode - ")
00309                       ACE_TEXT ("ACE_UNIX_Addr::set() failed\n")));
00310         }
00311     }
00312 
00313   // Clean up
00314   delete [] rendezvous;
00315 
00316   return 1;
00317 }
00318 
00319 void
00320 TAO_UIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
00321 {
00322   // CHAR describing byte order, starting the encapsulation
00323   encap.write_octet (TAO_ENCAP_BYTE_ORDER);
00324 
00325   // The GIOP version
00326   encap.write_octet (this->version_.major);
00327   encap.write_octet (this->version_.minor);
00328 
00329   // STRING rendezvous_pointname from profile
00330   encap.write_string (this->endpoint_.rendezvous_point ());
00331 
00332   // OCTET SEQUENCE for object key
00333   if (this->ref_object_key_)
00334     encap << this->ref_object_key_->object_key ();
00335   else
00336     {
00337       ACE_ERROR ((LM_ERROR,
00338                   "(%P|%t) TAO - UIOP_Profile::create_profile_body "
00339                   "no object key marshalled \n"));
00340     }
00341 
00342   if (this->version_.major > 1
00343       || this->version_.minor > 0)
00344     this->tagged_components ().encode (encap);
00345 }
00346 
00347 int
00348 TAO_UIOP_Profile::encode_endpoints (void)
00349 {
00350   // Create a data structure and fill it with endpoint info for wire
00351   // transfer.
00352   // We include information for the head of the list
00353   // together with other endpoints because even though its addressing
00354   // info is transmitted using standard ProfileBody components, its
00355   // priority is not!
00356   TAO_UIOPEndpointSequence endpoints;
00357   endpoints.length (this->count_);
00358 
00359   TAO_UIOP_Endpoint *endpoint = &this->endpoint_;
00360   for (size_t i = 0;
00361        i < this->count_;
00362        ++i)
00363     {
00364       endpoints[i].rendezvous_point = endpoint->rendezvous_point ();
00365       endpoints[i].priority = endpoint->priority ();
00366 
00367       endpoint = endpoint->next_;
00368     }
00369 
00370   // Encode the data structure.
00371   TAO_OutputCDR out_cdr;
00372   if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)
00373        == 0)
00374       || (out_cdr << endpoints) == 0)
00375     return -1;
00376 
00377   this->set_tagged_components (out_cdr);
00378 
00379   return  0;
00380 }
00381 
00382 int
00383 TAO_UIOP_Profile::decode_endpoints (void)
00384 {
00385   IOP::TaggedComponent tagged_component;
00386   tagged_component.tag = TAO_TAG_ENDPOINTS;
00387 
00388   if (this->tagged_components_.get_component (tagged_component))
00389     {
00390       const CORBA::Octet *buf =
00391         tagged_component.component_data.get_buffer ();
00392 
00393       TAO_InputCDR in_cdr (reinterpret_cast <const char*>(buf),
00394                            tagged_component.component_data.length ());
00395 
00396       // Extract the Byte Order.
00397       CORBA::Boolean byte_order;
00398       if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00399         return -1;
00400       in_cdr.reset_byte_order (static_cast<int>(byte_order));
00401 
00402       // Extract endpoints sequence.
00403       TAO_UIOPEndpointSequence endpoints;
00404 
00405       if ((in_cdr >> endpoints) == 0)
00406         return -1;
00407 
00408       // Get the priority of the first endpoint (head of the list.
00409       // It's other data is extracted as part of the standard profile
00410       // decoding.
00411       this->endpoint_.priority (endpoints[0].priority);
00412 
00413       // Use information extracted from the tagged component to
00414       // populate the profile.  Skip the first endpoint, since it is
00415       // always extracted through standard profile body.  Also, begin
00416       // from the end of the sequence to preserve endpoint order,
00417       // since <add_endpoint> method reverses the order of endpoints
00418       // in the list.
00419       for (CORBA::ULong i = endpoints.length () - 1;
00420            i > 0;
00421            --i)
00422         {
00423           TAO_UIOP_Endpoint *endpoint = 0;
00424           ACE_NEW_RETURN (endpoint,
00425                           TAO_UIOP_Endpoint,
00426                           -1);
00427           this->add_endpoint (endpoint);
00428           if (endpoint->object_addr_.set
00429               (endpoints[i].rendezvous_point)
00430               == -1)
00431             {
00432               // In the case of an ACE_UNIX_Addr, this should call should
00433               // never fail!
00434               // If the call fails, allow the profile to be created, and rely
00435               // on TAO's connection handling to throw the appropriate
00436               // exception.
00437               if (TAO_debug_level > 0)
00438                 {
00439                   ACE_DEBUG ((LM_DEBUG,
00440                               ACE_TEXT ("TAO (%P|%t) UIOP_Profile::decode_endpoints - ")
00441                               ACE_TEXT ("ACE_UNIX_Addr::set() failed\n")));
00442                 }
00443 
00444             }
00445           endpoint->priority (endpoints[i].priority);
00446         }
00447     }
00448 
00449   return 0;
00450 }
00451 
00452 TAO_END_VERSIONED_NAMESPACE_DECL
00453 
00454 #endif  /* TAO_HAS_UIOP == 1 */

Generated on Thu Nov 9 13:39:31 2006 for TAO_Strategies by doxygen 1.3.6