Profile.cpp

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

Generated on Thu Nov 9 11:54:20 2006 for TAO by doxygen 1.3.6