Skip to content

Commit

Permalink
Improve Guid.Parse for input without whitespaces (#84210)
Browse files Browse the repository at this point in the history
Co-authored-by: Stephen Toub <stoub@microsoft.com>
  • Loading branch information
EgorBo and stephentoub committed Apr 2, 2023
1 parent b9352f1 commit b7e7671
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/libraries/System.Private.CoreLib/src/System/Guid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ public static bool TryParseExact([NotNullWhen(true)] string? input, [NotNullWhen

public static bool TryParseExact(ReadOnlySpan<char> input, [StringSyntax(StringSyntaxAttribute.GuidFormat)] ReadOnlySpan<char> format, out Guid result)
{
if (format.Length != 1)
if (format.Length != 1 || input.Length < 32) // Minimal length we can parse ('N' format)
{
result = default;
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace System
{
Expand Down Expand Up @@ -565,27 +566,39 @@ public static ReadOnlyMemory<char> TrimEnd(this ReadOnlyMemory<char> memory)
/// Removes all leading and trailing white-space characters from the span.
/// </summary>
/// <param name="span">The source span from which the characters are removed.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span)
{
int start = 0;
for (; start < span.Length; start++)
// Assume that in most cases input doesn't need trimming
if (span.Length == 0 ||
(!char.IsWhiteSpace(span[0]) && !char.IsWhiteSpace(span[^1])))
{
if (!char.IsWhiteSpace(span[start]))
{
break;
}
return span;
}
return TrimFallback(span);

int end = span.Length - 1;
for (; end > start; end--)
[MethodImpl(MethodImplOptions.NoInlining)]
static ReadOnlySpan<char> TrimFallback(ReadOnlySpan<char> span)
{
if (!char.IsWhiteSpace(span[end]))
int start = 0;
for (; start < span.Length; start++)
{
break;
if (!char.IsWhiteSpace(span[start]))
{
break;
}
}
}

return span.Slice(start, end - start + 1);
int end = span.Length - 1;
for (; end > start; end--)
{
if (!char.IsWhiteSpace(span[end]))
{
break;
}
}
return span.Slice(start, end - start + 1);
}
}

/// <summary>
Expand Down Expand Up @@ -770,11 +783,39 @@ public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, ReadOnlyS
/// Removes all leading and trailing white-space characters from the span.
/// </summary>
/// <param name="span">The source span from which the characters are removed.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Span<char> Trim(this Span<char> span)
{
int start = ClampStart(span);
int length = ClampEnd(span, start);
return span.Slice(start, length);
// Assume that in most cases input doesn't need trimming
if (span.Length == 0 ||
(!char.IsWhiteSpace(span[0]) && !char.IsWhiteSpace(span[^1])))
{
return span;
}
return TrimFallback(span);

[MethodImpl(MethodImplOptions.NoInlining)]
static Span<char> TrimFallback(Span<char> span)
{
int start = 0;
for (; start < span.Length; start++)
{
if (!char.IsWhiteSpace(span[start]))
{
break;
}
}

int end = span.Length - 1;
for (; end > start; end--)
{
if (!char.IsWhiteSpace(span[end]))
{
break;
}
}
return span.Slice(start, end - start + 1);
}
}

/// <summary>
Expand Down

0 comments on commit b7e7671

Please sign in to comment.