Alexandre Julliard : kernelbase: Add a helper function to case-map an entire buffer.

Alexandre Julliard julliard at winehq.org
Thu Jun 2 16:26:08 CDT 2022


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jun  2 09:51:58 2022 +0200

kernelbase: Add a helper function to case-map an entire buffer.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernelbase/locale.c | 51 +++++++++++++++++++++++++++++-------------------
 1 file changed, 31 insertions(+), 20 deletions(-)

diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index 5a6022addc9..0fccc29bc6f 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -2000,6 +2000,16 @@ static inline WORD get_char_type( DWORD type, WCHAR ch )
 }
 
 
+static int casemap_string( const USHORT *table, const WCHAR *src, int srclen, WCHAR *dst, int dstlen )
+{
+    int pos, ret = srclen;
+
+    for (pos = 0; pos < dstlen && srclen; pos++, src++, srclen--)
+        dst[pos] = casemap( table, *src );
+    return ret;
+}
+
+
 static union char_weights get_char_weights( WCHAR c, UINT except )
 {
     union char_weights ret;
@@ -2205,13 +2215,12 @@ static NTSTATUS expand_ligatures( const WCHAR *src, int srclen, WCHAR *dst, int
 
 static NTSTATUS fold_digits( const WCHAR *src, int srclen, WCHAR *dst, int *dstlen )
 {
-    int i, len = *dstlen;
+    NTSTATUS ret = STATUS_SUCCESS;
+    int len = casemap_string( charmaps[CHARMAP_FOLDDIGITS], src, srclen, dst, *dstlen );
 
-    *dstlen = srclen;
-    if (!len) return STATUS_SUCCESS;
-    if (srclen > len) return STATUS_BUFFER_TOO_SMALL;
-    for (i = 0; i < srclen; i++) dst[i] = casemap( charmaps[CHARMAP_FOLDDIGITS], src[i] );
-    return STATUS_SUCCESS;
+    if (*dstlen && *dstlen < len) ret = STATUS_BUFFER_TOO_SMALL;
+    *dstlen = len;
+    return ret;
 }
 
 
@@ -6403,18 +6412,19 @@ INT WINAPI DECLSPEC_HOTPATCH LCMapStringEx( const WCHAR *locale, DWORD flags, co
             *dst_ptr++ = *src;
             len--;
         }
+        len = dst_ptr - dst;
         goto done;
     }
 
     if (flags & LCMAP_TRADITIONAL_CHINESE)
     {
-        for (len = dstlen, dst_ptr = dst; srclen && len; srclen--, len--)
-            *dst_ptr++ = casemap( charmaps[CHARMAP_TRADITIONAL], *src++ );
+        len = casemap_string( charmaps[CHARMAP_TRADITIONAL], src, srclen, dst, dstlen );
+        goto done;
     }
     if (flags & LCMAP_SIMPLIFIED_CHINESE)
     {
-        for (len = dstlen, dst_ptr = dst; srclen && len; srclen--, len--)
-            *dst_ptr++ = casemap( charmaps[CHARMAP_SIMPLIFIED], *src++ );
+        len = casemap_string( charmaps[CHARMAP_SIMPLIFIED], src, srclen, dst, dstlen );
+        goto done;
     }
 
     if (flags & (LCMAP_FULLWIDTH | LCMAP_HALFWIDTH | LCMAP_HIRAGANA | LCMAP_KATAKANA))
@@ -6450,8 +6460,13 @@ INT WINAPI DECLSPEC_HOTPATCH LCMapStringEx( const WCHAR *locale, DWORD flags, co
             }
             else *dst_ptr = wch;
         }
+        if (srclen)
+        {
+            SetLastError( ERROR_INSUFFICIENT_BUFFER );
+            return 0;
+        }
+        len = dst_ptr - dst;
         if (!(flags & (LCMAP_UPPERCASE | LCMAP_LOWERCASE)) || srclen) goto done;
-
         srclen = dst_ptr - dst;
         src = dst;
     }
@@ -6460,25 +6475,21 @@ INT WINAPI DECLSPEC_HOTPATCH LCMapStringEx( const WCHAR *locale, DWORD flags, co
     {
         const USHORT *table = sort.casemap + (flags & LCMAP_LINGUISTIC_CASING ? sortid->casemap : 0);
         table = table + 2 + (flags & LCMAP_LOWERCASE ? table[1] : 0);
-        for (len = dstlen, dst_ptr = dst; srclen && len; src++, srclen--, len--)
-            *dst_ptr++ = casemap( table, *src );
+        len = casemap_string( table, src, srclen, dst, dstlen );
     }
     else
     {
-        len = min( srclen, dstlen );
-        memcpy( dst, src, len * sizeof(WCHAR) );
-        dst_ptr = dst + len;
-        srclen -= len;
+        len = srclen;
+        memcpy( dst, src, min( srclen, dstlen ) * sizeof(WCHAR) );
     }
 
 done:
-    if (srclen)
+    if (dstlen && dstlen < len)
     {
         SetLastError( ERROR_INSUFFICIENT_BUFFER );
         return 0;
     }
-
-    return dst_ptr - dst;
+    return len;
 }
 
 




More information about the wine-cvs mailing list