00001
00002
00003 #include "tao/Strategies/DIOP_Profile.h"
00004
00005 #if defined (TAO_HAS_DIOP) && (TAO_HAS_DIOP != 0)
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 #include "tao/IIOP_EndpointsC.h"
00013
00014 #include "ace/OS_NS_stdio.h"
00015 #include "ace/OS_NS_string.h"
00016 #include "ace/os_include/os_netdb.h"
00017
00018 ACE_RCSID (Strategies,
00019 DIOP_Profile,
00020 "DIOP_Profile.cpp,v 1.25 2006/03/10 07:19:18 jtc Exp")
00021
00022 static const char the_prefix[] = "diop";
00023
00024 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00025
00026 const char TAO_DIOP_Profile::object_key_delimiter_ = '/';
00027
00028 char
00029 TAO_DIOP_Profile::object_key_delimiter (void) const
00030 {
00031 return TAO_DIOP_Profile::object_key_delimiter_;
00032 }
00033
00034
00035 TAO_DIOP_Profile::TAO_DIOP_Profile (const ACE_INET_Addr &addr,
00036 const TAO::ObjectKey &object_key,
00037 const TAO_GIOP_Message_Version &version,
00038 TAO_ORB_Core *orb_core)
00039 : TAO_Profile (TAO_TAG_DIOP_PROFILE,
00040 orb_core,
00041 object_key,
00042 version),
00043 endpoint_ (addr,
00044 orb_core->orb_params ()->use_dotted_decimal_addresses ()),
00045 count_ (1)
00046 {
00047 }
00048
00049 TAO_DIOP_Profile::TAO_DIOP_Profile (const char* host,
00050 CORBA::UShort port,
00051 const TAO::ObjectKey &object_key,
00052 const ACE_INET_Addr &addr,
00053 const TAO_GIOP_Message_Version &version,
00054 TAO_ORB_Core *orb_core)
00055 : TAO_Profile (TAO_TAG_DIOP_PROFILE,
00056 orb_core,
00057 object_key,
00058 version),
00059 endpoint_ (host, port, addr),
00060 count_ (1)
00061 {
00062 }
00063
00064 TAO_DIOP_Profile::TAO_DIOP_Profile (TAO_ORB_Core *orb_core)
00065 : TAO_Profile (TAO_TAG_DIOP_PROFILE,
00066 orb_core,
00067 TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)),
00068 endpoint_ (),
00069 count_ (1)
00070 {
00071 }
00072
00073 TAO_DIOP_Profile::~TAO_DIOP_Profile (void)
00074 {
00075
00076
00077 TAO_Endpoint *tmp = 0;
00078
00079 for (TAO_Endpoint *next = this->endpoint ()->next ();
00080 next != 0;
00081 next = tmp)
00082 {
00083 tmp = next->next ();
00084 delete next;
00085 }
00086 }
00087
00088
00089
00090
00091
00092
00093 int
00094 TAO_DIOP_Profile::decode_profile (TAO_InputCDR& cdr)
00095 {
00096
00097
00098
00099 if (cdr.read_string (this->endpoint_.host_.out ()) == 0
00100 || cdr.read_ushort (this->endpoint_.port_) == 0)
00101 {
00102 if (TAO_debug_level > 0)
00103 ACE_DEBUG ((LM_DEBUG,
00104 ACE_TEXT ("TAO (%P|%t) DIOP_Profile::decode - ")
00105 ACE_TEXT ("error while decoding host/port")));
00106 return -1;
00107 }
00108
00109 if (cdr.good_bit ())
00110 {
00111
00112 this->endpoint_.object_addr_.set_type (-1);
00113
00114 return 1;
00115 }
00116
00117 return -1;
00118 }
00119
00120 void
00121 TAO_DIOP_Profile::parse_string_i (const char *ior
00122 ACE_ENV_ARG_DECL)
00123 {
00124
00125
00126 const char *okd =
00127 ACE_OS::strchr (ior, this->object_key_delimiter_);
00128
00129 if (okd == 0 || okd == ior)
00130 {
00131
00132 ACE_THROW (CORBA::INV_OBJREF (
00133 CORBA::SystemException::_tao_minor_code (
00134 TAO::VMCID,
00135 EINVAL),
00136 CORBA::COMPLETED_NO));
00137 }
00138
00139
00140 CORBA::ULong length_host = 0;
00141
00142 const char *cp_pos = ACE_OS::strchr (ior, ':');
00143
00144 if (cp_pos == ior)
00145 {
00146
00147 ACE_THROW (CORBA::INV_OBJREF (
00148 CORBA::SystemException::_tao_minor_code (
00149 TAO::VMCID,
00150 EINVAL),
00151 CORBA::COMPLETED_NO));
00152 }
00153 else if (cp_pos != 0)
00154 {
00155
00156 CORBA::ULong length_port = okd - cp_pos - 1;
00157
00158 CORBA::String_var tmp = CORBA::string_alloc (length_port);
00159
00160 ACE_OS::strncpy (tmp.inout (), cp_pos + 1, length_port);
00161 tmp[length_port] = '\0';
00162
00163 this->endpoint_.port_ =
00164 static_cast<CORBA::UShort> (ACE_OS::atoi (tmp.in ()));
00165
00166 length_host = cp_pos - ior;
00167 }
00168 else
00169 length_host = okd - ior;
00170
00171 CORBA::String_var tmp = CORBA::string_alloc (length_host);
00172
00173
00174 ACE_OS::strncpy (tmp.inout (), ior, length_host);
00175 tmp[length_host] = '\0';
00176
00177 this->endpoint_.host_ = tmp._retn ();
00178
00179 if (ACE_OS::strcmp (this->endpoint_.host_.in (), "") == 0)
00180 {
00181 ACE_INET_Addr host_addr;
00182
00183 char tmp_host [MAXHOSTNAMELEN + 1];
00184
00185
00186
00187 if (host_addr.get_host_name (tmp_host,
00188 sizeof (tmp_host)) != 0)
00189 {
00190
00191
00192
00193 if (TAO_debug_level > 0)
00194 ACE_DEBUG ((LM_DEBUG,
00195 ACE_TEXT ("\n\nTAO (%P|%t) ")
00196 ACE_TEXT ("IIOP_Profile::parse_string ")
00197 ACE_TEXT ("- %p\n\n"),
00198 ACE_TEXT ("cannot determine hostname")));
00199
00200
00201 ACE_THROW (CORBA::INV_OBJREF (
00202 CORBA::SystemException::_tao_minor_code (
00203 TAO::VMCID,
00204 EINVAL),
00205 CORBA::COMPLETED_NO));
00206 }
00207 else
00208 this->endpoint_.host_ = CORBA::string_dup (tmp_host);
00209 }
00210
00211 TAO::ObjectKey ok;
00212 TAO::ObjectKey::decode_string_to_sequence (ok,
00213 okd + 1);
00214
00215 (void) this->orb_core ()->object_key_table ().bind (ok,
00216 this->ref_object_key_);
00217 }
00218
00219 CORBA::Boolean
00220 TAO_DIOP_Profile::do_is_equivalent (const TAO_Profile *other_profile)
00221 {
00222 const TAO_DIOP_Profile *op =
00223 dynamic_cast<const TAO_DIOP_Profile *> (other_profile);
00224
00225
00226 const TAO_DIOP_Endpoint *other_endp = &op->endpoint_;
00227 for (TAO_DIOP_Endpoint *endp = &this->endpoint_;
00228 endp != 0;
00229 endp = endp->next_)
00230 {
00231 if (endp->is_equivalent (other_endp))
00232 other_endp = other_endp->next_;
00233 else
00234 return 0;
00235 }
00236
00237 return 1;
00238 }
00239
00240 CORBA::ULong
00241 TAO_DIOP_Profile::hash (CORBA::ULong max
00242 ACE_ENV_ARG_DECL_NOT_USED)
00243 {
00244
00245 CORBA::ULong hashval = 0;
00246 for (TAO_DIOP_Endpoint *endp = &this->endpoint_;
00247 endp != 0;
00248 endp = endp->next_)
00249 {
00250 hashval += endp->hash ();
00251 }
00252
00253 hashval += this->version_.minor;
00254 hashval += this->tag ();
00255
00256 const TAO::ObjectKey &ok =
00257 this->ref_object_key_->object_key ();
00258
00259 if (ok.length () >= 4)
00260 {
00261 hashval += ok[1];
00262 hashval += ok[3];
00263 }
00264
00265 hashval += this->hash_service_i (max);
00266
00267 return hashval % max;
00268 }
00269
00270 TAO_Endpoint*
00271 TAO_DIOP_Profile::endpoint (void)
00272 {
00273 return &this->endpoint_;
00274 }
00275
00276 CORBA::ULong
00277 TAO_DIOP_Profile::endpoint_count (void) const
00278 {
00279 return this->count_;
00280 }
00281
00282 void
00283 TAO_DIOP_Profile::add_endpoint (TAO_DIOP_Endpoint *endp)
00284 {
00285 endp->next_ = this->endpoint_.next_;
00286 this->endpoint_.next_ = endp;
00287
00288 this->count_++;
00289 }
00290
00291 char *
00292 TAO_DIOP_Profile::to_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00293 {
00294 CORBA::String_var key;
00295 TAO::ObjectKey::encode_sequence_to_string (key.inout(),
00296 this->ref_object_key_->object_key ());
00297
00298 size_t buflen = (8 +
00299 1 +
00300 ACE_OS::strlen (::the_prefix) +
00301 1 +
00302 1 +
00303 1 +
00304 1 +
00305 1 +
00306 ACE_OS::strlen (this->endpoint_.host ()) +
00307 1 +
00308 5 +
00309 1 +
00310 ACE_OS::strlen (key.in ()));
00311
00312 char * buf = CORBA::string_alloc (static_cast<CORBA::ULong> (buflen));
00313
00314 static const char digits [] = "0123456789";
00315
00316 ACE_OS::sprintf (buf,
00317 "corbaloc:%s:%c.%c@%s:%d%c%s",
00318 ::the_prefix,
00319 digits [this->version_.major],
00320 digits [this->version_.minor],
00321 this->endpoint_.host (),
00322 this->endpoint_.port (),
00323 this->object_key_delimiter_,
00324 key.in ());
00325
00326 return buf;
00327 }
00328
00329 const char *
00330 TAO_DIOP_Profile::prefix (void)
00331 {
00332 return ::the_prefix;
00333 }
00334
00335 void
00336 TAO_DIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
00337 {
00338 encap.write_octet (TAO_ENCAP_BYTE_ORDER);
00339
00340
00341 encap.write_octet (this->version_.major);
00342 encap.write_octet (this->version_.minor);
00343
00344
00345 encap.write_string (this->endpoint_.host ());
00346
00347
00348 encap.write_ushort (this->endpoint_.port ());
00349
00350
00351 if (this->ref_object_key_)
00352 encap << this->ref_object_key_->object_key ();
00353 else
00354 {
00355 ACE_ERROR ((LM_ERROR,
00356 "(%P|%t) TAO - UIOP_Profile::create_profile_body "
00357 "no object key marshalled \n"));
00358 }
00359
00360 if (this->version_.major > 1
00361 || this->version_.minor > 0)
00362 this->tagged_components ().encode (encap);
00363 }
00364
00365 int
00366 TAO_DIOP_Profile::encode_endpoints (void)
00367 {
00368
00369
00370
00371
00372
00373
00374
00375 TAO::IIOPEndpointSequence endpoints;
00376 endpoints.length (this->count_);
00377
00378 const TAO_DIOP_Endpoint *endpoint = &this->endpoint_;
00379 for (CORBA::ULong i = 0;
00380 i < this->count_;
00381 ++i)
00382 {
00383 endpoints[i].host = endpoint->host ();
00384 endpoints[i].port = endpoint->port ();
00385 endpoints[i].priority = endpoint->priority ();
00386
00387 endpoint = endpoint->next_;
00388 }
00389
00390
00391 TAO_OutputCDR out_cdr;
00392 if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)
00393 == 0)
00394 || (out_cdr << endpoints) == 0)
00395 return -1;
00396 size_t length = out_cdr.total_length ();
00397
00398 IOP::TaggedComponent tagged_component;
00399 tagged_component.tag = TAO_TAG_ENDPOINTS;
00400 tagged_component.component_data.length (static_cast<CORBA::ULong> (length));
00401 CORBA::Octet *buf =
00402 tagged_component.component_data.get_buffer ();
00403
00404 for (const ACE_Message_Block *iterator = out_cdr.begin ();
00405 iterator != 0;
00406 iterator = iterator->cont ())
00407 {
00408 size_t i_length = iterator->length ();
00409 ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
00410
00411 buf += i_length;
00412 }
00413
00414
00415
00416 tagged_components_.set_component (tagged_component);
00417
00418 return 0;
00419 }
00420
00421 int
00422 TAO_DIOP_Profile::decode_endpoints (void)
00423 {
00424 IOP::TaggedComponent tagged_component;
00425 tagged_component.tag = TAO_TAG_ENDPOINTS;
00426
00427 if (this->tagged_components_.get_component (tagged_component))
00428 {
00429 const CORBA::Octet *buf =
00430 tagged_component.component_data.get_buffer ();
00431
00432 TAO_InputCDR in_cdr (reinterpret_cast<const char*> (buf),
00433 tagged_component.component_data.length ());
00434
00435
00436 CORBA::Boolean byte_order;
00437 if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00438 return -1;
00439 in_cdr.reset_byte_order (static_cast<int> (byte_order));
00440
00441
00442 TAO::IIOPEndpointSequence endpoints;
00443
00444 if ((in_cdr >> endpoints) == 0)
00445 return -1;
00446
00447
00448
00449
00450 this->endpoint_.priority (endpoints[0].priority);
00451
00452
00453
00454
00455
00456
00457
00458 for (CORBA::ULong i = endpoints.length () - 1;
00459 i > 0;
00460 --i)
00461 {
00462 TAO_DIOP_Endpoint *endpoint = 0;
00463 ACE_NEW_RETURN (endpoint,
00464 TAO_DIOP_Endpoint (endpoints[i].host,
00465 endpoints[i].port,
00466 endpoints[i].priority),
00467 -1);
00468
00469 this->add_endpoint (endpoint);
00470 }
00471 }
00472
00473 return 0;
00474 }
00475
00476 TAO_END_VERSIONED_NAMESPACE_DECL
00477
00478 #endif