Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
HexConverter.cs
Go to the documentation of this file.
6
7namespace System;
8
9internal static class HexConverter
10{
11 public enum Casing : uint
12 {
13 Upper = 0u,
14 Lower = 8224u
15 }
16
17 public static ReadOnlySpan<byte> CharToHexLookup => new byte[256]
18 {
19 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
20 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
21 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
22 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
23 255, 255, 255, 255, 255, 255, 255, 255, 0, 1,
24 2, 3, 4, 5, 6, 7, 8, 9, 255, 255,
25 255, 255, 255, 255, 255, 10, 11, 12, 13, 14,
26 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
27 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
28 255, 255, 255, 255, 255, 255, 255, 10, 11, 12,
29 13, 14, 15, 255, 255, 255, 255, 255, 255, 255,
30 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
31 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
32 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
33 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
34 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
35 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
36 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
37 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
38 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
39 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
41 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
42 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
43 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
44 255, 255, 255, 255, 255, 255
45 };
46
47 [MethodImpl(MethodImplOptions.AggressiveInlining)]
48 public static void ToBytesBuffer(byte value, Span<byte> buffer, int startingIndex = 0, Casing casing = Casing.Upper)
49 {
50 uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209);
51 uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing;
52 buffer[startingIndex + 1] = (byte)num2;
53 buffer[startingIndex] = (byte)(num2 >> 8);
54 }
55
56 [MethodImpl(MethodImplOptions.AggressiveInlining)]
57 public static void ToCharsBuffer(byte value, Span<char> buffer, int startingIndex = 0, Casing casing = Casing.Upper)
58 {
59 uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209);
60 uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing;
61 buffer[startingIndex + 1] = (char)(num2 & 0xFFu);
62 buffer[startingIndex] = (char)(num2 >> 8);
63 }
64
66 {
67 nint num = 0;
68 Vector128<byte> mask = Vector128.Create(byte.MaxValue, byte.MaxValue, 0, byte.MaxValue, byte.MaxValue, byte.MaxValue, 1, byte.MaxValue, byte.MaxValue, byte.MaxValue, 2, byte.MaxValue, byte.MaxValue, byte.MaxValue, 3, byte.MaxValue);
69 Vector128<byte> value = ((casing == Casing.Upper) ? Vector128.Create((byte)48, (byte)49, (byte)50, (byte)51, (byte)52, (byte)53, (byte)54, (byte)55, (byte)56, (byte)57, (byte)65, (byte)66, (byte)67, (byte)68, (byte)69, (byte)70) : Vector128.Create((byte)48, (byte)49, (byte)50, (byte)51, (byte)52, (byte)53, (byte)54, (byte)55, (byte)56, (byte)57, (byte)97, (byte)98, (byte)99, (byte)100, (byte)101, (byte)102));
70 do
71 {
72 uint value2 = Unsafe.ReadUnaligned<uint>(ref Unsafe.Add(ref MemoryMarshal.GetReference(bytes), num));
73 Vector128<byte> vector = Ssse3.Shuffle(Vector128.CreateScalarUnsafe(value2).AsByte(), mask);
74 Vector128<byte> right = Sse2.ShiftRightLogical(Sse2.ShiftRightLogical128BitLane(vector, 2).AsInt32(), 4).AsByte();
75 Vector128<byte> mask2 = Sse2.And(Sse2.Or(vector, right), Vector128.Create((byte)15));
76 Vector128<byte> left = Ssse3.Shuffle(value, mask2);
77 left = Sse2.And(left, Vector128.Create((ushort)255).AsByte());
78 Unsafe.WriteUnaligned(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref MemoryMarshal.GetReference(chars), num * 2)), left);
79 num += 4;
80 }
81 while (num < bytes.Length - 3);
82 for (; num < bytes.Length; num++)
83 {
84 ToCharsBuffer(Unsafe.Add(ref MemoryMarshal.GetReference(bytes), num), chars, (int)num * 2, casing);
85 }
86 }
87
88 public static void EncodeToUtf16(ReadOnlySpan<byte> bytes, Span<char> chars, Casing casing = Casing.Upper)
89 {
90 if (Ssse3.IsSupported && bytes.Length >= 4)
91 {
93 return;
94 }
95 for (int i = 0; i < bytes.Length; i++)
96 {
97 ToCharsBuffer(bytes[i], chars, i * 2, casing);
98 }
99 }
100
101 public unsafe static string ToString(ReadOnlySpan<byte> bytes, Casing casing = Casing.Upper)
102 {
103 fixed (byte* ptr = bytes)
104 {
105 return string.Create(bytes.Length * 2, ((IntPtr)ptr, bytes.Length, casing), delegate(Span<char> chars, (IntPtr Ptr, int Length, Casing casing) args)
106 {
107 ReadOnlySpan<byte> bytes2 = new ReadOnlySpan<byte>((void*)args.Ptr, args.Length);
108 EncodeToUtf16(bytes2, chars, args.casing);
109 });
110 }
111 }
112
113 [MethodImpl(MethodImplOptions.AggressiveInlining)]
114 public static char ToCharUpper(int value)
115 {
116 value &= 0xF;
117 value += 48;
118 if (value > 57)
119 {
120 value += 7;
121 }
122 return (char)value;
123 }
124
125 [MethodImpl(MethodImplOptions.AggressiveInlining)]
126 public static char ToCharLower(int value)
127 {
128 value &= 0xF;
129 value += 48;
130 if (value > 57)
131 {
132 value += 39;
133 }
134 return (char)value;
135 }
136
138 {
139 int charsProcessed;
140 return TryDecodeFromUtf16(chars, bytes, out charsProcessed);
141 }
142
143 public static bool TryDecodeFromUtf16(ReadOnlySpan<char> chars, Span<byte> bytes, out int charsProcessed)
144 {
145 int num = 0;
146 int num2 = 0;
147 int num3 = 0;
148 int num4 = 0;
149 while (num2 < bytes.Length)
150 {
151 num3 = FromChar(chars[num + 1]);
152 num4 = FromChar(chars[num]);
153 if ((num3 | num4) == 255)
154 {
155 break;
156 }
157 bytes[num2++] = (byte)((num4 << 4) | num3);
158 num += 2;
159 }
160 if (num3 == 255)
161 {
162 num++;
163 }
164 charsProcessed = num;
165 return (num3 | num4) != 255;
166 }
167
168 [MethodImpl(MethodImplOptions.AggressiveInlining)]
169 public static int FromChar(int c)
170 {
171 if (c < CharToHexLookup.Length)
172 {
173 return CharToHexLookup[c];
174 }
175 return 255;
176 }
177
178 [MethodImpl(MethodImplOptions.AggressiveInlining)]
179 public static bool IsHexChar(int c)
180 {
181 _ = IntPtr.Size;
182 ulong num = (uint)(c - 48);
183 ulong num2 = (ulong)(-17875860044349952L << (int)num);
184 ulong num3 = num - 64;
185 if ((long)(num2 & num3) >= 0L)
186 {
187 return false;
188 }
189 return true;
190 }
191}
static void EncodeToUtf16(ReadOnlySpan< byte > bytes, Span< char > chars, Casing casing=Casing.Upper)
static void ToCharsBuffer(byte value, Span< char > buffer, int startingIndex=0, Casing casing=Casing.Upper)
static char ToCharLower(int value)
static ReadOnlySpan< byte > CharToHexLookup
static bool TryDecodeFromUtf16(ReadOnlySpan< char > chars, Span< byte > bytes)
static void EncodeToUtf16_Ssse3(ReadOnlySpan< byte > bytes, Span< char > chars, Casing casing)
static bool IsHexChar(int c)
static bool TryDecodeFromUtf16(ReadOnlySpan< char > chars, Span< byte > bytes, out int charsProcessed)
static int FromChar(int c)
static char ToCharUpper(int value)
static void ToBytesBuffer(byte value, Span< byte > buffer, int startingIndex=0, Casing casing=Casing.Upper)
static unsafe string ToString(ReadOnlySpan< byte > bytes, Casing casing=Casing.Upper)
static Vector128< byte > Create(byte value)
Definition Vector128.cs:138
static unsafe Vector128< byte > CreateScalarUnsafe(byte value)
Definition Vector128.cs:829
static Vector128< sbyte > ShiftRightLogical128BitLane(Vector128< sbyte > value, byte numBytes)
Definition Sse2.cs:1117
static Vector128< byte > Or(Vector128< byte > left, Vector128< byte > right)
Definition Sse2.cs:837
static Vector128< byte > And(Vector128< byte > left, Vector128< byte > right)
Definition Sse2.cs:132
static Vector128< short > ShiftRightLogical(Vector128< short > value, Vector128< short > count)
Definition Sse2.cs:1057
static Vector128< sbyte > Shuffle(Vector128< sbyte > value, Vector128< sbyte > mask)
Definition Ssse3.cs:112
static int Size
Definition IntPtr.cs:21