[v2 PATCH 2/4] kernelbase: Add string handling functions from user32.
Nikolay Sivov
nsivov at codeweavers.com
Fri May 17 06:28:18 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 6f38fc3b3d..3d2766aff2 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);
@@ -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;
+ }
+}
--
2.20.1
More information about the wine-devel
mailing list