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