OS_NS_string.cpp

Go to the documentation of this file.
00001 // OS_NS_string.cpp,v 1.25 2006/05/05 20:43:15 schmidt Exp
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            "OS_NS_string.cpp,v 1.25 2006/05/05 20:43:15 schmidt Exp")
00010 
00011 #if !defined (ACE_HAS_INLINED_OSCALLS)
00012 # include "ace/OS_NS_string.inl"
00013 #endif /* ACE_HAS_INLINED_OS_CALLS */
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_HAS_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_HAS_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;
00123 
00124 #if defined (ACE_WIN32)
00125    if (errnum < 0 || errnum >= _sys_nerr)
00126       errno = EINVAL;
00127 #endif /* ACE_WIN32 */
00128    errmsg = ::strerror (errnum);
00129 
00130   if (errno == EINVAL || errmsg == 0 || errmsg[0] == 0)
00131     {
00132       ACE_OS::sprintf (ret_errortext, "Unknown error %d", errnum);
00133       errmsg = ret_errortext;
00134       g = EINVAL;
00135     }
00136   return errmsg;
00137 #endif /* ACE_LACKS_STRERROR */
00138 }
00139 
00140 #if defined (ACE_LACKS_STRERROR)
00141 /**
00142  * Just returns "Unknown Error" all the time.
00143  */
00144 char *
00145 ACE_OS::strerror_emulation (int errnum)
00146 {
00147   return "Unknown Error";
00148 }
00149 #endif /* ACE_LACKS_STRERROR */
00150 
00151 const char *
00152 ACE_OS::strnchr (const char *s, int c, size_t len)
00153 {
00154   for (size_t i = 0; i < len; ++i)
00155     if (s[i] == c)
00156       return s + i;
00157 
00158   return 0;
00159 }
00160 
00161 const ACE_WCHAR_T *
00162 ACE_OS::strnchr (const ACE_WCHAR_T *s, ACE_WCHAR_T c, size_t len)
00163 {
00164   for (size_t i = 0; i < len; ++i)
00165     if (s[i] == c)
00166       return s + i;
00167 
00168   return 0;
00169 }
00170 
00171 const char *
00172 ACE_OS::strnstr (const char *s1, const char *s2, size_t len2)
00173 {
00174   // Substring length
00175   const size_t len1 = ACE_OS::strlen (s1);
00176 
00177   // Check if the substring is longer than the string being searched.
00178   if (len2 > len1)
00179     return 0;
00180 
00181   // Go upto <len>
00182   const size_t len = len1 - len2;
00183 
00184   for (size_t i = 0; i <= len; i++)
00185     {
00186       if (ACE_OS::memcmp (s1 + i, s2, len2) == 0)
00187         // Found a match!  Return the index.
00188         return s1 + i;
00189     }
00190 
00191   return 0;
00192 }
00193 
00194 const ACE_WCHAR_T *
00195 ACE_OS::strnstr (const ACE_WCHAR_T *s1, const ACE_WCHAR_T *s2, size_t len2)
00196 {
00197   // Substring length
00198   const size_t len1 = ACE_OS::strlen (s1);
00199 
00200   // Check if the substring is longer than the string being searched.
00201   if (len2 > len1)
00202     return 0;
00203 
00204   // Go upto <len>
00205   const size_t len = len1 - len2;
00206 
00207   for (size_t i = 0; i <= len; i++)
00208     {
00209       if (ACE_OS::memcmp (s1 + i, s2, len2 * sizeof (ACE_WCHAR_T)) == 0)
00210         // Found a match!  Return the index.
00211         return s1 + i;
00212     }
00213 
00214   return 0;
00215 }
00216 
00217 #if defined (ACE_HAS_MEMCPY_LOOP_UNROLL)
00218 void *
00219 ACE_OS::fast_memcpy (void *t, const void *s, size_t len)
00220 {
00221   unsigned char* to = static_cast<unsigned char*> (t) ;
00222   const unsigned char* from = static_cast<const unsigned char*> (s) ;
00223   // Unroll the loop...
00224   switch (len)
00225     {
00226     case 16: to[15] = from[15];
00227     case 15: to[14] = from[14];
00228     case 14: to[13] = from[13];
00229     case 13: to[12] = from[12];
00230     case 12: to[11] = from[11];
00231     case 11: to[10] = from[10];
00232     case 10: to[9] = from[9];
00233     case  9: to[8] = from[8];
00234     case  8: to[7] = from[7];
00235     case  7: to[6] = from[6];
00236     case  6: to[5] = from[5];
00237     case  5: to[4] = from[4];
00238     case  4: to[3] = from[3];
00239     case  3: to[2] = from[2];
00240     case  2: to[1] = from[1];
00241     case  1: to[0] = from[0];
00242     case  0: return t;
00243     default: return ::memcpy (t, s, len);
00244     }
00245 }
00246 #endif /* ACE_HAS_MEMCPY_LOOP_UNROLL */
00247 
00248 #if defined (ACE_LACKS_STRPBRK)
00249 char *
00250 ACE_OS::strpbrk_emulation (const char *string,
00251                            const char *charset)
00252 {
00253   const char *scanp;
00254   int c, sc;
00255 
00256   while ((c = *string++) != 0)
00257     {
00258       for (scanp = charset; (sc = *scanp++) != 0;)
00259         if (sc == c)
00260           return const_cast<char *> (string - 1);
00261     }
00262 
00263   return 0;
00264 }
00265 #endif /* ACE_LACKS_STRPBRK */
00266 
00267 #if defined (ACE_LACKS_STRRCHR)
00268 char *
00269 ACE_OS::strrchr_emulation (char *s, int c)
00270 {
00271   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 
00282 const char *
00283 ACE_OS::strrchr_emulation (const char *s, int c)
00284 {
00285   const char *p = s + ACE_OS::strlen (s);
00286 
00287   while (*p != c)
00288     if (p == s)
00289       return 0;
00290     else
00291       --p;
00292 
00293   return p;
00294 }
00295 #endif /* ACE_LACKS_STRRCHR */
00296 
00297 char *
00298 ACE_OS::strsncpy (char *dst, const char *src, size_t maxlen)
00299 {
00300   register char *rdst = dst;
00301   register const char *rsrc = src;
00302   register size_t rmaxlen = maxlen;
00303 
00304   if (rmaxlen > 0)
00305     {
00306       if (rdst!=rsrc)
00307         {
00308           *rdst = '\0';
00309           if (rsrc != 0)
00310             strncat (rdst, rsrc, --rmaxlen);
00311         }
00312       else
00313         {
00314           rdst += (rmaxlen - 1);
00315           *rdst = '\0';
00316         }
00317     }
00318   return dst;
00319 }
00320 
00321 ACE_WCHAR_T *
00322 ACE_OS::strsncpy (ACE_WCHAR_T *dst, const ACE_WCHAR_T *src, size_t maxlen)
00323 {
00324   register ACE_WCHAR_T *rdst = dst;
00325   register const ACE_WCHAR_T *rsrc = src;
00326   register size_t rmaxlen = maxlen;
00327 
00328   if (rmaxlen > 0)
00329     {
00330       if (rdst!=rsrc)
00331         {
00332           *rdst = ACE_TEXT_WIDE ('\0');
00333           if (rsrc != 0)
00334             strncat (rdst, rsrc, --rmaxlen);
00335         }
00336       else
00337         {
00338           rdst += (rmaxlen - 1);
00339           *rdst = ACE_TEXT_WIDE ('\0');
00340         }
00341     }
00342   return dst;
00343 }
00344 
00345 #if defined (ACE_LACKS_STRSPN)
00346 size_t
00347 ACE_OS::strspn_emulation (const char *string,
00348                           const char *charset)
00349 {
00350   const char *p = string;
00351   const char *spanp;
00352   wchar_t c, sc;
00353 
00354   // Skip any characters in charset, excluding the terminating \0.
00355  cont:
00356   c = *p++;
00357   for (spanp = charset; (sc = *spanp++) != 0;)
00358     if (sc == c)
00359       goto cont;
00360   return (p - 1 - string);
00361 }
00362 #endif /* ACE_LACKS_STRSPN */
00363 
00364 #if !defined (ACE_HAS_REENTRANT_FUNCTIONS)
00365 char *
00366 ACE_OS::strtok_r_emulation (char *s, const char *tokens, char **lasts)
00367 {
00368   if (s == 0)
00369     s = *lasts;
00370   else
00371     *lasts = s;
00372   if (*s == 0)                  // We have reached the end
00373     return 0;
00374   size_t l_org = ACE_OS::strlen (s);
00375   s = ::strtok (s, tokens);
00376   if (s == 0)
00377     return 0;
00378   const size_t l_sub = ACE_OS::strlen (s);
00379   if (s + l_sub < *lasts + l_org)
00380     *lasts = s + l_sub + 1;
00381   else
00382     *lasts = s + l_sub;
00383   return s ;
00384 }
00385 #endif /* !ACE_HAS_REENTRANT_FUNCTIONS */
00386 
00387 # if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSTOK)
00388 wchar_t*
00389 ACE_OS::strtok_r_emulation (ACE_WCHAR_T *s,
00390                             const ACE_WCHAR_T *tokens,
00391                             ACE_WCHAR_T **lasts)
00392 {
00393   if (s == 0)
00394     s = *lasts;
00395   else
00396     *lasts = s;
00397   if (*s == 0)                  // We have reached the end
00398     return 0;
00399   int l_org = ACE_OS::strlen (s);
00400   s = ACE_OS::strtok (s, tokens);
00401   if (s == 0)
00402     return 0;
00403   const int l_sub = ACE_OS::strlen (s);
00404   if (s + l_sub < *lasts + l_org)
00405     *lasts = s + l_sub + 1;
00406   else
00407     *lasts = s + l_sub;
00408   return s ;
00409 }
00410 # endif  /* ACE_HAS_WCHAR && ACE_LACKS_WCSTOK */
00411 
00412 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:58 2006 for ACE by doxygen 1.3.6