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
32 #include "wine/unicode.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ntdll
);
38 /*********************************************************************
41 INT __cdecl
NTDLL__wcsicmp( LPCWSTR str1
, LPCWSTR str2
)
43 return strcmpiW( str1
, str2
);
47 /*********************************************************************
50 LPWSTR __cdecl
NTDLL__wcslwr( LPWSTR str
)
52 return strlwrW( str
);
56 /*********************************************************************
59 INT __cdecl
NTDLL__wcsnicmp( LPCWSTR str1
, LPCWSTR str2
, INT n
)
61 return strncmpiW( str1
, str2
, n
);
65 /*********************************************************************
68 LPWSTR __cdecl
NTDLL__wcsupr( LPWSTR str
)
70 return struprW( str
);
74 /*********************************************************************
77 WCHAR __cdecl
NTDLL_towlower( WCHAR ch
)
83 /*********************************************************************
86 WCHAR __cdecl
NTDLL_towupper( WCHAR ch
)
92 /***********************************************************************
95 LPWSTR __cdecl
NTDLL_wcscat( LPWSTR dst
, LPCWSTR src
)
97 return strcatW( dst
, src
);
101 /*********************************************************************
104 LPWSTR __cdecl
NTDLL_wcschr( LPCWSTR str
, WCHAR ch
)
106 return strchrW( str
, ch
);
110 /*********************************************************************
113 INT __cdecl
NTDLL_wcscmp( LPCWSTR str1
, LPCWSTR str2
)
115 return strcmpW( str1
, str2
);
119 /***********************************************************************
122 LPWSTR __cdecl
NTDLL_wcscpy( LPWSTR dst
, LPCWSTR src
)
124 return strcpyW( dst
, src
);
128 /*********************************************************************
131 INT __cdecl
NTDLL_wcscspn( LPCWSTR str
, LPCWSTR reject
)
137 while (*p
&& (*p
!= *str
)) p
++;
145 /***********************************************************************
148 INT __cdecl
NTDLL_wcslen( LPCWSTR str
)
150 return strlenW( str
);
154 /*********************************************************************
157 LPWSTR __cdecl
NTDLL_wcsncat( LPWSTR s1
, LPCWSTR s2
, INT n
)
161 while (n
-- > 0) if (!(*s1
++ = *s2
++)) return ret
;
167 /*********************************************************************
170 INT __cdecl
NTDLL_wcsncmp( LPCWSTR str1
, LPCWSTR str2
, INT n
)
172 return strncmpW( str1
, str2
, n
);
176 /*********************************************************************
179 LPWSTR __cdecl
NTDLL_wcsncpy( LPWSTR s1
, LPCWSTR s2
, INT n
)
181 return strncpyW( s1
, s2
, n
);
185 /*********************************************************************
188 LPWSTR __cdecl
NTDLL_wcspbrk( LPCWSTR str
, LPCWSTR accept
)
193 for (p
= accept
; *p
; p
++) if (*p
== *str
) return (LPWSTR
)str
;
200 /*********************************************************************
203 LPWSTR __cdecl
NTDLL_wcsrchr( LPWSTR str
, WCHAR ch
)
208 if (*str
== ch
) last
= str
;
215 /*********************************************************************
218 INT __cdecl
NTDLL_wcsspn( LPCWSTR str
, LPCWSTR accept
)
224 while (*p
&& (*p
!= *str
)) p
++;
232 /*********************************************************************
235 LPWSTR __cdecl
NTDLL_wcsstr( LPCWSTR str
, LPCWSTR sub
)
237 return strstrW( str
, sub
);
241 /*********************************************************************
244 LPWSTR __cdecl
NTDLL_wcstok( LPWSTR str
, LPCWSTR delim
)
246 static LPWSTR next
= NULL
;
250 if (!(str
= next
)) return NULL
;
252 while (*str
&& NTDLL_wcschr( delim
, *str
)) str
++;
253 if (!*str
) return NULL
;
255 while (*str
&& !NTDLL_wcschr( delim
, *str
)) str
++;
256 if (*str
) *str
++ = 0;
262 /*********************************************************************
265 INT __cdecl
NTDLL_wcstombs( LPSTR dst
, LPCWSTR src
, INT n
)
271 RtlUnicodeToMultiByteSize( &len
, src
, strlenW(src
)*sizeof(WCHAR
) );
276 if (n
<= 0) return 0;
277 RtlUnicodeToMultiByteN( dst
, n
, &len
, src
, strlenW(src
)*sizeof(WCHAR
) );
278 if (len
< n
) dst
[len
] = 0;
284 /*********************************************************************
287 INT __cdecl
NTDLL_mbstowcs( LPWSTR dst
, LPCSTR src
, INT n
)
293 RtlMultiByteToUnicodeSize( &len
, src
, strlen(src
) );
297 if (n
<= 0) return 0;
298 RtlMultiByteToUnicodeN( dst
, n
*sizeof(WCHAR
), &len
, src
, strlen(src
) );
299 if (len
/ sizeof(WCHAR
) < n
) dst
[len
/ sizeof(WCHAR
)] = 0;
301 return len
/ sizeof(WCHAR
);
305 /*********************************************************************
308 long __cdecl
NTDLL_wcstol(LPCWSTR s
,LPWSTR
*end
,INT base
)
310 return strtolW( s
, end
, base
);
314 /*********************************************************************
317 unsigned long __cdecl
NTDLL_wcstoul(LPCWSTR s
,LPWSTR
*end
,INT base
)
319 return strtoulW( s
, end
, base
);
323 /*********************************************************************
326 INT __cdecl
NTDLL_iswctype( WCHAR wc
, WCHAR wct
)
328 return (get_char_typeW(wc
) & 0xfff) & wct
;
332 /*********************************************************************
335 * Checks if an unicode char wc is a letter
338 * TRUE: The unicode char wc is a letter.
341 INT __cdecl
NTDLL_iswalpha( WCHAR wc
)
347 /*********************************************************************
350 * Checks if an unicode char wc is a digit
353 * TRUE: The unicode char wc is a digit.
356 INT __cdecl
NTDLL_iswdigit( WCHAR wc
)
362 /*********************************************************************
365 * Checks if an unicode char wc is a lower case letter
368 * TRUE: The unicode char wc is a lower case letter.
371 INT __cdecl
NTDLL_iswlower( WCHAR wc
)
377 /*********************************************************************
380 * Checks if an unicode char wc is a white space character
383 * TRUE: The unicode char wc is a white space character.
386 INT __cdecl
NTDLL_iswspace( WCHAR wc
)
392 /*********************************************************************
393 * iswxdigit (NTDLL.@)
395 * Checks if an unicode char wc is an extended digit
398 * TRUE: The unicode char wc is an extended digit.
401 INT __cdecl
NTDLL_iswxdigit( WCHAR wc
)
403 return isxdigitW(wc
);
407 /*********************************************************************
410 * Converts an unsigned long integer to an unicode string.
413 * Always returns str.
416 * Converts value to a '\0' terminated wstring which is copied to str.
417 * The maximum length of the copied str is 33 bytes.
418 * Does not check if radix is in the range of 2 to 36.
419 * If str is NULL it just returns NULL.
421 LPWSTR __cdecl
_ultow(
422 unsigned long value
, /* [I] Value to be converted */
423 LPWSTR str
, /* [O] Destination for the converted value */
424 INT radix
) /* [I] Number base for conversion */
434 digit
= value
% radix
;
435 value
= value
/ radix
;
437 *--pos
= '0' + digit
;
439 *--pos
= 'a' + digit
- 10;
441 } while (value
!= 0L);
444 memcpy(str
, pos
, (&buffer
[32] - pos
+ 1) * sizeof(WCHAR
));
450 /*********************************************************************
453 * Converts a long integer to an unicode string.
456 * Always returns str.
459 * Converts value to a '\0' terminated wstring which is copied to str.
460 * The maximum length of the copied str is 33 bytes. If radix
461 * is 10 and value is negative, the value is converted with sign.
462 * Does not check if radix is in the range of 2 to 36.
463 * If str is NULL it just returns NULL.
465 LPWSTR __cdecl
_ltow(
466 long value
, /* [I] Value to be converted */
467 LPWSTR str
, /* [O] Destination for the converted value */
468 INT radix
) /* [I] Number base for conversion */
476 if (value
< 0 && radix
== 10) {
491 *--pos
= '0' + digit
;
493 *--pos
= 'a' + digit
- 10;
502 memcpy(str
, pos
, (&buffer
[32] - pos
+ 1) * sizeof(WCHAR
));
508 /*********************************************************************
511 * Converts an integer to an unicode string.
514 * Always returns str.
517 * Converts value to a '\0' terminated wstring which is copied to str.
518 * The maximum length of the copied str is 33 bytes. If radix
519 * is 10 and value is negative, the value is converted with sign.
520 * Does not check if radix is in the range of 2 to 36.
521 * If str is NULL it just returns NULL.
524 * - The native function crashes when the string is longer than 19 chars.
525 * This function does not have this bug.
527 LPWSTR __cdecl
_itow(
528 int value
, /* [I] Value to be converted */
529 LPWSTR str
, /* [O] Destination for the converted value */
530 INT radix
) /* [I] Number base for conversion */
532 return _ltow(value
, str
, radix
);
536 /*********************************************************************
539 * Converts a large unsigned integer to an unicode string.
542 * Always returns str.
545 * Converts value to a '\0' terminated wstring which is copied to str.
546 * The maximum length of the copied str is 33 bytes.
547 * Does not check if radix is in the range of 2 to 36.
548 * If str is NULL it just returns NULL.
551 * - This function does not exist in the native DLL (but in msvcrt).
552 * But since the maintenance of all these functions is better done
553 * in one place we implement it here.
555 LPWSTR __cdecl
_ui64tow(
556 ULONGLONG value
, /* [I] Value to be converted */
557 LPWSTR str
, /* [O] Destination for the converted value */
558 INT radix
) /* [I] Number base for conversion */
568 digit
= value
% radix
;
569 value
= value
/ radix
;
571 *--pos
= '0' + digit
;
573 *--pos
= 'a' + digit
- 10;
575 } while (value
!= 0L);
578 memcpy(str
, pos
, (&buffer
[64] - pos
+ 1) * sizeof(WCHAR
));
584 /*********************************************************************
587 * Converts a large integer to an unicode string.
590 * Always returns str.
593 * Converts value to a '\0' terminated wstring which is copied to str.
594 * The maximum length of the copied str is 33 bytes. If radix
595 * is 10 and value is negative, the value is converted with sign.
596 * Does not check if radix is in the range of 2 to 36.
597 * If str is NULL it just returns NULL.
600 * - The native DLL converts negative values (for base 10) wrong:
601 * -1 is converted to -18446744073709551615
602 * -2 is converted to -18446744073709551614
603 * -9223372036854775807 is converted to -9223372036854775809
604 * -9223372036854775808 is converted to -9223372036854775808
605 * The native msvcrt _i64tow function and our ntdll function do
608 LPWSTR __cdecl
_i64tow(
609 LONGLONG value
, /* [I] Value to be converted */
610 LPWSTR str
, /* [O] Destination for the converted value */
611 INT radix
) /* [I] Number base for conversion */
619 if (value
< 0 && radix
== 10) {
634 *--pos
= '0' + digit
;
636 *--pos
= 'a' + digit
- 10;
645 memcpy(str
, pos
, (&buffer
[64] - pos
+ 1) * sizeof(WCHAR
));
651 /*********************************************************************
654 * Converts an unicode string to a long integer.
657 * str [I] Wstring to be converted
660 * On success it returns the integer value otherwise it returns 0.
663 * Accepts: {whitespace} [+|-] {digits}
664 * No check is made for value overflow, only the lower 32 bits are assigned.
665 * If str is NULL it crashes, as the native function does.
667 LONG __cdecl
_wtol( LPWSTR str
)
669 ULONG RunningTotal
= 0;
672 while (isspaceW(*str
)) {
678 } else if (*str
== '-') {
683 while (*str
>= '0' && *str
<= '9') {
684 RunningTotal
= RunningTotal
* 10 + *str
- '0';
688 return bMinus
? -RunningTotal
: RunningTotal
;
692 /*********************************************************************
695 * Converts an unicode string to an integer.
698 * str [I] Wstring to be converted
701 * On success it returns the integer value otherwise it returns 0.
704 * Accepts: {whitespace} [+|-] {digits}
705 * No check is made for value overflow, only the lower 32 bits are assigned.
706 * If str is NULL it crashes, as the native function does.
708 int __cdecl
_wtoi( LPWSTR str
)
714 /*********************************************************************
717 * Converts an unicode string to a large integer.
720 * str [I] Wstring to be converted
723 * On success it returns the integer value otherwise it returns 0.
726 * Accepts: {whitespace} [+|-] {digits}
727 * No check is made for value overflow, only the lower 64 bits are assigned.
728 * If str is NULL it crashes, as the native function does.
730 LONGLONG __cdecl
_wtoi64( LPWSTR str
)
732 ULONGLONG RunningTotal
= 0;
735 while (isspaceW(*str
)) {
741 } else if (*str
== '-') {
746 while (*str
>= '0' && *str
<= '9') {
747 RunningTotal
= RunningTotal
* 10 + *str
- '0';
751 return bMinus
? -RunningTotal
: RunningTotal
;
755 /***********************************************************************
756 * _snwprintf (NTDLL.@)
758 int __cdecl
_snwprintf(WCHAR
*str
, unsigned int len
, const WCHAR
*format
, ...)
762 va_start(valist
, format
);
763 retval
= vsnprintfW(str
, len
, format
, valist
);
769 /***********************************************************************
772 int __cdecl
NTDLL_swprintf(WCHAR
*str
, const WCHAR
*format
, ...)
776 va_start(valist
, format
);
777 retval
= vsnprintfW(str
, INT_MAX
, format
, valist
);