Naming_Context_Interface.cpp

Go to the documentation of this file.
00001 // Naming_Context_Interface.cpp,v 1.21 2006/03/14 06:14:33 jtc Exp
00002 
00003 // ============================================================================
00004 //
00005 // = LIBRARY
00006 //    cos
00007 //
00008 // = FILENAME
00009 //   Naming_Context_Interface.cpp
00010 //
00011 // = AUTHOR
00012 //    Marina Spivak <marina@cs.wustl.edu>
00013 //
00014 // ============================================================================
00015 
00016 #include "orbsvcs/Naming/Naming_Context_Interface.h"
00017 #include "ace/ACE.h"
00018 #include "ace/OS_NS_string.h"
00019 #include "ace/os_include/os_ctype.h"
00020 
00021 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00022 
00023 TAO_Naming_Context::TAO_Naming_Context (TAO_Naming_Context_Impl *impl)
00024   : impl_ (impl)
00025 {
00026 }
00027 
00028 TAO_Naming_Context::~TAO_Naming_Context (void)
00029 {
00030   delete impl_;
00031 }
00032 
00033 PortableServer::POA_ptr
00034 TAO_Naming_Context::_default_POA (ACE_ENV_SINGLE_ARG_DECL_NOT_USED/*env*/)
00035 {
00036   return impl_->_default_POA ();
00037 }
00038 
00039 void
00040 TAO_Naming_Context::bind (const CosNaming::Name &n,
00041                           CORBA::Object_ptr obj
00042                           ACE_ENV_ARG_DECL)
00043     ACE_THROW_SPEC ((CORBA::SystemException,
00044                      CosNaming::NamingContext::NotFound,
00045                      CosNaming::NamingContext::CannotProceed,
00046                      CosNaming::NamingContext::InvalidName,
00047                      CosNaming::NamingContext::AlreadyBound))
00048 {
00049   impl_->bind (n, obj ACE_ENV_ARG_PARAMETER);
00050 }
00051 
00052 void
00053 TAO_Naming_Context::rebind (const CosNaming::Name &n,
00054                             CORBA::Object_ptr obj
00055                             ACE_ENV_ARG_DECL)
00056       ACE_THROW_SPEC ((CORBA::SystemException,
00057                        CosNaming::NamingContext::NotFound,
00058                        CosNaming::NamingContext::CannotProceed,
00059                        CosNaming::NamingContext::InvalidName))
00060 {
00061   impl_->rebind (n, obj ACE_ENV_ARG_PARAMETER);
00062 }
00063 
00064 void
00065 TAO_Naming_Context::bind_context (const CosNaming::Name &n,
00066                                   CosNaming::NamingContext_ptr nc
00067                                   ACE_ENV_ARG_DECL)
00068       ACE_THROW_SPEC ((CORBA::SystemException,
00069                        CosNaming::NamingContext::NotFound,
00070                        CosNaming::NamingContext::CannotProceed,
00071                        CosNaming::NamingContext::InvalidName,
00072                        CosNaming::NamingContext::AlreadyBound))
00073 {
00074   impl_->bind_context (n, nc ACE_ENV_ARG_PARAMETER);
00075 }
00076 
00077 void
00078 TAO_Naming_Context::rebind_context (const CosNaming::Name &n,
00079                                     CosNaming::NamingContext_ptr nc
00080                                     ACE_ENV_ARG_DECL)
00081       ACE_THROW_SPEC ((CORBA::SystemException,
00082                        CosNaming::NamingContext::NotFound,
00083                        CosNaming::NamingContext::CannotProceed,
00084                        CosNaming::NamingContext::InvalidName))
00085 {
00086   impl_->rebind_context (n, nc ACE_ENV_ARG_PARAMETER);
00087 }
00088 
00089 CORBA::Object_ptr
00090 TAO_Naming_Context::resolve (const CosNaming::Name &n
00091                              ACE_ENV_ARG_DECL)
00092       ACE_THROW_SPEC ((CORBA::SystemException,
00093                        CosNaming::NamingContext::NotFound,
00094                        CosNaming::NamingContext::CannotProceed,
00095                        CosNaming::NamingContext::InvalidName))
00096 {
00097   return impl_->resolve (n ACE_ENV_ARG_PARAMETER);
00098 }
00099 
00100 void
00101 TAO_Naming_Context::unbind (const CosNaming::Name &n
00102                             ACE_ENV_ARG_DECL)
00103       ACE_THROW_SPEC ((CORBA::SystemException,
00104                        CosNaming::NamingContext::NotFound,
00105                        CosNaming::NamingContext::CannotProceed,
00106                        CosNaming::NamingContext::InvalidName))
00107 {
00108   impl_->unbind (n ACE_ENV_ARG_PARAMETER);
00109 }
00110 
00111 CosNaming::NamingContext_ptr
00112 TAO_Naming_Context::new_context (ACE_ENV_SINGLE_ARG_DECL)
00113       ACE_THROW_SPEC ((CORBA::SystemException))
00114 {
00115   return impl_->new_context (ACE_ENV_SINGLE_ARG_PARAMETER);
00116 }
00117 
00118 CosNaming::NamingContext_ptr
00119 TAO_Naming_Context::bind_new_context (const CosNaming::Name &n
00120                                       ACE_ENV_ARG_DECL)
00121       ACE_THROW_SPEC ((CORBA::SystemException,
00122                        CosNaming::NamingContext::NotFound,
00123                        CosNaming::NamingContext::AlreadyBound,
00124                        CosNaming::NamingContext::CannotProceed,
00125                        CosNaming::NamingContext::InvalidName))
00126 {
00127   return impl_->bind_new_context (n ACE_ENV_ARG_PARAMETER);
00128 }
00129 
00130 void
00131 TAO_Naming_Context::destroy (ACE_ENV_SINGLE_ARG_DECL)
00132       ACE_THROW_SPEC ((CORBA::SystemException,
00133                        CosNaming::NamingContext::NotEmpty))
00134 {
00135   impl_->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00136 }
00137 
00138 void
00139 TAO_Naming_Context::list (CORBA::ULong how_many,
00140                           CosNaming::BindingList_out bl,
00141                           CosNaming::BindingIterator_out bi
00142                           ACE_ENV_ARG_DECL)
00143       ACE_THROW_SPEC ((CORBA::SystemException))
00144 {
00145   impl_->list (how_many, bl, bi ACE_ENV_ARG_PARAMETER);
00146 }
00147 
00148 void
00149 TAO_Naming_Context::
00150 to_string_helper_length (CORBA::ULong &len, const char * &src)
00151 {
00152   for (const char *j =src; *j != '\0'; ++j)
00153     {
00154       ++len;
00155       if (*j == '.' || *j == '\\' || *j == '/')
00156         ++len;
00157     }
00158   ++len; // '.' seperator or '/' seperator
00159 
00160 }
00161 
00162 void
00163 TAO_Naming_Context::
00164 to_string_helper_assign (char * &k, const char * &src)
00165 {
00166   for (; *src != '\0'; ++src)
00167     {
00168       if (*src == '.' || *src == '\\' || *src == '/')
00169         {
00170           *k = '\\';
00171           ++k;
00172         }
00173       *k = *src;
00174       ++k;
00175     }
00176 
00177 }
00178 
00179 char *
00180 TAO_Naming_Context::to_string (const CosNaming::Name &n
00181                                ACE_ENV_ARG_DECL)
00182   ACE_THROW_SPEC ((CORBA::SystemException,
00183                    CosNaming::NamingContext::InvalidName))
00184 {
00185   // Accepts a Name and returns a stringified name.
00186 
00187   // Check for invalid name.
00188   if (n.length () == 0)
00189     ACE_THROW_RETURN (CosNaming::NamingContext::InvalidName(),
00190                       0);
00191 
00192   // Length of the return string
00193   CORBA::ULong len = 0;
00194 
00195   CORBA::ULong i;
00196   for (i=0; i < n.length (); ++i)
00197     {
00198       const char *id = n[i].id.in ();
00199 
00200       // Count number of characters in id
00201       this->to_string_helper_length (len, id);
00202 
00203       const char *kind = n[i].kind.in ();
00204 
00205       // Count number of characters in kind
00206       this->to_string_helper_length (len, kind);
00207     }
00208 
00209   // Allocate memory to the return parameter
00210   //
00211   char *str_name = CORBA::string_alloc (len);
00212 
00213   // check for memory allocation
00214   //
00215   if (str_name == 0)
00216     {
00217       ACE_THROW_RETURN (CORBA::NO_MEMORY (), 0);
00218     }
00219 
00220   char *k = str_name;
00221 
00222   // Stringify the name
00223   for (i=0; i < n.length (); ++i)
00224     {
00225 
00226       // Stringify Id
00227       //
00228       const char *id = n[i].id.in ();
00229       this->to_string_helper_assign (k, id);
00230 
00231       const char *kind = n[i].kind.in ();
00232 
00233       if (*kind != '\0')
00234         {
00235           // If 'kind' is set,
00236           // Append a seperator between the id and kind.
00237           //
00238           *k = '.';
00239           ++k;
00240 
00241           // Stringify Kind
00242           //
00243           this->to_string_helper_assign (k, kind);
00244         }
00245 
00246       // If this is not the last name component, add a seperator
00247       // between the name components
00248       //
00249       if (i != (n.length ()-1))
00250         {
00251           *k = '/';
00252           ++k;
00253         }
00254 
00255     }
00256   // Terminate
00257   *k = '\0';
00258   ++k;
00259 
00260   return str_name;
00261 }
00262 
00263 void
00264 TAO_Naming_Context::
00265 to_name_helper (char *dest, const char*& src, Hint hint)
00266 {
00267   for (; *src != '\0'; ++src, ++dest)
00268     {
00269       if ((hint == HINT_ID && *src == '.') || *src == '/')
00270         {
00271           *dest = '\0';
00272           return;
00273         }
00274 
00275       if (*src == '\\')
00276         {
00277           src++;
00278           if (*src == '\0')
00279             {
00280               // Case: The very last component
00281               *dest = '\0';
00282               return;
00283             }
00284         }
00285 
00286       // In all cases.
00287       *dest = *src;
00288     }
00289 
00290   // Terminate.
00291   *dest = '\0';
00292 }
00293 
00294 CosNaming::Name *
00295 TAO_Naming_Context::to_name (const char *sn
00296                              ACE_ENV_ARG_DECL)
00297   ACE_THROW_SPEC ((CORBA::SystemException,
00298                    CosNaming::NamingContext::InvalidName))
00299 {
00300   // Returns the Name from its stringified form.
00301   CosNaming::Name n;
00302 
00303   // Total number of name components in the name
00304   CORBA::ULong ncomp = 0;
00305 
00306   // Total length of the unstrigified name
00307   CORBA::ULong len=0;
00308 
00309 
00310   for (const char *j = sn; *j != '\0'; ++j)
00311     {
00312       // Make a pass through the Name and count each character
00313       if (*j == '/')
00314         {
00315           ncomp++;
00316         }
00317       else if (*j == '\\')
00318         {
00319           ++j;
00320 
00321           if (*j == '\0')
00322             {
00323               // Case: The very last component
00324               ++len;
00325             }
00326         }
00327 
00328       // In all cases.
00329       ++len;
00330     }
00331 
00332 
00333   // Check for InvalidName i.e. Invalid stringified name
00334   //
00335   if (len == 0)
00336     ACE_THROW_RETURN (CosNaming::NamingContext::InvalidName(),
00337                       0);
00338 
00339   // Assign the length of the return unstringified name.
00340   //
00341   n.length (ncomp+1);
00342 
00343   // Keeps track of the number of the name component
00344   //
00345   CORBA::ULong count = 0;
00346 
00347   for (const char *k = sn; *k != '\0';)
00348     {
00349       if (count > ncomp)
00350         {
00351           ACE_THROW_RETURN (CosNaming::NamingContext::InvalidName(), 0);
00352         }
00353 
00354       char *id = CORBA::string_alloc (len);
00355       char *kind = CORBA::string_alloc (len);
00356 
00357       // Assign to the id.
00358       this->to_name_helper (id, k, HINT_ID);
00359 
00360       if (*k == '.')
00361         {
00362           k++;
00363           // Assign to kind
00364           this->to_name_helper (kind, k, HINT_KIND);
00365         }
00366       else
00367         {
00368           *kind = '\0';
00369         }
00370 
00371       n[count].id   = id;
00372       n[count].kind = kind;
00373 
00374       count++;
00375 
00376       // End
00377        if (*k == '\0')
00378          break;
00379       k++;
00380     }
00381 
00382   return new CosNaming::Name (n);
00383 }
00384 
00385 int
00386 TAO_Naming_Context::to_url_is_alnum_or_punctuation (char c)
00387 {
00388   if (isalnum (c))
00389     return 1;
00390 
00391   // NON US-ASCII charcters excluding those in this array are the
00392   // characters that need to be escaped
00393   static char non_escaped_punctuation[] =
00394     { ';', '/', ':', '?', '@', '=', '+', '$', ',', '-',
00395       '_', '.', '!', '~', '*', '\'', '(', ')' };
00396   const size_t non_escaped_punctuation_count =
00397     sizeof(non_escaped_punctuation)/sizeof(non_escaped_punctuation[0]);
00398   for (const char *j = non_escaped_punctuation;
00399        j != non_escaped_punctuation + non_escaped_punctuation_count;
00400        ++j)
00401     {
00402       // But if the character is one of the 18 non US-ASCII characters
00403       // and hence need not be escaped, then don't increment the
00404       // count.
00405       if (*j == c)
00406         return 1;
00407     }
00408   return 0;
00409 }
00410 
00411 size_t
00412 TAO_Naming_Context::to_url_validate_and_compute_size (
00413     const char *addr,
00414     const char *sn
00415     ACE_ENV_ARG_DECL)
00416 {
00417   size_t addr_len = ACE_OS::strlen (addr);
00418 
00419   // Check for invalid address
00420   if (addr_len == 0)
00421     ACE_THROW_RETURN (CosNaming::NamingContextExt::InvalidAddress (),
00422                       0);
00423 
00424   // Make a pass through the in string name to count the number of
00425   // characters and if the character
00426   // is to be escaped, increment the number of characters by 3.
00427   size_t sn_len = 0;
00428   for (const char *i = sn; *i != '\0'; ++i)
00429     {
00430       ++sn_len;
00431 
00432       if (TAO_Naming_Context::to_url_is_alnum_or_punctuation (*i))
00433         continue;
00434       sn_len += 3;
00435     }
00436 
00437   if (sn_len == 0)
00438     ACE_THROW_RETURN (CosNaming::NamingContextExt::InvalidName (), 0);
00439 
00440   return addr_len + sn_len;
00441 }
00442 
00443 char *
00444 TAO_Naming_Context::to_url (const char * addr,
00445                             const char * sn
00446                             ACE_ENV_ARG_DECL)
00447   ACE_THROW_SPEC ((CORBA::SystemException,
00448                    CosNaming::NamingContextExt::InvalidAddress,
00449                    CosNaming::NamingContext::InvalidName))
00450 {
00451   /// Compute how many characters will be required for the URL
00452   size_t no_char =
00453     TAO_Naming_Context::to_url_validate_and_compute_size (addr, sn
00454                                                           ACE_ENV_ARG_PARAMETER);
00455   ACE_CHECK_RETURN (0);
00456 
00457 
00458   // The 'corbaname:' tag is to be prepended at the starting of the
00459   // return parameter.
00460   //
00461   char prefix []= "corbaname:";
00462 
00463   // Allocate dynamic memory
00464   //
00465   char *str_url = CORBA::string_alloc (static_cast<CORBA::ULong> (no_char + sizeof (prefix)));
00466 
00467   // Copy 'prefix' to the return parameter.
00468   char *dest = ACE_OS::strcpy (str_url , prefix);
00469 
00470   /// move to end of dest string
00471   dest += ACE_OS::strlen(dest);
00472 
00473   // Concatenate the address
00474   dest = ACE_OS::strcat (dest, addr);
00475 
00476   /// Concatenate the seperator between the addr and Name
00477   dest += ACE_OS::strlen(dest);
00478   dest = ACE_OS::strcat (dest, "#");
00479 
00480   /// move to end of dest string
00481   dest += ACE_OS::strlen(dest);
00482 
00483   // Now append the stringified object name to the return variable.
00484   // The percent '%' character is used as an escape. If a character
00485   // that requires escaping is present in a name component it is
00486   // encoded as two hexadecimal digits following a '%' character to
00487   // represent the octet. The first hexadecimal character represents
00488   // the low-order nibble of the octet and the second hexadecimal
00489   // character represents the low order nibble.
00490 
00491   for (const char *i = sn; *i != '\0'; ++i)
00492     {
00493       if (TAO_Naming_Context::to_url_is_alnum_or_punctuation (*i))
00494         {
00495           // If the character is a US-ASCII Alphanumeric value...
00496           *dest = *i; ++dest;
00497           continue;
00498         }
00499       // this must be an escaped character
00500 
00501       *dest = '%'; ++dest;
00502 
00503       // Append the hexadecimal representation of the character.
00504       *dest = ACE::nibble2hex ((*i) >> 4); ++dest;
00505       *dest = ACE::nibble2hex (*i); ++dest;
00506     }
00507 
00508   // Terminate the string
00509   *dest = '\0';
00510 
00511   //  ACE_OS::strcat (str_url, dest);
00512   return str_url;
00513 }
00514 
00515 CORBA::Object_ptr
00516 TAO_Naming_Context::resolve_str (const char * n
00517                                  ACE_ENV_ARG_DECL)
00518   ACE_THROW_SPEC ((CORBA::SystemException,
00519                    CosNaming::NamingContext::NotFound,
00520                    CosNaming::NamingContext::CannotProceed,
00521                    CosNaming::NamingContext::InvalidName
00522                    ))
00523 {
00524   // Similar to <resolve> above. It accepts a strigified name as an
00525   // argument instead of a Name.
00526 
00527   // Get the unstrigified name.
00528   CosNaming::Name_var name = this->to_name (n ACE_ENV_ARG_PARAMETER);
00529   ACE_CHECK_RETURN (CORBA::Object::_nil ());
00530 
00531   // Pass this unstringified name to resolve and return an Object_ptr
00532   return this->resolve (name.in () ACE_ENV_ARG_PARAMETER);
00533 }
00534 
00535 TAO_Naming_Context_Impl::~TAO_Naming_Context_Impl (void)
00536 {
00537 }
00538 
00539 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 13:57:02 2006 for TAO_CosNaming by doxygen 1.3.6