Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ internal static partial class Interop
internal static unsafe partial class JsGlobalization
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe nint GetCalendarInfo(in string culture, CalendarId calendarId, char* buffer, int bufferMaxLength, out int bufferLength);
internal static extern unsafe nint GetCalendarInfo(char* culture, int cultureLength, CalendarId calendarId, char* buffer, int bufferMaxLength, out int bufferLength);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ internal static partial class Interop
internal static unsafe partial class JsGlobalization
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe nint CompareString(in string culture, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out int resultPtr);
internal static extern unsafe nint CompareString(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out int resultPtr);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe nint StartsWith(in string culture, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out bool resultPtr);
internal static extern unsafe nint StartsWith(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out bool resultPtr);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe nint EndsWith(in string culture, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out bool resultPtr);
internal static extern unsafe nint EndsWith(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, out bool resultPtr);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe nint IndexOf(in string culture, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, bool fromBeginning, out int resultPtr);
internal static extern unsafe nint IndexOf(char* culture, int cultureLength, char* str1, int str1Len, char* str2, int str2Len, global::System.Globalization.CompareOptions options, bool fromBeginning, out int resultPtr);
}
}
8 changes: 4 additions & 4 deletions src/libraries/Common/src/Interop/Browser/Interop.Locale.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ internal static partial class Interop
internal static unsafe partial class JsGlobalization
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe nint GetCultureInfo(in string culture, char* buffer, int bufferMaxLength, out int resultLength);
internal static extern unsafe nint GetCultureInfo(char* culture, int cultureLength, char* buffer, int bufferMaxLength, out int resultLength);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe nint GetFirstDayOfWeek(in string culture, out int resultPtr);
internal static extern unsafe nint GetFirstDayOfWeek(char* culture, int cultureLength, out int resultPtr);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe nint GetFirstWeekOfYear(in string culture, out int resultPtr);
internal static extern unsafe nint GetFirstWeekOfYear(char* culture, int cultureLength, out int resultPtr);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe nint GetLocaleInfo(in string locale, in string culture, char* buffer, int bufferLength, out int resultLength);
internal static extern unsafe nint GetLocaleInfo(char* locale, int localeLength, char* culture, int cultureLength, char* buffer, int bufferLength, out int resultLength);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ internal static unsafe partial class JsGlobalization
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe nint ChangeCaseInvariant(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern unsafe nint ChangeCase(in string culture, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper);
internal static extern unsafe nint ChangeCase(char* culture, int cultureLen, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,33 @@ internal sealed partial class CalendarData
private const int CALENDAR_INFO_BUFFER_LEN = 1000;
private unsafe bool JSLoadCalendarDataFromBrowser(string localeName, CalendarId calendarId)
{
char* buffer = stackalloc char[CALENDAR_INFO_BUFFER_LEN];
nint exceptionPtr = Interop.JsGlobalization.GetCalendarInfo(localeName, calendarId, buffer, CALENDAR_INFO_BUFFER_LEN, out int resultLength);
Helper.MarshalAndThrowIfException(exceptionPtr);
string result = new string(buffer, 0, resultLength);
string[] subresults = result.Split("##");
if (subresults.Length < 14)
throw new Exception("CalendarInfo recieved from the Browser is in icorrect format.");
// JS always has one result per locale, so even arrays are initialized with one element
this.sNativeName = string.IsNullOrEmpty(subresults[0]) ? ((CalendarId)calendarId).ToString() : subresults[0]; // this is EnglishName, not NativeName but it's the best we can do
this.saYearMonths = new string[] { subresults[1] };
this.sMonthDay = subresults[2];
this.saLongDates = new string[] { subresults[3] };
this.saShortDates = new string[] { subresults[4] };
this.saEraNames = new string[] { subresults[5] };
this.saAbbrevEraNames = new string[] { subresults[6] };
this.saDayNames = subresults[7].Split("||");
this.saAbbrevDayNames = subresults[8].Split("||");
this.saSuperShortDayNames = subresults[9].Split("||");
this.saMonthNames = ResizeMonthsArray(subresults[10].Split("||"));
this.saAbbrevMonthNames = ResizeMonthsArray(subresults[11].Split("||"));
this.saMonthGenitiveNames = ResizeMonthsArray(subresults[12].Split("||"));
this.saAbbrevMonthGenitiveNames = ResizeMonthsArray(subresults[13].Split("||"));
return true;
ReadOnlySpan<char> localeNameSpan = localeName.AsSpan();
fixed (char* pLocaleName = &MemoryMarshal.GetReference(localeNameSpan))
{
char* buffer = stackalloc char[CALENDAR_INFO_BUFFER_LEN];
nint exceptionPtr = Interop.JsGlobalization.GetCalendarInfo(pLocaleName, localeNameSpan.Length, calendarId, buffer, CALENDAR_INFO_BUFFER_LEN, out int resultLength);
Helper.MarshalAndThrowIfException(exceptionPtr);
string result = new string(buffer, 0, resultLength);
string[] subresults = result.Split("##");
if (subresults.Length < 14)
throw new Exception("CalendarInfo recieved from the Browser is in icorrect format.");
// JS always has one result per locale, so even arrays are initialized with one element
this.sNativeName = string.IsNullOrEmpty(subresults[0]) ? ((CalendarId)calendarId).ToString() : subresults[0]; // this is EnglishName, not NativeName but it's the best we can do
this.saYearMonths = new string[] { subresults[1] };
this.sMonthDay = subresults[2];
this.saLongDates = new string[] { subresults[3] };
this.saShortDates = new string[] { subresults[4] };
this.saEraNames = new string[] { subresults[5] };
this.saAbbrevEraNames = new string[] { subresults[6] };
this.saDayNames = subresults[7].Split("||");
this.saAbbrevDayNames = subresults[8].Split("||");
this.saSuperShortDayNames = subresults[9].Split("||");
this.saMonthNames = ResizeMonthsArray(subresults[10].Split("||"));
this.saAbbrevMonthNames = ResizeMonthsArray(subresults[11].Split("||"));
this.saMonthGenitiveNames = ResizeMonthsArray(subresults[12].Split("||"));
this.saAbbrevMonthGenitiveNames = ResizeMonthsArray(subresults[13].Split("||"));
return true;
}

static string[] ResizeMonthsArray(string[] months)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,13 @@ private unsafe int IndexOfOrdinalIgnoreCaseHelper(ReadOnlySpan<char> source, Rea
#if TARGET_BROWSER
if (GlobalizationMode.Hybrid)
{
nint exceptionPtr = Interop.JsGlobalization.IndexOf(m_name, b, target.Length, a, source.Length, options, fromBeginning, out int result);
Helper.MarshalAndThrowIfException(exceptionPtr);
return result;
ReadOnlySpan<char> cultureNameSpan = m_name.AsSpan();
fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan))
{
nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, b, target.Length, a, source.Length, options, fromBeginning, out int result);
Helper.MarshalAndThrowIfException(exceptionPtr);
return result;
}
}
#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
if (GlobalizationMode.Hybrid)
Expand Down Expand Up @@ -299,9 +303,13 @@ private unsafe int IndexOfOrdinalHelper(ReadOnlySpan<char> source, ReadOnlySpan<
#if TARGET_BROWSER
if (GlobalizationMode.Hybrid)
{
nint exceptionPtr = Interop.JsGlobalization.IndexOf(m_name, b, target.Length, a, source.Length, options, fromBeginning, out int result);
Helper.MarshalAndThrowIfException(exceptionPtr);
return result;
ReadOnlySpan<char> cultureNameSpan = m_name.AsSpan();
fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan))
{
nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, b, target.Length, a, source.Length, options, fromBeginning, out int result);
Helper.MarshalAndThrowIfException(exceptionPtr);
return result;
}
}
#elif TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
if (GlobalizationMode.Hybrid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,14 @@ private static void AssertIndexingSupported(CompareOptions options, string cultu
private unsafe int JsCompareString(ReadOnlySpan<char> string1, ReadOnlySpan<char> string2, CompareOptions options)
{
AssertHybridOnWasm(options);
string cultureName = m_name;
AssertComparisonSupported(options, cultureName);
AssertComparisonSupported(options, m_name);

ReadOnlySpan<char> cultureNameSpan = m_name.AsSpan();
fixed (char* pString1 = &MemoryMarshal.GetReference(string1))
fixed (char* pString2 = &MemoryMarshal.GetReference(string2))
fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan))
{
nint exceptionPtr = Interop.JsGlobalization.CompareString(cultureName, pString1, string1.Length, pString2, string2.Length, options, out int cmpResult);
nint exceptionPtr = Interop.JsGlobalization.CompareString(pCultureName, cultureNameSpan.Length, pString1, string1.Length, pString2, string2.Length, options, out int cmpResult);
Helper.MarshalAndThrowIfException(exceptionPtr);
return cmpResult;
}
Expand All @@ -63,13 +64,14 @@ private unsafe bool JsStartsWith(ReadOnlySpan<char> source, ReadOnlySpan<char> p
{
AssertHybridOnWasm(options);
Debug.Assert(!prefix.IsEmpty);
string cultureName = m_name;
AssertIndexingSupported(options, cultureName);
AssertIndexingSupported(options, m_name);

ReadOnlySpan<char> cultureNameSpan = m_name.AsSpan();
fixed (char* pSource = &MemoryMarshal.GetReference(source))
fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix))
fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan))
{
nint exceptionPtr = Interop.JsGlobalization.StartsWith(cultureName, pSource, source.Length, pPrefix, prefix.Length, options, out bool result);
nint exceptionPtr = Interop.JsGlobalization.StartsWith(pCultureName, cultureNameSpan.Length, pSource, source.Length, pPrefix, prefix.Length, options, out bool result);
Helper.MarshalAndThrowIfException(exceptionPtr);
return result;
}
Expand All @@ -79,13 +81,14 @@ private unsafe bool JsEndsWith(ReadOnlySpan<char> source, ReadOnlySpan<char> pre
{
AssertHybridOnWasm(options);
Debug.Assert(!prefix.IsEmpty);
string cultureName = m_name;
AssertIndexingSupported(options, cultureName);
AssertIndexingSupported(options, m_name);

ReadOnlySpan<char> cultureNameSpan = m_name.AsSpan();
fixed (char* pSource = &MemoryMarshal.GetReference(source))
fixed (char* pPrefix = &MemoryMarshal.GetReference(prefix))
fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan))
{
nint exceptionPtr = Interop.JsGlobalization.EndsWith(cultureName, pSource, source.Length, pPrefix, prefix.Length, options, out bool result);
nint exceptionPtr = Interop.JsGlobalization.EndsWith(pCultureName, cultureNameSpan.Length, pSource, source.Length, pPrefix, prefix.Length, options, out bool result);
Helper.MarshalAndThrowIfException(exceptionPtr);
return result;
}
Expand All @@ -95,19 +98,20 @@ private unsafe int JsIndexOfCore(ReadOnlySpan<char> source, ReadOnlySpan<char> t
{
AssertHybridOnWasm(options);
Debug.Assert(!target.IsEmpty);
string cultureName = m_name;
AssertIndexingSupported(options, cultureName);
AssertIndexingSupported(options, m_name);

if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options))
{
return (options & CompareOptions.IgnoreCase) != 0 ?
IndexOfOrdinalIgnoreCaseHelper(source, target, options, matchLengthPtr, fromBeginning) :
IndexOfOrdinalHelper(source, target, options, matchLengthPtr, fromBeginning);
}
ReadOnlySpan<char> cultureNameSpan = m_name.AsSpan();
fixed (char* pSource = &MemoryMarshal.GetReference(source))
fixed (char* pTarget = &MemoryMarshal.GetReference(target))
fixed (char* pCultureName = &MemoryMarshal.GetReference(cultureNameSpan))
{
nint exceptionPtr = Interop.JsGlobalization.IndexOf(m_name, pTarget, target.Length, pSource, source.Length, options, fromBeginning, out int idx);
nint exceptionPtr = Interop.JsGlobalization.IndexOf(pCultureName, cultureNameSpan.Length, pTarget, target.Length, pSource, source.Length, options, fromBeginning, out int idx);
Helper.MarshalAndThrowIfException(exceptionPtr);
return idx;
}
Expand Down
Loading