Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Next Next commit
Implement GetSortKey on hybrid mode
  • Loading branch information
mkhamoyan committed Nov 27, 2023
commit 4b042653307d8c7b4883280c792abc7e64a56dab
3 changes: 3 additions & 0 deletions src/libraries/Common/src/Interop/Interop.Collation.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,8 @@ internal static partial class Globalization
[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_StartsWithNative", StringMarshalling = StringMarshalling.Utf16)]
[MethodImpl(MethodImplOptions.NoInlining)]
internal static unsafe partial int StartsWithNative(string localeName, int lNameLen, char* target, int cwTargetLength, char* source, int cwSourceLength, CompareOptions options);

[LibraryImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetSortKeyNative", StringMarshalling = StringMarshalling.Utf16)]
internal static unsafe partial int GetSortKeyNative(string localeName, int lNameLen, char* str, int strLength, byte* sortKey, int sortKeyLength, CompareOptions options);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -700,14 +700,36 @@ private unsafe SortKey IcuCreateSortKey(string source, CompareOptions options)
byte[] keyData;
fixed (char* pSource = source)
{
int sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, null, 0, options);
int sortKeyLength;
#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
if (GlobalizationMode.Hybrid)
{
sortKeyLength = Interop.Globalization.GetSortKeyNative(m_name, m_name.Length, pSource, source.Length, null, 0, options);
}
else
#endif
{
sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, null, 0, options);
}
keyData = new byte[sortKeyLength];

fixed (byte* pSortKey = keyData)
{
if (Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pSortKey, sortKeyLength, options) != sortKeyLength)
#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
if (GlobalizationMode.Hybrid)
{
throw new ArgumentException(SR.Arg_ExternalException);
if (Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, null, 0, options) != sortKeyLength)
{
throw new ArgumentException(SR.Arg_ExternalException);
}
}
else
#endif
{
if (Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pSortKey, sortKeyLength, options) != sortKeyLength)
{
throw new ArgumentException(SR.Arg_ExternalException);
}
}
}
}
Expand All @@ -728,7 +750,16 @@ private unsafe int IcuGetSortKey(ReadOnlySpan<char> source, Span<byte> destinati
fixed (char* pSource = &MemoryMarshal.GetReference(source))
fixed (byte* pDest = &MemoryMarshal.GetReference(destination))
{
actualSortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pDest, destination.Length, options);
#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
if (GlobalizationMode.Hybrid)
{
actualSortKeyLength = Interop.Globalization.GetSortKeyNative(m_name, m_name.Length, pSource, source.Length, pDest, destination.Length, options);
}
else
#endif
{
actualSortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pDest, destination.Length, options);
}
}

// The check below also handles errors due to negative values / overflow being returned.
Expand Down Expand Up @@ -758,7 +789,16 @@ private unsafe int IcuGetSortKeyLength(ReadOnlySpan<char> source, CompareOptions

fixed (char* pSource = &MemoryMarshal.GetReference(source))
{
return Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, null, 0, options);
#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
if (GlobalizationMode.Hybrid)
{
return Interop.Globalization.GetSortKeyNative(m_name, m_name.Length, pSource, source.Length, null, 0, options);
}
else
#endif
{
return Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, null, 0, options);
}
}
}

Expand Down Expand Up @@ -809,7 +849,16 @@ private unsafe int IcuGetHashCodeOfString(ReadOnlySpan<char> source, CompareOpti
{
fixed (byte* pSortKey = &MemoryMarshal.GetReference(sortKey))
{
sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pSortKey, sortKey.Length, options);
#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
if (GlobalizationMode.Hybrid)
{
sortKeyLength = Interop.Globalization.GetSortKeyNative(m_name, m_name.Length, pSource, source.Length, pSortKey, sortKey.Length, options);
}
else
#endif
{
sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pSortKey, sortKey.Length, options);
}
}

