private static unsafe int CompareStringOrdinalIgnoreCase(char* string1, int count1, char* string2, int count2)
{
Debug.Assert(!GlobalizationMode.Invariant);
+ Debug.Assert(string1 != null);
+ Debug.Assert(string2 != null);
return Interop.Globalization.CompareStringOrdinalIgnoreCase(string1, count1, string2, count2);
}
bool bIgnoreCase)
{
Debug.Assert(!GlobalizationMode.Invariant);
+ Debug.Assert(stringSource != null);
+ Debug.Assert(value != null);
fixed (char* pSource = stringSource)
fixed (char* pValue = value)
bool bIgnoreCase)
{
Debug.Assert(!GlobalizationMode.Invariant);
+ Debug.Assert(!source.IsEmpty);
+ Debug.Assert(!value.IsEmpty);
fixed (char* pSource = &MemoryMarshal.GetReference(source))
fixed (char* pValue = &MemoryMarshal.GetReference(value))
private static unsafe int CompareStringOrdinalIgnoreCase(char* string1, int count1, char* string2, int count2)
{
Debug.Assert(!GlobalizationMode.Invariant);
+ Debug.Assert(string1 != null);
+ Debug.Assert(string2 != null);
// Use the OS to compare and then convert the result to expected value by subtracting 2
return Interop.Kernel32.CompareStringOrdinal(string1, count1, string2, count2, true) - 2;
fixed (char* pString1 = &MemoryMarshal.GetReference(string1))
fixed (char* pString2 = &string2.GetRawStringData())
{
+ Debug.Assert(pString1 != null);
int result = Interop.Kernel32.CompareStringEx(
pLocaleName,
(uint)GetNativeCompareFlags(options),
fixed (char* pString1 = &MemoryMarshal.GetReference(string1))
fixed (char* pString2 = &MemoryMarshal.GetReference(string2))
{
+ Debug.Assert(pString1 != null);
+ Debug.Assert(pString2 != null);
int result = Interop.Kernel32.CompareStringEx(
pLocaleName,
(uint)GetNativeCompareFlags(options),
int* pcchFound)
{
Debug.Assert(!_invariantMode);
+ Debug.Assert(!lpStringSource.IsEmpty);
+ Debug.Assert(!lpStringValue.IsEmpty);
string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
int* pcchFound)
{
Debug.Assert(!_invariantMode);
+ Debug.Assert(lpStringSource != null);
+ Debug.Assert(lpStringValue != null);
string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
private static unsafe bool IsSortable(char* text, int length)
{
Debug.Assert(!GlobalizationMode.Invariant);
+ Debug.Assert(text != null);
return Interop.Kernel32.IsNLSDefinedString(Interop.Kernel32.COMPARE_STRING, 0, IntPtr.Zero, text, length);
}
return CompareString(string1, string2, options);
}
- internal virtual int CompareOptionNone(ReadOnlySpan<char> string1, ReadOnlySpan<char> string2)
+ internal int CompareOptionNone(ReadOnlySpan<char> string1, ReadOnlySpan<char> string2)
{
+ // Check for empty span or span from a null string
+ if (string1.Length == 0 || string2.Length == 0)
+ return string1.Length - string2.Length;
+
return _invariantMode ?
string.CompareOrdinal(string1, string2) :
CompareString(string1, string2, CompareOptions.None);
}
- internal virtual int CompareOptionIgnoreCase(ReadOnlySpan<char> string1, ReadOnlySpan<char> string2)
+ internal int CompareOptionIgnoreCase(ReadOnlySpan<char> string1, ReadOnlySpan<char> string2)
{
+ // Check for empty span or span from a null string
+ if (string1.Length == 0 || string2.Length == 0)
+ return string1.Length - string2.Length;
+
return _invariantMode ?
CompareOrdinalIgnoreCase(string1, string2) :
CompareString(string1, string2, CompareOptions.IgnoreCase);
return IndexOfCore(source, value, startIndex, count, options, null);
}
- internal virtual int IndexOfOrdinal(ReadOnlySpan<char> source, ReadOnlySpan<char> value, bool ignoreCase)
+ internal int IndexOfOrdinal(ReadOnlySpan<char> source, ReadOnlySpan<char> value, bool ignoreCase)
{
Debug.Assert(!_invariantMode);
+ Debug.Assert(!source.IsEmpty);
+ Debug.Assert(!value.IsEmpty);
return IndexOfOrdinalCore(source, value, ignoreCase);
}
- internal unsafe virtual int IndexOf(ReadOnlySpan<char> source, ReadOnlySpan<char> value, CompareOptions options)
+ internal unsafe int IndexOf(ReadOnlySpan<char> source, ReadOnlySpan<char> value, CompareOptions options)
{
Debug.Assert(!_invariantMode);
+ Debug.Assert(!source.IsEmpty);
+ Debug.Assert(!value.IsEmpty);
return IndexOfCore(source, value, options, null);
}
/// </summary>
/// <param name="span">The source span from which the characters are removed.</param>
/// <param name="trimChars">The span which contains the set of characters to remove.</param>
+ /// <remarks>If <paramref name="trimChars"/> is empty, white-space characters are removed instead.</remarks>
public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
{
return span.TrimStart(trimChars).TrimEnd(trimChars);
/// </summary>
/// <param name="span">The source span from which the characters are removed.</param>
/// <param name="trimChars">The span which contains the set of characters to remove.</param>
+ /// <remarks>If <paramref name="trimChars"/> is empty, white-space characters are removed instead.</remarks>
public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
{
+ if (trimChars.IsEmpty)
+ {
+ return span.TrimStart();
+ }
+
int start = 0;
for (; start < span.Length; start++)
{
/// </summary>
/// <param name="span">The source span from which the characters are removed.</param>
/// <param name="trimChars">The span which contains the set of characters to remove.</param>
+ /// <remarks>If <paramref name="trimChars"/> is empty, white-space characters are removed instead.</remarks>
public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
{
+ if (trimChars.IsEmpty)
+ {
+ return span.TrimEnd();
+ }
+
int end = span.Length - 1;
for (; end >= 0; end--)
{