ntdll: Reimplement multibyte to Unicode conversion functions using the Win32-format tables.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-12-03 08:43:08 +01:00
parent b7fcb956ef
commit e13c4d859e
2 changed files with 83 additions and 110 deletions

View File

@ -103,6 +103,24 @@ static NTSTATUS load_string( ULONG id, LANGID lang, WCHAR *buffer, ULONG len )
}
static DWORD mbtowc_size( const CPTABLEINFO *info, LPCSTR str, UINT len )
{
DWORD res;
if (!info->DBCSCodePage) return len;
for (res = 0; len; len--, str++, res++)
{
if (info->DBCSOffsets[(unsigned char)*str] && len > 1)
{
str++;
len--;
}
}
return res;
}
static WCHAR casemap( USHORT *table, WCHAR ch )
{
return ch + table[table[table[ch >> 8] + ((ch >> 4) & 0x0f)] + (ch & 0x0f)];
@ -781,6 +799,24 @@ void WINAPI RtlResetRtlTranslations( const NLSTABLEINFO *info )
}
/**************************************************************************
* RtlAnsiCharToUnicodeChar (NTDLL.@)
*/
WCHAR WINAPI RtlAnsiCharToUnicodeChar( char **ansi )
{
if (nls_info.AnsiTableInfo.DBCSOffsets)
{
USHORT off = nls_info.AnsiTableInfo.DBCSOffsets[(unsigned char)**ansi];
if (off && (*ansi)[1])
{
(*ansi)++;
return nls_info.AnsiTableInfo.MultiByteTable[off + (unsigned char)*(*ansi)++];
}
}
return nls_info.AnsiTableInfo.MultiByteTable[(unsigned char)*(*ansi)++];
}
/**************************************************************************
* RtlCustomCPToUnicodeN (NTDLL.@)
*/
@ -851,6 +887,53 @@ NTSTATUS WINAPI RtlUnicodeToCustomCPN( CPTABLEINFO *info, char *dst, DWORD dstle
}
/**************************************************************************
* RtlMultiByteToUnicodeN (NTDLL.@)
*/
NTSTATUS WINAPI RtlMultiByteToUnicodeN( WCHAR *dst, DWORD dstlen, DWORD *reslen,
const char *src, DWORD srclen )
{
if (nls_info.AnsiTableInfo.WideCharTable)
return RtlCustomCPToUnicodeN( &nls_info.AnsiTableInfo, dst, dstlen, reslen, src, srclen );
/* locale not setup yet */
dstlen = min( srclen, dstlen / sizeof(WCHAR) );
if (reslen) *reslen = dstlen * sizeof(WCHAR);
while (dstlen--) *dst++ = *src++ & 0x7f;
return STATUS_SUCCESS;
}
/**************************************************************************
* RtlMultiByteToUnicodeSize (NTDLL.@)
*/
NTSTATUS WINAPI RtlMultiByteToUnicodeSize( DWORD *size, const char *str, DWORD len )
{
*size = mbtowc_size( &nls_info.AnsiTableInfo, str, len ) * sizeof(WCHAR);
return STATUS_SUCCESS;
}
/**************************************************************************
* RtlOemToUnicodeN (NTDLL.@)
*/
NTSTATUS WINAPI RtlOemToUnicodeN( WCHAR *dst, DWORD dstlen, DWORD *reslen,
const char *src, DWORD srclen )
{
return RtlCustomCPToUnicodeN( &nls_info.OemTableInfo, dst, dstlen, reslen, src, srclen );
}
/**************************************************************************
* RtlOemStringToUnicodeSize (NTDLL.@)
* RtlxOemStringToUnicodeSize (NTDLL.@)
*/
DWORD WINAPI RtlOemStringToUnicodeSize( const STRING *str )
{
return (mbtowc_size( &nls_info.OemTableInfo, str->Buffer, str->Length ) + 1) * sizeof(WCHAR);
}
/**************************************************************************
* RtlUpcaseUnicodeToCustomCPN (NTDLL.@)
*/

View File

