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