-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Use Utf8Span for type system names #128969
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System; | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using System.Numerics; | ||
| using System.Text; | ||
|
|
||
| namespace Internal.Text | ||
| { | ||
| public readonly ref struct Utf8Span | ||
| { | ||
| private readonly ReadOnlySpan<byte> _value; | ||
|
|
||
| public Utf8Span(ReadOnlySpan<byte> value) => _value = value; | ||
|
|
||
| public int Length => _value.Length; | ||
|
|
||
| public bool IsEmpty => _value.IsEmpty; | ||
|
|
||
| public ReadOnlySpan<byte> AsSpan() => _value; | ||
|
|
||
| public byte[] ToArray() => _value.ToArray(); | ||
|
|
||
| public bool StartsWith(Utf8Span value) => _value.StartsWith(value.AsSpan()); | ||
|
|
||
| public bool EndsWith(Utf8Span value) => _value.EndsWith(value.AsSpan()); | ||
|
|
||
| // This is deliberately not a == operator because we don't want to make it easy | ||
| // to accidentally do UTF-8 vs UTF-16 string comparisons. | ||
| public bool StringEquals(string value) | ||
| { | ||
| if (_value.Length < value.Length) | ||
| return false; | ||
|
|
||
| for (int i = 0; i < value.Length; i++) | ||
| { | ||
| int ch = _value[i]; | ||
| if (ch > 0x7F) | ||
| return Encoding.UTF8.GetString(_value) == value; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if this is perf critical, but it feel that a single char at the end of the utf8 |
||
|
|
||
| // We are assuming here that valid UTF8 encoded byte > 0x7F cannot map to a character with code point <= 0x7F | ||
| if (ch != value[i]) | ||
| return false; | ||
| } | ||
|
|
||
| return _value.Length == value.Length; // All char ANSI, all matching | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if it would make sense to branch on the equality of |
||
| } | ||
|
|
||
| public override bool Equals(object obj) => false; | ||
|
|
||
| public override int GetHashCode() | ||
| { | ||
| HashCode h = default; | ||
| h.AddBytes(_value); | ||
| return h.ToHashCode(); | ||
| } | ||
|
|
||
| public override string ToString() => Encoding.UTF8.GetString(_value); | ||
|
|
||
| public static implicit operator Utf8Span(ReadOnlySpan<byte> s) => new Utf8Span(s); | ||
|
|
||
| public static bool operator ==(Utf8Span left, Utf8Span right) | ||
| => left._value.SequenceEqual(right._value); | ||
|
|
||
| public static bool operator !=(Utf8Span left, Utf8Span right) | ||
| => !left._value.SequenceEqual(right._value); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion for the member: this could be a "Span" property (
public ReadOnlySpan<byte> Span => _value;) similar to https://learn.microsoft.com/en-us/dotnet/api/system.readonlymemory-1.span?view=net-10.0#system-readonlymemory-1-spanBecause it reads weird to have an
AsSpanmethod on a type that is already named with the Span suffix.