COIOP_Acceptor.cpp

Go to the documentation of this file.
00001 // This may look like C, but it's really -*- C++ -*-
00002 // $Id: COIOP_Acceptor.cpp 79678 2007-09-20 20:51:22Z schmidt $
00003 
00004 #include "tao/Strategies/COIOP_Acceptor.h"
00005 
00006 #if defined (TAO_HAS_COIOP) && (TAO_HAS_COIOP != 0)
00007 
00008 #include "tao/Strategies/COIOP_Profile.h"
00009 #include "tao/MProfile.h"
00010 #include "tao/ORB_Core.h"
00011 #include "tao/debug.h"
00012 #include "tao/Protocols_Hooks.h"
00013 #include "tao/Codeset_Manager.h"
00014 #include "tao/CDR.h"
00015 
00016 #include "ace/Auto_Ptr.h"
00017 #include "ace/OS_NS_string.h"
00018 
00019 ACE_RCSID (Strategies,
00020            COIOP_Acceptor,
00021            "$Id: COIOP_Acceptor.cpp 79678 2007-09-20 20:51:22Z schmidt $")
00022 
00023 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00024 
00025 TAO_COIOP_Acceptor::TAO_COIOP_Acceptor (void)
00026   : TAO_Acceptor (TAO_TAG_COIOP_PROFILE),
00027     uuid_ (*ACE_Utils::UUID_GENERATOR::instance ()->generate_UUID ()),
00028     version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR),
00029     orb_core_ (0)
00030 {
00031 }
00032 
00033 TAO_COIOP_Acceptor::~TAO_COIOP_Acceptor (void)
00034 {
00035   // Make sure we are closed before we start destroying the
00036   // strategies.
00037   this->close ();
00038 }
00039 
00040 // TODO =
00041 //    2) For V1.[1,2] there are tagged components
00042 
00043 int
00044 TAO_COIOP_Acceptor::create_profile (const TAO::ObjectKey & object_key,
00045                                    TAO_MProfile &mprofile,
00046                                    CORBA::Short priority)
00047 {
00048   // Check if multiple endpoints should be put in one profile or if
00049   // they should be spread across multiple profiles.
00050   if (priority == TAO_INVALID_PRIORITY)
00051     return this->create_new_profile (object_key, mprofile, priority);
00052   else
00053     return this->create_shared_profile (object_key, mprofile, priority);
00054 }
00055 
00056 int
00057 TAO_COIOP_Acceptor::create_new_profile (const TAO::ObjectKey &object_key,
00058                                        TAO_MProfile &mprofile,
00059                                        CORBA::Short priority)
00060 {
00061   // Adding this->endpoint_count_ to the TAO_MProfile.
00062   if (mprofile.grow (1) == -1)
00063     return -1;
00064 
00065   TAO_COIOP_Profile *pfile = 0;
00066   ACE_NEW_RETURN (pfile,
00067                   TAO_COIOP_Profile (uuid_,
00068                                       object_key,
00069                                       this->version_,
00070                                       this->orb_core_),
00071                   -1);
00072   pfile->endpoint ()->priority (priority);
00073 
00074   if (mprofile.give_profile (pfile) == -1)
00075     {
00076       pfile->_decr_refcnt ();
00077       pfile = 0;
00078       return -1;
00079     }
00080 
00081   // Do not add any tagged components to the profile if configured
00082   // by the user not to do so, or if an IIOP 1.0 endpoint is being
00083   // created (IIOP 1.0 did not support tagged components).
00084   if (this->orb_core_->orb_params ()->std_profile_components () != 0
00085       && (this->version_.major >= 1 && this->version_.minor > 0))
00086     {
00087       pfile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
00088 
00089       TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager();
00090       if (csm)
00091         csm->set_codeset(pfile->tagged_components());
00092     }
00093 
00094   return 0;
00095 }
00096 
00097 int
00098 TAO_COIOP_Acceptor::create_shared_profile (const TAO::ObjectKey &object_key,
00099                                            TAO_MProfile &mprofile,
00100                                            CORBA::Short priority)
00101 {
00102   size_t index = 0;
00103   TAO_Profile *pfile = 0;
00104   TAO_COIOP_Profile *coiop_profile = 0;
00105 
00106   // First see if <mprofile> already contains a COIOP profile.
00107   for (TAO_PHandle i = 0; i != mprofile.profile_count (); ++i)
00108     {
00109       pfile = mprofile.get_profile (i);
00110       if (pfile->tag () == TAO_TAG_COIOP_PROFILE)
00111       {
00112         coiop_profile = dynamic_cast<TAO_COIOP_Profile *> (pfile);
00113         break;
00114       }
00115     }
00116 
00117   // If <mprofile> doesn't contain a COIOP_Profile, we need to create
00118   // one.
00119   if (coiop_profile == 0)
00120     {
00121       ACE_NEW_RETURN (coiop_profile,
00122                       TAO_COIOP_Profile (uuid_,
00123                                         object_key,
00124                                         this->version_,
00125                                         this->orb_core_),
00126                       -1);
00127       coiop_profile->endpoint ()->priority (priority);
00128 
00129       if (mprofile.give_profile (coiop_profile) == -1)
00130         {
00131           coiop_profile->_decr_refcnt ();
00132           coiop_profile = 0;
00133           return -1;
00134         }
00135 
00136       if (this->orb_core_->orb_params ()->std_profile_components () != 0
00137           && (this->version_.major >= 1 && this->version_.minor >= 1))
00138         {
00139           coiop_profile->tagged_components ().set_orb_type (TAO_ORB_TYPE);
00140           TAO_Codeset_Manager *csm = this->orb_core_->codeset_manager();
00141           if (csm)
00142             csm->set_codeset(pfile->tagged_components());
00143         }
00144 
00145       index = 1;
00146     }
00147 
00148   TAO_COIOP_Endpoint *endpoint = 0;
00149   ACE_NEW_RETURN (endpoint,
00150                   TAO_COIOP_Endpoint (uuid_),
00151                   -1);
00152   endpoint->priority (priority);
00153   coiop_profile->add_endpoint (endpoint);
00154 
00155   return 0;
00156 }
00157 
00158 int
00159 TAO_COIOP_Acceptor::is_collocated (const TAO_Endpoint *endpoint)
00160 {
00161   const TAO_COIOP_Endpoint *endp =
00162     dynamic_cast<const TAO_COIOP_Endpoint *> (endpoint);
00163 
00164   // Make sure the dynamically cast pointer is valid.
00165   if (endp == 0)
00166     return false;
00167 
00168   return (endp->uuid() == uuid_);
00169 }
00170 
00171 int
00172 TAO_COIOP_Acceptor::close (void)
00173 {
00174   return 0;
00175 }
00176 
00177 int
00178 TAO_COIOP_Acceptor::open (TAO_ORB_Core *orb_core,
00179                           ACE_Reactor *,
00180                           int major,
00181                           int minor,
00182                           const char *address,
00183                           const char *options)
00184 {
00185   this->orb_core_ = orb_core;
00186 
00187   if (major >=0 && minor >= 0)
00188     this->version_.set_version (static_cast<CORBA::Octet> (major),
00189                                 static_cast<CORBA::Octet> (minor));
00190   // Parse options
00191   if (this->parse_options (options) == -1)
00192     return -1;
00193 
00194   uuid_.from_string (address);
00195 
00196   return 0;
00197 }
00198 
00199 int
00200 TAO_COIOP_Acceptor::open_default (TAO_ORB_Core *orb_core,
00201                                  ACE_Reactor *,
00202                                  int major,
00203                                  int minor,
00204                                  const char *options)
00205 {
00206   this->orb_core_ = orb_core;
00207 
00208   if (major >=0 && minor >= 0)
00209     this->version_.set_version (static_cast<CORBA::Octet> (major),
00210                                 static_cast<CORBA::Octet> (minor));
00211 
00212   // Parse options
00213   if (this->parse_options (options) == -1)
00214     return -1;
00215 
00216   return 0;
00217 }
00218 
00219 CORBA::ULong
00220 TAO_COIOP_Acceptor::endpoint_count (void)
00221 {
00222   return 1;
00223 }
00224 
00225 int
00226 TAO_COIOP_Acceptor::object_key (IOP::TaggedProfile &profile,
00227                                TAO::ObjectKey &object_key)
00228 {
00229   // Create the decoding stream from the encapsulation in the buffer,
00230 #if (TAO_NO_COPY_OCTET_SEQUENCES == 1)
00231   TAO_InputCDR cdr (profile.profile_data.mb ());
00232 #else
00233   TAO_InputCDR cdr (reinterpret_cast<char*> (profile.profile_data.get_buffer ()),
00234                     profile.profile_data.length ());
00235 #endif /* TAO_NO_COPY_OCTET_SEQUENCES == 1 */
00236 
00237   CORBA::Octet major;
00238   CORBA::Octet minor = CORBA::Octet();
00239 
00240   // Read the version. We just read it here. We don't*do any*
00241   // processing.
00242   if (!(cdr.read_octet (major) && cdr.read_octet (minor)))
00243   {
00244     if (TAO_debug_level > 0)
00245       {
00246         ACE_DEBUG ((LM_DEBUG,
00247                     ACE_TEXT ("TAO (%P|%t) COIOP_Profile::decode - v%d.%d\n"),
00248                     major,
00249                     minor));
00250       }
00251     return -1;
00252   }
00253 
00254   CORBA::String_var uuid;
00255 
00256   // Get host and port. No processing here too..
00257   if (cdr.read_string (uuid.out ()) == 0)
00258     {
00259       if (TAO_debug_level > 0)
00260         {
00261           ACE_DEBUG ((LM_DEBUG,
00262                       ACE_TEXT ("TAO (%P|%t) TAO_COIOP_Acceptor::object_key - ")
00263                       ACE_TEXT ("error while decoding host/port")));
00264         }
00265       return -1;
00266     }
00267 
00268   // ... and object key.
00269   if ((cdr >> object_key) == 0)
00270     return -1;
00271 
00272   // We are NOT bothered about the rest.
00273 
00274   return 1;
00275 }
00276 
00277 int
00278 TAO_COIOP_Acceptor::parse_options (const char *str)
00279 {
00280   if (str == 0)
00281     return 0;  // No options to parse.  Not a problem.
00282 
00283   // Use an option format similar to the one used for CGI scripts in
00284   // HTTP URLs.
00285   // e.g.:  option1=foo&option2=bar
00286 
00287   ACE_CString options (str);
00288 
00289   size_t len = options.length ();
00290 
00291   const char option_delimiter = '&';
00292 
00293   // Count the number of options.
00294 
00295   CORBA::ULong option_count = 1;
00296   // Number of endpoints in the string  (initialized to 1).
00297 
00298   // Only check for endpoints after the protocol specification and
00299   // before the object key.
00300   for (size_t i = 0; i < len; ++i)
00301     if (options[i] == option_delimiter)
00302       option_count++;
00303 
00304   // The idea behind the following loop is to split the options into
00305   // (option, name) pairs.
00306   // For example,
00307   //    `option1=foo&option2=bar'
00308   // will be parsed into:
00309   //    `option1=foo'
00310   //    `option2=bar'
00311 
00312   ACE_CString::size_type begin = 0;
00313   ACE_CString::size_type end = 0;
00314 
00315   for (CORBA::ULong j = 0; j < option_count; ++j)
00316     {
00317       if (j < option_count - 1)
00318         end = options.find (option_delimiter, begin);
00319       else
00320         end = len;
00321 
00322       if (end == begin)
00323         {
00324           ACE_ERROR_RETURN ((LM_ERROR,
00325                              ACE_TEXT ("TAO (%P|%t) Zero length COIOP option.\n")),
00326                             -1);
00327         }
00328       else if (end != ACE_CString::npos)
00329         {
00330           ACE_CString opt = options.substring (begin, end);
00331 
00332           ACE_CString::size_type const slot = opt.find ("=");
00333 
00334           if (slot == len - 1
00335               || slot == ACE_CString::npos)
00336             ACE_ERROR_RETURN ((LM_ERROR,
00337                                ACE_TEXT ("TAO (%P|%t) COIOP option <%s> is ")
00338                                ACE_TEXT ("missing a value.\n"),
00339                                ACE_TEXT_CHAR_TO_TCHAR (opt.c_str ())),
00340                               -1);
00341 
00342           ACE_CString name = opt.substring (0, slot);
00343           ACE_CString value = opt.substring (slot + 1);
00344 
00345           begin = end + 1;
00346 
00347           if (name.length () == 0)
00348             ACE_ERROR_RETURN ((LM_ERROR,
00349                                ACE_TEXT ("TAO (%P|%t) Zero length COIOP ")
00350                                ACE_TEXT ("option name.\n")),
00351                               -1);
00352 
00353           if (name == "priority")
00354             {
00355               ACE_ERROR_RETURN ((LM_ERROR,
00356                                  ACE_TEXT ("TAO (%P|%t) Invalid COIOP endpoint format: ")
00357                                  ACE_TEXT ("endpoint priorities no longer supported. \n")),
00358                                 -1);
00359             }
00360           else
00361             {
00362               ACE_ERROR_RETURN ((LM_ERROR,
00363                                  ACE_TEXT ("TAO (%P|%t) Invalid COIOP option: <%s>\n"),
00364                                  ACE_TEXT_CHAR_TO_TCHAR (name.c_str ())),
00365                                 -1);
00366             }
00367         }
00368       else
00369         {
00370           break;  // No other options.
00371         }
00372     }
00373   return 0;
00374 }
00375 
00376 TAO_END_VERSIONED_NAMESPACE_DECL
00377 
00378 #endif /* TAO_HAS_COIOP && TAO_HAS_COIOP != 0 */

Generated on Tue Feb 2 17:47:18 2010 for TAO_Strategies by  doxygen 1.4.7