Skip to content

Commit

Permalink
[Safe code] Clean up Guid.TryFormatX (#110923)
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorBo authored Dec 27, 2024
1 parent d3943fd commit 2eb59bf
Showing 1 changed file with 61 additions and 75 deletions.
136 changes: 61 additions & 75 deletions src/libraries/System.Private.CoreLib/src/System/Guid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -423,29 +423,15 @@ public static bool TryParseExact(ReadOnlySpan<char> input, [StringSyntax(StringS
input = input.Trim();

var parseResult = new GuidResult(GuidParseThrowStyle.None);
bool success = false;
switch ((char)(format[0] | 0x20))
{
case 'd':
success = TryParseExactD(input, ref parseResult);
break;

case 'n':
success = TryParseExactN(input, ref parseResult);
break;

case 'b':
success = TryParseExactB(input, ref parseResult);
break;

case 'p':
success = TryParseExactP(input, ref parseResult);
break;

case 'x':
success = TryParseExactX(input, ref parseResult);
break;
}
bool success = (format[0] | 0x20) switch
{
'd' => TryParseExactD(input, ref parseResult),
'n' => TryParseExactN(input, ref parseResult),
'b' => TryParseExactB(input, ref parseResult),
'p' => TryParseExactP(input, ref parseResult),
'x' => TryParseExactX(input, ref parseResult),
_ => false
};

if (success)
{
Expand Down Expand Up @@ -1108,24 +1094,6 @@ private static unsafe int HexsToChars<TChar>(TChar* guidChars, int a, int b) whe
return 4;
}

private static unsafe int HexsToCharsHexOutput<TChar>(TChar* guidChars, int a, int b) where TChar : unmanaged, IUtfChar<TChar>
{
guidChars[0] = TChar.CastFrom('0');
guidChars[1] = TChar.CastFrom('x');

guidChars[2] = TChar.CastFrom(HexConverter.ToCharLower(a >> 4));
guidChars[3] = TChar.CastFrom(HexConverter.ToCharLower(a));

guidChars[4] = TChar.CastFrom(',');
guidChars[5] = TChar.CastFrom('0');
guidChars[6] = TChar.CastFrom('x');

guidChars[7] = TChar.CastFrom(HexConverter.ToCharLower(b >> 4));
guidChars[8] = TChar.CastFrom(HexConverter.ToCharLower(b));

return 9;
}

// Returns the guid in "registry" format.
public override string ToString() => ToString("d", null);

Expand Down Expand Up @@ -1379,49 +1347,67 @@ internal unsafe bool TryFormatCore<TChar>(Span<TChar> destination, out int chars
return true;
}

private unsafe bool TryFormatX<TChar>(Span<TChar> destination, out int charsWritten) where TChar : unmanaged, IUtfChar<TChar>
private bool TryFormatX<TChar>(Span<TChar> dest, out int charsWritten) where TChar : unmanaged, IUtfChar<TChar>
{
if (destination.Length < 68)
if (dest.Length < 68)
{
charsWritten = 0;
return false;
}

// {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}
dest[0] = TChar.CastFrom('{');
dest[1] = TChar.CastFrom('0');
dest[2] = TChar.CastFrom('x');
dest[3] = TChar.CastFrom(HexConverter.ToCharLower(_a >> 28));
dest[4] = TChar.CastFrom(HexConverter.ToCharLower(_a >> 24));
dest[5] = TChar.CastFrom(HexConverter.ToCharLower(_a >> 20));
dest[6] = TChar.CastFrom(HexConverter.ToCharLower(_a >> 16));
dest[7] = TChar.CastFrom(HexConverter.ToCharLower(_a >> 12));
dest[8] = TChar.CastFrom(HexConverter.ToCharLower(_a >> 8));
dest[9] = TChar.CastFrom(HexConverter.ToCharLower(_a >> 4));
dest[10] = TChar.CastFrom(HexConverter.ToCharLower(_a));
dest[11] = TChar.CastFrom(',');
dest[12] = TChar.CastFrom('0');
dest[13] = TChar.CastFrom('x');
dest[14] = TChar.CastFrom(HexConverter.ToCharLower(_b >> 12));
dest[15] = TChar.CastFrom(HexConverter.ToCharLower(_b >> 8));
dest[16] = TChar.CastFrom(HexConverter.ToCharLower(_b >> 4));
dest[17] = TChar.CastFrom(HexConverter.ToCharLower(_b));
dest[18] = TChar.CastFrom(',');
dest[19] = TChar.CastFrom('0');
dest[20] = TChar.CastFrom('x');
dest[21] = TChar.CastFrom(HexConverter.ToCharLower(_c >> 12));
dest[22] = TChar.CastFrom(HexConverter.ToCharLower(_c >> 8));
dest[23] = TChar.CastFrom(HexConverter.ToCharLower(_c >> 4));
dest[24] = TChar.CastFrom(HexConverter.ToCharLower(_c));
dest[25] = TChar.CastFrom(',');
dest[26] = TChar.CastFrom('{');
WriteHex(dest, 27, _d);
WriteHex(dest, 32, _e);
WriteHex(dest, 37, _f);
WriteHex(dest, 42, _g);
WriteHex(dest, 47, _h);
WriteHex(dest, 52, _i);
WriteHex(dest, 57, _j);
WriteHex(dest, 62, _k, appendComma: false);
dest[66] = TChar.CastFrom('}');
dest[67] = TChar.CastFrom('}');
charsWritten = 68;
return true;

fixed (TChar* guidChars = &MemoryMarshal.GetReference(destination))
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void WriteHex(Span<TChar> dest, int offset, int val, bool appendComma = true)
{
TChar* p = guidChars;

// {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}
*p++ = TChar.CastFrom('{');
*p++ = TChar.CastFrom('0');
*p++ = TChar.CastFrom('x');
p += HexsToChars(p, _a >> 24, _a >> 16);
p += HexsToChars(p, _a >> 8, _a);
*p++ = TChar.CastFrom(',');
*p++ = TChar.CastFrom('0');
*p++ = TChar.CastFrom('x');
p += HexsToChars(p, _b >> 8, _b);
*p++ = TChar.CastFrom(',');
*p++ = TChar.CastFrom('0');
*p++ = TChar.CastFrom('x');
p += HexsToChars(p, _c >> 8, _c);
*p++ = TChar.CastFrom(',');
*p++ = TChar.CastFrom('{');
p += HexsToCharsHexOutput(p, _d, _e);
*p++ = TChar.CastFrom(',');
p += HexsToCharsHexOutput(p, _f, _g);
*p++ = TChar.CastFrom(',');
p += HexsToCharsHexOutput(p, _h, _i);
*p++ = TChar.CastFrom(',');
p += HexsToCharsHexOutput(p, _j, _k);
*p++ = TChar.CastFrom('}');
*p = TChar.CastFrom('}');

Debug.Assert(p == guidChars + charsWritten - 1);
dest[offset + 0] = TChar.CastFrom('0');
dest[offset + 1] = TChar.CastFrom('x');
dest[offset + 2] = TChar.CastFrom(HexConverter.ToCharLower(val >> 4));
dest[offset + 3] = TChar.CastFrom(HexConverter.ToCharLower(val));
if (appendComma)
{
dest[offset + 4] = TChar.CastFrom(',');
}
}

return true;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down

0 comments on commit 2eb59bf

Please sign in to comment.