Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,14 @@ public bool EndsWith(char value, StringComparison comparisonType)
/// <returns><see langword="true"/> if <paramref name="value"/> matches the end of this instance; otherwise, <see langword="false"/>.</returns>
public bool EndsWith(Rune value)
{
return EndsWith(value, StringComparison.Ordinal);
if (value.IsBmp)
{
return EndsWith((char)value.Value);
}

UnicodeUtility.GetUtf16SurrogatesFromSupplementaryPlaneScalar((uint)value.Value, out char highSurrogate, out char lowSurrogate);

return Length > 1 && this[^2] == highSurrogate && this[^1] == lowSurrogate;
}

/// <summary>
Expand Down Expand Up @@ -1134,7 +1141,14 @@ public bool StartsWith(char value, StringComparison comparisonType)
/// <returns><see langword="true"/> if value matches the beginning of this string; otherwise, <see langword="false"/>.</returns>
public bool StartsWith(Rune value)
{
return StartsWith(value, StringComparison.Ordinal);
if (value.IsBmp)
{
return StartsWith((char)value.Value);
}

UnicodeUtility.GetUtf16SurrogatesFromSupplementaryPlaneScalar((uint)value.Value, out char highSurrogate, out char lowSurrogate);

return Length > 1 && _firstChar == highSurrogate && this[1] == lowSurrogate;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1454,9 +1454,9 @@ private string ReplaceHelper(int oldValueLength, string newValue, ReadOnlySpan<i
/// </returns>
public string Replace(Rune oldRune, Rune newRune)
{
if (Length == 0)
if (oldRune.IsBmp && newRune.IsBmp)
{
return this;
return Replace((char)oldRune.Value, (char)newRune.Value);
}

ReadOnlySpan<char> oldChars = oldRune.AsSpan(stackalloc char[Rune.MaxUtf16CharsPerRune]);
Expand Down Expand Up @@ -1682,19 +1682,23 @@ public string[] Split(Rune separator, StringSplitOptions options = StringSplitOp
/// <returns>An array whose elements contain the substrings from this instance that are delimited by <paramref name="separator"/>.</returns>
public string[] Split(Rune separator, int count, StringSplitOptions options = StringSplitOptions.None)
{
ReadOnlySpan<char> separatorSpan = separator.AsSpan(stackalloc char[Rune.MaxUtf16CharsPerRune]);

if (separatorSpan.Length == 1)
if (separator.IsBmp)
{
return Split(separatorSpan[0], count, options);
return Split((char)separator.Value, count, options);
}

ArgumentOutOfRangeException.ThrowIfNegative(count);

CheckStringSplitOptions(options);

// Ensure matching the string separator overload.
return (count <= 1 || Length == 0) ? CreateSplitArrayOfThisAsSoleValue(options, count) : Split(separatorSpan, count, options);
if (count <= 1 || Length == 0)
{
return CreateSplitArrayOfThisAsSoleValue(options, count);
}

ReadOnlySpan<char> separatorSpan = separator.AsSpan(stackalloc char[Rune.MaxUtf16CharsPerRune]);
return Split(separatorSpan, count, options);
}

// Creates an array of strings by splitting this string at each
Expand Down Expand Up @@ -2411,39 +2415,28 @@ public unsafe string Trim(char trimChar)
/// </returns>
public string Trim(Rune trimRune)
{
if (Length == 0)
if (trimRune.IsBmp)
{
return this;
return Trim((char)trimRune.Value);
}

// Convert trimRune to span
ReadOnlySpan<char> trimChars = trimRune.AsSpan(stackalloc char[Rune.MaxUtf16CharsPerRune]);
UnicodeUtility.GetUtf16SurrogatesFromSupplementaryPlaneScalar((uint)trimRune.Value, out char highSurrogate, out char lowSurrogate);

// Trim start
int index = 0;
while (index < Length && this.AsSpan(index).StartsWith(trimChars))
while ((uint)(index + 1) < (uint)Length && this[index] == highSurrogate && this[index + 1] == lowSurrogate)
{
index += trimChars.Length;
}

if (index >= Length)
{
return Empty;
index += 2;
}

// Trim end
int endIndex = Length - 1;
while (endIndex >= index && this.AsSpan(index..(endIndex + 1)).EndsWith(trimChars))
{
endIndex -= trimChars.Length;
}

if (endIndex < index)
int endIndex = Length - 2;
while (endIndex > index && this[endIndex] == highSurrogate && this[endIndex + 1] == lowSurrogate)
{
return Empty;
endIndex -= 2;
}
Comment thread
MihaZupan marked this conversation as resolved.

return this[index..(endIndex + 1)];
return this[index..(endIndex + 2)];
}

// Removes a set of characters from the beginning and end of this string.
Expand Down Expand Up @@ -2497,24 +2490,17 @@ public unsafe string Trim(params ReadOnlySpan<char> trimChars)
/// </returns>
public string TrimStart(Rune trimRune)
{
if (Length == 0)
if (trimRune.IsBmp)
{
return this;
return TrimStart((char)trimRune.Value);
}

// Convert trimRune to span
ReadOnlySpan<char> trimChars = trimRune.AsSpan(stackalloc char[Rune.MaxUtf16CharsPerRune]);
UnicodeUtility.GetUtf16SurrogatesFromSupplementaryPlaneScalar((uint)trimRune.Value, out char highSurrogate, out char lowSurrogate);

// Trim start
int index = 0;
while (index < Length && this.AsSpan(index).StartsWith(trimChars))
while ((uint)(index + 1) < (uint)Length && this[index] == highSurrogate && this[index + 1] == lowSurrogate)
{
index += trimChars.Length;
}

if (index >= Length)
{
return Empty;
index += 2;
}

return this[index..];
Expand Down Expand Up @@ -2571,27 +2557,20 @@ public unsafe string TrimStart(params ReadOnlySpan<char> trimChars)
/// </returns>
public string TrimEnd(Rune trimRune)
{
if (Length == 0)
if (trimRune.IsBmp)
{
return this;
return TrimEnd((char)trimRune.Value);
}

// Convert trimRune to span
ReadOnlySpan<char> trimChars = trimRune.AsSpan(stackalloc char[Rune.MaxUtf16CharsPerRune]);
UnicodeUtility.GetUtf16SurrogatesFromSupplementaryPlaneScalar((uint)trimRune.Value, out char highSurrogate, out char lowSurrogate);

// Trim end
int endIndex = Length - 1;
while (endIndex >= 0 && this.AsSpan(..(endIndex + 1)).EndsWith(trimChars))
int endIndex = Length - 2;
while ((uint)endIndex < (uint)Length && this[endIndex] == highSurrogate && this[endIndex + 1] == lowSurrogate)
{
endIndex -= trimChars.Length;
}

if (endIndex < 0)
{
return Empty;
endIndex -= 2;
}

return this[..(endIndex + 1)];
return this[..(endIndex + 2)];
}

// Removes a set of characters from the end of this string.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public bool Contains(char value, StringComparison comparisonType)
/// <returns><see langword="true"/> if <paramref name="value"/> occurs within this string; otherwise, <see langword="false"/>.</returns>
public bool Contains(Rune value)
{
if (value.IsBmp)
{
return Contains((char)value.Value);
}

return Contains(value, StringComparison.Ordinal);
Comment thread
MihaZupan marked this conversation as resolved.
Comment thread
MihaZupan marked this conversation as resolved.
}

Expand Down
Loading