Profile.cpp

Go to the documentation of this file.
00001 // $Id: Profile.cpp 81429 2008-04-24 18:49:54Z johnnyw $
00002 
00003 #include "tao/Profile.h"
00004 #include "tao/Messaging_PolicyValueC.h"
00005 #include "tao/Stub.h"
00006 #include "tao/debug.h"
00007 #include "tao/target_specification.h"
00008 #include "tao/ORB_Core.h"
00009 #include "tao/Client_Strategy_Factory.h"
00010 #include "tao/CDR.h"
00011 #include "tao/SystemException.h"
00012 #include "tao/PolicyC.h"
00013 #include "tao/Endpoint.h"
00014 
00015 #include "ace/ACE.h"
00016 #include "ace/OS_NS_string.h"
00017 #include "ace/OS_NS_ctype.h"
00018 
00019 #if !defined (__ACE_INLINE__)
00020 #include "tao/Profile.inl"
00021 #endif /* __ACE_INLINE__ */
00022 
00023 
00024 ACE_RCSID (tao,
00025            Profile,
00026            "$Id: Profile.cpp 81429 2008-04-24 18:49:54Z johnnyw $")
00027 
00028 // ****************************************************************
00029 
00030 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00031 
00032 TAO_Profile::TAO_Profile (CORBA::ULong tag,
00033                           TAO_ORB_Core *orb_core,
00034                           const TAO::ObjectKey &obj_key,
00035                           const TAO_GIOP_Message_Version &version)
00036   : version_ (version)
00037     , are_policies_parsed_ (false)
00038     , addressing_mode_ (0)
00039     , tagged_profile_ (0)
00040     , ref_object_key_ (0)
00041     , tag_ (tag)
00042     , orb_core_ (orb_core)
00043     , forward_to_ (0)
00044     , refcount_ (this->orb_core_->
00045                    client_factory ()->create_profile_refcount ())
00046     , tagged_profile_lock_ ()
00047     , tagged_profile_created_ (false)
00048 {
00049   (void) this->orb_core_->object_key_table ().bind (obj_key,
00050                                                     this->ref_object_key_);
00051 }
00052 
00053 TAO_Profile::TAO_Profile (CORBA::ULong tag,
00054                           TAO_ORB_Core *orb_core,
00055                           const TAO_GIOP_Message_Version &version)
00056   : version_ (version)
00057     , are_policies_parsed_ (false)
00058     , addressing_mode_ (0)
00059     , tagged_profile_ (0)
00060     , ref_object_key_ (0)
00061     , tag_ (tag)
00062     , orb_core_ (orb_core)
00063     , forward_to_ (0)
00064     , refcount_ (this->orb_core_->
00065                    client_factory ()->create_profile_refcount ())
00066     , tagged_profile_lock_ ()
00067     , tagged_profile_created_ (false)
00068 {
00069 }
00070 
00071 TAO_Profile::~TAO_Profile (void)
00072 {
00073   if (this->tagged_profile_)
00074     {
00075       delete this->tagged_profile_;
00076     }
00077 
00078   this->orb_core_->object_key_table ().unbind (this->ref_object_key_);
00079 
00080   //@@ TAO_PROFILE_SPL_DESTRUCTOR_ADD_HOOK
00081 }
00082 
00083 void
00084 TAO_Profile::add_tagged_component (const IOP::TaggedComponent &component)
00085 {
00086   // Sanity checks.
00087   this->verify_orb_configuration ();
00088 
00089   this->verify_profile_version ();
00090 
00091   // ----------------------------------------------------------------
00092 
00093   // Add the given tagged component to this profile.
00094   //
00095   // Note that multiple tagged profiles with the same tag value may be
00096   // added, unless the tagged component is known to be unique by TAO.
00097   this->tagged_components_.set_component (component);
00098 }
00099 
00100 
00101 TAO_Endpoint *
00102 TAO_Profile::base_endpoint (void)
00103 {
00104   return this->endpoint();
00105 }
00106 
00107 TAO::ObjectKey *
00108 TAO_Profile::_key (void) const
00109 {
00110   TAO::ObjectKey *key = 0;
00111 
00112   if (this->ref_object_key_)
00113     {
00114       ACE_NEW_RETURN (key,
00115                       TAO::ObjectKey (this->ref_object_key_->object_key ()),
00116                       0);
00117     }
00118   return key;
00119 }
00120 
00121 
00122 int
00123 TAO_Profile::encode (TAO_OutputCDR &stream) const
00124 {
00125   // UNSIGNED LONG, protocol tag
00126   stream.write_ulong (this->tag_);
00127 
00128   // Create the encapsulation....
00129   TAO_OutputCDR encap (ACE_CDR::DEFAULT_BUFSIZE,
00130                        TAO_ENCAP_BYTE_ORDER,
00131                        this->orb_core ()->output_cdr_buffer_allocator (),
00132                        this->orb_core ()->output_cdr_dblock_allocator (),
00133                        this->orb_core ()->output_cdr_msgblock_allocator (),
00134                        this->orb_core ()->orb_params ()->cdr_memcpy_tradeoff (),
00135                        TAO_DEF_GIOP_MAJOR,
00136                        TAO_DEF_GIOP_MINOR);
00137 
00138 #if defined (TAO_ZERO_TAO_OUTPUTCDR_ALLOCATED_BUFFERS)
00139   // Support limited oref ACE_OS::strcmp
00140   (void) ACE_OS::memset (encap.current()->wr_ptr (),
00141                          0,
00142                          encap.current()->space ());
00143 #endif /* TAO_ZERO_TAO_OUTPUTCDR_ALLOCATED_BUFFERS */
00144 
00145   // Create the profile body
00146   this->create_profile_body (encap);
00147 
00148   // write the encapsulation as an octet sequence...
00149   stream << CORBA::ULong (encap.total_length ());
00150   stream.write_octet_array_mb (encap.begin ());
00151 
00152   return 1;
00153 }
00154 
00155 int
00156 TAO_Profile::decode (TAO_InputCDR& cdr)
00157 {
00158 #if !defined (ACE_NLOGGING)
00159   size_t const encap_len = cdr.length ();
00160 #endif
00161 
00162   // Read and verify major, minor versions, ignoring profiles
00163   // whose versions we don't understand.
00164   if (!(cdr.read_octet (this->version_.major)
00165         && this->version_.major == TAO_DEF_GIOP_MAJOR
00166         && cdr.read_octet (this->version_.minor)
00167         && this->version_.minor <= TAO_DEF_GIOP_MINOR))
00168     {
00169       if (TAO_debug_level > 0)
00170         {
00171           ACE_DEBUG ((LM_DEBUG,
00172                       ACE_TEXT ("TAO (%P|%t) - Profile::decode - v%d.%d\n"),
00173                       this->version_.major,
00174                       this->version_.minor));
00175         }
00176 
00177       return -1;
00178     }
00179 
00180   // Transport specific details
00181   if (this->decode_profile (cdr) < 0)
00182     {
00183       return -1;
00184     }
00185 
00186   // @@NOTE: This place *may* need strategizing. Here are the
00187   // issues. Placing the ObjectKey in the table adds an allocation and
00188   // a lock while decoding. This is bad for some cases especially if
00189   // the application is marshalling object references across to the
00190   // server end. But the server could use "lazy" evaluation and avoid
00191   // this during marshalling.
00192   //
00193   // The only place this will get important is when a thead tries to
00194   // use the object reference to create a CORBA object to make an
00195   // invocation. Since creation of a CORBA object itself is expensive,
00196   // it looks like we may not need to worry much.
00197   //
00198   // Remember strategizing needs  reconciliation of forces imposed
00199   // by runtime memory growth. Doing a random strategization would
00200   // destroy the wins in runtime memory growth got by using this
00201   // table scheme.
00202   TAO::ObjectKey ok;
00203 
00204   // ... and object key.
00205   if (TAO::ObjectKey::demarshal_key (ok,
00206                                      cdr) == 0)
00207     {
00208       return -1;
00209     }
00210 
00211   TAO::ObjectKey_Table &okt = this->orb_core ()->object_key_table ();
00212 
00213   if (okt.bind (ok, this->ref_object_key_) == -1)
00214     {
00215       return -1;
00216     }
00217 
00218   // Tagged Components *only* exist after version 1.0!
00219   // For GIOP 1.2, IIOP and GIOP have same version numbers!
00220   if (this->version_.major > 1
00221       || this->version_.minor > 0)
00222     {
00223       if (this->tagged_components_.decode (cdr) == 0)
00224         {
00225           return -1;
00226         }
00227     }
00228 
00229   if (cdr.length () != 0 && TAO_debug_level)
00230     {
00231       // If there is extra data in the profile we are supposed to
00232       // ignore it, but print a warning just in case...
00233       ACE_DEBUG ((LM_DEBUG,
00234                   ACE_TEXT ("%d bytes out of %d left after profile data\n"),
00235                   cdr.length (),
00236                   encap_len));
00237     }
00238 
00239   // Decode any additional endpoints per profile. This is used by RTCORBA
00240   // and by IIOP when TAG_ALTERNATE_IIOP_ADDRESS components are present.
00241   if (this->decode_endpoints () == -1)
00242     {
00243       return -1;
00244     }
00245 
00246   return 1;
00247 }
00248 
00249 IOP::TaggedProfile *
00250 TAO_Profile::create_tagged_profile (void)
00251 {
00252   if (this->tagged_profile_created_)
00253     return this->tagged_profile_;
00254 
00255   ACE_GUARD_RETURN (TAO_SYNCH_MUTEX,
00256                     guard,
00257                     this->tagged_profile_lock_,
00258                     this->tagged_profile_);
00259 
00260   // .. DCL
00261   if (!this->tagged_profile_created_)
00262     {
00263       ACE_NEW_RETURN (this->tagged_profile_,
00264                       IOP::TaggedProfile,
00265                       0);
00266 
00267       // As we have not created we will now create the TaggedProfile
00268       this->tagged_profile_->tag = this->tag_;
00269 
00270       // Create the encapsulation....
00271       TAO_OutputCDR encap (ACE_DEFAULT_CDR_BUFSIZE,
00272                            TAO_ENCAP_BYTE_ORDER,
00273                            this->orb_core ()->output_cdr_buffer_allocator (),
00274                            this->orb_core ()->output_cdr_dblock_allocator (),
00275                            this->orb_core ()->output_cdr_msgblock_allocator (),
00276                            this->orb_core ()->orb_params ()->cdr_memcpy_tradeoff (),
00277                            TAO_DEF_GIOP_MAJOR,
00278                            TAO_DEF_GIOP_MINOR);
00279 
00280       // Create the profile body
00281       this->create_profile_body (encap);
00282 
00283       CORBA::ULong const length =
00284         static_cast <CORBA::ULong> (encap.total_length ());
00285 
00286 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
00287       // Place the message block in to the Sequence of Octets that we
00288       // have
00289       this->tagged_profile_->profile_data.replace (length, encap.begin ());
00290 #else
00291       this->tagged_profile_->profile_data.length (length);
00292       CORBA::Octet *buffer =
00293         this->tagged_profile_->profile_data.get_buffer ();
00294 
00295       for (const ACE_Message_Block *i = encap.begin ();
00296            i != encap.end ();
00297            i = i->next ())
00298         {
00299           ACE_OS::memcpy (buffer, i->rd_ptr (), i->length ());
00300           buffer += i->length ();
00301         }
00302 #endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
00303 
00304       this->tagged_profile_created_ = true;
00305     }
00306 
00307   return this->tagged_profile_;
00308 }
00309 
00310 void
00311 TAO_Profile::set_tagged_components (TAO_OutputCDR &out_cdr)
00312 {
00313   CORBA::ULong const length = static_cast <CORBA::ULong> (out_cdr.total_length ());
00314 
00315   IOP::TaggedComponent tagged_component;
00316   tagged_component.tag = TAO_TAG_ENDPOINTS;
00317   tagged_component.component_data.length (length);
00318   CORBA::Octet *buf =
00319     tagged_component.component_data.get_buffer ();
00320 
00321   for (const ACE_Message_Block *iterator = out_cdr.begin ();
00322        iterator != 0;
00323        iterator = iterator->cont ())
00324     {
00325       size_t const i_length = iterator->length ();
00326       ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
00327 
00328       buf += i_length;
00329     }
00330 
00331   // Add component with encoded endpoint data to this profile's
00332   // TaggedComponents.
00333   tagged_components_.set_component (tagged_component);
00334 }
00335 
00336 
00337 void
00338 TAO_Profile::policies (CORBA::PolicyList *policy_list)
00339 {
00340 #if (TAO_HAS_CORBA_MESSAGING == 1)
00341 
00342   if (policy_list == 0)
00343     {
00344       if (TAO_debug_level)
00345         {
00346           ACE_DEBUG ((LM_DEBUG,
00347                       ACE_TEXT ("TAO_Profile::policies: ")
00348                       ACE_TEXT ("Null Policy List!\n")));
00349         }
00350 
00351       return;
00352     }
00353 
00354   Messaging::PolicyValue pv;
00355   Messaging::PolicyValueSeq policy_value_seq;
00356 
00357   size_t length;
00358   CORBA::Octet *buf = 0;
00359 
00360   policy_value_seq.length (policy_list->length ());
00361 
00362   // This loop iterates through CORBA::PolicyList to convert
00363   // each CORBA::Policy into a CORBA::PolicyValue
00364   const size_t plen = policy_list->length ();
00365 
00366   for (CORBA::ULong i = 0; i < plen; ++i)
00367     {
00368       TAO_OutputCDR out_CDR;
00369       policy_value_seq[i].ptype =
00370         (*policy_list)[i]->policy_type ();
00371 
00372       out_CDR << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER);
00373       (*policy_list)[i]->_tao_encode (out_CDR);
00374 
00375       length = out_CDR.total_length ();
00376       policy_value_seq[i].pvalue.length (static_cast <CORBA::ULong>(length));
00377 
00378       buf = policy_value_seq[i].pvalue.get_buffer ();
00379 
00380       // Copy the CDR buffer data into the octet sequence buffer.
00381 
00382       for (const ACE_Message_Block *iterator = out_CDR.begin ();
00383            iterator != 0;
00384            iterator = iterator->cont ())
00385         {
00386           ACE_OS::memcpy (buf, iterator->rd_ptr (), iterator->length ());
00387           buf += iterator->length ();
00388         }
00389     }
00390 
00391   TAO_OutputCDR out_cdr;
00392   // Now we have to embed the Messaging::PolicyValueSeq into
00393   // a TaggedComponent.
00394 
00395   IOP::TaggedComponent tagged_component;
00396   tagged_component.tag = Messaging::TAG_POLICIES;
00397 
00398   out_cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER);
00399   out_cdr << policy_value_seq;
00400 
00401   length = out_cdr.total_length ();
00402 
00403   tagged_component.component_data.length (static_cast <CORBA::ULong>(length));
00404   buf = tagged_component.component_data.get_buffer ();
00405 
00406   for (const ACE_Message_Block *iterator = out_cdr.begin ();
00407        iterator != 0;
00408        iterator = iterator->cont ())
00409     {
00410       size_t const i_length = iterator->length ();
00411       ACE_OS::memcpy (buf, iterator->rd_ptr (), i_length);
00412 
00413       buf += i_length;
00414     }
00415 
00416   // Eventually we add the TaggedComponent to the TAO_TaggedComponents
00417   // member variable.
00418   tagged_components_.set_component (tagged_component);
00419   this->are_policies_parsed_ = true;
00420 
00421 #else /* TAO_HAS_CORBA_MESSAGING == 1 */
00422 
00423   ACE_UNUSED_ARG (policy_list);
00424 
00425 #endif /* TAO_HAS_CORBA_MESSAGING == 1 */
00426 }
00427 
00428 
00429 
00430 void
00431 TAO_Profile::get_policies (CORBA::PolicyList& pl)
00432 {
00433 #if (TAO_HAS_CORBA_MESSAGING == 1) && !defined (CORBA_E_MICRO)
00434 
00435   if (!this->are_policies_parsed_)
00436     // None has already parsed the policies.
00437     {
00438       IOP::TaggedComponent tagged_component;
00439       tagged_component.tag = Messaging::TAG_POLICIES;
00440 
00441       // This gets a component with the proper "tag" field
00442       // if it exists.
00443       if (this->tagged_components_.get_component (tagged_component))
00444         {
00445           const CORBA::Octet *buf =
00446             tagged_component.component_data.get_buffer ();
00447 
00448           TAO_InputCDR in_cdr (reinterpret_cast <const char *> (buf),
00449                                tagged_component.component_data.length ());
00450 
00451           // Extract the Byte Order
00452           CORBA::Boolean byte_order;
00453 
00454           if ((in_cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0)
00455             {
00456               return ;
00457             }
00458 
00459           in_cdr.reset_byte_order (static_cast <int> (byte_order));
00460 
00461           // Now we take out the Messaging::PolicyValueSeq out from the
00462           // CDR.
00463           Messaging::PolicyValueSeq policy_value_seq;
00464 
00465           if (!(in_cdr >> policy_value_seq))
00466             {
00467               throw ::CORBA::INV_OBJREF ();
00468             }
00469 
00470           // Here we extract the Messaging::PolicyValue out of the sequence
00471           // and we convert those into the proper CORBA::Policy
00472 
00473           CORBA::Policy_var policy;
00474           CORBA::ULong const length = policy_value_seq.length ();
00475 
00476           // Set the policy list length.
00477           pl.length (length);
00478 
00479           for (CORBA::ULong i = 0; i < length; ++i)
00480             {
00481               try
00482                 {
00483                   policy =
00484                     this->orb_core_->orb ()->_create_policy (
00485                       policy_value_seq[i].ptype);
00486 
00487                   if (!CORBA::is_nil (policy.in ()))
00488                     {
00489                       buf = policy_value_seq[i].pvalue.get_buffer ();
00490 
00491                       TAO_InputCDR in_cdr (
00492                         reinterpret_cast <const char*>  (buf),
00493                         policy_value_seq[i].pvalue.length ());
00494 
00495                       if (!(in_cdr >> ACE_InputCDR::to_boolean (byte_order)))
00496                         throw ::CORBA::INV_OBJREF ();
00497 
00498                       in_cdr.reset_byte_order (static_cast <int> (byte_order));
00499 
00500                       policy->_tao_decode (in_cdr);
00501                       pl[i] = policy._retn ();
00502                     }
00503                   else
00504                     {
00505                       // This case should occure when in the IOR are
00506                       // embedded policies that TAO doesn't support,
00507                       // so as specified by the RT-CORBA
00508                       // spec. ptc/99-05-03 we just ignore these
00509                       // un-understood policies.
00510 
00511                       if (TAO_debug_level >= 5)
00512                         ACE_DEBUG ((LM_DEBUG,
00513                                     ACE_TEXT ("The IOR contains unsupported ")
00514                                     ACE_TEXT ("policies.\n")));
00515                     }
00516                 }
00517               catch (const ::CORBA::Exception& ex)
00518                 {
00519                   // This case should occur when in the IOR are
00520                   // embedded policies that TAO doesn't support, so as
00521                   // specified by the RT-CORBA spec. ptc/99-05-03 we
00522                   // just ignore these un-understood policies.
00523 
00524                   if (TAO_debug_level >= 5)
00525                     ex._tao_print_exception (
00526                       ACE_TEXT ("IOR contains ")
00527                       ACE_TEXT ("unsupported policies."));
00528                 }
00529             }
00530         }
00531     }
00532 
00533 #else
00534   ACE_UNUSED_ARG (pl);
00535 #endif /* (TAO_HAS_CORBA_MESSAGING == 1) */
00536 
00537 }
00538 
00539 
00540 void
00541 TAO_Profile::verify_orb_configuration (void)
00542 {
00543   // If the ORB isn't configured to support tagged components, then
00544   // throw an exception.
00545   if (this->orb_core_->orb_params ()->std_profile_components () == 0
00546       || !this->orb_core_->orb ()->_use_omg_ior_format ())
00547     {
00548       if (TAO_debug_level > 0)
00549         {
00550           ACE_ERROR ((LM_ERROR,
00551                       ACE_TEXT ("(%P|%t) Cannot add ")
00552                       ACE_TEXT ("IOP::TaggedComponent to profile.\n")
00553                       ACE_TEXT ("(%P|%t) Standard profile components ")
00554                       ACE_TEXT ("have been disabled or URL style IORs\n")
00555                       ACE_TEXT ("(%P|%t) are in use.  Try ")
00556                       ACE_TEXT ("\"-ORBStdProfileComponents 1\" and/or\n")
00557                       ACE_TEXT ("(%P|%t) \"-ORBObjRefStyle IOR\".\n")));
00558         }
00559 
00560       // According to the Portable Interceptor specification, we're
00561       // supposed to throw a CORBA::BAD_PARAM exception if it isn't
00562       // possible to add components to the profile.
00563       // @todo: We need the proper minor code as soon as the spec is
00564       //        updated.
00565       throw ::CORBA::BAD_PARAM (
00566                    CORBA::SystemException::_tao_minor_code (
00567                       0,
00568                       EINVAL),
00569                    CORBA::COMPLETED_NO);
00570     }
00571 }
00572 
00573 void
00574 TAO_Profile::verify_profile_version (void)
00575 {
00576   // GIOP 1.0 does not support tagged components.  Throw an exception
00577   // if the profile is a GIOP 1.0 profile.
00578 
00579   if (this->version_.major == 1 && this->version_.minor == 0)
00580     {
00581       if (TAO_debug_level > 0)
00582         {
00583           ACE_ERROR ((LM_ERROR,
00584                       ACE_TEXT ("(%P|%t) Cannot add ")
00585                       ACE_TEXT ("IOP::TaggedComponent to GIOP 1.0")
00586                       ACE_TEXT ("IOR profile.\n")
00587                       ACE_TEXT ("(%P|%t) Try using a GIOP 1.1 or ")
00588                       ACE_TEXT ("greater endpoint.\n")));
00589         }
00590 
00591       // According to the Portable Interceptor specification, we're
00592       // supposed to throw a CORBA::BAD_PARAM exception if it isn't
00593       // possible to add components to the profile.
00594       // @todo: We need the proper minor code as soon as the spec is
00595       //        updated.
00596       throw ::CORBA::BAD_PARAM (
00597                    CORBA::SystemException::_tao_minor_code (
00598                      0,
00599                      EINVAL),
00600                    CORBA::COMPLETED_NO);
00601     }
00602 }
00603 
00604 int
00605 TAO_Profile::supports_multicast (void) const
00606 {
00607   // Most profiles do not support multicast endpoints.
00608   return 0;
00609 }
00610 
00611 bool
00612 TAO_Profile::supports_non_blocking_oneways (void) const
00613 {
00614   return !(this->version_.major == 1 && this->version_.minor == 0);
00615 }
00616 
00617 void
00618 TAO_Profile::addressing_mode (CORBA::Short addr)
00619 {
00620   // ** See race condition note about addressing mode in Profile.h **
00621   switch (addr)
00622     {
00623     case TAO_Target_Specification::Key_Addr:
00624     case TAO_Target_Specification::Profile_Addr:
00625     case TAO_Target_Specification::Reference_Addr:
00626       this->addressing_mode_ = addr;
00627       break;
00628 
00629     default:
00630       throw ::CORBA::BAD_PARAM (
00631              CORBA::SystemException::_tao_minor_code (
00632                0,
00633                EINVAL),
00634              CORBA::COMPLETED_NO);
00635     }
00636 }
00637 
00638 void
00639 TAO_Profile::parse_string (const char *ior)
00640 {
00641   if (!ior || !*ior)
00642     {
00643       throw ::CORBA::INV_OBJREF (
00644                    CORBA::SystemException::_tao_minor_code (
00645                      0,
00646                      EINVAL),
00647                    CORBA::COMPLETED_NO);
00648     }
00649 
00650   // Remove the "N.n@" version prefix, if it exists, and verify the
00651   // version is one that we accept.
00652 
00653   // Check for version
00654   if (ACE_OS::ace_isdigit (ior [0]) &&
00655       ior[1] == '.' &&
00656       ACE_OS::ace_isdigit (ior [2]) &&
00657       ior[3] == '@')
00658     {
00659       // @@ This may fail for non-ascii character sets [but take that
00660       // with a grain of salt]
00661       this->version_.set_version ((char) (ior[0] - '0'),
00662                                   (char) (ior[2] - '0'));
00663       ior += 4;
00664       // Skip over the "N.n@"
00665     }
00666   else
00667     {
00668       // CORBA spec requires 1.0 if a version isn't specified.
00669       this->version_.set_version (1, 0);
00670     }
00671 
00672   if (this->version_.major != TAO_DEF_GIOP_MAJOR ||
00673       this->version_.minor >  TAO_DEF_GIOP_MINOR)
00674     {
00675       throw ::CORBA::INV_OBJREF (
00676                    CORBA::SystemException::_tao_minor_code (
00677                      0,
00678                      EINVAL),
00679                    CORBA::COMPLETED_NO);
00680     }
00681 
00682   this->parse_string_i (ior);
00683 }
00684 
00685 CORBA::Boolean
00686 TAO_Profile::is_equivalent (const TAO_Profile *other)
00687 {
00688   CORBA::Boolean result = false;
00689   if (other)
00690     {
00691       TAO_Service_Callbacks::Profile_Equivalence callback
00692         = this->is_equivalent_hook (other);
00693       switch (callback)
00694         {
00695           case TAO_Service_Callbacks::DONT_KNOW:
00696             return this->tag () == other->tag ()
00697                 && this->version_ == other->version ()
00698                 && this->endpoint_count () == other->endpoint_count ()
00699                 && this->object_key () == other->object_key ()
00700                 && this->do_is_equivalent (other);
00701           case TAO_Service_Callbacks::EQUIVALENT:
00702             result = true;
00703             break;
00704           case TAO_Service_Callbacks::NOT_EQUIVALENT:
00705             break;
00706         }
00707     }
00708   return result;
00709 }
00710 
00711 CORBA::Boolean
00712 TAO_Profile::compare_key (const TAO_Profile *other) const
00713 {
00714   return (this->ref_object_key_ == other->ref_object_key_) ||
00715     ((this->ref_object_key_ != 0 &&
00716       other->ref_object_key_ != 0 &&
00717       this->ref_object_key_->object_key() ==
00718       other->ref_object_key_->object_key()));
00719 }
00720 
00721 TAO_Endpoint *
00722 TAO_Profile::first_filtered_endpoint (void)
00723 {
00724   TAO_Endpoint *ep = this->endpoint();
00725   return ep == 0 ? 0 : ep->next_filtered(this->orb_core_,0);
00726 }
00727 
00728 TAO_Endpoint *
00729 TAO_Profile::next_filtered_endpoint (TAO_Endpoint *source)
00730 {
00731   if (source == 0)
00732     return this->first_filtered_endpoint();
00733   return source->next_filtered(this->orb_core_,this->endpoint());
00734 }
00735 
00736 void
00737 TAO_Profile::add_generic_endpoint (TAO_Endpoint *)
00738 {
00739   // noop for the base type
00740 }
00741 
00742 TAO_Service_Callbacks::Profile_Equivalence
00743 TAO_Profile::is_equivalent_hook (const TAO_Profile *other)
00744 {
00745   // Allow services to apply their own definition of "equivalence."
00746   return this->orb_core_->is_profile_equivalent (this, other);
00747 }
00748 
00749 CORBA::ULong
00750 TAO_Profile::hash_service_i (CORBA::ULong m)
00751 {
00752   return this->orb_core_->hash_service (this, m);
00753 }
00754 
00755 /*
00756  * Hook to comment out no op method
00757  * in the base class that is specialized in the
00758  * derived class.
00759  */
00760 //@@ TAO_PROFILE_SPL_COMMENT_HOOK_START
00761 
00762 int
00763 TAO_Profile::encode_alternate_endpoints(void)
00764 {
00765   // this should be a pure virtual, but there are many
00766   // existing specializations that would need to be
00767   // modified. This maintains the existing behavior, since
00768   // the previous version of the POA did not gather alternate
00769   // endpoints.
00770 
00771   return 0;
00772 }
00773 
00774 void
00775 TAO_Profile::remove_generic_endpoint (TAO_Endpoint *)
00776 {
00777   // default for virtual methods, thus a no-op
00778 }
00779 
00780 //@@ TAO_PROFILE_SPL_COMMENT_HOOK_END
00781 
00782 //@@ TAO_PROFILE_SPL_METHODS_ADD_HOOK
00783 
00784 // ****************************************************************
00785 
00786 TAO_Unknown_Profile::TAO_Unknown_Profile (CORBA::ULong tag,
00787                                           TAO_ORB_Core *orb_core)
00788   : TAO_Profile (tag,
00789                  orb_core,
00790                  TAO_GIOP_Message_Version (TAO_DEF_GIOP_MAJOR,
00791                                            TAO_DEF_GIOP_MINOR))
00792 {
00793 }
00794 
00795 TAO_Endpoint*
00796 TAO_Unknown_Profile::endpoint (void)
00797 {
00798   return 0;
00799 }
00800 
00801 CORBA::ULong
00802 TAO_Unknown_Profile::endpoint_count (void) const
00803 {
00804   return 0;
00805 }
00806 
00807 void
00808 TAO_Unknown_Profile::parse_string (const char *)
00809 {
00810   // @@ THROW something????
00811 }
00812 
00813 void
00814 TAO_Unknown_Profile::parse_string_i (const char *)
00815 {
00816   // @@ THROW something????
00817 }
00818 
00819 char
00820 TAO_Unknown_Profile::object_key_delimiter (void) const
00821 {
00822   return 0;
00823 }
00824 
00825 char *
00826 TAO_Unknown_Profile::to_string (void)
00827 {
00828   // @@ THROW something?
00829   return 0;
00830 }
00831 
00832 int
00833 TAO_Unknown_Profile::decode (TAO_InputCDR& cdr)
00834 {
00835   if ((cdr >> this->body_) == 0)
00836     {
00837       return -1;
00838     }
00839 
00840   return 0;
00841 }
00842 
00843 int
00844 TAO_Unknown_Profile::decode_profile (TAO_InputCDR &)
00845 {
00846   return 0;
00847 }
00848 
00849 int
00850 TAO_Unknown_Profile::decode_endpoints (void)
00851 {
00852   return 0;
00853 }
00854 
00855 int
00856 TAO_Unknown_Profile::encode (TAO_OutputCDR &stream) const
00857 {
00858   stream.write_ulong (this->tag ());
00859   return (stream << this->body_);
00860 }
00861 
00862 int
00863 TAO_Unknown_Profile::encode_endpoints (void)
00864 {
00865   return 0;
00866 }
00867 
00868 TAO::ObjectKey *
00869 TAO_Unknown_Profile::_key (void) const
00870 {
00871   return 0;
00872 }
00873 
00874 CORBA::Boolean
00875 TAO_Unknown_Profile::do_is_equivalent (const TAO_Profile* other_profile)
00876 {
00877   const TAO_Unknown_Profile * op =
00878     dynamic_cast <const TAO_Unknown_Profile *> (other_profile);
00879 
00880   return (CORBA::Boolean) (op == 0 ? 0 : this->body_ == op->body_);
00881 }
00882 
00883 TAO_Service_Callbacks::Profile_Equivalence
00884 TAO_Unknown_Profile::is_equivalent_hook (const TAO_Profile * /* other */)
00885 {
00886   // Override the default implementation since we don't need the
00887   // additional checks it performs.
00888 
00889   return TAO_Service_Callbacks::DONT_KNOW;
00890 }
00891 
00892 CORBA::ULong
00893 TAO_Unknown_Profile::hash (CORBA::ULong max
00894                            )
00895 {
00896   return (ACE::hash_pjw (reinterpret_cast <const char*>
00897                                           (this->body_.get_buffer ()),
00898                          this->body_.length ()) % max);
00899 }
00900 
00901 void
00902 TAO_Unknown_Profile::create_profile_body (TAO_OutputCDR &) const
00903 {
00904   // No idea about the profile body! Just return
00905   return;
00906 }
00907 
00908 
00909 
00910 // *************************************************************
00911 // Operators for TAO_opaque encoding and decoding
00912 // *************************************************************
00913 
00914 CORBA::Boolean
00915 operator<< (TAO_OutputCDR& cdr, const TAO_opaque& x)
00916 {
00917   CORBA::ULong const length = x.length ();
00918   cdr.write_ulong (length);
00919 
00920 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
00921   if (x.mb () != 0)
00922     {
00923       cdr.write_octet_array_mb (x.mb ());
00924     }
00925   else
00926 #endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
00927     {
00928       cdr.write_octet_array (x.get_buffer (), length);
00929     }
00930 
00931   return (CORBA::Boolean) cdr.good_bit ();
00932 }
00933 
00934 CORBA::Boolean
00935 operator>>(TAO_InputCDR& cdr, TAO_opaque& x)
00936 {
00937   CORBA::ULong length;
00938   cdr.read_ulong (length);
00939 
00940 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
00941   if(ACE_BIT_DISABLED(cdr.start()->flags(),
00942                       ACE_Message_Block::DONT_DELETE)
00943      && (cdr.orb_core() == 0
00944          || 1 == cdr.orb_core()->
00945          resource_factory()->
00946          input_cdr_allocator_type_locked()
00947          )
00948      )
00949     {
00950       x.replace (length, cdr.start ());
00951       x.mb ()->wr_ptr (x.mb ()->rd_ptr () + length);
00952       cdr.skip_bytes (length);
00953     }
00954   else
00955 #endif /* TAO_NO_COPY_OCTET_SEQUENCES == 0 */
00956     {
00957       x.length (length);
00958       cdr.read_octet_array (x.get_buffer (), length);
00959     }
00960 
00961   return (CORBA::Boolean) cdr.good_bit ();
00962 }
00963 
00964 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:37:52 2010 for TAO by  doxygen 1.4.7