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