00001
00002
00003 #include "orbsvcs/PortableGroup/UIPMC_Profile.h"
00004 #include "orbsvcs/PortableGroup/miopconf.h"
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/target_specification.h"
00011 #include "ace/os_include/os_ctype.h"
00012
00013 #include "orbsvcs/miopC.h"
00014 #include "orbsvcs/PortableGroupC.h"
00015
00016 ACE_RCSID (PortableGroup,
00017 UIPMC_Profile,
00018 "UIPMC_Profile.cpp,v 1.28 2006/05/23 16:09:34 mitza Exp")
00019
00020 static const char the_prefix[] = "uipmc";
00021
00022
00023
00024 static const CORBA::Short default_addressing_mode_ = TAO_Target_Specification::Profile_Addr;
00025
00026 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00027
00028 const char TAO_UIPMC_Profile::object_key_delimiter_ = '/';
00029
00030 char
00031 TAO_UIPMC_Profile::object_key_delimiter (void) const
00032 {
00033 return TAO_UIPMC_Profile::object_key_delimiter_;
00034 }
00035
00036
00037 TAO_UIPMC_Profile::TAO_UIPMC_Profile (TAO_ORB_Core *orb_core)
00038 : TAO_Profile (IOP::TAG_UIPMC,
00039 orb_core,
00040 TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)),
00041 endpoint_ (),
00042 count_ (1),
00043 tagged_profile_ ()
00044 {
00045 addressing_mode_ = default_addressing_mode_;
00046 }
00047
00048 TAO_UIPMC_Profile::TAO_UIPMC_Profile (const ACE_INET_Addr &addr,
00049 TAO_ORB_Core *orb_core)
00050 : TAO_Profile (IOP::TAG_UIPMC,
00051 orb_core,
00052 TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)),
00053 endpoint_ (addr),
00054 count_ (1),
00055 tagged_profile_ ()
00056 {
00057 addressing_mode_ = default_addressing_mode_;
00058 }
00059
00060 TAO_UIPMC_Profile::TAO_UIPMC_Profile (const CORBA::Octet class_d_address[4],
00061 CORBA::UShort port,
00062 TAO_ORB_Core *orb_core)
00063 : TAO_Profile (IOP::TAG_UIPMC,
00064 orb_core,
00065 TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)),
00066 endpoint_ (class_d_address, port),
00067 count_ (1),
00068 tagged_profile_ ()
00069 {
00070 addressing_mode_ = default_addressing_mode_;
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 TAO_UIPMC_Profile::~TAO_UIPMC_Profile (void)
00104 {
00105 }
00106
00107 int
00108 TAO_UIPMC_Profile::decode (TAO_InputCDR& cdr)
00109 {
00110
00111
00112 CORBA::ULong encap_len = cdr.length ();
00113
00114
00115
00116 if (!(cdr.read_octet (this->version_.major)
00117 && this->version_.major == TAO_DEF_GIOP_MAJOR
00118 && cdr.read_octet (this->version_.minor)
00119 && this->version_.minor <= TAO_DEF_GIOP_MINOR))
00120 {
00121 if (TAO_debug_level > 0)
00122 {
00123 ACE_DEBUG ((LM_DEBUG,
00124 ACE_TEXT ("TAO (%P|%t) - Profile::decode - v%d.%d\n"),
00125 this->version_.major,
00126 this->version_.minor));
00127 }
00128
00129 return -1;
00130 }
00131
00132
00133 if (this->decode_profile (cdr) < 0)
00134 {
00135 return -1;
00136 }
00137
00138
00139 if (this->tagged_components_.decode (cdr) == 0)
00140 {
00141 return -1;
00142 }
00143
00144 if (cdr.length () != 0 && TAO_debug_level)
00145 {
00146
00147
00148 ACE_DEBUG ((LM_DEBUG,
00149 ACE_TEXT ("%d bytes out of %d left after profile data\n"),
00150 cdr.length (),
00151 encap_len));
00152 }
00153
00154
00155
00156
00157 return 1;
00158 }
00159
00160 int
00161 TAO_UIPMC_Profile::decode_endpoints (void)
00162 {
00163 ACE_NOTSUP_RETURN (-1);
00164 }
00165
00166 int
00167 TAO_UIPMC_Profile::decode_profile (TAO_InputCDR& cdr)
00168 {
00169 CORBA::UShort port = 0;
00170 ACE_CString address;
00171 if (!(cdr.read_string (address)
00172 && cdr.read_ushort (port)))
00173 {
00174 if (TAO_debug_level > 0)
00175 ACE_DEBUG ((LM_DEBUG,
00176 ACE_TEXT ("TAO (%P|%t) UIPMC_Profile::decode - ")
00177 ACE_TEXT ("Couldn't unmarshal address and port!\n")));
00178 return -1;
00179 }
00180
00181 if (cdr.good_bit ())
00182 {
00183
00184
00185 ACE_INET_Addr addr (port, address.c_str ());
00186 this->endpoint_.object_addr (addr);
00187 return 1;
00188 }
00189
00190 return -1;
00191 }
00192
00193 void
00194 TAO_UIPMC_Profile::parse_string (const char *string
00195 ACE_ENV_ARG_DECL)
00196 {
00197 this->parse_string_i (string
00198 ACE_ENV_ARG_PARAMETER);
00199 }
00200
00201 void
00202 TAO_UIPMC_Profile::parse_string_i (const char *string
00203 ACE_ENV_ARG_DECL)
00204 {
00205
00206
00207
00208
00209 if (isdigit (string [0]) &&
00210 string[1] == '.' &&
00211 isdigit (string [2]) &&
00212 string[3] == '@')
00213 {
00214 if (string[0] != '1' ||
00215 string[2] != '0')
00216 {
00217 ACE_THROW (CORBA::INV_OBJREF (
00218 CORBA::SystemException::_tao_minor_code (
00219 TAO::VMCID,
00220 EINVAL),
00221 CORBA::COMPLETED_NO));
00222 }
00223
00224 string += 4;
00225
00226 }
00227
00228
00229 this->version_.set_version (1, 2);
00230
00231
00232
00233
00234
00235
00236 if (isdigit (string [0]) &&
00237 string[1] == '.' &&
00238 isdigit (string [2]) &&
00239 string[3] == '-')
00240 {
00241 CORBA::Char major;
00242 CORBA::Char minor;
00243
00244 major = (char) (string [0] - '0');
00245 minor = (char) (string [2] - '0');
00246
00247
00248 if (major != TAO_DEF_MIOP_MAJOR ||
00249 minor > TAO_DEF_MIOP_MINOR)
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
00259 string += 4;
00260 }
00261 else
00262 {
00263
00264 ACE_THROW (CORBA::INV_OBJREF (
00265 CORBA::SystemException::_tao_minor_code (
00266 TAO::VMCID,
00267 EINVAL),
00268 CORBA::COMPLETED_NO));
00269 }
00270
00271
00272
00273
00274
00275 ACE_CString ace_str (string, 0, 0);
00276
00277
00278 ssize_t pos = ace_str.find ('-');
00279
00280 if (pos == ACE_CString::npos)
00281 {
00282
00283
00284 ACE_THROW (CORBA::INV_OBJREF (
00285 CORBA::SystemException::_tao_minor_code (
00286 TAO::VMCID,
00287 EINVAL),
00288 CORBA::COMPLETED_NO));
00289 }
00290
00291
00292 ACE_CString group_domain_id = ace_str.substring (0, pos);
00293
00294
00295
00296
00297
00298 pos++;
00299 ssize_t end_pos = ace_str.find ('-',pos);
00300
00301 CORBA::Boolean parse_group_ref_version_flag = 0;
00302
00303 if (end_pos != ACE_CString::npos)
00304 {
00305
00306
00307 parse_group_ref_version_flag = 1;
00308 }
00309 else
00310 {
00311
00312 end_pos = ace_str.find ('/', pos);
00313
00314 if (end_pos == ACE_CString::npos)
00315 {
00316
00317 ACE_THROW (CORBA::INV_OBJREF (
00318 CORBA::SystemException::_tao_minor_code (
00319 TAO::VMCID,
00320 EINVAL),
00321 CORBA::COMPLETED_NO));
00322 }
00323 }
00324
00325
00326 ACE_CString str_domain_id = ace_str.substring (pos, end_pos - pos);
00327
00328
00329
00330
00331 PortableGroup::ObjectGroupId group_id =
00332 ACE_OS::strtoul (str_domain_id.c_str (), 0, 10);
00333
00334 PortableGroup::ObjectGroupRefVersion ref_version = 0;
00335 if (parse_group_ref_version_flag)
00336 {
00337
00338 pos = end_pos + 1;
00339 end_pos = ace_str.find ('/', pos);
00340 if (end_pos == ACE_CString::npos)
00341 {
00342
00343
00344 ACE_THROW (CORBA::INV_OBJREF (
00345 CORBA::SystemException::_tao_minor_code (
00346 TAO::VMCID,
00347 EINVAL),
00348 CORBA::COMPLETED_NO));
00349 }
00350
00351 ACE_CString str_group_ref_ver = ace_str.substring (pos, end_pos - pos);
00352
00353 ref_version =
00354 ACE_OS::strtoul (str_group_ref_ver.c_str (), 0, 10);
00355 }
00356
00357
00358
00359 pos = end_pos + 1;
00360 end_pos = ace_str.find (':', pos);
00361
00362 if (end_pos == ACE_CString::npos)
00363 {
00364
00365
00366 ACE_THROW (CORBA::INV_OBJREF (
00367 CORBA::SystemException::_tao_minor_code (
00368 TAO::VMCID,
00369 EINVAL),
00370 CORBA::COMPLETED_NO));
00371 }
00372
00373 ACE_CString mcast_addr = ace_str.substring (pos, end_pos - pos);
00374
00375
00376
00377
00378 pos = end_pos + 1;
00379 if (ace_str[pos] == '\0')
00380 {
00381
00382
00383 ACE_THROW (CORBA::INV_OBJREF (
00384 CORBA::SystemException::_tao_minor_code (
00385 TAO::VMCID,
00386 EINVAL),
00387 CORBA::COMPLETED_NO));
00388 }
00389
00390 CORBA::UShort mcast_port =
00391 static_cast<CORBA::UShort> (ACE_OS::strtoul (ace_str.c_str () + pos, 0, 10));
00392
00393
00394
00395
00396
00397 ACE_INET_Addr addr (mcast_port, mcast_addr.c_str ());
00398 this->endpoint_.object_addr (addr);
00399
00400 this->set_group_info (group_domain_id.c_str (),
00401 group_id,
00402 ref_version);
00403
00404 }
00405
00406 CORBA::Boolean
00407 TAO_UIPMC_Profile::do_is_equivalent (const TAO_Profile *other_profile)
00408 {
00409 const TAO_UIPMC_Profile *op =
00410 dynamic_cast<const TAO_UIPMC_Profile *> (other_profile);
00411
00412 if (op == 0)
00413 return 0;
00414
00415 return this->endpoint_.is_equivalent (&op->endpoint_);
00416 }
00417
00418 CORBA::ULong
00419 TAO_UIPMC_Profile::hash (CORBA::ULong max
00420 ACE_ENV_ARG_DECL_NOT_USED)
00421 {
00422
00423 CORBA::ULong hashval = this->endpoint_.hash ();
00424
00425 hashval += this->version_.minor;
00426 hashval += this->tag ();
00427
00428 return hashval % max;
00429 }
00430
00431 TAO_Endpoint*
00432 TAO_UIPMC_Profile::endpoint (void)
00433 {
00434 return &this->endpoint_;
00435 }
00436
00437 int
00438 TAO_UIPMC_Profile::encode_endpoints (void)
00439 {
00440 return 1;
00441 }
00442
00443 CORBA::ULong
00444 TAO_UIPMC_Profile::endpoint_count (void) const
00445 {
00446 return 1;
00447 }
00448
00449 char *
00450 TAO_UIPMC_Profile::to_string (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
00451 {
00452
00453
00454 size_t buflen = (ACE_OS::strlen (::the_prefix) +
00455 3 +
00456 1 +
00457 2 +
00458 1 +
00459 1 +
00460 1 +
00461 1 +
00462 15 +
00463 1 +
00464 5 );
00465
00466 char * buf = CORBA::string_alloc (static_cast<CORBA::ULong> (buflen));
00467
00468 ACE_OS::sprintf (buf,
00469 "corbaloc:%s://1.0@%s:%d",
00470 ::the_prefix,
00471 this->endpoint_.get_host_addr (),
00472 this->endpoint_.port ());
00473 return buf;
00474 }
00475
00476 const char *
00477 TAO_UIPMC_Profile::prefix (void)
00478 {
00479 return ::the_prefix;
00480 }
00481
00482 IOP::TaggedProfile &
00483 TAO_UIPMC_Profile::create_tagged_profile (void)
00484 {
00485
00486 if (this->tagged_profile_.profile_data.length () == 0)
00487 {
00488
00489 this->tagged_profile_.tag = IOP::TAG_UIPMC;
00490
00491
00492 TAO_OutputCDR encap;
00493
00494
00495 this->create_profile_body (encap);
00496
00497 CORBA::ULong length =
00498 static_cast<CORBA::ULong> (encap.total_length ());
00499
00500 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
00501
00502
00503 this->tagged_profile_.profile_data.replace (length,
00504 encap.begin ());
00505 #else
00506 this->tagged_profile_.profile_data.length (length);
00507 CORBA::Octet *buffer =
00508 this->tagged_profile_.profile_data.get_buffer ();
00509 for (const ACE_Message_Block *i = encap.begin ();
00510 i != encap.end ();
00511 i = i->next ())
00512 {
00513 ACE_OS::memcpy (buffer, i->rd_ptr (), i->length ());
00514 buffer += i->length ();
00515 }
00516 #endif
00517 }
00518
00519 return this->tagged_profile_;
00520 }
00521
00522 void
00523 TAO_UIPMC_Profile::create_profile_body (TAO_OutputCDR &encap) const
00524 {
00525 encap.write_octet (TAO_ENCAP_BYTE_ORDER);
00526
00527
00528
00529 encap.write_octet (this->version_.major);
00530 encap.write_octet (this->version_.minor);
00531
00532
00533 encap.write_string (this->endpoint_.get_host_addr ());
00534
00535
00536 encap.write_ushort (this->endpoint_.port ());
00537
00538
00539
00540 this->tagged_components ().encode (encap);
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 void
00601 TAO_UIPMC_Profile::set_group_info (const char *domain_id,
00602 PortableGroup::ObjectGroupId group_id,
00603 PortableGroup::ObjectGroupRefVersion ref_version)
00604 {
00605
00606 this->group_domain_id_.set (domain_id);
00607 this->group_id_ = group_id;
00608 this->ref_version_ = ref_version;
00609
00610
00611 this->update_cached_group_component ();
00612 }
00613
00614 void
00615 TAO_UIPMC_Profile::update_cached_group_component (void)
00616 {
00617 PortableGroup::TagGroupTaggedComponent group;
00618
00619
00620 group.component_version.major = TAO_DEF_MIOP_MAJOR;
00621 group.component_version.minor = TAO_DEF_MIOP_MINOR;
00622
00623 group.group_domain_id = CORBA::string_dup (this->group_domain_id_.c_str ());
00624 group.object_group_id = this->group_id_;
00625 group.object_group_ref_version = this->ref_version_;
00626
00627 TAO_OutputCDR out_cdr;
00628
00629
00630 out_cdr << ACE_OutputCDR::from_boolean (ACE_CDR_BYTE_ORDER);
00631
00632
00633 if ((out_cdr << group) == 0)
00634 {
00635 ACE_DEBUG ((LM_DEBUG,
00636 "Error marshaling group component!"));
00637 return;
00638 }
00639
00640 size_t length = out_cdr.total_length ();
00641
00642 IOP::TaggedComponent tagged_component;
00643 tagged_component.tag = IOP::TAG_GROUP;
00644 tagged_component.component_data.length (static_cast<CORBA::ULong> (length));
00645 CORBA::Octet *buf =
00646 tagged_component.component_data.get_buffer ();
00647
00648 for (const ACE_Message_Block *iterator = out_cdr.begin ();
00649 iterator != 0;
00650 iterator = iterator->cont ())
00651 {
00652 size_t i_length = iterator->length ();
00653 ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
00654
00655 buf += i_length;
00656 }
00657
00658
00659
00660 this->tagged_components_.set_component (tagged_component);
00661 }
00662
00663 void
00664 TAO_UIPMC_Profile::request_target_specifier (
00665 TAO_Target_Specification &target_spec,
00666 TAO_Target_Specification::TAO_Target_Address required_type
00667 ACE_ENV_ARG_DECL)
00668 {
00669
00670 switch (required_type)
00671 {
00672 case TAO_Target_Specification::Profile_Addr:
00673
00674
00675
00676
00677 target_spec.target_specifier (
00678 this->create_tagged_profile ());
00679 break;
00680
00681 case TAO_Target_Specification::Key_Addr:
00682 case TAO_Target_Specification::Reference_Addr:
00683 default:
00684
00685 ACE_THROW (CORBA::MARSHAL ());
00686 }
00687 }
00688
00689 int
00690 TAO_UIPMC_Profile::supports_multicast (void) const
00691 {
00692
00693 return 1;
00694 }
00695
00696 void
00697 TAO_UIPMC_Profile::addressing_mode (CORBA::Short addr_mode
00698 ACE_ENV_ARG_DECL)
00699 {
00700
00701 switch (addr_mode)
00702 {
00703 case TAO_Target_Specification::Profile_Addr:
00704 case TAO_Target_Specification::Reference_Addr:
00705 this->addressing_mode_ = addr_mode;
00706 break;
00707
00708 case TAO_Target_Specification::Key_Addr:
00709
00710
00711 default:
00712 ACE_THROW (CORBA::BAD_PARAM (
00713 CORBA::SystemException::_tao_minor_code (
00714 TAO::VMCID,
00715 EINVAL),
00716 CORBA::COMPLETED_NO));
00717 }
00718 }
00719
00720 int
00721 TAO_UIPMC_Profile::extract_group_component (const IOP::TaggedProfile &profile,
00722 PortableGroup::TagGroupTaggedComponent &group)
00723 {
00724
00725
00726
00727
00728 TAO_InputCDR cdr (reinterpret_cast<const char*> (profile.profile_data.get_buffer ()),
00729 profile.profile_data.length ());
00730
00731
00732
00733 CORBA::Boolean byte_order;
00734 if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00735 return -1;
00736 cdr.reset_byte_order (static_cast<int> (byte_order));
00737
00738
00739
00740 CORBA::Octet major;
00741 CORBA::Octet minor = CORBA::Octet();
00742
00743
00744
00745 if (!(cdr.read_octet (major)
00746 && cdr.read_octet (minor)))
00747 {
00748 if (TAO_debug_level > 0)
00749 {
00750 ACE_DEBUG ((LM_DEBUG,
00751 ACE_TEXT ("TAO (%P|%t) UIPMC_Profile::extract_group_component - v%d.%d\n"),
00752 major,
00753 minor));
00754 }
00755 return -1;
00756 }
00757
00758
00759 ACE_CString address;
00760 CORBA::UShort port;
00761
00762 if (!(cdr.read_string (address)
00763 && cdr.read_ushort (port)))
00764 {
00765 if (TAO_debug_level > 0)
00766 ACE_DEBUG ((LM_DEBUG,
00767 ACE_TEXT ("TAO (%P|%t) UIPMC_Profile::extract_group_component - Couldn't unmarshal address and port!\n")));
00768 return -1;
00769 }
00770
00771 TAO_Tagged_Components tagged_components;
00772 if (tagged_components.decode (cdr) == 0)
00773 return -1;
00774
00775 IOP::TaggedComponent tagged_component;
00776 tagged_component.tag = IOP::TAG_GROUP;
00777
00778
00779 if (tagged_components.get_component (tagged_component) == 0)
00780 return -1;
00781
00782
00783 const CORBA::Octet *buf =
00784 tagged_component.component_data.get_buffer ();
00785
00786 TAO_InputCDR in_cdr (reinterpret_cast<const char*> (buf),
00787 tagged_component.component_data.length ());
00788
00789
00790 if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00791 return -1;
00792 in_cdr.reset_byte_order (static_cast<int> (byte_order));
00793
00794 if ((in_cdr >> group) == 0)
00795 return -1;
00796
00797 return 0;
00798 }
00799
00800 TAO_END_VERSIONED_NAMESPACE_DECL