Commit c83aa0d3 authored by Thomas Mertes's avatar Thomas Mertes Committed by Alexandre Julliard

- Implement RtlDowncaseUnicodeString, RtlUniform, iswdigit, iswlower,

iswspace, iswxdigit. - Fixed RtlInt64ToUnicodeString and RtlIntegerToUnicodeString. - According to tests RtlAppendUnicodeStringToString leaves the destination unchanged when the source length is 0 (FIXED). - Documentation updates in RtlExtendedMagicDivide, RtlLargeIntegerToChar, RtlInt64ToUnicodeString, RtlUpperChar, RtlUpperString, RtlUpcaseUnicodeChar, RtlCharToInteger, RtlIntegerToChar, RtlUnicodeStringToInteger, RtlIntegerToUnicodeString, _ultoa, _ltoa, _itoa, _ui64toa, _i64toa, _atoi64, _ultow, _ltow, _itow, _ui64tow, _i64tow, _wtol, _wtoi, _wtoi64.
parent 6a26e3f7
......@@ -185,21 +185,25 @@ LONGLONG WINAPI RtlExtendedIntegerMultiply( LONGLONG a, INT b )
*
* This function computes (a * b) >> (64 + shift)
*
* This allows replacing a division by a longlong constant
* by a multiplication by the inverse constant.
* RETURNS
* (a * b) >> (64 + shift)
*
* If 'c' is the constant divisor, the constants 'b' and 'shift'
* must be chosen such that b = 2^(64+shift) / c.
* Then we have RtlExtendedMagicDivide(a,b,shift) == a * b / 2^(64+shift) == a / c.
* NOTES
* This allows replacing a division by a longlong constant
* by a multiplication by the inverse constant.
*
* Parameter b although defined as LONGLONG is used as ULONGLONG.
* If 'c' is the constant divisor, the constants 'b' and 'shift'
* must be chosen such that b = 2^(64+shift) / c.
* Then we have RtlExtendedMagicDivide(a,b,shift) == a * b / 2^(64+shift) == a / c.
*
* The Parameter b although defined as LONGLONG is used as ULONGLONG.
*/
#define LOWER_32(A) ((A) & 0xffffffff)
#define UPPER_32(A) ((A) >> 32)
LONGLONG WINAPI RtlExtendedMagicDivide(
LONGLONG a,
LONGLONG b,
INT shift)
LONGLONG a, /* [I] Dividend to be divided by the constant divisor */
LONGLONG b, /* [I] Constant computed manually as 2^(64+shift) / divisor */
INT shift) /* [I] Constant shift chosen to make b as big as possible for 64 bits */
{
ULONGLONG a_high;
ULONGLONG a_low;
......@@ -243,25 +247,29 @@ LONGLONG WINAPI RtlExtendedMagicDivide(
*
* Convert an unsigned large integer to a character string.
*
* On success assign a string and return STATUS_SUCCESS.
* If base is not 0 (=10), 2, 8, 10 or 16 return STATUS_INVALID_PARAMETER
* Writes at most length characters to the string str.
* Str is '\0' terminated when length allowes it.
* When str fits exactly in length characters the '\0' is ommitted.
* When str would be larger than length: return STATUS_BUFFER_OVERFLOW
* For str == NULL return STATUS_ACCESS_VIOLATION.
* Do not check for value_ptr != NULL (as native DLL).
* RETURNS
* Success: STATUS_SUCCESS. str contains the converted number
* Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
* STATUS_BUFFER_OVERFLOW, if str would be larger than length.
* STATUS_ACCESS_VIOLATION, if str is NULL.
*
* NOTES
* Instead of base 0 it uses 10 as base.
* Writes at most length characters to the string str.
* Str is '\0' terminated when length allowes it.
* When str fits exactly in length characters the '\0' is ommitted.
* If value_ptr is NULL it crashes, as the native function does.
*
* Difference:
* - Accept base 0 as 10 instead of crashing as native DLL does.
* - The native DLL does produce garbage or STATUS_BUFFER_OVERFLOW for
* DIFFERENCES
* - Accept base 0 as 10 instead of crashing as native function does.
* - The native function does produce garbage or STATUS_BUFFER_OVERFLOW for
* base 2, 8 and 16 when the value is larger than 0xFFFFFFFF.
*/
NTSTATUS WINAPI RtlLargeIntegerToChar(
const ULONGLONG *value_ptr,
ULONG base,
ULONG length,
PCHAR str)
const ULONGLONG *value_ptr, /* [I] Pointer to the value to be converted */
ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
ULONG length, /* [I] Length of the str buffer in bytes */
PCHAR str) /* [O] Destination for the converted value */
{
ULONGLONG value = *value_ptr;
CHAR buffer[65];
......@@ -306,27 +314,32 @@ NTSTATUS WINAPI RtlLargeIntegerToChar(
/**************************************************************************
* RtlInt64ToUnicodeString (NTDLL.@)
*
* Convert a large unsigned integer to a NULL terminated unicode string.
* Convert a large unsigned integer to a '\0' terminated unicode string.
*
* RETURNS
* Success: STATUS_SUCCESS. str contains the converted number
* Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
* STATUS_BUFFER_OVERFLOW, if str is too small to hold the string
* (with the '\0' termination). In this case str->Length
* is set to the length, the string would have (which can
* be larger than the MaximumLength).
*
* On success assign a NULL terminated string and return STATUS_SUCCESS.
* If base is not 0 (=10), 2, 8, 10 or 16 return STATUS_INVALID_PARAMETER.
* If str is too small to hold the string (with the NULL termination):
* Set str->Length to the length the string would have (which can be
* larger than the MaximumLength) and return STATUS_BUFFER_OVERFLOW.
* Do not check for str != NULL (as native DLL).
* NOTES
* Instead of base 0 it uses 10 as base.
* If str is NULL it crashes, as the native function does.
*
* Difference:
* - Accept base 0 as 10 instead of crashing as native DLL does.
* DIFFERENCES
* - Accept base 0 as 10 instead of crashing as native function does.
* - Do not return STATUS_BUFFER_OVERFLOW when the string is long enough.
* The native DLL does this when the string would be longer than 31
* The native function does this when the string would be longer than 31
* characters even when the string parameter is long enough.
* - The native DLL does produce garbage or STATUS_BUFFER_OVERFLOW for
* - The native function does produce garbage or STATUS_BUFFER_OVERFLOW for
* base 2, 8 and 16 when the value is larger than 0xFFFFFFFF.
*/
NTSTATUS WINAPI RtlInt64ToUnicodeString(
ULONGLONG value,
ULONG base,
UNICODE_STRING *str)
ULONGLONG value, /* [I] Value to be converted */
ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
UNICODE_STRING *str) /* [O] Destination for the converted value */
{
WCHAR buffer[65];
PWCHAR pos;
......@@ -356,7 +369,7 @@ NTSTATUS WINAPI RtlInt64ToUnicodeString(
if (str->Length >= str->MaximumLength) {
return STATUS_BUFFER_OVERFLOW;
} else {
memcpy(str->Buffer, pos, str->Length + 1);
memcpy(str->Buffer, pos, str->Length + sizeof(WCHAR));
} /* if */
return STATUS_SUCCESS;
}
......
......@@ -351,6 +351,7 @@
@ stdcall RtlDosPathNameToNtPathName_U(ptr ptr long long)
@ stub RtlDosSearchPath_U
@ stdcall RtlDowncaseUnicodeChar(long)
@ stdcall RtlDowncaseUnicodeString(ptr ptr long)
@ stdcall RtlDumpResource(ptr)
@ stdcall -ret64 RtlEnlargedIntegerMultiply(long long)
@ stdcall RtlEnlargedUnsignedDivide(long long long ptr)
......@@ -544,7 +545,7 @@
@ stdcall RtlUnicodeToMultiByteN(ptr long ptr ptr long)
@ stdcall RtlUnicodeToMultiByteSize(ptr wstr long)
@ stdcall RtlUnicodeToOemN(ptr long ptr ptr long)
@ stub RtlUniform
@ stdcall RtlUniform(ptr)
@ stdcall RtlUnlockHeap(long)
@ stdcall RtlUnwind(ptr ptr ptr long)
@ stdcall RtlUpcaseUnicodeChar(long)
......@@ -946,6 +947,10 @@
@ cdecl isupper(long)
@ cdecl iswalpha(long) NTDLL_iswalpha
@ cdecl iswctype(long long) NTDLL_iswctype
@ cdecl iswdigit(long) NTDLL_iswdigit
@ cdecl iswlower(long) NTDLL_iswlower
@ cdecl iswspace(long) NTDLL_iswspace
@ cdecl iswxdigit(long) NTDLL_iswxdigit
@ cdecl isxdigit(long)
@ cdecl labs(long)
@ cdecl log(double)
......
......@@ -4,7 +4,8 @@
* This file contains the Rtl* API functions. These should be implementable.
*
* Copyright 1996-1998 Marcus Meissner
* 1999 Alex Korobka
* Copyright 1999 Alex Korobka
* Copyright 2003 Thomas Mertes
* Crc32 code Copyright 1986 Gary S. Brown (Public domain)
*
* This library is free software; you can redistribute it and/or
......@@ -729,3 +730,40 @@ __ASM_GLOBAL_FUNC(NTDLL_RtlUshortByteSwap,
"movb %cl,%ah\n\t"
"ret");
#endif
/*************************************************************************
* RtlUniform [NTDLL.@]
*
* Generates an uniform random number
*
* PARAMS
* seed [O] The seed of the Random function
*
* RETURNS
* It returns a random number uniformly distributed over [0..MAXLONG].
*
* NOTES
* Generates an uniform random number using a modified version of
* D.H. Lehmer's 1948 algorithm. The original algorithm would be:
*
* result = *seed * 0xffffffed + 0x7fffffc3;
* *seed = result;
*/
ULONG WINAPI RtlUniform (PULONG seed)
{
ULONG result;
result = *seed * 0xffffffed + 0x7fffffc3;
if (result == 0xffffffff || result == 0x7ffffffe) {
result = (result + 2) & MAXLONG;
} else if (result == 0x7fffffff) {
result = (result + 1) & MAXLONG;
} else if ((result & 0x80000000) == 0) {
result = result + (~result & 1);
} else {
result = (result + (result & 1)) & MAXLONG;
} /* if */
*seed = result;
return result;
}
......@@ -383,6 +383,7 @@ NTSTATUS WINAPI RtlEqualComputerName(const UNICODE_STRING *left,
return ret;
}
/**************************************************************************
* RtlEqualDomainName (NTDLL.@)
*
......@@ -404,6 +405,7 @@ NTSTATUS WINAPI RtlEqualDomainName(const UNICODE_STRING *left,
return RtlEqualComputerName(left, right);
}
/*
COPY BETWEEN ANSI_STRING or UNICODE_STRING
there is no parameter checking, it just crashes
......@@ -504,7 +506,7 @@ NTSTATUS WINAPI RtlUnicodeStringToAnsiString( STRING *ansi,
/**************************************************************************
* RtlUnicodeStringToOemString (NTDLL.@)
*
* Convert a Rtl Unicode string to an OEM string.
* Converts a Rtl Unicode string to an OEM string.
*
* PARAMS
* oem [O] Destination for OEM string
......@@ -613,13 +615,18 @@ NTSTATUS WINAPI RtlUnicodeToOemN( LPSTR dst, DWORD dstlen, LPDWORD reslen,
/**************************************************************************
* RtlUpperChar (NTDLL.@)
*
* Convert an Ascii character to uppercase.
* Converts an Ascii character to uppercase.
*
* PARAMS
* ch [I] Character to convert
*
* RETURNS
* The uppercase character value.
*
* NOTES
* For the input characters from 'a' .. 'z' it returns 'A' .. 'Z'.
* All other input characters are returned unchanged. The locale and
* multibyte characters are not taken into account (as native DLL).
*/
CHAR WINAPI RtlUpperChar( CHAR ch )
{
......@@ -627,14 +634,14 @@ CHAR WINAPI RtlUpperChar( CHAR ch )
return ch - 'a' + 'A';
} else {
return ch;
}
} /* if */
}
/**************************************************************************
* RtlUpperString (NTDLL.@)
*
* Convert an Ascii string to uppercase.
* Converts an Ascii string to uppercase.
*
* PARAMS
* dst [O] Destination for converted string
......@@ -642,6 +649,13 @@ CHAR WINAPI RtlUpperChar( CHAR ch )
*
* RETURNS
* Nothing.
*
* NOTES
* For the src characters from 'a' .. 'z' it assigns 'A' .. 'Z' to dst.
* All other src characters are copied unchanged to dst. The locale and
* multibyte characters are not taken into account (as native DLL).
* The number of character copied is the minimum of src->Length and
* the dst->MaximumLength.
*/
void WINAPI RtlUpperString( STRING *dst, const STRING *src )
{
......@@ -655,17 +669,24 @@ void WINAPI RtlUpperString( STRING *dst, const STRING *src )
/**************************************************************************
* RtlUpcaseUnicodeChar (NTDLL.@)
*
* Unicode version of of RtlUpperChar.
* Converts an Unicode character to uppercase.
*
* PARAMS
* wch [I] Character to convert
*
* RETURNS
* The uppercase character value.
*/
WCHAR WINAPI RtlUpcaseUnicodeChar( WCHAR wch )
{
return toupperW(wch);
}
/**************************************************************************
* RtlDowncaseUnicodeChar (NTDLL.@)
*
* Convert a Unicode character to lowercase.
* Converts an Unicode character to lowercase.
*
* PARAMS
* wch [I] Character to convert
......@@ -678,10 +699,11 @@ WCHAR WINAPI RtlDowncaseUnicodeChar(WCHAR wch)
return tolowerW(wch);
}
/**************************************************************************
* RtlUpcaseUnicodeString (NTDLL.@)
*
* Convert a Unicode string to uppercase.
* Converts an Unicode string to uppercase.
*
* PARAMS
* dest [O] Destination for converted string
......@@ -718,6 +740,50 @@ NTSTATUS WINAPI RtlUpcaseUnicodeString( UNICODE_STRING *dest,
/**************************************************************************
* RtlDowncaseUnicodeString (NTDLL.@)
*
* Converts an Unicode string to lowercase.
*
* PARAMS
* dest [O] Destination for converted string
* src [I] Source string to convert
* doalloc [I] TRUE=Allocate a buffer for dest if it doesn't have one
*
* RETURNS
* Success: STATUS_SUCCESS. dest contains the converted string.
* Failure: STATUS_NO_MEMORY, if doalloc is TRUE and memory allocation fails, or
* STATUS_BUFFER_OVERFLOW, if doalloc is FALSE and dest is too small.
*
* NOTES
* dest is never NUL terminated because it may be equal to src, and src
* might not be NUL terminated. dest->Length is only set upon success.
*/
NTSTATUS WINAPI RtlDowncaseUnicodeString(
UNICODE_STRING *dest,
const UNICODE_STRING *src,
BOOLEAN doalloc)
{
DWORD i;
DWORD len = src->Length;
if (doalloc) {
dest->MaximumLength = len;
if (!(dest->Buffer = RtlAllocateHeap( ntdll_get_process_heap(), 0, len ))) {
return STATUS_NO_MEMORY;
} /* if */
} else if (len > dest->MaximumLength) {
return STATUS_BUFFER_OVERFLOW;
} /* if */
for (i = 0; i < len/sizeof(WCHAR); i++) {
dest->Buffer[i] = tolowerW(src->Buffer[i]);
} /* for */
dest->Length = len;
return STATUS_SUCCESS;
}
/**************************************************************************
* RtlUpcaseUnicodeStringToAnsiString (NTDLL.@)
*
* NOTES
......@@ -867,7 +933,7 @@ NTSTATUS WINAPI RtlMultiByteToUnicodeSize( DWORD *size, LPCSTR str, UINT len )
/**************************************************************************
* RtlUnicodeToMultiByteSize (NTDLL.@)
*
* Calculate the size necessary for the multibyte conversion of str,
* Calculate the size in bytes necessary for the multibyte conversion of str,
* without the terminating NULL.
*
* PARAMS
......@@ -981,6 +1047,7 @@ NTSTATUS WINAPI RtlAppendUnicodeToString( UNICODE_STRING *dst, LPCWSTR src )
NTSTATUS WINAPI RtlAppendUnicodeStringToString( UNICODE_STRING *dst, const UNICODE_STRING *src )
{
unsigned int len = src->Length + dst->Length;
if (src->Length == 0) return STATUS_SUCCESS;
if (len > dst->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
memcpy( dst->Buffer + dst->Length/sizeof(WCHAR), src->Buffer, src->Length );
dst->Length = len;
......@@ -994,6 +1061,7 @@ NTSTATUS WINAPI RtlAppendUnicodeStringToString( UNICODE_STRING *dst, const UNICO
MISC
*/
/**************************************************************************
* RtlIsTextUnicode (NTDLL.@)
*
......@@ -1053,23 +1121,28 @@ out:
/**************************************************************************
* RtlCharToInteger (NTDLL.@)
*
* Convert a character string into its integer equivalent.
* Converts a character string into its integer equivalent.
*
* On success assign an integer value and return STATUS_SUCCESS.
* For base 0 accept: {whitespace} [+|-] [0[x|o|b]] {digits}
* For bases 2, 8, 10 and 16 accept: {whitespace} [+|-] {digits}
* For other bases return STATUS_INVALID_PARAMETER.
* For value == NULL return STATUS_ACCESS_VIOLATION.
* No check of value overflow: Just assign lower 32 bits (as native DLL).
* Do not check for str != NULL (as native DLL).
* RETURNS
* Success: STATUS_SUCCESS. value contains the converted number
* Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
* STATUS_ACCESS_VIOLATION, if value is NULL.
*
* Difference:
* - Do not read garbage behind '\0' as native DLL does.
* NOTES
* For base 0 it uses 10 as base and the string should be in the format
* "{whitespace} [+|-] [0[x|o|b]] {digits}".
* For other bases the string should be in the format
* "{whitespace} [+|-] {digits}".
* No check is made for value overflow, only the lower 32 bits are assigned.
* If str is NULL it crashes, as the native function does.
*
* DIFFERENCES
* This function does not read garbage behind '\0' as the native version does.
*/
NTSTATUS WINAPI RtlCharToInteger(
PCSZ str,
ULONG base,
ULONG *value)
PCSZ str, /* [I] '\0' terminated single-byte string containing a number */
ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
ULONG *value) /* [O] Destination for the converted value */
{
CHAR chCurrent;
int digit;
......@@ -1137,22 +1210,25 @@ NTSTATUS WINAPI RtlCharToInteger(
/**************************************************************************
* RtlIntegerToChar (NTDLL.@)
*
* Convert an unsigned integer to a character string.
* Converts an unsigned integer to a character string.
*
* RETURNS
* Success: STATUS_SUCCESS. str contains the converted number
* Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
* STATUS_BUFFER_OVERFLOW, if str would be larger than length.
* STATUS_ACCESS_VIOLATION, if str is NULL.
*
* NOTES
* On success assign a string and return STATUS_SUCCESS.
* If base is not 0 (=10), 2, 8, 10 or 16 return STATUS_INVALID_PARAMETER
* Writes at most length characters to the string str.
* Str is '\0' terminated when length allowes it.
* When str fits exactly in length characters the '\0' is ommitted.
* When str would be larger than length: return STATUS_BUFFER_OVERFLOW
* For str == NULL return STATUS_ACCESS_VIOLATION.
* Instead of base 0 it uses 10 as base.
* Writes at most length characters to the string str.
* Str is '\0' terminated when length allowes it.
* When str fits exactly in length characters the '\0' is ommitted.
*/
NTSTATUS WINAPI RtlIntegerToChar(
ULONG value,
ULONG base,
ULONG length,
PCHAR str)
ULONG value, /* [I] Value to be converted */
ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
ULONG length, /* [I] Length of the str buffer in bytes */
PCHAR str) /* [O] Destination for the converted value */
{
CHAR buffer[33];
PCHAR pos;
......@@ -1196,24 +1272,29 @@ NTSTATUS WINAPI RtlIntegerToChar(
/**************************************************************************
* RtlUnicodeStringToInteger (NTDLL.@)
*
* Convert an unicode string into its integer equivalent.
* Converts an unicode string into its integer equivalent.
*
* RETURNS
* Success: STATUS_SUCCESS. value contains the converted number
* Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
* STATUS_ACCESS_VIOLATION, if value is NULL.
*
* NOTES
* On success assign an integer value and return STATUS_SUCCESS.
* For base 0 accept: {whitespace} [+|-] [0[x|o|b]] {digits}
* For bases 2, 8, 10 and 16 accept: {whitespace} [+|-] {digits}
* For other bases return STATUS_INVALID_PARAMETER.
* For value == NULL return STATUS_ACCESS_VIOLATION.
* No check of value overflow: Just assign lower 32 bits (as native DLL).
* Do not check for str != NULL (as native DLL).
*
* Difference:
* - Do not read garbage on string length 0 as native DLL does.
* For base 0 it uses 10 as base and the string should be in the format
* "{whitespace} [+|-] [0[x|o|b]] {digits}".
* For other bases the string should be in the format
* "{whitespace} [+|-] {digits}".
* No check is made for value overflow, only the lower 32 bits are assigned.
* If str is NULL it crashes, as the native function does.
*
* DIFFERENCES
* This function does not read garbage on string length 0 as the native
* version does.
*/
NTSTATUS WINAPI RtlUnicodeStringToInteger(
const UNICODE_STRING *str,
ULONG base,
ULONG *value)
const UNICODE_STRING *str, /* [I] Unicode string to be converted */
ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
ULONG *value) /* [O] Destination for the converted value */
{
LPWSTR lpwstr = str->Buffer;
USHORT CharsRemaining = str->Length / sizeof(WCHAR);
......@@ -1292,25 +1373,29 @@ NTSTATUS WINAPI RtlUnicodeStringToInteger(
/**************************************************************************
* RtlIntegerToUnicodeString (NTDLL.@)
*
* Convert an unsigned integer to a NULL terminated unicode string.
* Converts an unsigned integer to a '\0' terminated unicode string.
*
* RETURNS
* Success: STATUS_SUCCESS. str contains the converted number
* Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
* STATUS_BUFFER_OVERFLOW, if str is too small to hold the string
* (with the '\0' termination). In this case str->Length
* is set to the length, the string would have (which can
* be larger than the MaximumLength).
*
* NOTES
* On success assign a NULL terminated string and return STATUS_SUCCESS.
* If base is not 0 (=10), 2, 8, 10 or 16 return STATUS_INVALID_PARAMETER.
* If str is too small to hold the string (with the NULL termination):
* Set str->Length to the length the string would have (which can be
* larger than the MaximumLength) and return STATUS_BUFFER_OVERFLOW.
* Do not check for str != NULL (as native DLL).
*
* Difference:
* - Do not return STATUS_BUFFER_OVERFLOW when the string is long enough.
* The native DLL does this when the string would be longer than 16
* characters even when the string parameter is long enough.
* Instead of base 0 it uses 10 as base.
* If str is NULL it crashes, as the native function does.
*
* DIFFERENCES
* Do not return STATUS_BUFFER_OVERFLOW when the string is long enough.
* The native function does this when the string would be longer than 16
* characters even when the string parameter is long enough.
*/
NTSTATUS WINAPI RtlIntegerToUnicodeString(
ULONG value,
ULONG base,
UNICODE_STRING *str)
ULONG value, /* [I] Value to be converted */
ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
UNICODE_STRING *str) /* [O] Destination for the converted value */
{
WCHAR buffer[33];
PWCHAR pos;
......@@ -1340,7 +1425,7 @@ NTSTATUS WINAPI RtlIntegerToUnicodeString(
if (str->Length >= str->MaximumLength) {
return STATUS_BUFFER_OVERFLOW;
} else {
memcpy(str->Buffer, pos, str->Length + 1);
memcpy(str->Buffer, pos, str->Length + sizeof(WCHAR));
} /* if */
return STATUS_SUCCESS;
}
......@@ -74,11 +74,19 @@ LPSTR __cdecl _strlwr( LPSTR str )
*
* Converts an unsigned long integer to a string.
*
* Assigns a '\0' terminated string to str and returns str.
* Does not check if radix is in the range of 2 to 36 (as native DLL).
* For str == NULL just crashes (as native DLL).
* RETURNS
* Always returns str.
*
* NOTES
* Converts value to a '\0' terminated string which is copied to str.
* The maximum length of the copied str is 33 bytes.
* Does not check if radix is in the range of 2 to 36.
* If str is NULL it crashes, as the native function does.
*/
char * __cdecl _ultoa( unsigned long value, char *str, int radix )
char * __cdecl _ultoa(
unsigned long value, /* [I] Value to be converted */
char *str, /* [O] Destination for the converted value */
int radix) /* [I] Number base for conversion */
{
char buffer[33];
char *pos;
......@@ -107,12 +115,20 @@ char * __cdecl _ultoa( unsigned long value, char *str, int radix )
*
* Converts a long integer to a string.
*
* Assigns a '\0' terminated string to str and returns str. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36 (as native DLL).
* For str == NULL just crashes (as native DLL).
* RETURNS
* Always returns str.
*
* NOTES
* Converts value to a '\0' terminated string which is copied to str.
* The maximum length of the copied str is 33 bytes. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36.
* If str is NULL it crashes, as the native function does.
*/
char * __cdecl _ltoa( long value, char *str, int radix )
char * __cdecl _ltoa(
long value, /* [I] Value to be converted */
char *str, /* [O] Destination for the converted value */
int radix) /* [I] Number base for conversion */
{
unsigned long val;
int negative;
......@@ -155,12 +171,20 @@ char * __cdecl _ltoa( long value, char *str, int radix )
*
* Converts an integer to a string.
*
* Assigns a '\0' terminated wstring to str and returns str. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36 (as native DLL).
* For str == NULL just crashes (as native DLL).
* RETURNS
* Always returns str.
*
* NOTES
* Converts value to a '\0' terminated string which is copied to str.
* The maximum length of the copied str is 33 bytes. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36.
* If str is NULL it crashes, as the native function does.
*/
char * __cdecl _itoa( int value, char *str, int radix )
char * __cdecl _itoa(
int value, /* [I] Value to be converted */
char *str, /* [O] Destination for the converted value */
int radix) /* [I] Number base for conversion */
{
return _ltoa(value, str, radix);
}
......@@ -171,11 +195,19 @@ char * __cdecl _itoa( int value, char *str, int radix )
*
* Converts a large unsigned integer to a string.
*
* Assigns a '\0' terminated string to str and returns str.
* Does not check if radix is in the range of 2 to 36 (as native DLL).
* For str == NULL just crashes (as native DLL).
* RETURNS
* Always returns str.
*
* NOTES
* Converts value to a '\0' terminated string which is copied to str.
* The maximum length of the copied str is 65 bytes.
* Does not check if radix is in the range of 2 to 36.
* If str is NULL it crashes, as the native function does.
*/
char * __cdecl _ui64toa( ULONGLONG value, char *str, int radix )
char * __cdecl _ui64toa(
ULONGLONG value, /* [I] Value to be converted */
char *str, /* [O] Destination for the converted value */
int radix) /* [I] Number base for conversion */
{
char buffer[65];
char *pos;
......@@ -204,21 +236,29 @@ char * __cdecl _ui64toa( ULONGLONG value, char *str, int radix )
*
* Converts a large integer to a string.
*
* Assigns a '\0' terminated string to str and returns str. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36 (as native DLL).
* For str == NULL just crashes (as native DLL).
* RETURNS
* Always returns str.
*
* Difference:
* NOTES
* Converts value to a '\0' terminated string which is copied to str.
* The maximum length of the copied str is 65 bytes. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36.
* If str is NULL it crashes, as the native function does.
*
* DIFFERENCES
* - The native DLL converts negative values (for base 10) wrong:
* -1 is converted to -18446744073709551615
* -2 is converted to -18446744073709551614
* -9223372036854775807 is converted to -9223372036854775809
* -9223372036854775808 is converted to -9223372036854775808
* The native msvcrt _i64toa function and our ntdll function do
* not have this bug.
* The native msvcrt _i64toa function and our ntdll _i64toa function
* do not have this bug.
*/
char * __cdecl _i64toa( LONGLONG value, char *str, int radix )
char * __cdecl _i64toa(
LONGLONG value, /* [I] Value to be converted */
char *str, /* [O] Destination for the converted value */
int radix) /* [I] Number base for conversion */
{
ULONGLONG val;
int negative;
......@@ -261,10 +301,16 @@ char * __cdecl _i64toa( LONGLONG value, char *str, int radix )
*
* Converts a string to a large integer.
*
* On success it returns the integer value otherwise it returns 0.
* Accepts: {whitespace} [+|-] {digits}
* No check of overflow: Just assigns lower 64 bits (as native DLL).
* Does not check for str != NULL (as native DLL).
* PARAMS
* str [I] Wstring to be converted
*
* RETURNS
* On success it returns the integer value otherwise it returns 0.
*
* NOTES
* Accepts: {whitespace} [+|-] {digits}
* No check is made for value overflow, only the lower 64 bits are assigned.
* If str is NULL it crashes, as the native function does.
*/
LONGLONG __cdecl _atoi64( char *str )
{
......
......@@ -331,10 +331,76 @@ INT __cdecl NTDLL_iswctype( WCHAR wc, WCHAR wct )
/*********************************************************************
* iswalpha (NTDLL.@)
*
* Checks if an unicode char wc is a letter
*
* RETURNS
* TRUE: The unicode char wc is a letter.
* FALSE: Otherwise
*/
INT __cdecl NTDLL_iswalpha( WCHAR wc )
{
return get_char_typeW(wc) & C1_ALPHA;
return isalphaW(wc);
}
/*********************************************************************
* iswdigit (NTDLL.@)
*
* Checks if an unicode char wc is a digit
*
* RETURNS
* TRUE: The unicode char wc is a digit.
* FALSE: Otherwise
*/
INT __cdecl NTDLL_iswdigit( WCHAR wc )
{
return isdigitW(wc);
}
/*********************************************************************
* iswlower (NTDLL.@)
*
* Checks if an unicode char wc is a lower case letter
*
* RETURNS
* TRUE: The unicode char wc is a lower case letter.
* FALSE: Otherwise
*/
INT __cdecl NTDLL_iswlower( WCHAR wc )
{
return islowerW(wc);
}
/*********************************************************************
* iswspace (NTDLL.@)
*
* Checks if an unicode char wc is a white space character
*
* RETURNS
* TRUE: The unicode char wc is a white space character.
* FALSE: Otherwise
*/
INT __cdecl NTDLL_iswspace( WCHAR wc )
{
return isspaceW(wc);
}
/*********************************************************************
* iswxdigit (NTDLL.@)
*
* Checks if an unicode char wc is an extended digit
*
* RETURNS
* TRUE: The unicode char wc is an extended digit.
* FALSE: Otherwise
*/
INT __cdecl NTDLL_iswxdigit( WCHAR wc )
{
return isxdigitW(wc);
}
......@@ -343,11 +409,19 @@ INT __cdecl NTDLL_iswalpha( WCHAR wc )
*
* Converts an unsigned long integer to an unicode string.
*
* Assigns a '\0' terminated string to str and returns str.
* Does not check if radix is in the range of 2 to 36 (as native DLL).
* For str == NULL just returns NULL (as native DLL).
* RETURNS
* Always returns str.
*
* NOTES
* Converts value to a '\0' terminated wstring which is copied to str.
* The maximum length of the copied str is 33 bytes.
* Does not check if radix is in the range of 2 to 36.
* If str is NULL it just returns NULL.
*/
LPWSTR __cdecl _ultow( unsigned long value, LPWSTR str, INT radix )
LPWSTR __cdecl _ultow(
unsigned long value, /* [I] Value to be converted */
LPWSTR str, /* [O] Destination for the converted value */
INT radix) /* [I] Number base for conversion */
{
WCHAR buffer[33];
PWCHAR pos;
......@@ -378,12 +452,20 @@ LPWSTR __cdecl _ultow( unsigned long value, LPWSTR str, INT radix )
*
* Converts a long integer to an unicode string.
*
* Assigns a '\0' terminated string to str and returns str. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36 (as native DLL).
* For str == NULL just returns NULL (as native DLL).
*/
LPWSTR __cdecl _ltow( long value, LPWSTR str, INT radix )
* RETURNS
* Always returns str.
*
* NOTES
* Converts value to a '\0' terminated wstring which is copied to str.
* The maximum length of the copied str is 33 bytes. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36.
* If str is NULL it just returns NULL.
*/
LPWSTR __cdecl _ltow(
long value, /* [I] Value to be converted */
LPWSTR str, /* [O] Destination for the converted value */
INT radix) /* [I] Number base for conversion */
{
unsigned long val;
int negative;
......@@ -428,16 +510,24 @@ LPWSTR __cdecl _ltow( long value, LPWSTR str, INT radix )
*
* Converts an integer to an unicode string.
*
* Assigns a '\0' terminated wstring to str and returns str. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36 (as native DLL).
* For str == NULL just returns NULL (as native DLL).
* RETURNS
* Always returns str.
*
* NOTES
* Converts value to a '\0' terminated wstring which is copied to str.
* The maximum length of the copied str is 33 bytes. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36.
* If str is NULL it just returns NULL.
*
* Difference:
* - The native DLL crashes when the string is longer than 19 chars.
* DIFFERENCES
* - The native function crashes when the string is longer than 19 chars.
* This function does not have this bug.
*/
LPWSTR __cdecl _itow( int value, LPWSTR str, INT radix )
LPWSTR __cdecl _itow(
int value, /* [I] Value to be converted */
LPWSTR str, /* [O] Destination for the converted value */
INT radix) /* [I] Number base for conversion */
{
return _ltow(value, str, radix);
}
......@@ -448,16 +538,24 @@ LPWSTR __cdecl _itow( int value, LPWSTR str, INT radix )
*
* Converts a large unsigned integer to an unicode string.
*
* Assigns a '\0' terminated wstring to str and returns str.
* Does not check if radix is in the range of 2 to 36 (as native DLL).
* For str == NULL just returns NULL (as native DLL).
* RETURNS
* Always returns str.
*
* NOTES
* Converts value to a '\0' terminated wstring which is copied to str.
* The maximum length of the copied str is 33 bytes.
* Does not check if radix is in the range of 2 to 36.
* If str is NULL it just returns NULL.
*
* Difference:
* DIFFERENCES
* - This function does not exist in the native DLL (but in msvcrt).
* But since the maintenance of all these functions is better done
* in one place we implement it here.
*/
LPWSTR __cdecl _ui64tow( ULONGLONG value, LPWSTR str, INT radix )
LPWSTR __cdecl _ui64tow(
ULONGLONG value, /* [I] Value to be converted */
LPWSTR str, /* [O] Destination for the converted value */
INT radix) /* [I] Number base for conversion */
{
WCHAR buffer[65];
PWCHAR pos;
......@@ -488,12 +586,17 @@ LPWSTR __cdecl _ui64tow( ULONGLONG value, LPWSTR str, INT radix )
*
* Converts a large integer to an unicode string.
*
* Assigns a '\0' terminated wstring to str and returns str. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36 (as native DLL).
* For str == NULL just returns NULL (as native DLL).
* RETURNS
* Always returns str.
*
* Difference:
* NOTES
* Converts value to a '\0' terminated wstring which is copied to str.
* The maximum length of the copied str is 33 bytes. If radix
* is 10 and value is negative, the value is converted with sign.
* Does not check if radix is in the range of 2 to 36.
* If str is NULL it just returns NULL.
*
* DIFFERENCES
* - The native DLL converts negative values (for base 10) wrong:
* -1 is converted to -18446744073709551615
* -2 is converted to -18446744073709551614
......@@ -502,7 +605,10 @@ LPWSTR __cdecl _ui64tow( ULONGLONG value, LPWSTR str, INT radix )
* The native msvcrt _i64tow function and our ntdll function do
* not have this bug.
*/
LPWSTR __cdecl _i64tow( LONGLONG value, LPWSTR str, INT radix )
LPWSTR __cdecl _i64tow(
LONGLONG value, /* [I] Value to be converted */
LPWSTR str, /* [O] Destination for the converted value */
INT radix) /* [I] Number base for conversion */
{
ULONGLONG val;
int negative;
......@@ -547,10 +653,16 @@ LPWSTR __cdecl _i64tow( LONGLONG value, LPWSTR str, INT radix )
*
* Converts an unicode string to a long integer.
*
* On success it returns the integer value otherwise it returns 0.
* Accepts: {whitespace} [+|-] {digits}
* No check of overflow: Just assigns lower 32 bits (as native DLL).
* Does not check for str != NULL (as native DLL).
* PARAMS
* str [I] Wstring to be converted
*
* RETURNS
* On success it returns the integer value otherwise it returns 0.
*
* NOTES
* Accepts: {whitespace} [+|-] {digits}
* No check is made for value overflow, only the lower 32 bits are assigned.
* If str is NULL it crashes, as the native function does.
*/
LONG __cdecl _wtol( LPWSTR str )
{
......@@ -582,14 +694,20 @@ LONG __cdecl _wtol( LPWSTR str )
*
* Converts an unicode string to an integer.
*
* On success it returns the integer value otherwise it returns 0.
* Accepts: {whitespace} [+|-] {digits}
* No check of overflow: Just assigns lower 32 bits (as native DLL).
* Does not check for str != NULL (as native DLL).
* PARAMS
* str [I] Wstring to be converted
*
* RETURNS
* On success it returns the integer value otherwise it returns 0.
*
* NOTES
* Accepts: {whitespace} [+|-] {digits}
* No check is made for value overflow, only the lower 32 bits are assigned.
* If str is NULL it crashes, as the native function does.
*/
int __cdecl _wtoi( LPWSTR string )
int __cdecl _wtoi( LPWSTR str )
{
return _wtol(string);
return _wtol(str);
}
......@@ -598,10 +716,16 @@ int __cdecl _wtoi( LPWSTR string )
*
* Converts an unicode string to a large integer.
*
* On success it returns the integer value otherwise it returns 0.
* Accepts: {whitespace} [+|-] {digits}
* No check of overflow: Just assigns lower 64 bits (as native DLL).
* Does not check for str != NULL (as native DLL).
* PARAMS
* str [I] Wstring to be converted
*
* RETURNS
* On success it returns the integer value otherwise it returns 0.
*
* NOTES
* Accepts: {whitespace} [+|-] {digits}
* No check is made for value overflow, only the lower 64 bits are assigned.
* If str is NULL it crashes, as the native function does.
*/
LONGLONG __cdecl _wtoi64( LPWSTR str )
{
......@@ -628,7 +752,6 @@ LONGLONG __cdecl _wtoi64( LPWSTR str )
}
/***********************************************************************
* _snwprintf (NTDLL.@)
*/
......
......@@ -918,6 +918,7 @@ DWORD WINAPI RtlDestroyEnvironment(DWORD);
HANDLE WINAPI RtlDestroyHeap(HANDLE);
BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(LPWSTR,PUNICODE_STRING,DWORD,DWORD);
WCHAR WINAPI RtlDowncaseUnicodeChar(WCHAR);
NTSTATUS WINAPI RtlDowncaseUnicodeString(UNICODE_STRING*,const UNICODE_STRING*,BOOLEAN);
void WINAPI RtlDumpResource(LPRTL_RWLOCK);
LONGLONG WINAPI RtlEnlargedIntegerMultiply(INT,INT);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment