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/Environment.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 "SHMIOP_Profile.cpp,v 1.34 2006/03/10 07:19:19 jtc Exp")
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 ACE_ENV_ARG_DECL)
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 ACE_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 ACE_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 ACE_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 ACE_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 ACE_THROW (CORBA::INV_OBJREF (
00252 CORBA::SystemException::_tao_minor_code (
00253 TAO::VMCID,
00254 EINVAL),
00255 CORBA::COMPLETED_NO));
00256 }
00257
00258 start = ++okd;
00259
00260 TAO::ObjectKey ok;
00261 TAO::ObjectKey::decode_string_to_sequence (ok,
00262 okd + 1);
00263
00264 (void) this->orb_core ()->object_key_table ().bind (ok,
00265 this->ref_object_key_);
00266 }
00267
00268 CORBA::Boolean
00269 TAO_SHMIOP_Profile::do_is_equivalent (const TAO_Profile *other_profile)
00270 {
00271 const TAO_SHMIOP_Profile *op =
00272 dynamic_cast <const TAO_SHMIOP_Profile *> (other_profile);
00273
00274 if (op == 0)
00275 return 0;
00276
00277
00278 const TAO_SHMIOP_Endpoint *other_endp = &op->endpoint_;
00279 for (TAO_SHMIOP_Endpoint *endp = &this->endpoint_;
00280 endp != 0;
00281 endp = endp->next_)
00282 {
00283 if (endp->is_equivalent (other_endp))
00284 other_endp = other_endp->next_;
00285 else
00286 return 0;
00287 }
00288
00289 return 1;
00290 }
00291
00292 CORBA::ULong
00293 TAO_SHMIOP_Profile::hash (CORBA::ULong max
00294 ACE_ENV_ARG_DECL_NOT_USED)
00295 {
00296
00297 CORBA::ULong hashval = 0;
00298 for (TAO_SHMIOP_Endpoint *endp = &this->endpoint_;
00299 endp != 0;
00300 endp = endp->next_)
00301 {
00302 hashval += endp->hash ();
00303 }
00304
00305 hashval += this->version_.minor;
00306 hashval += this->tag ();
00307
00308 const TAO::ObjectKey &ok =
00309 this->ref_object_key_->object_key ();
00310
00311 if (ok.length () >= 4)
00312 {
00313 hashval += ok[1];
00314 hashval += ok[3];
00315 }
00316
00317 hashval += this->hash_service_i (max);
00318
00319 return hashval % max;
00320 }
00321
00322 void
00323 TAO_SHMIOP_Profile::add_endpoint (TAO_SHMIOP_Endpoint *endp)
00324 {
00325 endp->next_ = this->endpoint_.next_;
00326 this->endpoint_.next_ = endp;
00327
00328 this->count_++;
00329 }
00330
00331 char *
00332 TAO_SHMIOP_Profile::to_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00333 {
00334 CORBA::String_var key;
00335 TAO::ObjectKey::encode_sequence_to_string (key.inout(),
00336 this->ref_object_key_->object_key ());
00337
00338 size_t buflen = (8 +
00339 1 +
00340 ACE_OS::strlen (::prefix_) +
00341 1 +
00342 1 +
00343 1 +
00344 1 +
00345 1 +
00346 ACE_OS::strlen (this->endpoint_.host ()) +
00347 1 +
00348 5 +
00349 1 +
00350 ACE_OS::strlen (key.in ()));
00351
00352 char * buf = CORBA::string_alloc (static_cast <CORBA::ULong> (buflen));
00353
00354 static const char digits [] = "0123456789";
00355
00356 ACE_OS::sprintf (buf,
00357 "corbaloc:%s:%c.%c@%s:%d%c%s",
00358 ::prefix_,
00359 digits [this->version_.major],
00360 digits [this->version_.minor],
00361 this->endpoint_.host (),
00362 this->endpoint_.port (),
00363 this->object_key_delimiter_,
00364 key.in ());
00365 return buf;
00366 }
00367
00368 const char *
00369 TAO_SHMIOP_Profile::prefix (void)
00370 {
00371 return ::prefix_;
00372 }
00373
00374 void
00375 TAO_SHMIOP_Profile::create_profile_body (TAO_OutputCDR &encap) const
00376 {
00377 encap.write_octet (TAO_ENCAP_BYTE_ORDER);
00378
00379
00380 encap.write_octet (this->version_.major);
00381 encap.write_octet (this->version_.minor);
00382
00383
00384 encap.write_string (this->endpoint_.host ());
00385
00386
00387 encap.write_ushort (this->endpoint_.port ());
00388
00389
00390 if (this->ref_object_key_)
00391 encap << this->ref_object_key_->object_key ();
00392 else
00393 {
00394 ACE_ERROR ((LM_ERROR,
00395 "(%P|%t) TAO - UIOP_Profile::create_profile_body "
00396 "no object key marshalled \n"));
00397 }
00398
00399 if (this->version_.major > 1
00400 || this->version_.minor > 0)
00401 this->tagged_components ().encode (encap);
00402 }
00403
00404 int
00405 TAO_SHMIOP_Profile::encode_endpoints (void)
00406 {
00407
00408
00409
00410
00411
00412
00413 TAO::IIOPEndpointSequence endpoints;
00414 endpoints.length (this->count_);
00415
00416 TAO_SHMIOP_Endpoint *endpoint = &this->endpoint_;
00417 for (CORBA::ULong i = 0;
00418 i < this->count_;
00419 ++i)
00420 {
00421 endpoints[i].host = endpoint->host ();
00422 endpoints[i].port = endpoint->port ();
00423 endpoints[i].priority = endpoint->priority ();
00424
00425 endpoint = endpoint->next_;
00426 }
00427
00428
00429 TAO_OutputCDR out_cdr;
00430 if ((out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)
00431 == 0)
00432 || (out_cdr << endpoints) == 0)
00433 return -1;
00434 size_t length = out_cdr.total_length ();
00435
00436 IOP::TaggedComponent tagged_component;
00437 tagged_component.tag = TAO_TAG_ENDPOINTS;
00438 tagged_component.component_data.length (static_cast <CORBA::ULong>(length));
00439 CORBA::Octet *buf =
00440 tagged_component.component_data.get_buffer ();
00441
00442 for (const ACE_Message_Block *iterator = out_cdr.begin ();
00443 iterator != 0;
00444 iterator = iterator->cont ())
00445 {
00446 size_t i_length = iterator->length ();
00447 ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
00448
00449 buf += i_length;
00450 }
00451
00452
00453
00454 tagged_components_.set_component (tagged_component);
00455
00456 return 0;
00457 }
00458
00459 int
00460 TAO_SHMIOP_Profile::decode_endpoints (void)
00461 {
00462 IOP::TaggedComponent tagged_component;
00463 tagged_component.tag = TAO_TAG_ENDPOINTS;
00464
00465 if (this->tagged_components_.get_component (tagged_component))
00466 {
00467 const CORBA::Octet *buf =
00468 tagged_component.component_data.get_buffer ();
00469
00470 TAO_InputCDR in_cdr (reinterpret_cast <const char*> (buf),
00471 tagged_component.component_data.length ());
00472
00473
00474 CORBA::Boolean byte_order;
00475 if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00476 return -1;
00477 in_cdr.reset_byte_order (static_cast<int> (byte_order));
00478
00479
00480 TAO::IIOPEndpointSequence endpoints;
00481
00482 if ((in_cdr >> endpoints) == 0)
00483 return -1;
00484
00485
00486
00487
00488 this->endpoint_.priority (endpoints[0].priority);
00489
00490
00491
00492
00493
00494
00495
00496 for (CORBA::ULong i = endpoints.length () - 1;
00497 i > 0;
00498 --i)
00499 {
00500 TAO_SHMIOP_Endpoint *endpoint = 0;
00501 ACE_NEW_RETURN (endpoint,
00502 TAO_SHMIOP_Endpoint (endpoints[i].host,
00503 endpoints[i].port,
00504 endpoints[i].priority),
00505 -1);
00506
00507 this->add_endpoint (endpoint);
00508 }
00509 }
00510
00511 return 0;
00512 }
00513
00514 TAO_END_VERSIONED_NAMESPACE_DECL
00515
00516 #endif