<PackageReference Include="System.Text.Encodings.Web" Version="9.0.5" />

Rune

struct Rune : IEquatable<Rune>
using System.Buffers; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Text.Encodings.Web; namespace System.Text { internal readonly struct Rune : IEquatable<System.Text.Rune> { private const int MaxUtf16CharsPerRune = 2; private const char HighSurrogateStart = '�'; private const char LowSurrogateStart = '�'; private const int HighSurrogateRange = 1023; private readonly uint _value; public bool IsAscii => System.Text.UnicodeUtility.IsAsciiCodePoint(_value); public bool IsBmp => System.Text.UnicodeUtility.IsBmpCodePoint(_value); public static System.Text.Rune ReplacementChar => UnsafeCreate(65533); public int Utf16SequenceLength => System.Text.UnicodeUtility.GetUtf16SequenceLength(_value); public int Value => (int)_value; public Rune(uint value) { if (!System.Text.UnicodeUtility.IsValidUnicodeScalar(value)) System.Text.Encodings.Web.ThrowHelper.ThrowArgumentOutOfRangeException(System.Text.Encodings.Web.ExceptionArgument.value); _value = value; } public Rune(int value) { this = new System.Text.Rune((uint)value); } private Rune(uint scalarValue, bool _) { _value = scalarValue; } public static bool operator ==(System.Text.Rune left, System.Text.Rune right) { return left._value == right._value; } public static bool operator !=(System.Text.Rune left, System.Text.Rune right) { return left._value != right._value; } public static bool IsControl(System.Text.Rune value) { return (uint)((int)(value._value + 1) & -129) <= 32; } public static OperationStatus DecodeFromUtf16(ReadOnlySpan<char> source, out System.Text.Rune result, out int charsConsumed) { if (!source.IsEmpty) { char c = source[0]; if (TryCreate(c, out result)) { charsConsumed = 1; return OperationStatus.Done; } if (1 < (uint)source.Length) { char lowSurrogate = source[1]; if (TryCreate(c, lowSurrogate, out result)) { charsConsumed = 2; return OperationStatus.Done; } } else if (char.IsHighSurrogate(c)) { goto IL_004c; } charsConsumed = 1; result = ReplacementChar; return OperationStatus.InvalidData; } goto IL_004c; IL_004c: charsConsumed = source.Length; result = ReplacementChar; return OperationStatus.NeedMoreData; } public static OperationStatus DecodeFromUtf8(ReadOnlySpan<byte> source, out System.Text.Rune result, out int bytesConsumed) { int num = 0; uint num2; if ((uint)num < (uint)source.Length) { num2 = source[num]; if (System.Text.UnicodeUtility.IsAsciiCodePoint(num2)) goto IL_0021; if (System.Text.UnicodeUtility.IsInRangeInclusive(num2, 194, 244)) { num2 = num2 - 194 << 6; num++; if ((uint)num >= (uint)source.Length) goto IL_0163; int num3 = (sbyte)source[num]; if (num3 < -64) { num2 = (uint)((int)num2 + num3); num2 += 128; num2 += 128; if (num2 < 2048) goto IL_0021; if (System.Text.UnicodeUtility.IsInRangeInclusive(num2, 2080, 3343) && !System.Text.UnicodeUtility.IsInRangeInclusive(num2, 2912, 2943) && !System.Text.UnicodeUtility.IsInRangeInclusive(num2, 3072, 3087)) { num++; if ((uint)num >= (uint)source.Length) goto IL_0163; num3 = (sbyte)source[num]; if (num3 < -64) { num2 <<= 6; num2 = (uint)((int)num2 + num3); num2 += 128; num2 -= 131072; if (num2 > 65535) { num++; if ((uint)num >= (uint)source.Length) goto IL_0163; num3 = (sbyte)source[num]; if (num3 >= -64) goto IL_0153; num2 <<= 6; num2 = (uint)((int)num2 + num3); num2 += 128; num2 -= 4194304; } goto IL_0021; } } } } else num = 1; goto IL_0153; } goto IL_0163; IL_0021: bytesConsumed = num + 1; result = UnsafeCreate(num2); return OperationStatus.Done; IL_0153: bytesConsumed = num; result = ReplacementChar; return OperationStatus.InvalidData; IL_0163: bytesConsumed = num; result = ReplacementChar; return OperationStatus.NeedMoreData; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] object obj) { if (obj is System.Text.Rune) { System.Text.Rune other = (System.Text.Rune)obj; return Equals(other); } return false; } public bool Equals(System.Text.Rune other) { return this == other; } public override int GetHashCode() { return Value; } public static bool TryCreate(char ch, out System.Text.Rune result) { if (!System.Text.UnicodeUtility.IsSurrogateCodePoint(ch)) { result = UnsafeCreate(ch); return true; } result = default(System.Text.Rune); return false; } public static bool TryCreate(char highSurrogate, char lowSurrogate, out System.Text.Rune result) { uint num = (uint)(highSurrogate - 55296); uint num2 = (uint)(lowSurrogate - 56320); if ((num | num2) <= 1023) { result = UnsafeCreate((uint)((int)(num << 10) + (lowSurrogate - 56320) + 65536)); return true; } result = default(System.Text.Rune); return false; } public bool TryEncodeToUtf16(Span<char> destination, out int charsWritten) { if (destination.Length >= 1) { if (IsBmp) { destination[0] = (char)_value; charsWritten = 1; return true; } if (destination.Length >= 2) { System.Text.UnicodeUtility.GetUtf16SurrogatesFromSupplementaryPlaneScalar(_value, out destination[0], out destination[1]); charsWritten = 2; return true; } } charsWritten = 0; return false; } public bool TryEncodeToUtf8(Span<byte> destination, out int bytesWritten) { if (destination.Length >= 1) { if (IsAscii) { destination[0] = (byte)_value; bytesWritten = 1; return true; } if (destination.Length >= 2) { if (_value <= 2047) { destination[0] = (byte)(_value + 12288 >> 6); destination[1] = (byte)((_value & 63) + 128); bytesWritten = 2; return true; } if (destination.Length >= 3) { if (_value <= 65535) { destination[0] = (byte)(_value + 917504 >> 12); destination[1] = (byte)(((_value & 4032) >> 6) + 128); destination[2] = (byte)((_value & 63) + 128); bytesWritten = 3; return true; } if (destination.Length >= 4) { destination[0] = (byte)(_value + 62914560 >> 18); destination[1] = (byte)(((_value & 258048) >> 12) + 128); destination[2] = (byte)(((_value & 4032) >> 6) + 128); destination[3] = (byte)((_value & 63) + 128); bytesWritten = 4; return true; } } } } bytesWritten = 0; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static System.Text.Rune UnsafeCreate(uint scalarValue) { return new System.Text.Rune(scalarValue, false); } } }