<PackageReference Include="Microsoft.Extensions.Primitives" Version="10.0.0-preview.5.25277.114" />

StringSegment

public struct StringSegment : IEquatable<StringSegment>, IEquatable<string>
An optimized representation of a substring.
using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Microsoft.Extensions.Primitives { [NullableContext(1)] [Nullable(0)] [DebuggerDisplay("{Value}")] public readonly struct StringSegment : IEquatable<StringSegment>, IEquatable<string> { public static readonly StringSegment Empty = string.Empty; [Nullable(2)] public string Buffer { [NullableContext(2)] get; } public int Offset { get; } public int Length { get; } [Nullable(2)] public string Value { [NullableContext(2)] get { if (!HasValue) return null; return Buffer.Substring(Offset, Length); } } [MemberNotNullWhen(true, "Buffer")] [MemberNotNullWhen(true, "Value")] public bool HasValue { [MemberNotNullWhen(true, "Buffer")] [MemberNotNullWhen(true, "Value")] get { return Buffer != null; } } public char this[int index] { get { if ((uint)index >= (uint)Length) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index); return Buffer[Offset + index]; } } [NullableContext(2)] public StringSegment(string buffer) { Buffer = buffer; Offset = 0; Length = (buffer?.Length ?? 0); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public StringSegment(string buffer, int offset, int length) { if (buffer == null || (uint)offset > (uint)buffer.Length || (uint)length > (uint)(buffer.Length - offset)) ThrowInvalidArguments(buffer, offset, length); Buffer = buffer; Offset = offset; Length = length; } [NullableContext(0)] public ReadOnlySpan<char> AsSpan() { return Buffer.AsSpan(Offset, Length); } [NullableContext(0)] public ReadOnlySpan<char> AsSpan(int start) { if (!HasValue || start < 0) ThrowInvalidArguments(start, Length - start, ExceptionArgument.start); return Buffer.AsSpan(Offset + start, Length - start); } [NullableContext(0)] public ReadOnlySpan<char> AsSpan(int start, int length) { if (!HasValue || start < 0 || length < 0 || (uint)(start + length) > (uint)Length) ThrowInvalidArguments(start, length, ExceptionArgument.start); return Buffer.AsSpan(Offset + start, length); } [NullableContext(0)] public ReadOnlyMemory<char> AsMemory() { return Buffer.AsMemory(Offset, Length); } public static int Compare(StringSegment a, StringSegment b, StringComparison comparisonType) { if (a.HasValue && b.HasValue) return a.AsSpan().CompareTo(b.AsSpan(), comparisonType); CheckStringComparison(comparisonType); if (a.HasValue) return 1; if (!b.HasValue) return 0; return -1; } [NullableContext(2)] public override bool Equals([NotNullWhen(true)] object obj) { if (obj is StringSegment) { StringSegment other = (StringSegment)obj; return Equals(other); } return false; } public bool Equals(StringSegment other) { return Equals(other, StringComparison.Ordinal); } public bool Equals(StringSegment other, StringComparison comparisonType) { if (HasValue && other.HasValue) return MemoryExtensions.Equals(AsSpan(), other.AsSpan(), comparisonType); CheckStringComparison(comparisonType); if (!HasValue) return !other.HasValue; return false; } public static bool Equals(StringSegment a, StringSegment b, StringComparison comparisonType) { return a.Equals(b, comparisonType); } [NullableContext(2)] public bool Equals(string text) { return Equals(text, StringComparison.Ordinal); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [NullableContext(2)] public bool Equals(string text, StringComparison comparisonType) { if (!HasValue || text == null) { CheckStringComparison(comparisonType); return text == Buffer; } return MemoryExtensions.Equals(AsSpan(), text.AsSpan(), comparisonType); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { return string.GetHashCode(AsSpan()); } public static bool operator ==(StringSegment left, StringSegment right) { return left.Equals(right); } public static bool operator !=(StringSegment left, StringSegment right) { return !left.Equals(right); } public static implicit operator StringSegment(string value) { return new StringSegment(value); } public static implicit operator ReadOnlySpan<char>(StringSegment segment) { return segment.AsSpan(); } public static implicit operator ReadOnlyMemory<char>(StringSegment segment) { return segment.AsMemory(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool StartsWith(string text, StringComparison comparisonType) { if (text == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text); if (!HasValue) { CheckStringComparison(comparisonType); return false; } return AsSpan().StartsWith(text.AsSpan(), comparisonType); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool EndsWith(string text, StringComparison comparisonType) { if (text == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text); if (!HasValue) { CheckStringComparison(comparisonType); return false; } return AsSpan().EndsWith(text.AsSpan(), comparisonType); } public string Substring(int offset) { return Substring(offset, Length - offset); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public string Substring(int offset, int length) { if (!HasValue || offset < 0 || length < 0 || (uint)(offset + length) > (uint)Length) ThrowInvalidArguments(offset, length, ExceptionArgument.offset); return Buffer.Substring(Offset + offset, length); } public StringSegment Subsegment(int offset) { return Subsegment(offset, Length - offset); } public StringSegment Subsegment(int offset, int length) { if (!HasValue || offset < 0 || length < 0 || (uint)(offset + length) > (uint)Length) ThrowInvalidArguments(offset, length, ExceptionArgument.offset); return new StringSegment(Buffer, Offset + offset, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int IndexOf(char c, int start, int count) { int num = -1; if (HasValue) { if ((uint)start > (uint)Length) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start); if ((uint)count > (uint)(Length - start)) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count); num = AsSpan(start, count).IndexOf(c); if (num >= 0) num += start; } return num; } public int IndexOf(char c, int start) { return IndexOf(c, start, Length - start); } public int IndexOf(char c) { return IndexOf(c, 0, Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int IndexOfAny(char[] anyOf, int startIndex, int count) { int num = -1; if (HasValue) { if ((uint)startIndex > (uint)Length) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start); if ((uint)count > (uint)(Length - startIndex)) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count); num = Buffer.IndexOfAny(anyOf, Offset + startIndex, count); if (num != -1) num -= Offset; } return num; } public int IndexOfAny(char[] anyOf, int startIndex) { return IndexOfAny(anyOf, startIndex, Length - startIndex); } public int IndexOfAny(char[] anyOf) { return IndexOfAny(anyOf, 0, Length); } public int LastIndexOf(char value) { return AsSpan().LastIndexOf(value); } public StringSegment Trim() { return TrimStart().TrimEnd(); } public StringSegment TrimStart() { ReadOnlySpan<char> readOnlySpan = AsSpan(); int i; for (i = 0; i < readOnlySpan.Length && char.IsWhiteSpace(readOnlySpan[i]); i++) { } return Subsegment(i); } public StringSegment TrimEnd() { ReadOnlySpan<char> readOnlySpan = AsSpan(); int num = readOnlySpan.Length - 1; while (num >= 0 && char.IsWhiteSpace(readOnlySpan[num])) { num--; } return Subsegment(0, num + 1); } public StringTokenizer Split(char[] chars) { return new StringTokenizer(this, chars); } public static bool IsNullOrEmpty(StringSegment value) { bool result = false; if (!value.HasValue || value.Length == 0) result = true; return result; } public override string ToString() { return Value ?? string.Empty; } private static void CheckStringComparison(StringComparison comparisonType) { if ((uint)comparisonType > 5) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.comparisonType); } [DoesNotReturn] private static void ThrowInvalidArguments(string buffer, int offset, int length) { <>c__DisplayClass55_0 <>c__DisplayClass55_ = default(<>c__DisplayClass55_0); <>c__DisplayClass55_.buffer = buffer; <>c__DisplayClass55_.offset = offset; <>c__DisplayClass55_.length = length; throw <ThrowInvalidArguments>g__GetInvalidArgumentsException|55_0(ref <>c__DisplayClass55_); } [DoesNotReturn] private void ThrowInvalidArguments(int offset, int length, ExceptionArgument offsetOrStart) { <>c__DisplayClass56_0 <>c__DisplayClass56_ = default(<>c__DisplayClass56_0); <>c__DisplayClass56_.offsetOrStart = offsetOrStart; <>c__DisplayClass56_.offset = offset; <>c__DisplayClass56_.length = length; throw <ThrowInvalidArguments>g__GetInvalidArgumentsException|56_0(HasValue, ref <>c__DisplayClass56_); } } }