Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS][non-icu] Implement missing Locale and Casing functions #94038

Merged
merged 10 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/libraries/Common/src/Interop/Interop.Casing.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ internal static partial class Globalization

[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_ChangeCaseInvariantNative", StringMarshalling = StringMarshalling.Utf8)]
internal static unsafe partial int ChangeCaseInvariantNative(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, [MarshalAs(UnmanagedType.Bool)] bool bToUpper);

[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_InitOrdinalCasingPageNative", StringMarshalling = StringMarshalling.Utf16)]
internal static unsafe partial void InitOrdinalCasingPageNative(int pageNumber, char* pTarget);
}
}
15 changes: 11 additions & 4 deletions src/libraries/Common/src/Interop/Interop.Locale.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ internal static partial class Interop
{
internal static partial class Globalization
{
[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLocaleNameNative", StringMarshalling = StringMarshalling.Utf8)]
internal static partial string GetLocaleNameNative(string localeName);
[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetDefaultLocaleNameNative", StringMarshalling = StringMarshalling.Utf8)]
internal static partial string GetDefaultLocaleNameNative();

[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLocaleInfoStringNative", StringMarshalling = StringMarshalling.Utf8)]
internal static partial string GetLocaleInfoStringNative(string localeName, uint localeStringData);
Expand All @@ -22,10 +22,17 @@ internal static partial class Globalization
[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLocaleInfoSecondaryGroupingSizeNative", StringMarshalling = StringMarshalling.Utf8)]
internal static partial int GetLocaleInfoSecondaryGroupingSizeNative(string localeName, uint localeGroupingData);

[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLocaleTimeFormatNative", StringMarshalling = StringMarshalling.Utf8)]
internal static partial string GetLocaleTimeFormatNative(string localeName, [MarshalAs(UnmanagedType.Bool)] bool shortFormat);
[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLocaleNameNative", StringMarshalling = StringMarshalling.Utf8)]
internal static partial string GetLocaleNameNative(string localeName);

[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLocalesNative", StringMarshalling = StringMarshalling.Utf16)]
internal static partial int GetLocalesNative([Out] char[]? value, int valueLength);

[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLocaleTimeFormatNative", StringMarshalling = StringMarshalling.Utf8)]
internal static partial string GetLocaleTimeFormatNative(string localeName, [MarshalAs(UnmanagedType.Bool)] bool shortFormat);

[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_IsPredefinedLocaleNative", StringMarshalling = StringMarshalling.Utf8)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool IsPredefinedLocaleNative(string localeName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -365,12 +365,16 @@ public static string GetDistroVersionString()
public static Version ICUVersion => m_icuVersion.Value;

public static bool IsInvariantGlobalization => m_isInvariant.Value;
public static bool IsHybridGlobalization => m_isHybrid.Value;
public static bool IsHybridGlobalizationOnBrowser => m_isHybrid.Value && IsBrowser;
public static bool IsHybridGlobalizationOnOSX => m_isHybrid.Value && (IsOSX || IsMacCatalyst || IsiOS || IstvOS);
public static bool IsNotHybridGlobalizationOnBrowser => !IsHybridGlobalizationOnBrowser;
public static bool IsNotInvariantGlobalization => !IsInvariantGlobalization;
public static bool IsNotHybridGlobalization => !IsHybridGlobalization;
public static bool IsNotHybridGlobalizationOnOSX => !IsHybridGlobalizationOnOSX;
public static bool IsIcuGlobalization => ICUVersion > new Version(0, 0, 0, 0);
public static bool IsIcuGlobalizationAndNotHybridOnBrowser => IsIcuGlobalization && IsNotHybridGlobalizationOnBrowser;
public static bool IsIcuGlobalizationAndNotHybrid => IsIcuGlobalization && IsNotHybridGlobalization;
public static bool IsNlsGlobalization => IsNotInvariantGlobalization && !IsIcuGlobalization;

public static bool IsSubstAvailable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public void IsSuffix(CompareInfo compareInfo, string source, string value, Compa
[Fact]
public void IsSuffix_UnassignedUnicode()
{
bool result = PlatformDetection.IsIcuGlobalization ? false : true;
bool result = PlatformDetection.IsIcuGlobalization || PlatformDetection.IsHybridGlobalizationOnOSX ? false : true;
int expectedMatchLength = (result) ? 6 : 0;

IsSuffix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.None, result, expectedMatchLength);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void EqualsTest(CompareInfo compare1, object value, bool expected)
new object[] { "", CompareOptions.None, "\u200c", CompareOptions.None, true }, // see comment at bottom of SortKey_TestData
};

[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalization))]
[MemberData(nameof(GetHashCodeTestData))]
public void GetHashCodeTest(string source1, CompareOptions options1, string source2, CompareOptions options2, bool expected)
{
Expand Down Expand Up @@ -345,14 +345,14 @@ public static void LcidTest(string cultureName, int lcid)
Assert.Equal(lcid, ci.LCID);
}

[ConditionalTheory(typeof(CompareInfoTests), nameof(IsNotWindowsKanaRegressedVersionAndNotHybridGlobalizationOnWasm))]
[ConditionalTheory(typeof(CompareInfoTests), nameof(IsNotWindowsKanaRegressedVersionAndNotHybridGlobalization))]
[MemberData(nameof(SortKey_Kana_TestData))]
public void SortKeyKanaTest(CompareInfo compareInfo, string string1, string string2, CompareOptions options, int expected)
{
SortKeyTest(compareInfo, string1, string2, options, expected);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalization))]
public void SortKeyTestNotSupported()
{
try
Expand Down Expand Up @@ -395,7 +395,7 @@ public void SortKeyTestNotSupported()
private static bool WindowsVersionHasTheCompareStringRegression =>
PlatformDetection.IsNlsGlobalization && CompareStringEx("", NORM_LINGUISTIC_CASING, "", 0, "\u200C", 1, IntPtr.Zero, IntPtr.Zero, 0) != 2;

[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalization))]
[MemberData(nameof(SortKey_TestData))]
public void SortKeyTest(CompareInfo compareInfo, string string1, string string2, CompareOptions options, int expectedSign)
{
Expand Down Expand Up @@ -444,7 +444,7 @@ unsafe static void RunSpanSortKeyTest(CompareInfo compareInfo, ReadOnlySpan<char
}
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalization))]
public void SortKeyMiscTest()
{
CompareInfo ci = new CultureInfo("en-US").CompareInfo;
Expand Down Expand Up @@ -518,7 +518,7 @@ public void IsSortableTest(object sourceObj, bool expected)
Assert.Equal(expected && !char.IsSurrogate(c), CompareInfo.IsSortable(c));
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalization))]
public void VersionTest()
{
SortVersion sv1 = CultureInfo.GetCultureInfo("en-US").CompareInfo.Version;
Expand All @@ -529,7 +529,7 @@ public void VersionTest()
Assert.NotEqual(sv1.SortId, sv2.SortId);
}

[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalization))]
[MemberData(nameof(GetHashCodeTestData))]
public void GetHashCode_Span(string source1, CompareOptions options1, string source2, CompareOptions options2, bool expectSameHashCode)
{
Expand All @@ -546,7 +546,7 @@ public void GetHashCode_Span(string source1, CompareOptions options1, string sou
Assert.Equal(expectSameHashCode, hashOfSource1AsSpan == hashOfSource2AsSpan);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalization))]
public void GetHashCode_NullAndEmptySpan()
{
// Ensure that null spans and non-null empty spans produce the same hash code.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@ protected static bool IsNotWindowsKanaRegressedVersion() => !PlatformDetection.I
s_invariantCompare.Compare("\u3060", "\uFF80\uFF9E", CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase) == 0;

protected static bool IsNotWindowsKanaRegressedVersionAndNotHybridGlobalizationOnWasm() => !PlatformDetection.IsHybridGlobalizationOnBrowser && IsNotWindowsKanaRegressedVersion();
protected static bool IsNotWindowsKanaRegressedVersionAndNotHybridGlobalization() => IsNotWindowsKanaRegressedVersion() && PlatformDetection.IsNotHybridGlobalization;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -635,13 +635,11 @@ public static IEnumerable<object[]> CultureInfo_TestData()
yield return new object[] { 0x2009, new [] { "en-jm" }, "en-JM", "eng", "ENJ", "en-JM", "en-JM" };
yield return new object[] { 0x241a, new [] { "sr-latn-rs" }, "sr-Latn-RS", "srp", "SRM", "sr-Latn-RS", "sr-Latn-RS" };
yield return new object[] { 0x2809, new [] { "en-bz" }, "en-BZ", "eng", "ENL", "en-BZ", "en-BZ" };
yield return new object[] { 0x281a, new [] { "sr-cyrl-rs" }, "sr-Cyrl-RS", "srp", "SRO", "sr-Cyrl-RS", "sr-Cyrl-RS" };
yield return new object[] { 0x2c09, new [] { "en-tt" }, "en-TT", "eng", "ENT", "en-TT", "en-TT" };
yield return new object[] { 0x3009, new [] { "en-zw" }, "en-ZW", "eng", "ENW", "en-ZW", "en-ZW" };
yield return new object[] { 0x3409, new [] { "en-ph" }, "en-PH", "eng", "ENP", "en-PH", "en-PH" };
yield return new object[] { 0x4009, new [] { "en-in" }, "en-IN", "eng", "ENN", "en-IN", "en-IN" };
yield return new object[] { 0x4809, new [] { "en-sg" }, "en-SG", "eng", "ENE", "en-SG", "en-SG" };
yield return new object[] { 0x6c1a, new [] { "sr-cyrl" }, "sr-Cyrl-RS", "srp", "SRO", "sr-Cyrl", "sr-Cyrl-RS" };
yield return new object[] { 0x701a, new [] { "sr-latn" }, "sr-Latn-RS", "srp", "SRM", "sr-Latn", "sr-Latn-RS" };
yield return new object[] { 0x7804, new [] { "zh" }, "zh-CN", "zho", "CHS", "zh", "zh-CN" };
yield return new object[] { 0x7c04, new [] { "zh-cht", "zh-hant" }, "zh-HK", "zho", "CHT", "zh-Hant", "zh-HK" };
Expand All @@ -654,6 +652,11 @@ public static IEnumerable<object[]> CultureInfo_TestData()
yield return new object[] { 0x40404, new [] { "zh-tw_radstr", "zh-tw" }, "zh-TW", "zho", "CHT", "zh-Hant-TW", "zh-TW" };
yield return new object[] { 0x40411, new [] { "ja-jp_radstr", "ja-jp" }, "ja-JP", "jpn", "JPN", "ja-JP", "ja-JP" };
yield return new object[] { 0x40c04, new [] { "zh-hk_radstr", "zh-hk" }, "zh-HK", "zho", "ZHH", "zh-Hant-HK", "zh-HK" };
if (!PlatformDetection.IsHybridGlobalizationOnOSX)
{
yield return new object[] { 0x281a, new [] { "sr-cyrl-rs" }, "sr-Cyrl-RS", "srp", "SRO", "sr-Cyrl-RS", "sr-Cyrl-RS" };
yield return new object[] { 0x6c1a, new [] { "sr-cyrl" }, "sr-Cyrl-RS", "srp", "SRO", "sr-Cyrl", "sr-Cyrl-RS" };
}
}

[Theory]
Expand Down
Loading
Loading