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

Generated on Sun Jan 27 15:59:51 2008 for TAO_Strategies by doxygen 1.3.6