Jacek Caban : ntdll: Provide some Unicode helpers for Unix libs.

Alexandre Julliard julliard at winehq.org
Thu Oct 7 16:21:20 CDT 2021


Module: wine
Branch: master
Commit: 1be12eaa942e38302c2b79806a184f58d664c617
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1be12eaa942e38302c2b79806a184f58d664c617

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Oct  6 16:19:58 2021 +0200

ntdll: Provide some Unicode helpers for Unix libs.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/env.c | 101 +++++++++++++++++++++++++++++++++++---------------
 1 file changed, 71 insertions(+), 30 deletions(-)

diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c
index 92ae04d90a5..13bf85d2eb6 100644
--- a/dlls/ntdll/unix/env.c
+++ b/dlls/ntdll/unix/env.c
@@ -644,37 +644,11 @@ DWORD ntdll_umbstowcs( const char *src, DWORD srclen, WCHAR *dst, DWORD dstlen )
     }
     else  /* utf-8 */
     {
-        unsigned int res;
-        const char *srcend = src + srclen;
-        WCHAR *dstend = dst + dstlen;
-
-        while ((dst < dstend) && (src < srcend))
-        {
-            unsigned char ch = *src++;
-            if (ch < 0x80)  /* special fast case for 7-bit ASCII */
-            {
-                *dst++ = ch;
-                continue;
-            }
-            if ((res = decode_utf8_char( ch, &src, srcend )) <= 0xffff)
-            {
-                *dst++ = res;
-            }
-            else if (res <= 0x10ffff)  /* we need surrogates */
-            {
-                res -= 0x10000;
-                *dst++ = 0xd800 | (res >> 10);
-                if (dst == dstend) break;
-                *dst++ = 0xdc00 | (res & 0x3ff);
-            }
-            else
-            {
-                *dst++ = 0xfffd;
-            }
-        }
-        reslen = dstlen - (dstend - dst);
+        reslen = 0;
+        RtlUTF8ToUnicodeN( dst, dstlen * sizeof(WCHAR), &reslen, src, srclen );
+        reslen /= sizeof(WCHAR);
 #ifdef __APPLE__  /* work around broken Mac OS X filesystem that enforces NFD */
-        if (reslen && nfc_table) reslen = compose_string( nfc_table, dst - reslen, reslen );
+        if (reslen && nfc_table) reslen = compose_string( nfc_table, dst, reslen );
 #endif
     }
     return reslen;
@@ -2486,3 +2460,70 @@ NTSTATUS WINAPI NtQueryInstallUILanguage( LANGID *lang )
     *lang = system_ui_language;
     return STATUS_SUCCESS;
 }
+
+WCHAR WINAPI RtlUpcaseUnicodeChar( WCHAR wch )
+{
+    return ntdll_towupper( wch );
+}
+
+WCHAR WINAPI RtlDowncaseUnicodeChar( WCHAR wch )
+{
+    return ntdll_towlower( wch );
+}
+
+NTSTATUS WINAPI RtlUTF8ToUnicodeN( WCHAR *dst, DWORD dstlen, DWORD *reslen, const char *src, DWORD srclen )
+{
+    unsigned int res, len;
+    NTSTATUS status = STATUS_SUCCESS;
+    const char *srcend = src + srclen;
+    WCHAR *dstend;
+
+    if (!src) return STATUS_INVALID_PARAMETER_4;
+    if (!reslen) return STATUS_INVALID_PARAMETER;
+
+    dstlen /= sizeof(WCHAR);
+    dstend = dst + dstlen;
+    if (!dst)
+    {
+        for (len = 0; src < srcend; len++)
+        {
+            unsigned char ch = *src++;
+            if (ch < 0x80) continue;
+            if ((res = decode_utf8_char( ch, &src, srcend )) > 0x10ffff)
+                status = STATUS_SOME_NOT_MAPPED;
+            else
+                if (res > 0xffff) len++;
+        }
+        *reslen = len * sizeof(WCHAR);
+        return status;
+    }
+
+    while ((dst < dstend) && (src < srcend))
+    {
+        unsigned char ch = *src++;
+        if (ch < 0x80)  /* special fast case for 7-bit ASCII */
+        {
+            *dst++ = ch;
+            continue;
+        }
+        if ((res = decode_utf8_char( ch, &src, srcend )) <= 0xffff)
+        {
+            *dst++ = res;
+        }
+        else if (res <= 0x10ffff)  /* we need surrogates */
+        {
+            res -= 0x10000;
+            *dst++ = 0xd800 | (res >> 10);
+            if (dst == dstend) break;
+            *dst++ = 0xdc00 | (res & 0x3ff);
+        }
+        else
+        {
+            *dst++ = 0xfffd;
+            status = STATUS_SOME_NOT_MAPPED;
+        }
+    }
+    if (src < srcend) status = STATUS_BUFFER_TOO_SMALL;  /* overflow */
+    *reslen = (dstlen - (dstend - dst)) * sizeof(WCHAR);
+    return status;
+}




More information about the wine-cvs mailing list