[PATCH 2/4] kernelbase: Add string handling functions from user32.

Nikolay Sivov nsivov at codeweavers.com
Thu May 16 10:04:02 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/kernelbase/kernelbase.spec |  44 +++----
 dlls/kernelbase/string.c        | 226 ++++++++++++++++++++++++++++++++
 2 files changed, 248 insertions(+), 22 deletions(-)

diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index 8294c95282..6ff91518c3 100644
--- a/dlls/kernelbase/kernelbase.spec
+++ b/dlls/kernelbase/kernelbase.spec
@@ -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
diff --git a/dlls/kernelbase/string.c b/dlls/kernelbase/string.c
index 8b3d94a9e6..7e128765d8 100644
--- a/dlls/kernelbase/string.c
+++ b/dlls/kernelbase/string.c
@@ -24,6 +24,7 @@
 #include "shlwapi.h"
 
 #include "wine/debug.h"
+#include "wine/exception.h"
 #include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(string);
@@ -100,6 +101,54 @@ BOOL WINAPI IsCharXDigitW(WCHAR wc)
     return !!isxdigitW(wc);
 }
 
+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_typeW(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 !!islowerW(ch);
+}
+
+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_typeW(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 !!isupperW(ch);
+}
+
 WCHAR * WINAPI StrChrW(const WCHAR *str, WCHAR ch)
 {
     TRACE("%s, %#x\n", wine_dbgstr_w(str), ch);
@@ -511,3 +560,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;
+    }
+}
-- 
2.20.1




More information about the wine-devel mailing list