kernelbase: Add string handling functions from user32.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2019-05-17 14:28:18 +03:00 committed by Alexandre Julliard
parent 3dedcf82f7
commit 40d2b25ac2
2 changed files with 248 additions and 22 deletions

View File

@ -109,20 +109,20 @@
@ stdcall CancelWaitableTimer(long) kernel32.CancelWaitableTimer
# @ stub CeipIsOptedIn
@ stdcall ChangeTimerQueueTimer(ptr ptr long long) kernel32.ChangeTimerQueueTimer
@ stdcall CharLowerA(str) user32.CharLowerA
@ stdcall CharLowerBuffA(str long) user32.CharLowerBuffA
@ stdcall CharLowerBuffW(wstr long) user32.CharLowerBuffW
@ stdcall CharLowerW(wstr) user32.CharLowerW
@ stdcall CharNextA(str) user32.CharNextA
@ stdcall CharNextExA(long str long) user32.CharNextExA
@ stdcall CharNextW(wstr) user32.CharNextW
@ stdcall CharPrevA(str str) user32.CharPrevA
@ stdcall CharPrevExA(long str str long) user32.CharPrevExA
@ stdcall CharPrevW(wstr wstr) user32.CharPrevW
@ stdcall CharUpperA(str) user32.CharUpperA
@ stdcall CharUpperBuffA(str long) user32.CharUpperBuffA
@ stdcall CharUpperBuffW(wstr long) user32.CharUpperBuffW
@ stdcall CharUpperW(wstr) user32.CharUpperW
@ stdcall CharLowerA(str)
@ stdcall CharLowerBuffA(str long)
@ stdcall CharLowerBuffW(wstr long)
@ stdcall CharLowerW(wstr)
@ stdcall CharNextA(str)
@ stdcall CharNextExA(long str long)
@ stdcall CharNextW(wstr)
@ stdcall CharPrevA(str str)
@ stdcall CharPrevExA(long str str long)
@ stdcall CharPrevW(wstr wstr)
@ stdcall CharUpperA(str)
@ stdcall CharUpperBuffA(str long)
@ stdcall CharUpperBuffW(wstr long)
@ stdcall CharUpperW(wstr)
# @ stub CheckAllowDecryptedRemoteDestinationPolicy
@ stub CheckGroupPolicyEnabled
# @ stub CheckIfStateChangeNotificationExists
@ -839,20 +839,20 @@
# @ stub InternetTimeToSystemTimeW
# @ stub InvalidateAppModelVersionCache
@ stub InvalidateTzSpecificCache
@ stdcall IsCharAlphaA(long) user32.IsCharAlphaA
@ stdcall IsCharAlphaNumericA(long) user32.IsCharAlphaNumericA
@ stdcall IsCharAlphaNumericW(long) user32.IsCharAlphaNumericW
@ stdcall IsCharAlphaW(long) user32.IsCharAlphaW
@ stdcall IsCharAlphaA(long)
@ stdcall IsCharAlphaNumericA(long)
@ stdcall IsCharAlphaNumericW(long)
@ stdcall IsCharAlphaW(long)
@ stdcall IsCharBlankW(long)
@ stdcall IsCharCntrlW(long)
@ stdcall IsCharDigitW(long)
@ stdcall IsCharLowerA(long) user32.IsCharLowerA
@ stdcall IsCharLowerW(long) user32.IsCharLowerW
@ stdcall IsCharLowerA(long)
@ stdcall IsCharLowerW(long)
@ stdcall IsCharPunctW(long)
@ stdcall IsCharSpaceA(long)
@ stdcall IsCharSpaceW(long)
@ stdcall IsCharUpperA(long) user32.IsCharUpperA
@ stdcall IsCharUpperW(long) user32.IsCharUpperW
@ stdcall IsCharUpperA(long)
@ stdcall IsCharUpperW(long)
@ stdcall IsCharXDigitW(long)
@ stdcall IsDBCSLeadByte(long) kernel32.IsDBCSLeadByte
@ stdcall IsDBCSLeadByteEx(long long) kernel32.IsDBCSLeadByteEx

View File

