kernelbase: Support UTF-7/8 codepages in get_codepage_table().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
fd2ecee06f
commit
8993e15cfa
|
@ -4251,6 +4251,7 @@ static void test_GetCPInfo(void)
|
|||
{
|
||||
BOOL ret;
|
||||
CPINFO cpinfo;
|
||||
CPINFOEXW cpiw;
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
ret = GetCPInfo(CP_SYMBOL, &cpinfo);
|
||||
|
@ -4275,6 +4276,18 @@ static void test_GetCPInfo(void)
|
|||
for (i = 0; i < sizeof(cpinfo.LeadByte); i++)
|
||||
ok(!cpinfo.LeadByte[i], "expected NUL byte in index %u\n", i);
|
||||
ok(cpinfo.MaxCharSize == 5, "expected 5, got 0x%x\n", cpinfo.MaxCharSize);
|
||||
|
||||
memset( &cpiw, 0xcc, sizeof(cpiw) );
|
||||
ret = GetCPInfoExW( CP_UTF7, 0, &cpiw );
|
||||
ok( ret, "GetCPInfoExW failed err %lu\n", GetLastError() );
|
||||
ok( cpiw.DefaultChar[0] == 0x3f, "wrong DefaultChar[0] %02x\n", cpiw.DefaultChar[0] );
|
||||
ok( cpiw.DefaultChar[1] == 0, "wrong DefaultChar[1] %02x\n", cpiw.DefaultChar[1] );
|
||||
for (i = 0; i < 12; i++) ok( cpiw.LeadByte[i] == 0, "wrong LeadByte[%u] %02x\n", i, cpiw.LeadByte[i] );
|
||||
ok( cpiw.MaxCharSize == 5, "wrong MaxCharSize %02x\n", cpiw.MaxCharSize );
|
||||
ok( cpiw.CodePage == CP_UTF7, "wrong CodePage %02x\n", cpiw.CodePage );
|
||||
ok( cpiw.UnicodeDefaultChar == 0xfffd, "wrong UnicodeDefaultChar %02x\n", cpiw.UnicodeDefaultChar );
|
||||
ok( !wcscmp( cpiw.CodePageName, L"65000 (UTF-7)" ),
|
||||
"wrong CodePageName %s\n", debugstr_w(cpiw.CodePageName) );
|
||||
}
|
||||
|
||||
memset(cpinfo.LeadByte, '-', ARRAY_SIZE(cpinfo.LeadByte));
|
||||
|
@ -4293,10 +4306,27 @@ static void test_GetCPInfo(void)
|
|||
ok(cpinfo.DefaultChar[1] == 0, "expected 0, got 0x%x\n", cpinfo.DefaultChar[1]);
|
||||
for (i = 0; i < sizeof(cpinfo.LeadByte); i++)
|
||||
ok(!cpinfo.LeadByte[i], "expected NUL byte in index %u\n", i);
|
||||
ok(cpinfo.MaxCharSize == 4 || broken(cpinfo.MaxCharSize == 3) /* win9x */,
|
||||
"expected 4, got %u\n", cpinfo.MaxCharSize);
|
||||
ok(cpinfo.MaxCharSize == 4, "expected 4, got %u\n", cpinfo.MaxCharSize);
|
||||
|
||||
memset( &cpiw, 0xcc, sizeof(cpiw) );
|
||||
ret = GetCPInfoExW( CP_UTF8, 0, &cpiw );
|
||||
ok( ret, "GetCPInfoExW failed err %lu\n", GetLastError() );
|
||||
ok( cpiw.DefaultChar[0] == 0x3f, "wrong DefaultChar[0] %02x\n", cpiw.DefaultChar[0] );
|
||||
ok( cpiw.DefaultChar[1] == 0, "wrong DefaultChar[1] %02x\n", cpiw.DefaultChar[1] );
|
||||
for (i = 0; i < 12; i++) ok( cpiw.LeadByte[i] == 0, "wrong LeadByte[%u] %02x\n", i, cpiw.LeadByte[i] );
|
||||
ok( cpiw.MaxCharSize == 4, "wrong MaxCharSize %02x\n", cpiw.MaxCharSize );
|
||||
ok( cpiw.CodePage == CP_UTF8, "wrong CodePage %02x\n", cpiw.CodePage );
|
||||
ok( cpiw.UnicodeDefaultChar == 0xfffd, "wrong UnicodeDefaultChar %02x\n", cpiw.UnicodeDefaultChar );
|
||||
ok( !wcscmp( cpiw.CodePageName, L"65001 (UTF-8)" ),
|
||||
"wrong CodePageName %s\n", debugstr_w(cpiw.CodePageName) );
|
||||
}
|
||||
|
||||
|
||||
SetLastError( 0xdeadbeef );
|
||||
ret = GetCPInfoExW( 0xbeef, 0, &cpiw );
|
||||
ok( !ret, "GetCPInfoExW succeeeded\n" );
|
||||
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
|
||||
|
||||
if (pNtGetNlsSectionPtr)
|
||||
{
|
||||
CPTABLEINFO table;
|
||||
|
|
|
@ -164,8 +164,8 @@ static const struct { UINT cp; const WCHAR *name; } codepage_names[] =
|
|||
{ 28604, L"ISO 8859-14 Latin 8 (Celtic)" },
|
||||
{ 28605, L"ISO 8859-15 Latin 9 (Euro)" },
|
||||
{ 28606, L"ISO 8859-16 Latin 10 (Balkan)" },
|
||||
{ 65000, L"Unicode (UTF-7)" },
|
||||
{ 65001, L"Unicode (UTF-8)" }
|
||||
{ 65000, L"65000 (UTF-7)" },
|
||||
{ 65001, L"65001 (UTF-8)" }
|
||||
};
|
||||
|
||||
/* Unicode expanded ligatures */
|
||||
|
@ -1964,24 +1964,28 @@ static WCHAR compose_chars( WCHAR ch1, WCHAR ch2 )
|
|||
static UINT get_locale_codepage( const NLS_LOCALE_DATA *locale, ULONG flags )
|
||||
{
|
||||
UINT ret = locale->idefaultansicodepage;
|
||||
if ((flags & LOCALE_USE_CP_ACP) || ret == CP_UTF8) ret = system_locale->idefaultansicodepage;
|
||||
if ((flags & LOCALE_USE_CP_ACP) || ret == CP_UTF8) ret = nls_info.AnsiTableInfo.CodePage;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static UINT get_lcid_codepage( LCID lcid, ULONG flags )
|
||||
{
|
||||
UINT ret = GetACP();
|
||||
UINT ret = nls_info.AnsiTableInfo.CodePage;
|
||||
|
||||
if (!(flags & LOCALE_USE_CP_ACP) && lcid != GetSystemDefaultLCID())
|
||||
GetLocaleInfoW( lcid, LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
|
||||
(WCHAR *)&ret, sizeof(ret)/sizeof(WCHAR) );
|
||||
if (!(flags & LOCALE_USE_CP_ACP) && lcid != system_lcid)
|
||||
{
|
||||
const NLS_LOCALE_DATA *locale = NlsValidateLocale( &lcid, 0 );
|
||||
if (locale) ret = locale->idefaultansicodepage;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static const CPTABLEINFO *get_codepage_table( UINT codepage )
|
||||
{
|
||||
static const CPTABLEINFO utf7_cpinfo = { CP_UTF7, 5, '?', 0xfffd, '?', '?' };
|
||||
static const CPTABLEINFO utf8_cpinfo = { CP_UTF8, 4, '?', 0xfffd, '?', '?' };
|
||||
unsigned int i;
|
||||
USHORT *ptr;
|
||||
SIZE_T size;
|
||||
|
@ -1996,15 +2000,13 @@ static const CPTABLEINFO *get_codepage_table( UINT codepage )
|
|||
codepage = mac_cp;
|
||||
break;
|
||||
case CP_THREAD_ACP:
|
||||
if (NtCurrentTeb()->CurrentLocale == GetUserDefaultLCID()) return &nls_info.AnsiTableInfo;
|
||||
codepage = get_lcid_codepage( NtCurrentTeb()->CurrentLocale, 0 );
|
||||
if (!codepage) return &nls_info.AnsiTableInfo;
|
||||
break;
|
||||
default:
|
||||
if (codepage == nls_info.AnsiTableInfo.CodePage) return &nls_info.AnsiTableInfo;
|
||||
if (codepage == nls_info.OemTableInfo.CodePage) return &nls_info.OemTableInfo;
|
||||
break;
|
||||
}
|
||||
if (codepage == nls_info.AnsiTableInfo.CodePage) return &nls_info.AnsiTableInfo;
|
||||
if (codepage == nls_info.OemTableInfo.CodePage) return &nls_info.OemTableInfo;
|
||||
if (codepage == CP_UTF8) return &utf8_cpinfo;
|
||||
if (codepage == CP_UTF7) return &utf7_cpinfo;
|
||||
|
||||
RtlEnterCriticalSection( &locale_section );
|
||||
|
||||
|
@ -4838,27 +4840,14 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetCPInfo( UINT codepage, CPINFO *cpinfo )
|
|||
{
|
||||
const CPTABLEINFO *table;
|
||||
|
||||
if (!cpinfo)
|
||||
if (!cpinfo || !(table = get_codepage_table( codepage )))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
switch (codepage)
|
||||
{
|
||||
case CP_UTF7:
|
||||
case CP_UTF8:
|
||||
cpinfo->DefaultChar[0] = 0x3f;
|
||||
cpinfo->DefaultChar[1] = 0;
|
||||
memset( cpinfo->LeadByte, 0, sizeof(cpinfo->LeadByte) );
|
||||
cpinfo->MaxCharSize = (codepage == CP_UTF7) ? 5 : 4;
|
||||
break;
|
||||
default:
|
||||
if (!(table = get_codepage_table( codepage ))) return FALSE;
|
||||
cpinfo->MaxCharSize = table->MaximumCharacterSize;
|
||||
memcpy( cpinfo->DefaultChar, &table->DefaultChar, sizeof(cpinfo->DefaultChar) );
|
||||
memcpy( cpinfo->LeadByte, table->LeadByte, sizeof(cpinfo->LeadByte) );
|
||||
break;
|
||||
}
|
||||
cpinfo->MaxCharSize = table->MaximumCharacterSize;
|
||||
memcpy( cpinfo->DefaultChar, &table->DefaultChar, sizeof(cpinfo->DefaultChar) );
|
||||
memcpy( cpinfo->LeadByte, table->LeadByte, sizeof(cpinfo->LeadByte) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -4871,38 +4860,16 @@ BOOL WINAPI GetCPInfoExW( UINT codepage, DWORD flags, CPINFOEXW *cpinfo )
|
|||
const CPTABLEINFO *table;
|
||||
int min, max, pos;
|
||||
|
||||
if (!cpinfo)
|
||||
if (!cpinfo || !(table = get_codepage_table( codepage )))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
switch (codepage)
|
||||
{
|
||||
case CP_UTF7:
|
||||
cpinfo->DefaultChar[0] = 0x3f;
|
||||
cpinfo->DefaultChar[1] = 0;
|
||||
cpinfo->LeadByte[0] = cpinfo->LeadByte[1] = 0;
|
||||
cpinfo->MaxCharSize = 5;
|
||||
cpinfo->CodePage = CP_UTF7;
|
||||
cpinfo->UnicodeDefaultChar = 0x3f;
|
||||
break;
|
||||
case CP_UTF8:
|
||||
cpinfo->DefaultChar[0] = 0x3f;
|
||||
cpinfo->DefaultChar[1] = 0;
|
||||
cpinfo->LeadByte[0] = cpinfo->LeadByte[1] = 0;
|
||||
cpinfo->MaxCharSize = 4;
|
||||
cpinfo->CodePage = CP_UTF8;
|
||||
cpinfo->UnicodeDefaultChar = 0x3f;
|
||||
break;
|
||||
default:
|
||||
if (!(table = get_codepage_table( codepage ))) return FALSE;
|
||||
cpinfo->MaxCharSize = table->MaximumCharacterSize;
|
||||
memcpy( cpinfo->DefaultChar, &table->DefaultChar, sizeof(cpinfo->DefaultChar) );
|
||||
memcpy( cpinfo->LeadByte, table->LeadByte, sizeof(cpinfo->LeadByte) );
|
||||
cpinfo->CodePage = table->CodePage;
|
||||
cpinfo->UnicodeDefaultChar = table->UniDefaultChar;
|
||||
break;
|
||||
}
|
||||
cpinfo->MaxCharSize = table->MaximumCharacterSize;
|
||||
memcpy( cpinfo->DefaultChar, &table->DefaultChar, sizeof(cpinfo->DefaultChar) );
|
||||
memcpy( cpinfo->LeadByte, table->LeadByte, sizeof(cpinfo->LeadByte) );
|
||||
cpinfo->CodePage = table->CodePage;
|
||||
cpinfo->UnicodeDefaultChar = table->UniDefaultChar;
|
||||
|
||||
min = 0;
|
||||
max = ARRAY_SIZE(codepage_names) - 1;
|
||||
|
@ -5775,9 +5742,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH IsValidCodePage( UINT codepage )
|
|||
case CP_MACCP:
|
||||
case CP_THREAD_ACP:
|
||||
return FALSE;
|
||||
case CP_UTF7:
|
||||
case CP_UTF8:
|
||||
return TRUE;
|
||||
default:
|
||||
return get_codepage_table( codepage ) != NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue