2 * NTDLL wide-char functions
4 * Copyright 2000 Alexandre Julliard
5 * Copyright 2000 Jon Griffiths
6 * Copyright 2003 Thomas Mertes
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include "wine/unicode.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
40 /*********************************************************************
43 INT __cdecl NTDLL__wcsicmp( LPCWSTR str1, LPCWSTR str2 )
45 return strcmpiW( str1, str2 );
49 /*********************************************************************
52 LPWSTR __cdecl NTDLL__wcslwr( LPWSTR str )
54 return strlwrW( str );
58 /*********************************************************************
61 INT __cdecl NTDLL__wcsnicmp( LPCWSTR str1, LPCWSTR str2, INT n )
63 return strncmpiW( str1, str2, n );
67 /*********************************************************************
70 LPWSTR __cdecl NTDLL__wcsupr( LPWSTR str )
72 return struprW( str );
76 /*********************************************************************
79 WCHAR __cdecl NTDLL_towlower( WCHAR ch )
85 /*********************************************************************
88 WCHAR __cdecl NTDLL_towupper( WCHAR ch )
94 /***********************************************************************
97 LPWSTR __cdecl NTDLL_wcscat( LPWSTR dst, LPCWSTR src )
99 return strcatW( dst, src );
103 /*********************************************************************
106 LPWSTR __cdecl NTDLL_wcschr( LPCWSTR str, WCHAR ch )
108 return strchrW( str, ch );
112 /*********************************************************************
115 INT __cdecl NTDLL_wcscmp( LPCWSTR str1, LPCWSTR str2 )
117 return strcmpW( str1, str2 );
121 /***********************************************************************
124 LPWSTR __cdecl NTDLL_wcscpy( LPWSTR dst, LPCWSTR src )
126 return strcpyW( dst, src );
130 /*********************************************************************
133 INT __cdecl NTDLL_wcscspn( LPCWSTR str, LPCWSTR reject )
135 return strcspnW( str, reject );
139 /***********************************************************************
142 INT __cdecl NTDLL_wcslen( LPCWSTR str )
144 return strlenW( str );
148 /*********************************************************************
151 LPWSTR __cdecl NTDLL_wcsncat( LPWSTR s1, LPCWSTR s2, INT n )
155 while (n-- > 0) if (!(*s1++ = *s2++)) return ret;
161 /*********************************************************************
164 INT __cdecl NTDLL_wcsncmp( LPCWSTR str1, LPCWSTR str2, INT n )
166 return strncmpW( str1, str2, n );
170 /*********************************************************************
173 LPWSTR __cdecl NTDLL_wcsncpy( LPWSTR s1, LPCWSTR s2, INT n )
176 while (n-- > 0) if (!(*s1++ = *s2++)) break;
177 while (n-- > 0) *s1++ = 0;
182 /*********************************************************************
185 LPWSTR __cdecl NTDLL_wcspbrk( LPCWSTR str, LPCWSTR accept )
187 return strpbrkW( str, accept );
191 /*********************************************************************
194 LPWSTR __cdecl NTDLL_wcsrchr( LPWSTR str, WCHAR ch )
196 return strrchrW( str, ch );
200 /*********************************************************************
203 INT __cdecl NTDLL_wcsspn( LPCWSTR str, LPCWSTR accept )
205 return strspnW( str, accept );
209 /*********************************************************************
212 LPWSTR __cdecl NTDLL_wcsstr( LPCWSTR str, LPCWSTR sub )
214 return strstrW( str, sub );
218 /*********************************************************************
221 LPWSTR __cdecl NTDLL_wcstok( LPWSTR str, LPCWSTR delim )
223 static LPWSTR next = NULL;
227 if (!(str = next)) return NULL;
229 while (*str && NTDLL_wcschr( delim, *str )) str++;
230 if (!*str) return NULL;
232 while (*str && !NTDLL_wcschr( delim, *str )) str++;
233 if (*str) *str++ = 0;
239 /*********************************************************************
242 INT __cdecl NTDLL_wcstombs( LPSTR dst, LPCWSTR src, INT n )
248 RtlUnicodeToMultiByteSize( &len, src, strlenW(src)*sizeof(WCHAR) );
253 if (n <= 0) return 0;
254 RtlUnicodeToMultiByteN( dst, n, &len, src, strlenW(src)*sizeof(WCHAR) );
255 if (len < n) dst[len] = 0;
261 /*********************************************************************
264 INT __cdecl NTDLL_mbstowcs( LPWSTR dst, LPCSTR src, INT n )
270 RtlMultiByteToUnicodeSize( &len, src, strlen(src) );
274 if (n <= 0) return 0;
275 RtlMultiByteToUnicodeN( dst, n*sizeof(WCHAR), &len, src, strlen(src) );
276 if (len / sizeof(WCHAR) < n) dst[len / sizeof(WCHAR)] = 0;
278 return len / sizeof(WCHAR);
282 /*********************************************************************
285 long __cdecl NTDLL_wcstol(LPCWSTR s,LPWSTR *end,INT base)
287 return strtolW( s, end, base );
291 /*********************************************************************
294 unsigned long __cdecl NTDLL_wcstoul(LPCWSTR s,LPWSTR *end,INT base)
296 return strtoulW( s, end, base );
300 /*********************************************************************
303 INT __cdecl NTDLL_iswctype( WCHAR wc, WCHAR wct )
305 return (get_char_typeW(wc) & 0xfff) & wct;
309 /*********************************************************************
312 * Checks if an unicode char wc is a letter
315 * TRUE: The unicode char wc is a letter.
318 INT __cdecl NTDLL_iswalpha( WCHAR wc )
324 /*********************************************************************
327 * Checks if an unicode char wc is a digit
330 * TRUE: The unicode char wc is a digit.
333 INT __cdecl NTDLL_iswdigit( WCHAR wc )
339 /*********************************************************************
342 * Checks if an unicode char wc is a lower case letter
345 * TRUE: The unicode char wc is a lower case letter.
348 INT __cdecl NTDLL_iswlower( WCHAR wc )
354 /*********************************************************************
357 * Checks if an unicode char wc is a white space character
360 * TRUE: The unicode char wc is a white space character.
363 INT __cdecl NTDLL_iswspace( WCHAR wc )
369 /*********************************************************************
370 * iswxdigit (NTDLL.@)
372 * Checks if an unicode char wc is an extended digit
375 * TRUE: The unicode char wc is an extended digit.
378 INT __cdecl NTDLL_iswxdigit( WCHAR wc )
380 return isxdigitW(wc);
384 /*********************************************************************
387 * Converts an unsigned long integer to an unicode string.
390 * Always returns str.
393 * Converts value to a '\0' terminated wstring which is copied to str.
394 * The maximum length of the copied str is 33 bytes.
395 * Does not check if radix is in the range of 2 to 36.
396 * If str is NULL it just returns NULL.
398 LPWSTR __cdecl _ultow(
399 unsigned long value, /* [I] Value to be converted */
400 LPWSTR str, /* [O] Destination for the converted value */
401 INT radix) /* [I] Number base for conversion */
411 digit = value % radix;
412 value = value / radix;
414 *--pos = '0' + digit;
416 *--pos = 'a' + digit - 10;
418 } while (value != 0L);
421 memcpy(str, pos, (&buffer[32] - pos + 1) * sizeof(WCHAR));
427 /*********************************************************************
430 * Converts a long integer to an unicode string.
433 * Always returns str.
436 * Converts value to a '\0' terminated wstring which is copied to str.
437 * The maximum length of the copied str is 33 bytes. If radix
438 * is 10 and value is negative, the value is converted with sign.
439 * Does not check if radix is in the range of 2 to 36.
440 * If str is NULL it just returns NULL.
442 LPWSTR __cdecl _ltow(
443 long value, /* [I] Value to be converted */
444 LPWSTR str, /* [O] Destination for the converted value */
445 INT radix) /* [I] Number base for conversion */
453 if (value < 0 && radix == 10) {
468 *--pos = '0' + digit;
470 *--pos = 'a' + digit - 10;
479 memcpy(str, pos, (&buffer[32] - pos + 1) * sizeof(WCHAR));
485 /*********************************************************************
488 * Converts an integer to an unicode string.
491 * Always returns str.
494 * Converts value to a '\0' terminated wstring which is copied to str.
495 * The maximum length of the copied str is 33 bytes. If radix
496 * is 10 and value is negative, the value is converted with sign.
497 * Does not check if radix is in the range of 2 to 36.
498 * If str is NULL it just returns NULL.
501 * - The native function crashes when the string is longer than 19 chars.
502 * This function does not have this bug.
504 LPWSTR __cdecl _itow(
505 int value, /* [I] Value to be converted */
506 LPWSTR str, /* [O] Destination for the converted value */
507 INT radix) /* [I] Number base for conversion */
509 return _ltow(value, str, radix);
513 /*********************************************************************
516 * Converts a large unsigned integer to an unicode string.
519 * Always returns str.
522 * Converts value to a '\0' terminated wstring which is copied to str.
523 * The maximum length of the copied str is 33 bytes.
524 * Does not check if radix is in the range of 2 to 36.
525 * If str is NULL it just returns NULL.
528 * - This function does not exist in the native DLL (but in msvcrt).
529 * But since the maintenance of all these functions is better done
530 * in one place we implement it here.
532 LPWSTR __cdecl _ui64tow(
533 ULONGLONG value, /* [I] Value to be converted */
534 LPWSTR str, /* [O] Destination for the converted value */
535 INT radix) /* [I] Number base for conversion */
545 digit = value % radix;
546 value = value / radix;
548 *--pos = '0' + digit;
550 *--pos = 'a' + digit - 10;
552 } while (value != 0L);
555 memcpy(str, pos, (&buffer[64] - pos + 1) * sizeof(WCHAR));
561 /*********************************************************************
564 * Converts a large integer to an unicode string.
567 * Always returns str.
570 * Converts value to a '\0' terminated wstring which is copied to str.
571 * The maximum length of the copied str is 33 bytes. If radix
572 * is 10 and value is negative, the value is converted with sign.
573 * Does not check if radix is in the range of 2 to 36.
574 * If str is NULL it just returns NULL.
577 * - The native DLL converts negative values (for base 10) wrong:
578 * -1 is converted to -18446744073709551615
579 * -2 is converted to -18446744073709551614
580 * -9223372036854775807 is converted to -9223372036854775809
581 * -9223372036854775808 is converted to -9223372036854775808
582 * The native msvcrt _i64tow function and our ntdll function do
585 LPWSTR __cdecl _i64tow(
586 LONGLONG value, /* [I] Value to be converted */
587 LPWSTR str, /* [O] Destination for the converted value */
588 INT radix) /* [I] Number base for conversion */
596 if (value < 0 && radix == 10) {
611 *--pos = '0' + digit;
613 *--pos = 'a' + digit - 10;
622 memcpy(str, pos, (&buffer[64] - pos + 1) * sizeof(WCHAR));
628 /*********************************************************************
631 * Converts an unicode string to a long integer.
634 * str [I] Wstring to be converted
637 * On success it returns the integer value otherwise it returns 0.
640 * Accepts: {whitespace} [+|-] {digits}
641 * No check is made for value overflow, only the lower 32 bits are assigned.
642 * If str is NULL it crashes, as the native function does.
644 LONG __cdecl _wtol( LPCWSTR str )
646 ULONG RunningTotal = 0;
649 while (isspaceW(*str)) {
655 } else if (*str == '-') {
660 while (*str >= '0' && *str <= '9') {
661 RunningTotal = RunningTotal * 10 + *str - '0';
665 return bMinus ? -RunningTotal : RunningTotal;
669 /*********************************************************************
672 * Converts an unicode string to an integer.
675 * str [I] Wstring to be converted
678 * On success it returns the integer value otherwise it returns 0.
681 * Accepts: {whitespace} [+|-] {digits}
682 * No check is made for value overflow, only the lower 32 bits are assigned.
683 * If str is NULL it crashes, as the native function does.
685 int __cdecl _wtoi( LPCWSTR str )
691 /*********************************************************************
694 * Converts an unicode string to a large integer.
697 * str [I] Wstring to be converted
700 * On success it returns the integer value otherwise it returns 0.
703 * Accepts: {whitespace} [+|-] {digits}
704 * No check is made for value overflow, only the lower 64 bits are assigned.
705 * If str is NULL it crashes, as the native function does.
707 LONGLONG __cdecl _wtoi64( LPCWSTR str )
709 ULONGLONG RunningTotal = 0;
712 while (isspaceW(*str)) {
718 } else if (*str == '-') {
723 while (*str >= '0' && *str <= '9') {
724 RunningTotal = RunningTotal * 10 + *str - '0';
728 return bMinus ? -RunningTotal : RunningTotal;
732 /***********************************************************************
733 * _snwprintf (NTDLL.@)
735 int __cdecl _snwprintf(WCHAR *str, unsigned int len, const WCHAR *format, ...)
739 va_start(valist, format);
740 retval = vsnprintfW(str, len, format, valist);
746 /***********************************************************************
749 int __cdecl NTDLL_swprintf(WCHAR *str, const WCHAR *format, ...)
753 va_start(valist, format);
754 retval = vsnprintfW(str, INT_MAX, format, valist);