@ -605,35 +605,6 @@ NTSTATUS WINAPI RtlEqualDomainName(const UNICODE_STRING *left,
}
/**************************************************************************
* RtlAnsiCharToUnicodeChar (NTDLL.@)
*
* Converts the first ansi character to a unicode character.
*
* PARAMS
* ansi [I/O] Pointer to the ansi string.
*
* RETURNS
* Unicode representation of the first character in the ansi string.
*
* NOTES
* Upon successful completion, the char pointer ansi points to is
* incremented by the size of the character.
*/
WCHAR WINAPI RtlAnsiCharToUnicodeChar(LPSTR *ansi)
{
WCHAR str;
DWORD charSize = sizeof(CHAR);
if (wine_is_dbcs_leadbyte(ansi_table, **ansi))
charSize++;
RtlMultiByteToUnicodeN(&str, sizeof(WCHAR), NULL, *ansi, charSize);
*ansi += charSize;
return str;
}
/*
COPY BETWEEN ANSI_STRING or UNICODE_STRING
there is no parameter checking, it just crashes
@ -802,46 +773,6 @@ NTSTATUS WINAPI RtlUnicodeStringToOemString( STRING *oem,
}
/**************************************************************************
* RtlMultiByteToUnicodeN (NTDLL.@)
*
* Converts a multi-byte string to a Unicode string.
*
* RETURNS
* NTSTATUS code
*
* NOTES
* Performs a partial copy if dst is too small.
*/
NTSTATUS WINAPI RtlMultiByteToUnicodeN( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
LPCSTR src, DWORD srclen )
{
int ret = wine_cp_mbstowcs( ansi_table, 0, src, srclen, dst, dstlen/sizeof(WCHAR) );
if (reslen)
*reslen = (ret >= 0) ? ret*sizeof(WCHAR) : dstlen; /* overflow -> we filled up to dstlen */
return STATUS_SUCCESS;
}
/**************************************************************************
* RtlOemToUnicodeN (NTDLL.@)
*
* Converts a multi-byte string in the OEM code page to a Unicode string.
*
* RETURNS
* NTSTATUS code
*/
NTSTATUS WINAPI RtlOemToUnicodeN( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
LPCSTR src, DWORD srclen )
{
int ret = wine_cp_mbstowcs( oem_table, 0, src, srclen, dst, dstlen/sizeof(WCHAR) );
if (reslen)
*reslen = (ret >= 0) ? ret*sizeof(WCHAR) : dstlen; /* overflow -> we filled up to dstlen */
return STATUS_SUCCESS;
}
/**************************************************************************
* RtlUnicodeToMultiByteN (NTDLL.@)
*
@ -1253,26 +1184,6 @@ NTSTATUS WINAPI RtlUpcaseUnicodeToOemN( LPSTR dst, DWORD dstlen, LPDWORD reslen,
*/
/**************************************************************************
* RtlOemStringToUnicodeSize (NTDLL.@)
* RtlxOemStringToUnicodeSize (NTDLL.@)
*
* Calculate the size in bytes necessary for the Unicode conversion of str,
* including the terminating '\0'.
*
* PARAMS
* str [I] String to calculate the size of
*
* RETURNS
* The calculated size.
*/
UINT WINAPI RtlOemStringToUnicodeSize( const STRING *str )
{
int ret = wine_cp_mbstowcs( oem_table, 0, str->Buffer, str->Length, NULL, 0 );
return (ret + 1) * sizeof(WCHAR);
}
/**************************************************************************
* RtlAnsiStringToUnicodeSize (NTDLL.@)
* RtlxAnsiStringToUnicodeSize (NTDLL.@)
@ -1294,27 +1205,6 @@ DWORD WINAPI RtlAnsiStringToUnicodeSize( const STRING *str )
}
/**************************************************************************
* RtlMultiByteToUnicodeSize (NTDLL.@)
*
* Compute the size in bytes necessary for the Unicode conversion of str,
* without the terminating '\0'.
*
* PARAMS
* size [O] Destination for size
* str [I] String to calculate the size of
* len [I] Length of str
*
* RETURNS
* STATUS_SUCCESS.
*/
NTSTATUS WINAPI RtlMultiByteToUnicodeSize( DWORD *size, LPCSTR str, UINT len )
{
*size = wine_cp_mbstowcs( ansi_table, 0, str, len, NULL, 0 ) * sizeof(WCHAR);
return STATUS_SUCCESS;
}
/**************************************************************************
* RtlUnicodeToMultiByteSize (NTDLL.@)
*