Profile.cpp

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

Generated on Sun Jan 27 13:07:35 2008 for TAO by doxygen 1.3.6