UIPMC_Profile.cpp

Go to the documentation of this file.
00001 // $Id: UIPMC_Profile.cpp 79015 2007-07-24 15:03:04Z vridosh $
00002 
00003 #include "orbsvcs/PortableGroup/UIPMC_Profile.h"
00004 #include "orbsvcs/PortableGroup/miopconf.h"
00005 #include "tao/CDR.h"
00006 #include "tao/ORB.h"
00007 #include "tao/ORB_Core.h"
00008 #include "tao/debug.h"
00009 #include "tao/target_specification.h"
00010 #include "ace/OS_NS_ctype.h"
00011 
00012 #include "orbsvcs/miopC.h"
00013 #include "orbsvcs/PortableGroupC.h"
00014 
00015 ACE_RCSID (PortableGroup,
00016            UIPMC_Profile,
00017            "$Id: UIPMC_Profile.cpp 79015 2007-07-24 15:03:04Z vridosh $")
00018 
00019 static const char the_prefix[] = "miop";
00020 
00021 // UIPMC doesn't support object keys, so send profiles by default in the GIOP 1.2 target
00022 // specification.
00023 static const CORBA::Short default_addressing_mode_ = TAO_Target_Specification::Profile_Addr;
00024 
00025 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00026 
00027 const char TAO_UIPMC_Profile::object_key_delimiter_ = '/';
00028 
00029 char
00030 TAO_UIPMC_Profile::object_key_delimiter (void) const
00031 {
00032   return TAO_UIPMC_Profile::object_key_delimiter_;
00033 }
00034 
00035 TAO_UIPMC_Profile::TAO_UIPMC_Profile (TAO_ORB_Core *orb_core)
00036   : TAO_Profile (IOP::TAG_UIPMC,
00037                  orb_core,
00038                  TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)),
00039     endpoint_ (),
00040     tagged_profile_ ()
00041 {
00042     addressing_mode_ = default_addressing_mode_;
00043 }
00044 
00045 TAO_UIPMC_Profile::TAO_UIPMC_Profile (const ACE_INET_Addr &addr,
00046                                       TAO_ORB_Core *orb_core)
00047   : TAO_Profile (IOP::TAG_UIPMC,
00048                  orb_core,
00049                  TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)),
00050     endpoint_ (addr),
00051     tagged_profile_ ()
00052 {
00053     addressing_mode_ = default_addressing_mode_;
00054 }
00055 
00056 TAO_UIPMC_Profile::TAO_UIPMC_Profile (const CORBA::Octet class_d_address[4],
00057                                       CORBA::UShort port,
00058                                       TAO_ORB_Core *orb_core)
00059   : TAO_Profile (IOP::TAG_UIPMC,
00060                  orb_core,
00061                  TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)),
00062     endpoint_ (class_d_address, port),
00063     tagged_profile_ ()
00064 {
00065     addressing_mode_ = default_addressing_mode_;
00066 }
00067 
00068 /*
00069 
00070 TAO_UIPMC_Profile::TAO_UIPMC_Profile (const char *string,
00071                                       TAO_ORB_Core *orb_core)
00072   : TAO_Profile (TAO_TAG_UIPMC_PROFILE,
00073                  orb_core,
00074                  TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR)),
00075     endpoint_ (),
00076     tagged_profile_ ()
00077 {
00078   this->add_group_component ();
00079   this->parse_string (string);
00080   addressing_mode_ = default_addressing_mode_;
00081 }
00082 
00083 */
00084 
00085 TAO_UIPMC_Profile::~TAO_UIPMC_Profile (void)
00086 {
00087 }
00088 
00089 int
00090 TAO_UIPMC_Profile::decode (TAO_InputCDR& cdr)
00091 {
00092   // The following is a selective reproduction of TAO_Profile::decode
00093 
00094   CORBA::ULong encap_len = cdr.length ();
00095 
00096   // Read and verify major, minor versions, ignoring profiles
00097   // whose versions we don't understand.
00098   if (!(cdr.read_octet (this->version_.major)
00099         && this->version_.major == TAO_DEF_GIOP_MAJOR
00100         && cdr.read_octet (this->version_.minor)
00101         && this->version_.minor <= TAO_DEF_GIOP_MINOR))
00102     {
00103       if (TAO_debug_level > 0)
00104         {
00105           ACE_DEBUG ((LM_DEBUG,
00106                       ACE_TEXT ("TAO (%P|%t) - UIPMC_Profile::decode - v%d.%d\n"),
00107                       this->version_.major,
00108                       this->version_.minor));
00109         }
00110 
00111       return -1;
00112     }
00113 
00114   // Transport specific details
00115   if (this->decode_profile (cdr) < 0)
00116     {
00117       return -1;
00118     }
00119 
00120   // UIPMC profiles must have tagged components.
00121   if (this->tagged_components_.decode (cdr) == 0)
00122     {
00123       return -1;
00124     }
00125 
00126   if (cdr.length () != 0 && TAO_debug_level)
00127     {
00128       // If there is extra data in the profile we are supposed to
00129       // ignore it, but print a warning just in case...
00130       ACE_DEBUG ((LM_DEBUG,
00131                   ACE_TEXT ("%d bytes out of %d left after profile data\n"),
00132                   cdr.length (),
00133                   encap_len));
00134     }
00135 
00136   // We don't call ::decode_endpoints because it is implemented
00137   // as ACE_NOTSUP_RETURN (-1) for this profile
00138 
00139   return 1;
00140 }
00141 
00142 int
00143 TAO_UIPMC_Profile::decode_endpoints (void)
00144 {
00145   ACE_NOTSUP_RETURN (-1);
00146 }
00147 
00148 int
00149 TAO_UIPMC_Profile::decode_profile (TAO_InputCDR& cdr)
00150 {
00151   CORBA::UShort port = 0;
00152   ACE_CString address;
00153   if (!(cdr.read_string (address)
00154         && cdr.read_ushort (port)))
00155     {
00156       if (TAO_debug_level > 0)
00157         ACE_DEBUG ((LM_DEBUG,
00158                     ACE_TEXT ("TAO (%P|%t) - UIPMC_Profile::decode - ")
00159                     ACE_TEXT ("Couldn't unmarshal address and port!\n")));
00160       return -1;
00161     }
00162 
00163   if (cdr.good_bit ())
00164     {
00165       // If everything was successful, update the endpoint's address
00166       // and port with the new data.
00167       ACE_INET_Addr addr (port, address.c_str ());
00168       this->endpoint_.object_addr (addr);
00169       return 1;
00170     }
00171 
00172   return -1;
00173 }
00174 
00175 void
00176 TAO_UIPMC_Profile::parse_string (const char *string)
00177 {
00178   this->parse_string_i (string);
00179 }
00180 
00181 void
00182 TAO_UIPMC_Profile::parse_string_i (const char *string)
00183 {
00184   // Remove the "N.n@" version prefix, if it exists, and verify the
00185   // version is one that we accept.
00186 
00187   // Check for MIOP version
00188   if (ACE_OS::ace_isdigit (string [0]) &&
00189       string[1] == '.' &&
00190       ACE_OS::ace_isdigit (string [2]) &&
00191       string[3] == '@')
00192     {
00193       if (string[0] != '1' ||
00194           string[2] != '0')
00195         {
00196           throw CORBA::INV_OBJREF (
00197             CORBA::SystemException::_tao_minor_code (
00198               TAO::VMCID,
00199               EINVAL),
00200             CORBA::COMPLETED_NO);
00201         }
00202 
00203       string += 4;
00204       // Skip over the "N.n@"
00205     }
00206 
00207   // UIPMC profiles always use GIOP 1.2
00208   this->version_.set_version (1, 2);
00209 
00210   //
00211   // Parse the group_id.
00212   //
00213 
00214   // Parse the group component version.
00215   if (ACE_OS::ace_isdigit (string [0]) &&
00216       string[1] == '.' &&
00217       ACE_OS::ace_isdigit (string [2]) &&
00218       string[3] == '-')
00219     {
00220       CORBA::Char major;
00221       CORBA::Char minor;
00222 
00223       major = (char) (string [0] - '0');
00224       minor = (char) (string [2] - '0');
00225 
00226       // Verify that a supported version of MIOP is specified.
00227       if (major != TAO_DEF_MIOP_MAJOR ||
00228           minor >  TAO_DEF_MIOP_MINOR)
00229         {
00230           throw CORBA::INV_OBJREF (
00231             CORBA::SystemException::_tao_minor_code (
00232               TAO::VMCID,
00233               EINVAL),
00234             CORBA::COMPLETED_NO);
00235         }
00236 
00237       // Skip over "N.n-"
00238       string += 4;
00239     }
00240   else
00241     {
00242       // The group component version is mandatory.
00243       throw CORBA::INV_OBJREF (
00244         CORBA::SystemException::_tao_minor_code (
00245           TAO::VMCID,
00246           EINVAL),
00247         CORBA::COMPLETED_NO);
00248     }
00249 
00250   // Parse the group_domain_id.
00251   // The Domain ID is terminated with a '-'.
00252 
00253   // Look for the group domain delimitor.
00254   const char *pos = ACE_OS::strchr (string, '-');
00255 
00256   if (pos == 0)
00257     {
00258       // The group_domain_id is mandatory, so throw an
00259       // exception if it isn't found.
00260       throw CORBA::INV_OBJREF (
00261         CORBA::SystemException::_tao_minor_code (
00262           TAO::VMCID,
00263           EINVAL),
00264         CORBA::COMPLETED_NO);
00265     }
00266 
00267   // Save the group_domain_id.
00268   ACE_CString group_domain_id (string, pos - string);
00269 
00270   // Parse the group_id.
00271   // The group_id is terminated with a '-' or a '/'.
00272 
00273   // Skip past the last '-'.
00274   string = pos + 1;
00275   pos = ACE_OS::strchr (string, '-');
00276 
00277   CORBA::Boolean parse_group_ref_version_flag = 0;
00278 
00279   if (pos != 0)
00280     {
00281       // String was terminated by a '-', so there's a group
00282       // reference version to be parsed.
00283       parse_group_ref_version_flag = 1;
00284     }
00285   else
00286     {
00287       // Look for a slash as the separator.
00288       pos = ACE_OS::strchr (string, '/');
00289 
00290       if (pos == 0)
00291         {
00292           // The Group ID is mandatory, so throw an exception.
00293           throw CORBA::INV_OBJREF (
00294             CORBA::SystemException::_tao_minor_code (
00295               TAO::VMCID,
00296               EINVAL),
00297             CORBA::COMPLETED_NO);
00298         }
00299     }
00300 
00301   if (ACE_OS::strspn (string, "0123456789") !=
00302       static_cast<size_t> (pos - string))
00303     {
00304       // Throw an exception if it's not a proper number
00305       throw CORBA::INV_OBJREF (
00306         CORBA::SystemException::_tao_minor_code (
00307           TAO::VMCID,
00308           EINVAL),
00309         CORBA::COMPLETED_NO);
00310     }
00311 
00312   // Get the group_id.
00313   ACE_CString str_group_id (string, pos - string);
00314 
00315   // Convert the domain_id into numerical form.
00316   // @@ group_id is actually 64 bits, but strtoul only can parse 32 bits.
00317   // @@ Need a 64 bit strtoul...
00318   PortableGroup::ObjectGroupId group_id =
00319     ACE_OS::strtoul (str_group_id.c_str (), 0, 10);
00320 
00321   this->has_ref_version_ = false;
00322   PortableGroup::ObjectGroupRefVersion ref_version = 0;
00323   if (parse_group_ref_version_flag)
00324     {
00325       // Try to find the group version.  It is terminated by a '/'.
00326       string = pos + 1;
00327       pos = ACE_OS::strchr (string, '/');
00328       if (pos == 0)
00329         {
00330           // The group version was expected but not found,
00331           // so throw an exception.
00332           throw CORBA::INV_OBJREF (
00333             CORBA::SystemException::_tao_minor_code (
00334               TAO::VMCID,
00335               EINVAL),
00336             CORBA::COMPLETED_NO);
00337         }
00338 
00339       if (ACE_OS::strspn (string, "0123456789") !=
00340           static_cast<size_t> (pos - string))
00341         {
00342           // Throw an exception if it's not a proper number
00343           throw CORBA::INV_OBJREF (
00344             CORBA::SystemException::_tao_minor_code (
00345               TAO::VMCID,
00346               EINVAL),
00347             CORBA::COMPLETED_NO);
00348         }
00349 
00350       ACE_CString str_group_ref_ver (string, pos - string);
00351 
00352       ref_version =
00353         ACE_OS::strtoul (str_group_ref_ver.c_str (), 0, 10);
00354       this->has_ref_version_ = true;
00355     }
00356 
00357   // Parse the group multicast address.
00358   // The multicast address is terminated by a ':'.
00359   string = pos + 1;
00360   pos = ACE_OS::strchr (string, ':');
00361 
00362   if (pos == 0)
00363     {
00364       // The multicast address is mandatory, so throw an exception,
00365       // since it wasn't found.
00366       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;
00374 
00375 #if defined (ACE_HAS_IPV6)
00376   // Check if this is a (possibly) IPv6 supporting profile containing a
00377   // decimal IPv6 address representation.
00378   if ((this->version ().major > TAO_MIN_IPV6_IIOP_MAJOR ||
00379         this->version ().minor >= TAO_MIN_IPV6_IIOP_MINOR) &&
00380       string[0] == '[')
00381     {
00382       // In this case we have to find the end of the numeric address and
00383       // start looking for the port separator from there.
00384       pos = ACE_OS::strchr (string, ']');
00385       if (pos == 0)
00386         {
00387           // No valid IPv6 address specified.
00388           if (TAO_debug_level > 0)
00389             {
00390               ACE_ERROR ((LM_ERROR,
00391                           ACE_TEXT ("\nTAO (%P|%t) - UIPMC_Profile: ")
00392                           ACE_TEXT ("Invalid IPv6 decimal address specified.\n")));
00393             }
00394 
00395           throw CORBA::INV_OBJREF (
00396             CORBA::SystemException::_tao_minor_code (
00397               0,
00398               EINVAL),
00399             CORBA::COMPLETED_NO);
00400         }
00401       else
00402         {
00403           ++string;
00404           mcast_addr = ACE_CString (string, pos - string);
00405           string = pos + 2;
00406         }
00407     }
00408   else
00409     {
00410 #endif /* ACE_HAS_IPV6 */
00411       mcast_addr = ACE_CString (string, pos - string);
00412       string = pos + 1;
00413 #if defined (ACE_HAS_IPV6)
00414     }
00415 #endif /* ACE_HAS_IPV6 */
00416 
00417   size_t mcast_addr_len = mcast_addr.length ();
00418   if (ACE_OS::strspn (mcast_addr.c_str (),
00419                       ".:0123456789ABCDEFabcdef") != mcast_addr_len)
00420     {
00421       // Throw an exception if it's not a proper IPv4/IPv6 address
00422       throw CORBA::INV_OBJREF (
00423         CORBA::SystemException::_tao_minor_code (
00424           TAO::VMCID,
00425           EINVAL),
00426         CORBA::COMPLETED_NO);
00427     }
00428 
00429   // Parse the multicast port number.
00430 
00431   // First check that there's something left in the string.
00432   if (string[0] == '\0')
00433     {
00434       // The multicast port is mandatory, so throw an exception,
00435       // since it wasn't found.
00436       throw CORBA::INV_OBJREF (
00437         CORBA::SystemException::_tao_minor_code (
00438           TAO::VMCID,
00439           EINVAL),
00440         CORBA::COMPLETED_NO);
00441     }
00442 
00443   // Port can have name thus letters and '-' are allowed.
00444   const char port_chars[] =
00445     "-0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
00446   size_t port_len = ACE_OS::strlen (string);
00447   if (ACE_OS::strspn (string, port_chars) != port_len)
00448     {
00449       // Throw an exception if it's not a proper port
00450       throw CORBA::INV_OBJREF (
00451         CORBA::SystemException::_tao_minor_code (
00452           TAO::VMCID,
00453           EINVAL),
00454         CORBA::COMPLETED_NO);
00455     }
00456 
00457   ACE_INET_Addr ia;
00458   if (ia.string_to_addr (string) == -1)
00459     {
00460       throw CORBA::INV_OBJREF (
00461         CORBA::SystemException::_tao_minor_code (
00462           TAO::VMCID,
00463           EINVAL),
00464         CORBA::COMPLETED_NO);
00465     }
00466 
00467   u_short mcast_port = ia.get_port_number ();
00468 
00469   //
00470   // Finally, set all of the fields of the profile.
00471   //
00472 
00473   ACE_INET_Addr addr (mcast_port, mcast_addr.c_str ());
00474   this->endpoint_.object_addr (addr);
00475 
00476   this->set_group_info (group_domain_id.c_str (),
00477                         group_id,
00478                         ref_version);
00479 }
00480 
00481 CORBA::Boolean
00482 TAO_UIPMC_Profile::do_is_equivalent (const TAO_Profile *other_profile)
00483 {
00484   const TAO_UIPMC_Profile *op =
00485     dynamic_cast<const TAO_UIPMC_Profile *> (other_profile);
00486 
00487   if (op == 0)
00488     return 0;
00489 
00490   return this->endpoint_.is_equivalent (&op->endpoint_);
00491 }
00492 
00493 CORBA::ULong
00494 TAO_UIPMC_Profile::hash (CORBA::ULong max)
00495 {
00496   // Get the hashvalue for all endpoints.
00497   CORBA::ULong hashval = this->endpoint_.hash ();
00498 
00499   hashval += this->version_.minor;
00500   hashval += this->tag ();
00501 
00502   return hashval % max;
00503 }
00504 
00505 TAO_Endpoint*
00506 TAO_UIPMC_Profile::endpoint (void)
00507 {
00508   return &this->endpoint_;
00509 }
00510 
00511 int
00512 TAO_UIPMC_Profile::encode_endpoints (void)
00513 {
00514   return 1;
00515 }
00516 
00517 CORBA::ULong
00518 TAO_UIPMC_Profile::endpoint_count (void) const
00519 {
00520   return 1;
00521 }
00522 
00523 char *
00524 TAO_UIPMC_Profile::to_string (void)
00525 {
00526   // corbaloc:miop:1.2@1.0-group_id-1-1/host:port
00527 
00528   size_t buflen = (8 /* "corbaloc" */ +
00529                    1 /* colon separator */ +
00530                    ACE_OS::strlen (::the_prefix) + /* "miop" */
00531                    1 /* colon separator */ +
00532                    1 /* major version */ +
00533                    1 /* decimal point */ +
00534                    1 /* minor version */ +
00535                    1 /* `@' character */ +
00536                    1 /* component major version */ +
00537                    1 /* decimal point */ +
00538                    1 /* component minor version */ +
00539                    1 /* `-' character */ +
00540                    this->group_domain_id_.length () + /* domain id */
00541                    1 /* `-' character */ +
00542                    20 /* group id */ +
00543                    1 /* `-' character */ +
00544                    10 /* group reference version */ +
00545                    1 /* `/' character */ +
00546                    39 /* IPv4/IPv6 address */ +
00547                    1 /* colon separator */ +
00548                    5 /* port number */);
00549 #if defined (ACE_HAS_IPV6)
00550   if (this->endpoint_.object_addr ().get_type () == AF_INET6)
00551     buflen += 2; // room for '[' and ']'
00552 #endif /* ACE_HAS_IPV6 */
00553 
00554   static const char digits [] = "0123456789";
00555 
00556   char * buf = CORBA::string_alloc (static_cast<CORBA::ULong> (buflen));
00557 
00558   ACE_OS::sprintf (buf,
00559                    "corbaloc:%s:%c.%c@%c.%c-%s-%llu",
00560                    ::the_prefix,
00561                    digits [this->version_.major],
00562                    digits [this->version_.minor],
00563                    digits [TAO_DEF_MIOP_MAJOR],
00564                    digits [TAO_DEF_MIOP_MINOR],
00565                    this->group_domain_id_.c_str (),
00566                    this->group_id_);
00567 
00568   if (this->has_ref_version_)
00569     {
00570       ACE_OS::sprintf (&buf[ACE_OS::strlen (buf)],
00571                        "-%lu",
00572                        this->ref_version_);
00573     }
00574 
00575 #if defined (ACE_HAS_IPV6)
00576   if (this->endpoint_.object_addr ().get_type () == AF_INET6)
00577     {
00578       ACE_OS::sprintf (&buf[ACE_OS::strlen (buf)],
00579                        "/[%s]:%d",
00580                        this->endpoint_.host (),
00581                        this->endpoint_.port ());
00582     }
00583   else
00584 #endif /* ACE_HAS_IPV6 */
00585   ACE_OS::sprintf (&buf[ACE_OS::strlen (buf)],
00586                    "/%s:%d",
00587                    this->endpoint_.host (),
00588                    this->endpoint_.port ());
00589 
00590   return buf;
00591 }
00592 
00593 const char *
00594 TAO_UIPMC_Profile::prefix (void)
00595 {
00596   return ::the_prefix;
00597 }
00598 
00599 IOP::TaggedProfile &
00600 TAO_UIPMC_Profile::create_tagged_profile (void)
00601 {
00602   // Check whether we have already created the TaggedProfile
00603   if (this->tagged_profile_.profile_data.length () == 0)
00604     {
00605       // As we have not created we will now create the TaggedProfile
00606       this->tagged_profile_.tag = IOP::TAG_UIPMC;
00607 
00608       // Create the encapsulation....
00609       TAO_OutputCDR encap;
00610 
00611       // Create the profile body
00612       this->create_profile_body (encap);
00613 
00614       CORBA::ULong length =
00615         static_cast<CORBA::ULong> (encap.total_length ());
00616 
00617 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
00618       // Place the message block in to the Sequence of Octets that we
00619       // have
00620       this->tagged_profile_.profile_data.replace (length,
00621                                                   encap.begin ());
00622 #else
00623       this->tagged_profile_.profile_data.length (length);
00624       CORBA::Octet *buffer =
00625         this->tagged_profile_.profile_data.get_buffer ();
00626       for (const ACE_Message_Block *i = encap.begin ();
00627            i != encap.end ();
00628            i = i->next ())
00629         {
00630           ACE_OS::memcpy (buffer, i->rd_ptr (), i->length ());
00631           buffer += i->length ();
00632         }
00633 #endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
00634     }
00635 
00636   return this->tagged_profile_;
00637 }
00638 
00639 void
00640 TAO_UIPMC_Profile::create_profile_body (TAO_OutputCDR &encap) const
00641 {
00642   encap.write_octet (TAO_ENCAP_BYTE_ORDER);
00643 
00644   // The GIOP version
00645   // Note: Only GIOP 1.2 and above are supported currently for MIOP.
00646   encap.write_octet (this->version_.major);
00647   encap.write_octet (this->version_.minor);
00648 
00649   // Address.
00650   encap.write_string (this->endpoint_.host ());
00651 
00652   // Port number.
00653   encap.write_ushort (this->endpoint_.port ());
00654 
00655   // UIPMC is only supported by versions of GIOP that have tagged components,
00656   // so unconditionally encode the components.
00657   this->tagged_components ().encode (encap);
00658 }
00659 
00660 /*
00661 int
00662 TAO_UIPMC_Profile::decode_endpoints (void)
00663 {
00664   IOP::TaggedComponent tagged_component;
00665   tagged_component.tag = TAO_TAG_ENDPOINTS;
00666 
00667   if (this->tagged_components_.get_component (tagged_component))
00668     {
00669       const CORBA::Octet *buf =
00670         tagged_component.component_data.get_buffer ();
00671 
00672       TAO_InputCDR in_cdr (reinterpret_cast<const char*> (buf),
00673                            tagged_component.component_data.length ());
00674 
00675       // Extract the Byte Order.
00676       CORBA::Boolean byte_order;
00677       if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00678         return -1;
00679       in_cdr.reset_byte_order (static_cast<int> (byte_order));
00680 
00681       // Extract endpoints sequence.
00682       TAO_UIPMCEndpointSequence endpoints;
00683 
00684       if ((in_cdr >> endpoints) == 0)
00685         return -1;
00686 
00687       // Get the priority of the first endpoint (head of the list.
00688       // It's other data is extracted as part of the standard profile
00689       // decoding.
00690       this->endpoint_.priority (endpoints[0].priority);
00691 
00692       // Use information extracted from the tagged component to
00693       // populate the profile.  Skip the first endpoint, since it is
00694       // always extracted through standard profile body.  Also, begin
00695       // from the end of the sequence to preserve endpoint order,
00696       // since <add_endpoint> method reverses the order of endpoints
00697       // in the list.
00698       for (CORBA::ULong i = endpoints.length () - 1;
00699            i > 0;
00700            --i)
00701         {
00702           TAO_UIPMC_Endpoint *endpoint = 0;
00703           ACE_NEW_RETURN (endpoint,
00704                           TAO_UIPMC_Endpoint (endpoints[i].host,
00705                                              endpoints[i].port,
00706                                              endpoints[i].priority),
00707                           -1);
00708 
00709           this->add_endpoint (endpoint);
00710         }
00711     }
00712 
00713   return 0;
00714 }
00715 */
00716 
00717 void
00718 TAO_UIPMC_Profile::set_group_info (const char *domain_id,
00719                                    PortableGroup::ObjectGroupId group_id,
00720                                    PortableGroup::ObjectGroupRefVersion ref_version)
00721 {
00722   // First, record the group information.
00723   this->group_domain_id_.set (domain_id);
00724   this->group_id_ = group_id;
00725   this->ref_version_ = ref_version;
00726 
00727   // Update the cached version of the group component.
00728   this->update_cached_group_component ();
00729 }
00730 
00731 void
00732 TAO_UIPMC_Profile::update_cached_group_component (void)
00733 {
00734   PortableGroup::TagGroupTaggedComponent group;
00735 
00736   // Encode the data structure.
00737   group.component_version.major = TAO_DEF_MIOP_MAJOR;
00738   group.component_version.minor = TAO_DEF_MIOP_MINOR;
00739 
00740   group.group_domain_id = CORBA::string_dup (this->group_domain_id_.c_str ());
00741   group.object_group_id = this->group_id_;
00742   group.object_group_ref_version = this->ref_version_;
00743 
00744   TAO_OutputCDR out_cdr;
00745 
00746   // Write the byte order.
00747   out_cdr << ACE_OutputCDR::from_boolean (ACE_CDR_BYTE_ORDER);
00748 
00749   // Write the group information.
00750   if ((out_cdr << group) == 0)
00751     {
00752       ACE_DEBUG ((LM_DEBUG,
00753                   "Error marshaling group component!"));
00754       return;
00755     }
00756 
00757   size_t length = out_cdr.total_length ();
00758 
00759   IOP::TaggedComponent tagged_component;
00760   tagged_component.tag = IOP::TAG_GROUP;
00761   tagged_component.component_data.length (static_cast<CORBA::ULong> (length));
00762   CORBA::Octet *buf =
00763     tagged_component.component_data.get_buffer ();
00764 
00765   for (const ACE_Message_Block *iterator = out_cdr.begin ();
00766        iterator != 0;
00767        iterator = iterator->cont ())
00768     {
00769       size_t i_length = iterator->length ();
00770       ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
00771 
00772       buf += i_length;
00773     }
00774 
00775   // Add component with encoded endpoint data to this profile's
00776   // TaggedComponents.
00777   this->tagged_components_.set_component (tagged_component);
00778 }
00779 
00780 void
00781 TAO_UIPMC_Profile::request_target_specifier (
00782                       TAO_Target_Specification &target_spec,
00783                       TAO_Target_Specification::TAO_Target_Address required_type)
00784 {
00785   // Fill out the target specifier based on the required type.
00786   switch (required_type)
00787     {
00788     case TAO_Target_Specification::Profile_Addr:
00789 
00790       // Only using a profile as the target specifier is supported
00791       // at this time.  Object keys are strictly not supported since
00792       // UIPMC profiles do not have object keys.
00793       target_spec.target_specifier (
00794             this->create_tagged_profile ());
00795       break;
00796 
00797     case TAO_Target_Specification::Key_Addr:
00798     case TAO_Target_Specification::Reference_Addr:
00799     default:
00800       // Unsupported or unknown required type.  Throw an exception.
00801       throw CORBA::MARSHAL ();
00802     }
00803 }
00804 
00805 int
00806 TAO_UIPMC_Profile::supports_multicast (void) const
00807 {
00808   // Yes!  We support multicast!
00809   return 1;
00810 }
00811 
00812 void
00813 TAO_UIPMC_Profile::addressing_mode (CORBA::Short addr_mode)
00814 {
00815   // ** See race condition note about addressing mode in Profile.h **
00816   switch (addr_mode)
00817     {
00818     case TAO_Target_Specification::Profile_Addr:
00819     case TAO_Target_Specification::Reference_Addr:
00820       this->addressing_mode_ = addr_mode;
00821       break;
00822 
00823     case TAO_Target_Specification::Key_Addr:
00824       // There is no object key, so it is not supported.
00825 
00826     default:
00827       throw CORBA::BAD_PARAM (
00828         CORBA::SystemException::_tao_minor_code (
00829           TAO::VMCID,
00830           EINVAL),
00831         CORBA::COMPLETED_NO);
00832     }
00833 }
00834 
00835 int
00836 TAO_UIPMC_Profile::extract_group_component (const IOP::TaggedProfile &profile,
00837                                             PortableGroup::TagGroupTaggedComponent &group)
00838 {
00839   // Create the decoding stream from the encapsulation in the buffer,
00840 //#if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
00841 //  TAO_InputCDR cdr (profile.profile_data.mb ());
00842 //#else
00843   TAO_InputCDR cdr (reinterpret_cast<const char*> (profile.profile_data.get_buffer ()),
00844                     profile.profile_data.length ());
00845 //#endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
00846 
00847   // Extract the Byte Order.
00848   CORBA::Boolean byte_order;
00849   if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00850     return -1;
00851   cdr.reset_byte_order (static_cast<int> (byte_order));
00852 
00853   // Read and verify major, minor versions, ignoring UIPMC profiles
00854   // whose versions we don't understand.
00855   CORBA::Octet major;
00856   CORBA::Octet minor = CORBA::Octet();
00857 
00858   // Read the version. We just read it here. We don't*do any*
00859   // processing.
00860   if (!(cdr.read_octet (major)
00861         && cdr.read_octet (minor)))
00862   {
00863     if (TAO_debug_level > 0)
00864       {
00865         ACE_DEBUG ((LM_DEBUG,
00866                     ACE_TEXT ("TAO (%P|%t) - UIPMC_Profile::extract_group_component - v%d.%d\n"),
00867                     major,
00868                     minor));
00869       }
00870     return -1;
00871   }
00872 
00873   // Decode the endpoint.
00874   ACE_CString address;
00875   CORBA::UShort port;
00876 
00877   if (!(cdr.read_string (address)
00878         && cdr.read_ushort (port)))
00879     {
00880       if (TAO_debug_level > 0)
00881         ACE_DEBUG ((LM_DEBUG,
00882                     ACE_TEXT ("TAO (%P|%t) - UIPMC_Profile::extract_group_component - Couldn't unmarshal address and port!\n")));
00883       return -1;
00884     }
00885 
00886   TAO_Tagged_Components tagged_components;
00887   if (tagged_components.decode (cdr) == 0)
00888     return -1;
00889 
00890   IOP::TaggedComponent tagged_component;
00891   tagged_component.tag = IOP::TAG_GROUP;
00892 
00893   // Try to find it.
00894   if (tagged_components.get_component (tagged_component) == 0)
00895     return -1;
00896 
00897   // Found it.
00898   const CORBA::Octet *buf =
00899     tagged_component.component_data.get_buffer ();
00900 
00901   TAO_InputCDR in_cdr (reinterpret_cast<const char*> (buf),
00902                        tagged_component.component_data.length ());
00903 
00904   // Extract the Byte Order.
00905   if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00906     return -1;
00907   in_cdr.reset_byte_order (static_cast<int> (byte_order));
00908 
00909   if ((in_cdr >> group) == 0)
00910     return -1;
00911 
00912   return 0;
00913 }
00914 
00915 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:49:50 2010 for TAO_PortableGroup by  doxygen 1.4.7