OS_NS_string.cpp

Go to the documentation of this file.
00001 // $Id: OS_NS_string.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 
00003 #include "ace/OS_NS_string.h"
00004 #include "ace/OS_NS_stdlib.h"
00005 #include "ace/ACE.h"
00006 
00007 ACE_RCSID (ace,
00008            OS_NS_string,
00009            "$Id: OS_NS_string.cpp 80826 2008-03-04 14:51:23Z wotte $")
00010 
00011 #if !defined (ACE_HAS_INLINED_OSCALLS)
00012 # include "ace/OS_NS_string.inl"
00013 #endif /* ACE_HAS_INLINED_OSCALLS */
00014 
00015 #if defined (ACE_HAS_WCHAR)
00016 #  include "ace/OS_NS_stdlib.h"
00017 #endif /* ACE_HAS_WCHAR */
00018 
00019 #if !defined (ACE_LACKS_STRERROR)
00020 #  include "ace/OS_NS_stdio.h"
00021 #endif /* ACE_LACKS_STRERROR */
00022 
00023 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00024 
00025 #if defined (ACE_LACKS_MEMCHR)
00026 const void *
00027 ACE_OS::memchr_emulation (const void *s, int c, size_t len)
00028 {
00029   const unsigned char *t = (const unsigned char *) s;
00030   const unsigned char *e = (const unsigned char *) s + len;
00031 
00032   while (t < e)
00033     if (((int) *t) == c)
00034       return t;
00035     else
00036       ++t;
00037 
00038   return 0;
00039 }
00040 #endif /* ACE_LACKS_MEMCHR */
00041 
00042 #if (defined (ACE_LACKS_STRDUP) && !defined (ACE_STRDUP_EQUIVALENT)) \
00043   || defined (ACE_HAS_STRDUP_EMULATION)
00044 char *
00045 ACE_OS::strdup_emulation (const char *s)
00046 {
00047   char *t = (char *) ACE_OS::malloc (ACE_OS::strlen (s) + 1);
00048   if (t == 0)
00049     return 0;
00050 
00051   return ACE_OS::strcpy (t, s);
00052 }
00053 #endif /* (ACE_LACKS_STRDUP && !ACE_STRDUP_EQUIVALENT) || ... */
00054 
00055 #if defined (ACE_HAS_WCHAR)
00056 #if (defined (ACE_LACKS_WCSDUP) && !defined (ACE_WCSDUP_EQUIVALENT)) \
00057   || defined (ACE_HAS_WCSDUP_EMULATION)
00058 wchar_t *
00059 ACE_OS::strdup_emulation (const wchar_t *s)
00060 {
00061   wchar_t *buffer =
00062     (wchar_t *) ACE_OS::malloc ((ACE_OS::strlen (s) + 1)
00063                                 * sizeof (wchar_t));
00064   if (buffer == 0)
00065     return 0;
00066 
00067   return ACE_OS::strcpy (buffer, s);
00068 }
00069 #endif /* (ACE_LACKS_WCSDUP && !ACE_WCSDUP_EQUIVALENT) || ... */
00070 #endif /* ACE_HAS_WCHAR */
00071 
00072 char *
00073 ACE_OS::strecpy (char *s, const char *t)
00074 {
00075   register char *dscan = s;
00076   register const char *sscan = t;
00077 
00078   while ((*dscan++ = *sscan++) != '\0')
00079     continue;
00080 
00081   return dscan;
00082 }
00083 
00084 #if defined (ACE_HAS_WCHAR)
00085 wchar_t *
00086 ACE_OS::strecpy (wchar_t *s, const wchar_t *t)
00087 {
00088   register wchar_t *dscan = s;
00089   register const wchar_t *sscan = t;
00090 
00091   while ((*dscan++ = *sscan++) != ACE_TEXT_WIDE ('\0'))
00092     continue;
00093 
00094   return dscan;
00095 }
00096 #endif /* ACE_HAS_WCHAR */
00097 
00098 char *
00099 ACE_OS::strerror (int errnum)
00100 {
00101   static char ret_errortext[128];
00102 
00103   if (ACE::is_sock_error (errnum))
00104     {
00105       const ACE_TCHAR *errortext = ACE::sock_error (errnum);
00106       ACE_OS::strncpy (ret_errortext,
00107                        ACE_TEXT_ALWAYS_CHAR (errortext),
00108                        sizeof (ret_errortext));
00109       return ret_errortext;
00110     }
00111 #if defined (ACE_LACKS_STRERROR)
00112   errno = EINVAL;
00113   return ACE_OS::strerror_emulation (errnum);
00114 #else /* ACE_LACKS_STRERROR */
00115   // Adapt to the various ways that strerror() indicates a bad errnum.
00116   // Most modern systems set errno to EINVAL. Some older platforms return
00117   // a pointer to a NULL string. This code makes the behavior more consistent
00118   // across platforms. On a bad errnum, we make a string with the error number
00119   // and set errno to EINVAL.
00120   ACE_Errno_Guard g (errno);
00121   errno = 0;
00122   char *errmsg = 0;
00123 
00124 #if defined (ACE_HAS_TR24731_2005_CRT)
00125   errmsg = ret_errortext;
00126   ACE_SECURECRTCALL (strerror_s (ret_errortext, sizeof(ret_errortext), errnum),
00127                      char *, 0, errmsg);
00128   return errmsg;
00129 #elif defined (ACE_WIN32)
00130   if (errnum < 0 || errnum >= _sys_nerr)
00131     errno = EINVAL;
00132 #endif /* ACE_WIN32 */
00133   errmsg = ::strerror (errnum);
00134 
00135   if (errno == EINVAL || errmsg == 0 || errmsg[0] == 0)
00136     {
00137       ACE_OS::sprintf (ret_errortext, "Unknown error %d", errnum);
00138       errmsg = ret_errortext;
00139       g = EINVAL;
00140     }
00141   return errmsg;
00142 #endif /* ACE_LACKS_STRERROR */
00143 }
00144 
00145 #if defined (ACE_LACKS_STRERROR)
00146 /**
00147  * Just returns "Unknown Error" all the time.
00148  */
00149 char *
00150 ACE_OS::strerror_emulation (int errnum)
00151 {
00152   return "Unknown Error";
00153 }
00154 #endif /* ACE_LACKS_STRERROR */
00155 
00156 const char *
00157 ACE_OS::strnchr (const char *s, int c, size_t len)
00158 {
00159   for (size_t i = 0; i < len; ++i)
00160     if (s[i] == c)
00161       return s + i;
00162 
00163   return 0;
00164 }
00165 
00166 const ACE_WCHAR_T *
00167 ACE_OS::strnchr (const ACE_WCHAR_T *s, ACE_WCHAR_T c, size_t len)
00168 {
00169   for (size_t i = 0; i < len; ++i)
00170     if (s[i] == c)
00171       return s + i;
00172 
00173   return 0;
00174 }
00175 
00176 const char *
00177 ACE_OS::strnstr (const char *s1, const char *s2, size_t len2)
00178 {
00179   // Substring length
00180   size_t const len1 = ACE_OS::strlen (s1);
00181 
00182   // Check if the substring is longer than the string being searched.
00183   if (len2 > len1)
00184     return 0;
00185 
00186   // Go upto <len>
00187   size_t const len = len1 - len2;
00188 
00189   for (size_t i = 0; i <= len; i++)
00190     {
00191       if (ACE_OS::memcmp (s1 + i, s2, len2) == 0)
00192         // Found a match!  Return the index.
00193         return s1 + i;
00194     }
00195 
00196   return 0;
00197 }
00198 
00199 const ACE_WCHAR_T *
00200 ACE_OS::strnstr (const ACE_WCHAR_T *s1, const ACE_WCHAR_T *s2, size_t len2)
00201 {
00202   // Substring length
00203   const size_t len1 = ACE_OS::strlen (s1);
00204 
00205   // Check if the substring is longer than the string being searched.
00206   if (len2 > len1)
00207     return 0;
00208 
00209   // Go upto <len>
00210   const size_t len = len1 - len2;
00211 
00212   for (size_t i = 0; i <= len; i++)
00213     {
00214       if (ACE_OS::memcmp (s1 + i, s2, len2 * sizeof (ACE_WCHAR_T)) == 0)
00215         // Found a match!  Return the index.
00216         return s1 + i;
00217     }
00218 
00219   return 0;
00220 }
00221 
00222 #if defined (ACE_HAS_MEMCPY_LOOP_UNROLL)
00223 void *
00224 ACE_OS::fast_memcpy (void *t, const void *s, size_t len)
00225 {
00226   unsigned char* to = static_cast<unsigned char*> (t) ;
00227   const unsigned char* from = static_cast<const unsigned char*> (s) ;
00228   // Unroll the loop...
00229   switch (len)
00230     {
00231     case 16: to[15] = from[15];
00232     case 15: to[14] = from[14];
00233     case 14: to[13] = from[13];
00234     case 13: to[12] = from[12];
00235     case 12: to[11] = from[11];
00236     case 11: to[10] = from[10];
00237     case 10: to[9] = from[9];
00238     case  9: to[8] = from[8];
00239     case  8: to[7] = from[7];
00240     case  7: to[6] = from[6];
00241     case  6: to[5] = from[5];
00242     case  5: to[4] = from[4];
00243     case  4: to[3] = from[3];
00244     case  3: to[2] = from[2];
00245     case  2: to[1] = from[1];
00246     case  1: to[0] = from[0];
00247     case  0: return t;
00248     default: return ::memcpy (t, s, len);
00249     }
00250 }
00251 #endif /* ACE_HAS_MEMCPY_LOOP_UNROLL */
00252 
00253 #if defined (ACE_LACKS_STRRCHR)
00254 char *
00255 ACE_OS::strrchr_emulation (char *s, int c)
00256 {
00257   char *p = s + ACE_OS::strlen (s);
00258 
00259   while (*p != c)
00260     if (p == s)
00261       return 0;
00262     else
00263       --p;
00264 
00265   return p;
00266 }
00267 
00268 const char *
00269 ACE_OS::strrchr_emulation (const char *s, int c)
00270 {
00271   const char *p = s + ACE_OS::strlen (s);
00272 
00273   while (*p != c)
00274     if (p == s)
00275       return 0;
00276     else
00277       --p;
00278 
00279   return p;
00280 }
00281 #endif /* ACE_LACKS_STRRCHR */
00282 
00283 char *
00284 ACE_OS::strsncpy (char *dst, const char *src, size_t maxlen)
00285 {
00286   register char *rdst = dst;
00287   register const char *rsrc = src;
00288   register size_t rmaxlen = maxlen;
00289 
00290   if (rmaxlen > 0)
00291     {
00292       if (rdst!=rsrc)
00293         {
00294           *rdst = '\0';
00295           if (rsrc != 0)
00296             strncat (rdst, rsrc, --rmaxlen);
00297         }
00298       else
00299         {
00300           rdst += (rmaxlen - 1);
00301           *rdst = '\0';
00302         }
00303     }
00304   return dst;
00305 }
00306 
00307 ACE_WCHAR_T *
00308 ACE_OS::strsncpy (ACE_WCHAR_T *dst, const ACE_WCHAR_T *src, size_t maxlen)
00309 {
00310   register ACE_WCHAR_T *rdst = dst;
00311   register const ACE_WCHAR_T *rsrc = src;
00312   register size_t rmaxlen = maxlen;
00313 
00314   if (rmaxlen > 0)
00315     {
00316       if (rdst!=rsrc)
00317         {
00318           *rdst = ACE_TEXT_WIDE ('\0');
00319           if (rsrc != 0)
00320             strncat (rdst, rsrc, --rmaxlen);
00321         }
00322       else
00323         {
00324           rdst += (rmaxlen - 1);
00325           *rdst = ACE_TEXT_WIDE ('\0');
00326         }
00327     }
00328   return dst;
00329 }
00330 
00331 #if (!defined (ACE_HAS_REENTRANT_FUNCTIONS) || defined (ACE_LACKS_STRTOK_R)) \
00332     && !defined (ACE_HAS_TR24731_2005_CRT)
00333 char *
00334 ACE_OS::strtok_r_emulation (char *s, const char *tokens, char **lasts)
00335 {
00336   if (s == 0)
00337     s = *lasts;
00338   else
00339     *lasts = s;
00340   if (*s == 0)                  // We have reached the end
00341     return 0;
00342   size_t l_org = ACE_OS::strlen (s);
00343   s = ::strtok (s, tokens);
00344   if (s == 0)
00345     return 0;
00346   const size_t l_sub = ACE_OS::strlen (s);
00347   if (s + l_sub < *lasts + l_org)
00348     *lasts = s + l_sub + 1;
00349   else
00350     *lasts = s + l_sub;
00351   return s ;
00352 }
00353 #endif /* !ACE_HAS_REENTRANT_FUNCTIONS */
00354 
00355 # if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSTOK)
00356 wchar_t*
00357 ACE_OS::strtok_r_emulation (ACE_WCHAR_T *s,
00358                             const ACE_WCHAR_T *tokens,
00359                             ACE_WCHAR_T **lasts)
00360 {
00361   ACE_WCHAR_T* sbegin = s ? s : *lasts;
00362   sbegin += ACE_OS::strspn(sbegin, tokens);
00363   if (*sbegin == 0)
00364     {
00365       static ACE_WCHAR_T empty[1] = { 0 };
00366       *lasts = empty;
00367       return 0;
00368   }
00369   ACE_WCHAR_T*send = sbegin + ACE_OS::strcspn(sbegin, tokens);
00370   if (*send != 0)
00371       *send++ = 0;
00372   *lasts = send;
00373   return sbegin;
00374 }
00375 # endif  /* ACE_HAS_WCHAR && ACE_LACKS_WCSTOK */
00376 
00377 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:41 2010 for ACE by  doxygen 1.4.7