Alexandre Julliard : kernelbase: Add a helper function to map an entire buffer to full width.
Alexandre Julliard
julliard at winehq.org
Thu Jun 2 16:26:08 CDT 2022
Module: wine
Branch: master
Commit: cd44979ce1794a092a4c2b99c74d49ed88d4098d
URL: https://source.winehq.org/git/wine.git/?a=commit;h=cd44979ce1794a092a4c2b99c74d49ed88d4098d
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Jun 2 09:56:19 2022 +0200
kernelbase: Add a helper function to map an entire buffer to full width.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/kernel32/tests/locale.c | 6 +++
dlls/kernelbase/locale.c | 111 ++++++++++++++++++++++---------------------
2 files changed, 64 insertions(+), 53 deletions(-)
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index 125d0c1f2ca..87c12430dac 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -2490,6 +2490,12 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
ret2 = func_ptr(LCMAP_FULLWIDTH | LCMAP_HIRAGANA, halfwidth_text, -1, NULL, 0);
ok(ret == ret2, "%s ret %d, expected value %d\n", func_name, ret, ret2);
+ /* LCMAP_FULLWIDTH | LCMAP_KATAKANA maps to full-width first */
+ ret = func_ptr(LCMAP_FULLWIDTH | LCMAP_KATAKANA, halfwidth_text, -1, buf, ARRAY_SIZE(buf));
+ ok(ret == lstrlenW(katakana_text) + 1, "%s ret %d, error %ld, expected value %d\n", func_name,
+ ret, GetLastError(), lstrlenW(katakana_text) + 1);
+ ok(!lstrcmpW(buf, katakana_text), "%s string compare mismatch\n", func_name);
+
/* test LCMAP_HALFWIDTH */
ret = func_ptr(LCMAP_HALFWIDTH, japanese_text, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(halfwidth_text) + 1, "%s ret %d, error %ld, expected value %d\n", func_name,
diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index 0fccc29bc6f..a0e4a74658f 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -3901,40 +3901,53 @@ static int find_substring( const struct sortguid *sortid, DWORD flags, const WCH
}
-/* compose a full-width katakana. return consumed source characters. */
-static int map_to_fullwidth( const WCHAR *src, int srclen, WCHAR *dst )
-{
- *dst = casemap( charmaps[CHARMAP_FULLWIDTH], *src );
- if (srclen <= 1) return 1;
-
- switch (src[1])
- {
- case 0xff9e: /* datakuten (voiced sound) */
- if ((*src >= 0xff76 && *src <= 0xff84) || (*src >= 0xff8a && *src <= 0xff8e) || *src == 0x30fd)
- *dst += 1;
- else if (*src == 0xff73)
- *dst = 0x30f4; /* KATAKANA LETTER VU */
- else if (*src == 0xff9c)
- *dst = 0x30f7; /* KATAKANA LETTER VA */
- else if (*src == 0x30f0)
- *dst = 0x30f8; /* KATAKANA LETTER VI */
- else if (*src == 0x30f1)
- *dst = 0x30f9; /* KATAKANA LETTER VE */
- else if (*src == 0xff66)
- *dst = 0x30fa; /* KATAKANA LETTER VO */
- else
- return 1;
- break;
- case 0xff9f: /* handakuten (semi-voiced sound) */
- if (*src >= 0xff8a && *src <= 0xff8e)
- *dst += 2;
- else
- return 1;
- break;
- default:
- return 1;
+/* map buffer to full-width katakana */
+static int map_to_fullwidth( const WCHAR *src, int srclen, WCHAR *dst, int dstlen )
+{
+ int pos;
+
+ for (pos = 0; srclen; pos++, src++, srclen--)
+ {
+ WCHAR wch = casemap( charmaps[CHARMAP_FULLWIDTH], *src );
+ if (srclen > 1)
+ {
+ switch (src[1])
+ {
+ case 0xff9e: /* dakuten (voiced sound) */
+ if ((*src >= 0xff76 && *src <= 0xff84) ||
+ (*src >= 0xff8a && *src <= 0xff8e) ||
+ *src == 0x30fd)
+ wch++;
+ else if (*src == 0xff73)
+ wch = 0x30f4; /* KATAKANA LETTER VU */
+ else if (*src == 0xff9c)
+ wch = 0x30f7; /* KATAKANA LETTER VA */
+ else if (*src == 0x30f0)
+ wch = 0x30f8; /* KATAKANA LETTER VI */
+ else if (*src == 0x30f1)
+ wch = 0x30f9; /* KATAKANA LETTER VE */
+ else if (*src == 0xff66)
+ wch = 0x30fa; /* KATAKANA LETTER VO */
+ else
+ break;
+ src++;
+ srclen--;
+ break;
+ case 0xff9f: /* handakuten (semi-voiced sound) */
+ if (*src >= 0xff8a && *src <= 0xff8e)
+ {
+ wch += 2;
+ src++;
+ srclen--;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (pos < dstlen) dst[pos] = wch;
}
- return 2;
+ return pos;
}
/* map single full-width character to single or double half-width characters. */
@@ -6373,15 +6386,7 @@ INT WINAPI DECLSPEC_HOTPATCH LCMapStringEx( const WCHAR *locale, DWORD flags, co
}
else if (flags & LCMAP_FULLWIDTH)
{
- WCHAR wch;
- for (len = 0; srclen; src++, srclen--, len++)
- {
- if (map_to_fullwidth( src, srclen, &wch ) == 2)
- {
- src++;
- srclen--;
- }
- }
+ len = map_to_fullwidth( src, srclen, NULL, 0 );
}
else if (flags & LCMAP_HALFWIDTH)
{
@@ -6429,20 +6434,20 @@ INT WINAPI DECLSPEC_HOTPATCH LCMapStringEx( const WCHAR *locale, DWORD flags, co
if (flags & (LCMAP_FULLWIDTH | LCMAP_HALFWIDTH | LCMAP_HIRAGANA | LCMAP_KATAKANA))
{
- for (len = dstlen, dst_ptr = dst; len && srclen; src++, srclen--, len--, dst_ptr++)
+ if (flags & LCMAP_FULLWIDTH)
{
- WCHAR wch;
- if (flags & LCMAP_FULLWIDTH)
+ len = map_to_fullwidth( src, srclen, dst, dstlen );
+ if (dstlen && dstlen < len)
{
- /* map half-width character to full-width one,
- e.g. U+FF71 -> U+30A2, U+FF8C U+FF9F -> U+30D7. */
- if (map_to_fullwidth( src, srclen, &wch ) == 2)
- {
- src++;
- srclen--;
- }
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ return 0;
}
- else wch = *src;
+ srclen = len;
+ src = dst;
+ }
+ for (len = dstlen, dst_ptr = dst; len && srclen; src++, srclen--, len--, dst_ptr++)
+ {
+ WCHAR wch = *src;
if (flags & LCMAP_KATAKANA) wch = casemap( charmaps[CHARMAP_KATAKANA], wch );
else if (flags & LCMAP_HIRAGANA) wch = casemap( charmaps[CHARMAP_HIRAGANA], wch );
More information about the wine-cvs
mailing list