00001
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
00014
00015 #if defined (ACE_HAS_WCHAR)
00016 # include "ace/OS_NS_stdlib.h"
00017 #endif
00018
00019 #if !defined (ACE_LACKS_STRERROR)
00020 # include "ace/OS_NS_stdio.h"
00021 #endif
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
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
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
00070 #endif
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
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
00115
00116
00117
00118
00119
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
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
00138 }
00139
00140 #if defined (ACE_LACKS_STRERROR)
00141
00142
00143
00144 char *
00145 ACE_OS::strerror_emulation (int errnum)
00146 {
00147 return "Unknown Error";
00148 }
00149 #endif
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
00175 const size_t len1 = ACE_OS::strlen (s1);
00176
00177
00178 if (len2 > len1)
00179 return 0;
00180
00181
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
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
00198 const size_t len1 = ACE_OS::strlen (s1);
00199
00200
00201 if (len2 > len1)
00202 return 0;
00203
00204
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
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
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
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
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
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
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
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)
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
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)
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
00411
00412 ACE_END_VERSIONED_NAMESPACE_DECL