Files
2026-08-27 10:56:38 -06:00

1383 lines
39 KiB
C#

using System.Buffers.Binary;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System.Buffers.Text;
public static class Utf8Formatter
{
[StructLayout(LayoutKind.Explicit)]
private struct DecomposedGuid
{
[FieldOffset(0)]
public Guid Guid;
[FieldOffset(0)]
public byte Byte00;
[FieldOffset(1)]
public byte Byte01;
[FieldOffset(2)]
public byte Byte02;
[FieldOffset(3)]
public byte Byte03;
[FieldOffset(4)]
public byte Byte04;
[FieldOffset(5)]
public byte Byte05;
[FieldOffset(6)]
public byte Byte06;
[FieldOffset(7)]
public byte Byte07;
[FieldOffset(8)]
public byte Byte08;
[FieldOffset(9)]
public byte Byte09;
[FieldOffset(10)]
public byte Byte10;
[FieldOffset(11)]
public byte Byte11;
[FieldOffset(12)]
public byte Byte12;
[FieldOffset(13)]
public byte Byte13;
[FieldOffset(14)]
public byte Byte14;
[FieldOffset(15)]
public byte Byte15;
}
private const byte TimeMarker = 84;
private const byte UtcMarker = 90;
private const byte GMT1 = 71;
private const byte GMT2 = 77;
private const byte GMT3 = 84;
private const byte GMT1Lowercase = 103;
private const byte GMT2Lowercase = 109;
private const byte GMT3Lowercase = 116;
private static readonly uint[] DayAbbreviations = new uint[7] { 7238995u, 7237453u, 6649172u, 6579543u, 7694420u, 6910534u, 7627091u };
private static readonly uint[] DayAbbreviationsLowercase = new uint[7] { 7239027u, 7237485u, 6649204u, 6579575u, 7694452u, 6910566u, 7627123u };
private static readonly uint[] MonthAbbreviations = new uint[12]
{
7233866u, 6448454u, 7496013u, 7499841u, 7954765u, 7238986u, 7107914u, 6780225u, 7365971u, 7627599u,
7761742u, 6513988u
};
private static readonly uint[] MonthAbbreviationsLowercase = new uint[12]
{
7233898u, 6448486u, 7496045u, 7499873u, 7954797u, 7239018u, 7107946u, 6780257u, 7366003u, 7627631u,
7761774u, 6514020u
};
private const byte OpenBrace = 123;
private const byte CloseBrace = 125;
private const byte OpenParen = 40;
private const byte CloseParen = 41;
private const byte Dash = 45;
public static bool TryFormat(bool value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
char symbolOrDefault = System.Buffers.Text.FormattingHelpers.GetSymbolOrDefault(in format, 'G');
if (value)
{
if (symbolOrDefault == 'G')
{
if (BinaryPrimitives.TryWriteUInt32BigEndian(destination, 1416787301u))
{
goto IL_0033;
}
}
else
{
if (symbolOrDefault != 'l')
{
goto IL_0083;
}
if (BinaryPrimitives.TryWriteUInt32BigEndian(destination, 1953658213u))
{
goto IL_0033;
}
}
}
else if (symbolOrDefault == 'G')
{
if (4u < (uint)destination.Length)
{
BinaryPrimitives.WriteUInt32BigEndian(destination, 1180789875u);
goto IL_006e;
}
}
else
{
if (symbolOrDefault != 'l')
{
goto IL_0083;
}
if (4u < (uint)destination.Length)
{
BinaryPrimitives.WriteUInt32BigEndian(destination, 1717660787u);
goto IL_006e;
}
}
bytesWritten = 0;
return false;
IL_006e:
destination[4] = 101;
bytesWritten = 5;
return true;
IL_0083:
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
IL_0033:
bytesWritten = 4;
return true;
}
public static bool TryFormat(DateTimeOffset value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
TimeSpan offset = Utf8Constants.s_nullUtcOffset;
char c = format.Symbol;
if (format.IsDefault)
{
c = 'G';
offset = value.Offset;
}
return c switch
{
'R' => TryFormatDateTimeR(value.UtcDateTime, destination, out bytesWritten),
'l' => TryFormatDateTimeL(value.UtcDateTime, destination, out bytesWritten),
'O' => TryFormatDateTimeO(value.DateTime, value.Offset, destination, out bytesWritten),
'G' => TryFormatDateTimeG(value.DateTime, offset, destination, out bytesWritten),
_ => System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten),
};
}
public static bool TryFormat(DateTime value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
return System.Buffers.Text.FormattingHelpers.GetSymbolOrDefault(in format, 'G') switch
{
'R' => TryFormatDateTimeR(value, destination, out bytesWritten),
'l' => TryFormatDateTimeL(value, destination, out bytesWritten),
'O' => TryFormatDateTimeO(value, Utf8Constants.s_nullUtcOffset, destination, out bytesWritten),
'G' => TryFormatDateTimeG(value, Utf8Constants.s_nullUtcOffset, destination, out bytesWritten),
_ => System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten),
};
}
private static bool TryFormatDateTimeG(DateTime value, TimeSpan offset, Span<byte> destination, out int bytesWritten)
{
int num = 19;
if (offset != Utf8Constants.s_nullUtcOffset)
{
num += 7;
}
if (destination.Length < num)
{
bytesWritten = 0;
return false;
}
bytesWritten = num;
byte b = destination[18];
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Month, destination);
destination[2] = 47;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, destination, 3);
destination[5] = 47;
System.Buffers.Text.FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, destination, 6);
destination[10] = 32;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, destination, 11);
destination[13] = 58;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, destination, 14);
destination[16] = 58;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, destination, 17);
if (offset != Utf8Constants.s_nullUtcOffset)
{
byte b2;
if (offset < default(TimeSpan))
{
b2 = 45;
offset = TimeSpan.FromTicks(-offset.Ticks);
}
else
{
b2 = 43;
}
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Minutes, destination, 24);
destination[23] = 58;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Hours, destination, 21);
destination[20] = b2;
destination[19] = 32;
}
return true;
}
private static bool TryFormatDateTimeO(DateTime value, TimeSpan offset, Span<byte> destination, out int bytesWritten)
{
int num = 27;
DateTimeKind dateTimeKind = DateTimeKind.Local;
if (offset == Utf8Constants.s_nullUtcOffset)
{
dateTimeKind = value.Kind;
switch (dateTimeKind)
{
case DateTimeKind.Local:
offset = TimeZoneInfo.Local.GetUtcOffset(value);
num += 6;
break;
case DateTimeKind.Utc:
num++;
break;
}
}
else
{
num += 6;
}
if (destination.Length < num)
{
bytesWritten = 0;
return false;
}
bytesWritten = num;
byte b = destination[26];
System.Buffers.Text.FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, destination);
destination[4] = 45;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Month, destination, 5);
destination[7] = 45;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, destination, 8);
destination[10] = 84;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, destination, 11);
destination[13] = 58;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, destination, 14);
destination[16] = 58;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, destination, 17);
destination[19] = 46;
System.Buffers.Text.FormattingHelpers.WriteDigits((uint)((ulong)value.Ticks % 10000000uL), destination.Slice(20, 7));
switch (dateTimeKind)
{
case DateTimeKind.Local:
{
byte b2;
if (offset < default(TimeSpan))
{
b2 = 45;
offset = TimeSpan.FromTicks(-offset.Ticks);
}
else
{
b2 = 43;
}
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Minutes, destination, 31);
destination[30] = 58;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)offset.Hours, destination, 28);
destination[27] = b2;
break;
}
case DateTimeKind.Utc:
destination[27] = 90;
break;
}
return true;
}
private static bool TryFormatDateTimeR(DateTime value, Span<byte> destination, out int bytesWritten)
{
if (28u >= (uint)destination.Length)
{
bytesWritten = 0;
return false;
}
uint num = DayAbbreviations[(int)value.DayOfWeek];
destination[0] = (byte)num;
num >>= 8;
destination[1] = (byte)num;
num >>= 8;
destination[2] = (byte)num;
destination[3] = 44;
destination[4] = 32;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, destination, 5);
destination[7] = 32;
uint num2 = MonthAbbreviations[value.Month - 1];
destination[8] = (byte)num2;
num2 >>= 8;
destination[9] = (byte)num2;
num2 >>= 8;
destination[10] = (byte)num2;
destination[11] = 32;
System.Buffers.Text.FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, destination, 12);
destination[16] = 32;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, destination, 17);
destination[19] = 58;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, destination, 20);
destination[22] = 58;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, destination, 23);
destination[25] = 32;
destination[26] = 71;
destination[27] = 77;
destination[28] = 84;
bytesWritten = 29;
return true;
}
private static bool TryFormatDateTimeL(DateTime value, Span<byte> destination, out int bytesWritten)
{
if (28u >= (uint)destination.Length)
{
bytesWritten = 0;
return false;
}
uint num = DayAbbreviationsLowercase[(int)value.DayOfWeek];
destination[0] = (byte)num;
num >>= 8;
destination[1] = (byte)num;
num >>= 8;
destination[2] = (byte)num;
destination[3] = 44;
destination[4] = 32;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Day, destination, 5);
destination[7] = 32;
uint num2 = MonthAbbreviationsLowercase[value.Month - 1];
destination[8] = (byte)num2;
num2 >>= 8;
destination[9] = (byte)num2;
num2 >>= 8;
destination[10] = (byte)num2;
destination[11] = 32;
System.Buffers.Text.FormattingHelpers.WriteFourDecimalDigits((uint)value.Year, destination, 12);
destination[16] = 32;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Hour, destination, 17);
destination[19] = 58;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Minute, destination, 20);
destination[22] = 58;
System.Buffers.Text.FormattingHelpers.WriteTwoDecimalDigits((uint)value.Second, destination, 23);
destination[25] = 32;
destination[26] = 103;
destination[27] = 109;
destination[28] = 116;
bytesWritten = 29;
return true;
}
public static bool TryFormat(decimal value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
if (format.IsDefault)
{
format = 'G';
}
switch (format.Symbol)
{
case 'G':
case 'g':
{
if (format.Precision != byte.MaxValue)
{
throw new NotSupportedException(System.SR.Argument_GWithPrecisionNotSupported);
}
NumberBuffer number3 = default(NumberBuffer);
System.Number.DecimalToNumber(value, ref number3);
if (number3.Digits[0] == 0)
{
number3.IsNegative = false;
}
return TryFormatDecimalG(ref number3, destination, out bytesWritten);
}
case 'F':
case 'f':
{
NumberBuffer number2 = default(NumberBuffer);
System.Number.DecimalToNumber(value, ref number2);
byte b2 = (byte)((format.Precision == byte.MaxValue) ? 2 : format.Precision);
System.Number.RoundNumber(ref number2, number2.Scale + b2);
return TryFormatDecimalF(ref number2, destination, out bytesWritten, b2);
}
case 'E':
case 'e':
{
NumberBuffer number = default(NumberBuffer);
System.Number.DecimalToNumber(value, ref number);
byte b = (byte)((format.Precision == byte.MaxValue) ? 6 : format.Precision);
System.Number.RoundNumber(ref number, b + 1);
return TryFormatDecimalE(ref number, destination, out bytesWritten, b, (byte)format.Symbol);
}
default:
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
}
}
private static bool TryFormatDecimalE(ref NumberBuffer number, Span<byte> destination, out int bytesWritten, byte precision, byte exponentSymbol)
{
int scale = number.Scale;
ReadOnlySpan<byte> readOnlySpan = number.Digits;
int num = (number.IsNegative ? 1 : 0) + 1 + ((precision != 0) ? (precision + 1) : 0) + 2 + 3;
if (destination.Length < num)
{
bytesWritten = 0;
return false;
}
int num2 = 0;
int num3 = 0;
if (number.IsNegative)
{
destination[num2++] = 45;
}
byte b = readOnlySpan[num3];
int num4;
if (b == 0)
{
destination[num2++] = 48;
num4 = 0;
}
else
{
destination[num2++] = b;
num3++;
num4 = scale - 1;
}
if (precision > 0)
{
destination[num2++] = 46;
for (int i = 0; i < precision; i++)
{
byte b2 = readOnlySpan[num3];
if (b2 == 0)
{
while (i++ < precision)
{
destination[num2++] = 48;
}
break;
}
destination[num2++] = b2;
num3++;
}
}
destination[num2++] = exponentSymbol;
if (num4 >= 0)
{
destination[num2++] = 43;
}
else
{
destination[num2++] = 45;
num4 = -num4;
}
destination[num2++] = 48;
destination[num2++] = (byte)(num4 / 10 + 48);
destination[num2++] = (byte)(num4 % 10 + 48);
bytesWritten = num;
return true;
}
private static bool TryFormatDecimalF(ref NumberBuffer number, Span<byte> destination, out int bytesWritten, byte precision)
{
int scale = number.Scale;
ReadOnlySpan<byte> readOnlySpan = number.Digits;
int num = (number.IsNegative ? 1 : 0) + ((scale <= 0) ? 1 : scale) + ((precision != 0) ? (precision + 1) : 0);
if (destination.Length < num)
{
bytesWritten = 0;
return false;
}
int i = 0;
int num2 = 0;
if (number.IsNegative)
{
destination[num2++] = 45;
}
if (scale <= 0)
{
destination[num2++] = 48;
}
else
{
for (; i < scale; i++)
{
byte b = readOnlySpan[i];
if (b == 0)
{
int num3 = scale - i;
for (int j = 0; j < num3; j++)
{
destination[num2++] = 48;
}
break;
}
destination[num2++] = b;
}
}
if (precision > 0)
{
destination[num2++] = 46;
int k = 0;
if (scale < 0)
{
int num4 = Math.Min(precision, -scale);
for (int l = 0; l < num4; l++)
{
destination[num2++] = 48;
}
k += num4;
}
for (; k < precision; k++)
{
byte b2 = readOnlySpan[i];
if (b2 == 0)
{
while (k++ < precision)
{
destination[num2++] = 48;
}
break;
}
destination[num2++] = b2;
i++;
}
}
bytesWritten = num;
return true;
}
private static bool TryFormatDecimalG(ref NumberBuffer number, Span<byte> destination, out int bytesWritten)
{
int scale = number.Scale;
ReadOnlySpan<byte> readOnlySpan = number.Digits;
int numDigits = number.NumDigits;
bool flag = scale < numDigits;
int num;
if (flag)
{
num = numDigits + 1;
if (scale <= 0)
{
num += 1 + -scale;
}
}
else
{
num = ((scale <= 0) ? 1 : scale);
}
if (number.IsNegative)
{
num++;
}
if (destination.Length < num)
{
bytesWritten = 0;
return false;
}
int i = 0;
int num2 = 0;
if (number.IsNegative)
{
destination[num2++] = 45;
}
if (scale <= 0)
{
destination[num2++] = 48;
}
else
{
for (; i < scale; i++)
{
byte b = readOnlySpan[i];
if (b == 0)
{
int num3 = scale - i;
for (int j = 0; j < num3; j++)
{
destination[num2++] = 48;
}
break;
}
destination[num2++] = b;
}
}
if (flag)
{
destination[num2++] = 46;
if (scale < 0)
{
int num4 = -scale;
for (int k = 0; k < num4; k++)
{
destination[num2++] = 48;
}
}
byte b2;
while ((b2 = readOnlySpan[i++]) != 0)
{
destination[num2++] = b2;
}
}
bytesWritten = num;
return true;
}
public static bool TryFormat(double value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
return TryFormatFloatingPoint(value, destination, out bytesWritten, format);
}
public static bool TryFormat(float value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
return TryFormatFloatingPoint(value, destination, out bytesWritten, format);
}
private static bool TryFormatFloatingPoint<T>(T value, Span<byte> destination, out int bytesWritten, StandardFormat format) where T : IFormattable
{
if (format.IsDefault)
{
format = 'G';
}
switch (format.Symbol)
{
case 'G':
case 'g':
if (format.Precision != byte.MaxValue)
{
throw new NotSupportedException(System.SR.Argument_GWithPrecisionNotSupported);
}
break;
default:
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
case 'E':
case 'F':
case 'e':
case 'f':
break;
}
string text = format.ToString();
string text2 = value.ToString(text, CultureInfo.InvariantCulture);
int length = text2.Length;
if (length > destination.Length)
{
bytesWritten = 0;
return false;
}
for (int i = 0; i < length; i++)
{
destination[i] = (byte)text2[i];
}
bytesWritten = length;
return true;
}
public static bool TryFormat(Guid value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
int num;
switch (System.Buffers.Text.FormattingHelpers.GetSymbolOrDefault(in format, 'D'))
{
case 'D':
num = -2147483612;
break;
case 'B':
num = -2139260122;
break;
case 'P':
num = -2144786394;
break;
case 'N':
num = 32;
break;
default:
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
}
if ((byte)num > destination.Length)
{
bytesWritten = 0;
return false;
}
bytesWritten = (byte)num;
num >>= 8;
if ((byte)num != 0)
{
destination[0] = (byte)num;
destination = destination.Slice(1);
}
num >>= 8;
DecomposedGuid decomposedGuid = new DecomposedGuid
{
Guid = value
};
byte b = destination[8];
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte03, destination, 0, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte02, destination, 2, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte01, destination, 4, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte00, destination, 6, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
if (num < 0)
{
destination[8] = 45;
destination = destination.Slice(9);
}
else
{
destination = destination.Slice(8);
}
byte b2 = destination[4];
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte05, destination, 0, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte04, destination, 2, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
if (num < 0)
{
destination[4] = 45;
destination = destination.Slice(5);
}
else
{
destination = destination.Slice(4);
}
byte b3 = destination[4];
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte07, destination, 0, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte06, destination, 2, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
if (num < 0)
{
destination[4] = 45;
destination = destination.Slice(5);
}
else
{
destination = destination.Slice(4);
}
byte b4 = destination[4];
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte08, destination, 0, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte09, destination, 2, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
if (num < 0)
{
destination[4] = 45;
destination = destination.Slice(5);
}
else
{
destination = destination.Slice(4);
}
byte b5 = destination[11];
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte10, destination, 0, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte11, destination, 2, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte12, destination, 4, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte13, destination, 6, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte14, destination, 8, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
System.Buffers.Text.FormattingHelpers.WriteHexByte(decomposedGuid.Byte15, destination, 10, System.Buffers.Text.FormattingHelpers.HexCasing.Lowercase);
if ((byte)num != 0)
{
destination[12] = (byte)num;
}
return true;
}
public static bool TryFormat(byte value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
return TryFormatUInt64(value, destination, out bytesWritten, format);
}
[CLSCompliant(false)]
public static bool TryFormat(sbyte value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
return TryFormatInt64(value, 255uL, destination, out bytesWritten, format);
}
[CLSCompliant(false)]
public static bool TryFormat(ushort value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
return TryFormatUInt64(value, destination, out bytesWritten, format);
}
public static bool TryFormat(short value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
return TryFormatInt64(value, 65535uL, destination, out bytesWritten, format);
}
[CLSCompliant(false)]
public static bool TryFormat(uint value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
return TryFormatUInt64(value, destination, out bytesWritten, format);
}
public static bool TryFormat(int value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
return TryFormatInt64(value, 4294967295uL, destination, out bytesWritten, format);
}
[CLSCompliant(false)]
public static bool TryFormat(ulong value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
return TryFormatUInt64(value, destination, out bytesWritten, format);
}
public static bool TryFormat(long value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
return TryFormatInt64(value, ulong.MaxValue, destination, out bytesWritten, format);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatInt64(long value, ulong mask, Span<byte> destination, out int bytesWritten, StandardFormat format)
{
if (format.IsDefault)
{
return TryFormatInt64Default(value, destination, out bytesWritten);
}
switch (format.Symbol)
{
case 'G':
case 'g':
if (format.HasPrecision)
{
throw new NotSupportedException(System.SR.Argument_GWithPrecisionNotSupported);
}
return TryFormatInt64D(value, format.Precision, destination, out bytesWritten);
case 'D':
case 'd':
return TryFormatInt64D(value, format.Precision, destination, out bytesWritten);
case 'N':
case 'n':
return TryFormatInt64N(value, format.Precision, destination, out bytesWritten);
case 'x':
return TryFormatUInt64X((ulong)value & mask, format.Precision, useLower: true, destination, out bytesWritten);
case 'X':
return TryFormatUInt64X((ulong)value & mask, format.Precision, useLower: false, destination, out bytesWritten);
default:
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatInt64D(long value, byte precision, Span<byte> destination, out int bytesWritten)
{
bool insertNegationSign = false;
if (value < 0)
{
insertNegationSign = true;
value = -value;
}
return TryFormatUInt64D((ulong)value, precision, destination, insertNegationSign, out bytesWritten);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatInt64Default(long value, Span<byte> destination, out int bytesWritten)
{
if ((ulong)value < 10uL)
{
return TryFormatUInt32SingleDigit((uint)value, destination, out bytesWritten);
}
if (IntPtr.Size == 8)
{
return TryFormatInt64MultipleDigits(value, destination, out bytesWritten);
}
if (value <= int.MaxValue && value >= int.MinValue)
{
return TryFormatInt32MultipleDigits((int)value, destination, out bytesWritten);
}
if (value <= 4294967295000000000L && value >= -4294967295000000000L)
{
if (value >= 0)
{
return TryFormatUInt64LessThanBillionMaxUInt((ulong)value, destination, out bytesWritten);
}
return TryFormatInt64MoreThanNegativeBillionMaxUInt(-value, destination, out bytesWritten);
}
if (value >= 0)
{
return TryFormatUInt64MoreThanBillionMaxUInt((ulong)value, destination, out bytesWritten);
}
return TryFormatInt64LessThanNegativeBillionMaxUInt(-value, destination, out bytesWritten);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatInt32Default(int value, Span<byte> destination, out int bytesWritten)
{
if ((uint)value < 10u)
{
return TryFormatUInt32SingleDigit((uint)value, destination, out bytesWritten);
}
return TryFormatInt32MultipleDigits(value, destination, out bytesWritten);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatInt32MultipleDigits(int value, Span<byte> destination, out int bytesWritten)
{
if (value < 0)
{
value = -value;
int num = System.Buffers.Text.FormattingHelpers.CountDigits((uint)value);
if (num >= destination.Length)
{
bytesWritten = 0;
return false;
}
destination[0] = 45;
bytesWritten = num + 1;
System.Buffers.Text.FormattingHelpers.WriteDigits((uint)value, destination.Slice(1, num));
return true;
}
return TryFormatUInt32MultipleDigits((uint)value, destination, out bytesWritten);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatInt64MultipleDigits(long value, Span<byte> destination, out int bytesWritten)
{
if (value < 0)
{
value = -value;
int num = System.Buffers.Text.FormattingHelpers.CountDigits((ulong)value);
if (num >= destination.Length)
{
bytesWritten = 0;
return false;
}
destination[0] = 45;
bytesWritten = num + 1;
System.Buffers.Text.FormattingHelpers.WriteDigits((ulong)value, destination.Slice(1, num));
return true;
}
return TryFormatUInt64MultipleDigits((ulong)value, destination, out bytesWritten);
}
private static bool TryFormatInt64MoreThanNegativeBillionMaxUInt(long value, Span<byte> destination, out int bytesWritten)
{
uint num = (uint)(value / 1000000000);
uint value2 = (uint)(value - num * 1000000000);
int num2 = System.Buffers.Text.FormattingHelpers.CountDigits(num);
int num3 = num2 + 9;
if (num3 >= destination.Length)
{
bytesWritten = 0;
return false;
}
destination[0] = 45;
bytesWritten = num3 + 1;
System.Buffers.Text.FormattingHelpers.WriteDigits(num, destination.Slice(1, num2));
System.Buffers.Text.FormattingHelpers.WriteDigits(value2, destination.Slice(num2 + 1, 9));
return true;
}
private static bool TryFormatInt64LessThanNegativeBillionMaxUInt(long value, Span<byte> destination, out int bytesWritten)
{
ulong num = (ulong)value / 1000000000uL;
uint value2 = (uint)((ulong)value - num * 1000000000);
uint num2 = (uint)(num / 1000000000);
uint value3 = (uint)(num - num2 * 1000000000);
int num3 = System.Buffers.Text.FormattingHelpers.CountDigits(num2);
int num4 = num3 + 18;
if (num4 >= destination.Length)
{
bytesWritten = 0;
return false;
}
destination[0] = 45;
bytesWritten = num4 + 1;
System.Buffers.Text.FormattingHelpers.WriteDigits(num2, destination.Slice(1, num3));
System.Buffers.Text.FormattingHelpers.WriteDigits(value3, destination.Slice(num3 + 1, 9));
System.Buffers.Text.FormattingHelpers.WriteDigits(value2, destination.Slice(num3 + 1 + 9, 9));
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatInt64N(long value, byte precision, Span<byte> destination, out int bytesWritten)
{
bool insertNegationSign = false;
if (value < 0)
{
insertNegationSign = true;
value = -value;
}
return TryFormatUInt64N((ulong)value, precision, destination, insertNegationSign, out bytesWritten);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatUInt64(ulong value, Span<byte> destination, out int bytesWritten, StandardFormat format)
{
if (format.IsDefault)
{
return TryFormatUInt64Default(value, destination, out bytesWritten);
}
switch (format.Symbol)
{
case 'G':
case 'g':
if (format.HasPrecision)
{
throw new NotSupportedException(System.SR.Argument_GWithPrecisionNotSupported);
}
return TryFormatUInt64D(value, format.Precision, destination, insertNegationSign: false, out bytesWritten);
case 'D':
case 'd':
return TryFormatUInt64D(value, format.Precision, destination, insertNegationSign: false, out bytesWritten);
case 'N':
case 'n':
return TryFormatUInt64N(value, format.Precision, destination, insertNegationSign: false, out bytesWritten);
case 'x':
return TryFormatUInt64X(value, format.Precision, useLower: true, destination, out bytesWritten);
case 'X':
return TryFormatUInt64X(value, format.Precision, useLower: false, destination, out bytesWritten);
default:
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
}
}
private static bool TryFormatUInt64D(ulong value, byte precision, Span<byte> destination, bool insertNegationSign, out int bytesWritten)
{
int num = System.Buffers.Text.FormattingHelpers.CountDigits(value);
int num2 = ((precision != byte.MaxValue) ? precision : 0) - num;
if (num2 < 0)
{
num2 = 0;
}
int num3 = num + num2;
if (insertNegationSign)
{
num3++;
}
if (num3 > destination.Length)
{
bytesWritten = 0;
return false;
}
bytesWritten = num3;
if (insertNegationSign)
{
destination[0] = 45;
destination = destination.Slice(1);
}
if (num2 > 0)
{
System.Buffers.Text.FormattingHelpers.FillWithAsciiZeros(destination.Slice(0, num2));
}
System.Buffers.Text.FormattingHelpers.WriteDigits(value, destination.Slice(num2, num));
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatUInt64Default(ulong value, Span<byte> destination, out int bytesWritten)
{
if (value < 10)
{
return TryFormatUInt32SingleDigit((uint)value, destination, out bytesWritten);
}
if (IntPtr.Size == 8)
{
return TryFormatUInt64MultipleDigits(value, destination, out bytesWritten);
}
if (value <= uint.MaxValue)
{
return TryFormatUInt32MultipleDigits((uint)value, destination, out bytesWritten);
}
if (value <= 4294967295000000000L)
{
return TryFormatUInt64LessThanBillionMaxUInt(value, destination, out bytesWritten);
}
return TryFormatUInt64MoreThanBillionMaxUInt(value, destination, out bytesWritten);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatUInt32Default(uint value, Span<byte> destination, out int bytesWritten)
{
if (value < 10)
{
return TryFormatUInt32SingleDigit(value, destination, out bytesWritten);
}
return TryFormatUInt32MultipleDigits(value, destination, out bytesWritten);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatUInt32SingleDigit(uint value, Span<byte> destination, out int bytesWritten)
{
if (destination.Length == 0)
{
bytesWritten = 0;
return false;
}
destination[0] = (byte)(48 + value);
bytesWritten = 1;
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatUInt32MultipleDigits(uint value, Span<byte> destination, out int bytesWritten)
{
int num = System.Buffers.Text.FormattingHelpers.CountDigits(value);
if (num > destination.Length)
{
bytesWritten = 0;
return false;
}
bytesWritten = num;
System.Buffers.Text.FormattingHelpers.WriteDigits(value, destination.Slice(0, num));
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatUInt64SingleDigit(ulong value, Span<byte> destination, out int bytesWritten)
{
if (destination.Length == 0)
{
bytesWritten = 0;
return false;
}
destination[0] = (byte)(48 + value);
bytesWritten = 1;
return true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool TryFormatUInt64MultipleDigits(ulong value, Span<byte> destination, out int bytesWritten)
{
int num = System.Buffers.Text.FormattingHelpers.CountDigits(value);
if (num > destination.Length)
{
bytesWritten = 0;
return false;
}
bytesWritten = num;
System.Buffers.Text.FormattingHelpers.WriteDigits(value, destination.Slice(0, num));
return true;
}
private static bool TryFormatUInt64LessThanBillionMaxUInt(ulong value, Span<byte> destination, out int bytesWritten)
{
uint num = (uint)(value / 1000000000);
uint value2 = (uint)(value - num * 1000000000);
int num2 = System.Buffers.Text.FormattingHelpers.CountDigits(num);
int num3 = num2 + 9;
if (num3 > destination.Length)
{
bytesWritten = 0;
return false;
}
bytesWritten = num3;
System.Buffers.Text.FormattingHelpers.WriteDigits(num, destination.Slice(0, num2));
System.Buffers.Text.FormattingHelpers.WriteDigits(value2, destination.Slice(num2, 9));
return true;
}
private static bool TryFormatUInt64MoreThanBillionMaxUInt(ulong value, Span<byte> destination, out int bytesWritten)
{
ulong num = value / 1000000000;
uint value2 = (uint)(value - num * 1000000000);
uint num2 = (uint)(num / 1000000000);
uint value3 = (uint)(num - num2 * 1000000000);
int num3 = System.Buffers.Text.FormattingHelpers.CountDigits(num2);
int num4 = num3 + 18;
if (num4 > destination.Length)
{
bytesWritten = 0;
return false;
}
bytesWritten = num4;
System.Buffers.Text.FormattingHelpers.WriteDigits(num2, destination.Slice(0, num3));
System.Buffers.Text.FormattingHelpers.WriteDigits(value3, destination.Slice(num3, 9));
System.Buffers.Text.FormattingHelpers.WriteDigits(value2, destination.Slice(num3 + 9, 9));
return true;
}
private static bool TryFormatUInt64N(ulong value, byte precision, Span<byte> destination, bool insertNegationSign, out int bytesWritten)
{
int num = System.Buffers.Text.FormattingHelpers.CountDigits(value);
int num2 = (num - 1) / 3;
int num3 = ((precision == byte.MaxValue) ? 2 : precision);
int num4 = num + num2;
if (num3 > 0)
{
num4 += num3 + 1;
}
if (insertNegationSign)
{
num4++;
}
if (num4 > destination.Length)
{
bytesWritten = 0;
return false;
}
bytesWritten = num4;
if (insertNegationSign)
{
destination[0] = 45;
destination = destination.Slice(1);
}
System.Buffers.Text.FormattingHelpers.WriteDigitsWithGroupSeparator(value, destination.Slice(0, num + num2));
if (num3 > 0)
{
destination[num + num2] = 46;
System.Buffers.Text.FormattingHelpers.FillWithAsciiZeros(destination.Slice(num + num2 + 1, num3));
}
return true;
}
private static bool TryFormatUInt64X(ulong value, byte precision, bool useLower, Span<byte> destination, out int bytesWritten)
{
int num = System.Buffers.Text.FormattingHelpers.CountHexDigits(value);
int num2 = ((precision == byte.MaxValue) ? num : Math.Max(precision, num));
if (destination.Length < num2)
{
bytesWritten = 0;
return false;
}
bytesWritten = num2;
string text = (useLower ? "0123456789abcdef" : "0123456789ABCDEF");
while ((uint)(--num2) < (uint)destination.Length)
{
destination[num2] = (byte)text[(int)value & 0xF];
value >>= 4;
}
return true;
}
public static bool TryFormat(TimeSpan value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
char c = System.Buffers.Text.FormattingHelpers.GetSymbolOrDefault(in format, 'c');
switch (c)
{
case 'T':
case 't':
c = 'c';
break;
default:
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
case 'G':
case 'c':
case 'g':
break;
}
int num = 8;
long ticks = value.Ticks;
uint valueWithoutTrailingZeros;
ulong num2;
if (ticks < 0)
{
ticks = -ticks;
if (ticks < 0)
{
valueWithoutTrailingZeros = 4775808u;
num2 = 922337203685uL;
goto IL_0082;
}
}
num2 = System.Buffers.Text.FormattingHelpers.DivMod((ulong)Math.Abs(value.Ticks), 10000000uL, out var modulo);
valueWithoutTrailingZeros = (uint)modulo;
goto IL_0082;
IL_0082:
int num3 = 0;
switch (c)
{
case 'c':
if (valueWithoutTrailingZeros != 0)
{
num3 = 7;
}
break;
case 'G':
num3 = 7;
break;
default:
if (valueWithoutTrailingZeros != 0)
{
num3 = 7 - System.Buffers.Text.FormattingHelpers.CountDecimalTrailingZeros(valueWithoutTrailingZeros, out valueWithoutTrailingZeros);
}
break;
}
if (num3 != 0)
{
num += num3 + 1;
}
ulong num4 = 0uL;
ulong modulo2 = 0uL;
if (num2 != 0)
{
num4 = System.Buffers.Text.FormattingHelpers.DivMod(num2, 60uL, out modulo2);
}
ulong num5 = 0uL;
ulong modulo3 = 0uL;
if (num4 != 0)
{
num5 = System.Buffers.Text.FormattingHelpers.DivMod(num4, 60uL, out modulo3);
}
uint num6 = 0u;
uint modulo4 = 0u;
if (num5 != 0)
{
num6 = System.Buffers.Text.FormattingHelpers.DivMod((uint)num5, 24u, out modulo4);
}
int num7 = 2;
if (modulo4 < 10 && c == 'g')
{
num7--;
num--;
}
int num8 = 0;
if (num6 == 0)
{
if (c == 'G')
{
num += 2;
num8 = 1;
}
}
else
{
num8 = System.Buffers.Text.FormattingHelpers.CountDigits(num6);
num += num8 + 1;
}
if (value.Ticks < 0)
{
num++;
}
if (destination.Length < num)
{
bytesWritten = 0;
return false;
}
bytesWritten = num;
int num9 = 0;
if (value.Ticks < 0)
{
destination[num9++] = 45;
}
if (num8 > 0)
{
System.Buffers.Text.FormattingHelpers.WriteDigits(num6, destination.Slice(num9, num8));
num9 += num8;
destination[num9++] = (byte)((c == 'c') ? 46 : 58);
}
System.Buffers.Text.FormattingHelpers.WriteDigits(modulo4, destination.Slice(num9, num7));
num9 += num7;
destination[num9++] = 58;
System.Buffers.Text.FormattingHelpers.WriteDigits((uint)modulo3, destination.Slice(num9, 2));
num9 += 2;
destination[num9++] = 58;
System.Buffers.Text.FormattingHelpers.WriteDigits((uint)modulo2, destination.Slice(num9, 2));
num9 += 2;
if (num3 > 0)
{
destination[num9++] = 46;
System.Buffers.Text.FormattingHelpers.WriteDigits(valueWithoutTrailingZeros, destination.Slice(num9, num3));
num9 += num3;
}
return true;
}
}