if (sortKeyLength > sortKey.Length) // slow path for big strings
Expand All @@ -823,7 +872,16 @@ private unsafe int IcuGetHashCodeOfString(ReadOnlySpan<char> source, CompareOpti

fixed (byte* pSortKey = &MemoryMarshal.GetReference(sortKey))
{
sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pSortKey, sortKey.Length, options);
#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
if (GlobalizationMode.Hybrid)
{
sortKeyLength = Interop.Globalization.GetSortKeyNative(m_name, m_name.Length, pSource, source.Length, pSortKey, sortKey.Length, options);
}
else
#endif
{
sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, pSortKey, sortKey.Length, options);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1450,7 +1450,7 @@ public SortKey GetSortKey(string source)
private SortKey CreateSortKeyCore(string source, CompareOptions options) =>
GlobalizationMode.UseNls ?
NlsCreateSortKey(source, options) :
#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
#if TARGET_BROWSER
GlobalizationMode.Hybrid ?
throw new PlatformNotSupportedException(GetPNSEText("SortKey")) :
#endif
Expand Down Expand Up @@ -1493,7 +1493,7 @@ public int GetSortKey(ReadOnlySpan<char> source, Span<byte> destination, Compare
private int GetSortKeyCore(ReadOnlySpan<char> source, Span<byte> destination, CompareOptions options) =>
GlobalizationMode.UseNls ?
NlsGetSortKey(source, destination, options) :
#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
#if TARGET_BROWSER
GlobalizationMode.Hybrid ?
throw new PlatformNotSupportedException(GetPNSEText("SortKey")) :
#endif
Expand Down Expand Up @@ -1530,7 +1530,7 @@ public int GetSortKeyLength(ReadOnlySpan<char> source, CompareOptions options =
private int GetSortKeyLengthCore(ReadOnlySpan<char> source, CompareOptions options) =>
GlobalizationMode.UseNls ?
NlsGetSortKeyLength(source, options) :
#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
#if TARGET_BROWSER
GlobalizationMode.Hybrid ?
throw new PlatformNotSupportedException(GetPNSEText("SortKey")) :
#endif
Expand Down Expand Up @@ -1607,7 +1607,7 @@ public int GetHashCode(ReadOnlySpan<char> source, CompareOptions options)
private unsafe int GetHashCodeOfStringCore(ReadOnlySpan<char> source, CompareOptions options) =>
GlobalizationMode.UseNls ?
NlsGetHashCodeOfString(source, options) :
#if TARGET_BROWSER || TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
#if TARGET_BROWSER
GlobalizationMode.Hybrid ?
throw new PlatformNotSupportedException(GetPNSEText("HashCode")) :
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ public void SortKeyKanaTest(CompareInfo compareInfo, string string1, string stri
SortKeyTest(compareInfo, string1, string2, options, expected);
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalization))]
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
public void SortKeyTestNotSupported()
{
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TestRuntime>true</TestRuntime>
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
<HybridGlobalization>true</HybridGlobalization>
<UnicodeUcdVersion>15.0</UnicodeUcdVersion>

<!-- some tests require full ICU data, force it -->
Expand Down
1 change: 1 addition & 0 deletions src/native/libs/System.Globalization.Native/entrypoints.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ static const Entry s_globalizationNative[] =
DllImportEntry(GlobalizationNative_GetLocaleNameNative)
DllImportEntry(GlobalizationNative_GetLocalesNative)
DllImportEntry(GlobalizationNative_GetLocaleTimeFormatNative)
DllImportEntry(GlobalizationNative_GetSortKeyNative)
DllImportEntry(GlobalizationNative_GetTimeZoneDisplayNameNative)
DllImportEntry(GlobalizationNative_IndexOfNative)
DllImportEntry(GlobalizationNative_IsNormalizedNative)
Expand Down
10 changes: 9 additions & 1 deletion src/native/libs/System.Globalization.Native/pal_collation.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ PALEXPORT int32_t GlobalizationNative_EndsWithNative(const uint16_t* localeName,
int32_t cwSuffixLength,
const uint16_t* lpSource,
int32_t cwSourceLength,
int32_t options);
int32_t options);

PALEXPORT int32_t GlobalizationNative_GetSortKeyNative(const uint16_t* localeName,
int32_t lNameLength,
const UChar* lpStr,
int32_t cwStrLength,
uint8_t* sortKey,
int32_t cbSortKeyLength,
int32_t options);

#endif
47 changes: 47 additions & 0 deletions src/native/libs/System.Globalization.Native/pal_collation.m
Original file line number Diff line number Diff line change
Expand Up @@ -295,4 +295,51 @@ int32_t GlobalizationNative_EndsWithNative(const uint16_t* localeName, int32_t l
}
}

int32_t GlobalizationNative_GetSortKeyNative(const uint16_t* localeName, int32_t lNameLength, const UChar* lpStr, int32_t cwStrLength,
uint8_t* sortKey, int32_t cbSortKeyLength, int32_t options)
{
@autoreleasepool {
if (cwStrLength == 0)
{
sortKey = malloc(1);
sortKey[0] = '\0';
return 1;
}
NSString *sourceString = [NSString stringWithCharacters: lpStr length: cwStrLength];
NSString *sourceStringCleaned = RemoveWeightlessCharacters(sourceString);

NSLocale *locale = GetCurrentLocale(localeName, lNameLength);
NSStringCompareOptions comparisonOptions = options == 0 ? 0 : ConvertFromCompareOptionsToNSStringCompareOptions(options);

// Generate a sort key for the original string based on the locale
NSString *transformedString = [sourceStringCleaned stringByFoldingWithOptions:comparisonOptions locale:locale];

// Convert the string to UTF-8 representation
const char *utf8Bytes = [transformedString UTF8String];
if (utf8Bytes != NULL) {
NSUInteger utf8Length = [transformedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
memcpy(sortKey, utf8Bytes, utf8Length);
return utf8Length;
}
else
{
// Convert the string to UTF-16 representation
NSData *utf16Data = [transformedString dataUsingEncoding:NSUTF16StringEncoding];

if (utf16Data != nil) {
const uint16_t *utf16Bytes = (const uint16_t *)[utf16Data bytes];
NSUInteger utf16Length = [utf16Data length] / sizeof(uint16_t);

if (sortKey != NULL) {
// Convert UTF-16 to UTF-8 manually
memcpy(sortKey, utf16Bytes, utf16Length * 2);
return utf16Length * 2;
}
}
}

return 0;
}
}

#endif