@ -24,6 +24,7 @@
#include "shlwapi.h"
#include "wine/debug.h"
#include "wine/exception.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(string);
@ -101,6 +102,54 @@ BOOL WINAPI IsCharXDigitW(WCHAR wc)
return !!(get_char_type(wc) & C1_XDIGIT);
}
BOOL WINAPI IsCharAlphaA(CHAR x)
{
WCHAR wch;
MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
return IsCharAlphaW(wch);
}
BOOL WINAPI IsCharAlphaW(WCHAR ch)
{
return !!(get_char_type(ch) & C1_ALPHA);
}
BOOL WINAPI IsCharLowerA(CHAR x)
{
WCHAR wch;
MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
return IsCharLowerW(wch);
}
BOOL WINAPI IsCharLowerW(WCHAR ch)
{
return !!(get_char_type(ch) & C1_LOWER);
}
BOOL WINAPI IsCharAlphaNumericA(CHAR x)
{
WCHAR wch;
MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
return IsCharAlphaNumericW(wch);
}
BOOL WINAPI IsCharAlphaNumericW(WCHAR ch)
{
return !!(get_char_type(ch) & (C1_ALPHA | C1_DIGIT));
}
BOOL WINAPI IsCharUpperA(CHAR x)
{
WCHAR wch;
MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
return IsCharUpperW(wch);
}
BOOL WINAPI IsCharUpperW(WCHAR ch)
{
return !!(get_char_type(ch) & C1_UPPER);
}
WCHAR * WINAPI StrChrW(const WCHAR *str, WCHAR ch)
{
TRACE("%s, %#x\n", wine_dbgstr_w(str), ch);
@ -512,3 +561,180 @@ WCHAR * WINAPI StrCpyNXW(WCHAR *dst, const WCHAR *src, int len)
return dst;
}
LPSTR WINAPI CharLowerA(char *str)
{
if (IS_INTRESOURCE(str))
{
char ch = LOWORD(str);
CharLowerBuffA( &ch, 1 );
return (LPSTR)(UINT_PTR)(BYTE)ch;
}
__TRY
{
CharLowerBuffA( str, strlen(str) );
}
__EXCEPT_PAGE_FAULT
{
SetLastError( ERROR_INVALID_PARAMETER );
return NULL;
}
__ENDTRY
return str;
}
DWORD WINAPI CharLowerBuffA(char *str, DWORD len)
{
DWORD lenW;
WCHAR buffer[32];
WCHAR *strW = buffer;
if (!str) return 0; /* YES */
lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
if (lenW > ARRAY_SIZE(buffer))
{
strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
if (!strW) return 0;
}
MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
CharLowerBuffW(strW, lenW);
len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
return len;
}
DWORD WINAPI CharLowerBuffW(WCHAR *str, DWORD len)
{
if (!str) return 0; /* YES */
return LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE, str, len, str, len);
}
LPWSTR WINAPI CharLowerW(WCHAR *str)
{
if (!IS_INTRESOURCE(str))
{
CharLowerBuffW(str, lstrlenW(str));
return str;
}
else
{
WCHAR ch = LOWORD(str);
CharLowerBuffW(&ch, 1);
return (LPWSTR)(UINT_PTR)ch;
}
}
LPSTR WINAPI CharNextA(const char *ptr)
{
if (!*ptr) return (LPSTR)ptr;
if (IsDBCSLeadByte( ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
return (LPSTR)(ptr + 1);
}
LPSTR WINAPI CharNextExA(WORD codepage, const char *ptr, DWORD flags)
{
if (!*ptr) return (LPSTR)ptr;
if (IsDBCSLeadByteEx( codepage, ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
return (LPSTR)(ptr + 1);
}
LPWSTR WINAPI CharNextW(const WCHAR *x)
{
if (*x) x++;
return (WCHAR *)x;
}
LPSTR WINAPI CharPrevA(const char *start, const char *ptr)
{
while (*start && (start < ptr))
{
LPCSTR next = CharNextA(start);
if (next >= ptr) break;
start = next;
}
return (LPSTR)start;
}
LPSTR WINAPI CharPrevExA(WORD codepage, const char *start, const char *ptr, DWORD flags)
{
while (*start && (start < ptr))
{
LPCSTR next = CharNextExA(codepage, start, flags);
if (next >= ptr) break;
start = next;
}
return (LPSTR)start;
}
LPWSTR WINAPI CharPrevW(const WCHAR *start, const WCHAR *x)
{
if (x > start) return (LPWSTR)(x - 1);
else return (LPWSTR)x;
}
LPSTR WINAPI CharUpperA(LPSTR str)
{
if (IS_INTRESOURCE(str))
{
char ch = LOWORD(str);
CharUpperBuffA(&ch, 1);
return (LPSTR)(UINT_PTR)(BYTE)ch;
}
__TRY
{
CharUpperBuffA(str, strlen(str));
}
__EXCEPT_PAGE_FAULT
{
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
__ENDTRY
return str;
}
DWORD WINAPI CharUpperBuffA(LPSTR str, DWORD len)
{
DWORD lenW;
WCHAR buffer[32];
WCHAR *strW = buffer;
if (!str) return 0; /* YES */
lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
if (lenW > ARRAY_SIZE(buffer))
{
strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
if (!strW) return 0;
}
MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
CharUpperBuffW(strW, lenW);
len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
return len;
}
DWORD WINAPI CharUpperBuffW(WCHAR *str, DWORD len)
{
if (!str) return 0; /* YES */
return LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE, str, len, str, len);
}
LPWSTR WINAPI CharUpperW(WCHAR *str)
{
if (!IS_INTRESOURCE(str))
{
CharUpperBuffW(str, lstrlenW(str));
return str;
}
else
{
WCHAR ch = LOWORD(str);
CharUpperBuffW(&ch, 1);
return (LPWSTR)(UINT_PTR)ch;
}
}