com.alicizax.unity.cysharp..../Number/GuidEx.cs
陈思海 4fbea560b5 init
2025-01-09 13:57:51 +08:00

171 lines
5.8 KiB
C#

using System.Runtime.InteropServices;
namespace System
{
[StructLayout(LayoutKind.Sequential)]
internal struct GuidEx
{
private int _a; // Do not rename (binary serialization)
private short _b; // Do not rename (binary serialization)
private short _c; // Do not rename (binary serialization)
private byte _d; // Do not rename (binary serialization)
private byte _e; // Do not rename (binary serialization)
private byte _f; // Do not rename (binary serialization)
private byte _g; // Do not rename (binary serialization)
private byte _h; // Do not rename (binary serialization)
private byte _i; // Do not rename (binary serialization)
private byte _j; // Do not rename (binary serialization)
private byte _k; // Do not rename (binary serialization)
private static unsafe int HexsToChars(char* guidChars, int a, int b)
{
guidChars[0] = HexConverter.ToCharLower(a >> 4);
guidChars[1] = HexConverter.ToCharLower(a);
guidChars[2] = HexConverter.ToCharLower(b >> 4);
guidChars[3] = HexConverter.ToCharLower(b);
return 4;
}
private static unsafe int HexsToCharsHexOutput(char* guidChars, int a, int b)
{
guidChars[0] = '0';
guidChars[1] = 'x';
guidChars[2] = HexConverter.ToCharLower(a >> 4);
guidChars[3] = HexConverter.ToCharLower(a);
guidChars[4] = ',';
guidChars[5] = '0';
guidChars[6] = 'x';
guidChars[7] = HexConverter.ToCharLower(b >> 4);
guidChars[8] = HexConverter.ToCharLower(b);
return 9;
}
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format = default)
{
if (format.Length == 0)
{
format = "D".AsSpan();
}
// all acceptable format strings are of length 1
if (format.Length != 1)
{
throw new FormatException("InvalidGuidFormatSpecification");
}
bool dash = true;
bool hex = false;
int braces = 0;
int guidSize;
switch (format[0])
{
case 'D':
case 'd':
guidSize = 36;
break;
case 'N':
case 'n':
dash = false;
guidSize = 32;
break;
case 'B':
case 'b':
braces = '{' + ('}' << 16);
guidSize = 38;
break;
case 'P':
case 'p':
braces = '(' + (')' << 16);
guidSize = 38;
break;
case 'X':
case 'x':
braces = '{' + ('}' << 16);
dash = false;
hex = true;
guidSize = 68;
break;
default:
throw new FormatException("InvalidGuidFormatSpecification");
}
if (destination.Length < guidSize)
{
charsWritten = 0;
return false;
}
unsafe
{
fixed (char* guidChars = &MemoryMarshal.GetReference(destination))
{
char* p = guidChars;
if (braces != 0)
*p++ = (char)braces;
if (hex)
{
// {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}
*p++ = '0';
*p++ = 'x';
p += HexsToChars(p, _a >> 24, _a >> 16);
p += HexsToChars(p, _a >> 8, _a);
*p++ = ',';
*p++ = '0';
*p++ = 'x';
p += HexsToChars(p, _b >> 8, _b);
*p++ = ',';
*p++ = '0';
*p++ = 'x';
p += HexsToChars(p, _c >> 8, _c);
*p++ = ',';
*p++ = '{';
p += HexsToCharsHexOutput(p, _d, _e);
*p++ = ',';
p += HexsToCharsHexOutput(p, _f, _g);
*p++ = ',';
p += HexsToCharsHexOutput(p, _h, _i);
*p++ = ',';
p += HexsToCharsHexOutput(p, _j, _k);
*p++ = '}';
}
else
{
// [{|(]dddddddd[-]dddd[-]dddd[-]dddd[-]dddddddddddd[}|)]
p += HexsToChars(p, _a >> 24, _a >> 16);
p += HexsToChars(p, _a >> 8, _a);
if (dash)
*p++ = '-';
p += HexsToChars(p, _b >> 8, _b);
if (dash)
*p++ = '-';
p += HexsToChars(p, _c >> 8, _c);
if (dash)
*p++ = '-';
p += HexsToChars(p, _d, _e);
if (dash)
*p++ = '-';
p += HexsToChars(p, _f, _g);
p += HexsToChars(p, _h, _i);
p += HexsToChars(p, _j, _k);
}
if (braces != 0)
*p++ = (char)(braces >> 16);
}
}
charsWritten = guidSize;
return true;
}
}
}