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