Naming_Context_Interface.cpp

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

Generated on Sun Jan 27 16:15:29 2008 for TAO_CosNaming by doxygen 1.3.6