1 // $Id: OS_NS_string.cpp 80826 2008-03-04 14:51:23Z wotte $
3 #include "ace/OS_NS_string.h"
4 #include "ace/OS_NS_stdlib.h"
9 "$Id: OS_NS_string.cpp 80826 2008-03-04 14:51:23Z wotte $")
11 #if !defined (ACE_HAS_INLINED_OSCALLS)
12 # include "ace/OS_NS_string.inl"
13 #endif /* ACE_HAS_INLINED_OSCALLS */
15 #if defined (ACE_HAS_WCHAR)
16 # include "ace/OS_NS_stdlib.h"
17 #endif /* ACE_HAS_WCHAR */
19 #if !defined (ACE_LACKS_STRERROR)
20 # include "ace/OS_NS_stdio.h"
21 #endif /* ACE_LACKS_STRERROR */
23 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
25 #if defined (ACE_LACKS_MEMCHR)
27 ACE_OS::memchr_emulation (const void *s
, int c
, size_t len
)
29 const unsigned char *t
= (const unsigned char *) s
;
30 const unsigned char *e
= (const unsigned char *) s
+ len
;
40 #endif /* ACE_LACKS_MEMCHR */
42 #if (defined (ACE_LACKS_STRDUP) && !defined (ACE_STRDUP_EQUIVALENT)) \
43 || defined (ACE_HAS_STRDUP_EMULATION)
45 ACE_OS::strdup_emulation (const char *s
)
47 char *t
= (char *) ACE_OS::malloc (ACE_OS::strlen (s
) + 1);
51 return ACE_OS::strcpy (t
, s
);
53 #endif /* (ACE_LACKS_STRDUP && !ACE_STRDUP_EQUIVALENT) || ... */
55 #if defined (ACE_HAS_WCHAR)
56 #if (defined (ACE_LACKS_WCSDUP) && !defined (ACE_WCSDUP_EQUIVALENT)) \
57 || defined (ACE_HAS_WCSDUP_EMULATION)
59 ACE_OS::strdup_emulation (const wchar_t *s
)
62 (wchar_t *) ACE_OS::malloc ((ACE_OS::strlen (s
) + 1)
67 return ACE_OS::strcpy (buffer
, s
);
69 #endif /* (ACE_LACKS_WCSDUP && !ACE_WCSDUP_EQUIVALENT) || ... */
70 #endif /* ACE_HAS_WCHAR */
73 ACE_OS::strecpy (char *s
, const char *t
)
75 register char *dscan
= s
;
76 register const char *sscan
= t
;
78 while ((*dscan
++ = *sscan
++) != '\0')
84 #if defined (ACE_HAS_WCHAR)
86 ACE_OS::strecpy (wchar_t *s
, const wchar_t *t
)
88 register wchar_t *dscan
= s
;
89 register const wchar_t *sscan
= t
;
91 while ((*dscan
++ = *sscan
++) != ACE_TEXT_WIDE ('\0'))
96 #endif /* ACE_HAS_WCHAR */
99 ACE_OS::strerror (int errnum
)
101 static char ret_errortext
[128];
103 if (ACE::is_sock_error (errnum
))
105 const ACE_TCHAR
*errortext
= ACE::sock_error (errnum
);
106 ACE_OS::strncpy (ret_errortext
,
107 ACE_TEXT_ALWAYS_CHAR (errortext
),
108 sizeof (ret_errortext
));
109 return ret_errortext
;
111 #if defined (ACE_LACKS_STRERROR)
113 return ACE_OS::strerror_emulation (errnum
);
114 #else /* ACE_LACKS_STRERROR */
115 // Adapt to the various ways that strerror() indicates a bad errnum.
116 // Most modern systems set errno to EINVAL. Some older platforms return
117 // a pointer to a NULL string. This code makes the behavior more consistent
118 // across platforms. On a bad errnum, we make a string with the error number
119 // and set errno to EINVAL.
120 ACE_Errno_Guard
g (errno
);
124 #if defined (ACE_HAS_TR24731_2005_CRT)
125 errmsg
= ret_errortext
;
126 ACE_SECURECRTCALL (strerror_s (ret_errortext
, sizeof(ret_errortext
), errnum
),
129 #elif defined (ACE_WIN32)
130 if (errnum
< 0 || errnum
>= _sys_nerr
)
132 #endif /* ACE_WIN32 */
133 errmsg
= ::strerror (errnum
);
135 if (errno
== EINVAL
|| errmsg
== 0 || errmsg
[0] == 0)
137 ACE_OS::sprintf (ret_errortext
, "Unknown error %d", errnum
);
138 errmsg
= ret_errortext
;
142 #endif /* ACE_LACKS_STRERROR */
145 #if defined (ACE_LACKS_STRERROR)
147 * Just returns "Unknown Error" all the time.
150 ACE_OS::strerror_emulation (int errnum
)
152 return "Unknown Error";
154 #endif /* ACE_LACKS_STRERROR */
157 ACE_OS::strnchr (const char *s
, int c
, size_t len
)
159 for (size_t i
= 0; i
< len
; ++i
)
167 ACE_OS::strnchr (const ACE_WCHAR_T
*s
, ACE_WCHAR_T c
, size_t len
)
169 for (size_t i
= 0; i
< len
; ++i
)
177 ACE_OS::strnstr (const char *s1
, const char *s2
, size_t len2
)
180 size_t const len1
= ACE_OS::strlen (s1
);
182 // Check if the substring is longer than the string being searched.
187 size_t const len
= len1
- len2
;
189 for (size_t i
= 0; i
<= len
; i
++)
191 if (ACE_OS::memcmp (s1
+ i
, s2
, len2
) == 0)
192 // Found a match! Return the index.
200 ACE_OS::strnstr (const ACE_WCHAR_T
*s1
, const ACE_WCHAR_T
*s2
, size_t len2
)
203 const size_t len1
= ACE_OS::strlen (s1
);
205 // Check if the substring is longer than the string being searched.
210 const size_t len
= len1
- len2
;
212 for (size_t i
= 0; i
<= len
; i
++)
214 if (ACE_OS::memcmp (s1
+ i
, s2
, len2
* sizeof (ACE_WCHAR_T
)) == 0)
215 // Found a match! Return the index.
222 #if defined (ACE_HAS_MEMCPY_LOOP_UNROLL)
224 ACE_OS::fast_memcpy (void *t
, const void *s
, size_t len
)
226 unsigned char* to
= static_cast<unsigned char*> (t
) ;
227 const unsigned char* from
= static_cast<const unsigned char*> (s
) ;
228 // Unroll the loop...
231 case 16: to
[15] = from
[15];
232 case 15: to
[14] = from
[14];
233 case 14: to
[13] = from
[13];
234 case 13: to
[12] = from
[12];
235 case 12: to
[11] = from
[11];
236 case 11: to
[10] = from
[10];
237 case 10: to
[9] = from
[9];
238 case 9: to
[8] = from
[8];
239 case 8: to
[7] = from
[7];
240 case 7: to
[6] = from
[6];
241 case 6: to
[5] = from
[5];
242 case 5: to
[4] = from
[4];
243 case 4: to
[3] = from
[3];
244 case 3: to
[2] = from
[2];
245 case 2: to
[1] = from
[1];
246 case 1: to
[0] = from
[0];
248 default: return ::memcpy (t
, s
, len
);
251 #endif /* ACE_HAS_MEMCPY_LOOP_UNROLL */
253 #if defined (ACE_LACKS_STRRCHR)
255 ACE_OS::strrchr_emulation (char *s
, int c
)
257 char *p
= s
+ ACE_OS::strlen (s
);
269 ACE_OS::strrchr_emulation (const char *s
, int c
)
271 const char *p
= s
+ ACE_OS::strlen (s
);
281 #endif /* ACE_LACKS_STRRCHR */
284 ACE_OS::strsncpy (char *dst
, const char *src
, size_t maxlen
)
286 register char *rdst
= dst
;
287 register const char *rsrc
= src
;
288 register size_t rmaxlen
= maxlen
;
296 strncat (rdst
, rsrc
, --rmaxlen
);
300 rdst
+= (rmaxlen
- 1);
308 ACE_OS::strsncpy (ACE_WCHAR_T
*dst
, const ACE_WCHAR_T
*src
, size_t maxlen
)
310 register ACE_WCHAR_T
*rdst
= dst
;
311 register const ACE_WCHAR_T
*rsrc
= src
;
312 register size_t rmaxlen
= maxlen
;
318 *rdst
= ACE_TEXT_WIDE ('\0');
320 strncat (rdst
, rsrc
, --rmaxlen
);
324 rdst
+= (rmaxlen
- 1);
325 *rdst
= ACE_TEXT_WIDE ('\0');
331 #if (!defined (ACE_HAS_REENTRANT_FUNCTIONS) || defined (ACE_LACKS_STRTOK_R)) \
332 && !defined (ACE_HAS_TR24731_2005_CRT)
334 ACE_OS::strtok_r_emulation (char *s
, const char *tokens
, char **lasts
)
340 if (*s
== 0) // We have reached the end
342 size_t l_org
= ACE_OS::strlen (s
);
343 s
= ::strtok (s
, tokens
);
346 const size_t l_sub
= ACE_OS::strlen (s
);
347 if (s
+ l_sub
< *lasts
+ l_org
)
348 *lasts
= s
+ l_sub
+ 1;
353 #endif /* !ACE_HAS_REENTRANT_FUNCTIONS */
355 # if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSTOK)
357 ACE_OS::strtok_r_emulation (ACE_WCHAR_T
*s
,
358 const ACE_WCHAR_T
*tokens
,
361 ACE_WCHAR_T
* sbegin
= s
? s
: *lasts
;
362 sbegin
+= ACE_OS::strspn(sbegin
, tokens
);
365 static ACE_WCHAR_T empty
[1] = { 0 };
369 ACE_WCHAR_T
*send
= sbegin
+ ACE_OS::strcspn(sbegin
, tokens
);
375 # endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSTOK */
377 ACE_END_VERSIONED_NAMESPACE_DECL