Utf8Formatter
Methods to format common data types as Utf8 strings.
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] {
7238995,
7237453,
6649172,
6579543,
7694420,
6910534,
7627091
};
private static readonly uint[] DayAbbreviationsLowercase = new uint[7] {
7239027,
7237485,
6649204,
6579575,
7694452,
6910566,
7627123
};
private static readonly uint[] MonthAbbreviations = new uint[12] {
7233866,
6448454,
7496013,
7499841,
7954765,
7238986,
7107914,
6780225,
7365971,
7627599,
7761742,
6513988
};
private static readonly uint[] MonthAbbreviationsLowercase = new uint[12] {
7233898,
6448486,
7496045,
7499873,
7954797,
7239018,
7107946,
6780257,
7366003,
7627631,
7761774,
6514020
};
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(ref format, 'G');
if (!value) {
switch (symbolOrDefault) {
case 'G':
if (4 < (uint)destination.Length) {
BinaryPrimitives.WriteUInt32BigEndian(destination, 1180789875);
goto IL_006e;
}
goto IL_007e;
case 'l':
{
if (4 < (uint)destination.Length) {
BinaryPrimitives.WriteUInt32BigEndian(destination, 1717660787);
goto IL_006e;
}
goto IL_007e;
}
IL_006e:
destination[4] = 101;
bytesWritten = 5;
return true;
}
} else {
switch (symbolOrDefault) {
case 'G':
if (BinaryPrimitives.TryWriteUInt32BigEndian(destination, 1416787301))
goto IL_0033;
goto IL_007e;
case 'l':
{
if (BinaryPrimitives.TryWriteUInt32BigEndian(destination, 1953658213))
goto IL_0033;
goto IL_007e;
}
IL_0033:
bytesWritten = 4;
return true;
}
}
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
IL_007e:
bytesWritten = 0;
return false;
}
public static bool TryFormat(DateTimeOffset value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
TimeSpan offset = System.Buffers.Text.Utf8Constants.s_nullUtcOffset;
char c = format.Symbol;
if (format.IsDefault) {
c = 'G';
offset = value.Offset;
}
switch (c) {
case 'R':
return TryFormatDateTimeR(value.UtcDateTime, destination, out bytesWritten);
case 'l':
return TryFormatDateTimeL(value.UtcDateTime, destination, out bytesWritten);
case 'O':
return TryFormatDateTimeO(value.DateTime, value.Offset, destination, out bytesWritten);
case 'G':
return TryFormatDateTimeG(value.DateTime, offset, destination, out bytesWritten);
default:
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
}
}
public static bool TryFormat(DateTime value, Span<byte> destination, out int bytesWritten, StandardFormat format = default(StandardFormat))
{
switch (System.Buffers.Text.FormattingHelpers.GetSymbolOrDefault(ref format, 'G')) {
case 'R':
return TryFormatDateTimeR(value, destination, out bytesWritten);
case 'l':
return TryFormatDateTimeL(value, destination, out bytesWritten);
case 'O':
return TryFormatDateTimeO(value, System.Buffers.Text.Utf8Constants.s_nullUtcOffset, destination, out bytesWritten);
case 'G':
return TryFormatDateTimeG(value, System.Buffers.Text.Utf8Constants.s_nullUtcOffset, destination, out bytesWritten);
default:
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
}
}
private static bool TryFormatDateTimeG(DateTime value, TimeSpan offset, Span<byte> destination, out int bytesWritten)
{
int num = 19;
if (offset != System.Buffers.Text.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, 0);
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 != System.Buffers.Text.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 TryFormatDateTimeL(DateTime value, Span<byte> destination, out int bytesWritten)
{
if (28 >= (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;
}
private static bool TryFormatDateTimeO(DateTime value, TimeSpan offset, Span<byte> destination, out int bytesWritten)
{
int num = 27;
DateTimeKind dateTimeKind = DateTimeKind.Local;
if (offset == System.Buffers.Text.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, 0);
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 % 10000000), 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 (28 >= (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;
}
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 != 255)
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 == 255) ? 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 == 255) ? 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 num6;
if (b == 0) {
destination[num2++] = 48;
num6 = 0;
} else {
destination[num2++] = b;
num3++;
num6 = 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 (num6 >= 0)
destination[num2++] = 43;
else {
destination[num2++] = 45;
num6 = -num6;
}
destination[num2++] = 48;
destination[num2++] = (byte)(num6 / 10 + 48);
destination[num2++] = (byte)(num6 % 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) {
for (; i < scale; i++) {
byte b = readOnlySpan[i];
if (b == 0) {
int num4 = scale - i;
for (int j = 0; j < num4; j++) {
destination[num2++] = 48;
}
break;
}
destination[num2++] = b;
}
} else
destination[num2++] = 48;
if (precision > 0) {
destination[num2++] = 46;
int k = 0;
if (scale < 0) {
int num9 = Math.Min(precision, -scale);
for (int l = 0; l < num9; l++) {
destination[num2++] = 48;
}
k += num9;
}
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) {
for (; i < scale; i++) {
byte b = readOnlySpan[i];
if (b == 0) {
int num4 = scale - i;
for (int j = 0; j < num4; j++) {
destination[num2++] = 48;
}
break;
}
destination[num2++] = b;
}
} else
destination[num2++] = 48;
if (flag) {
destination[num2++] = 46;
if (scale < 0) {
int num9 = -scale;
for (int k = 0; k < num9; 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 != 255)
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 format2 = format.ToString();
ref T reference = ref value;
T val = default(T);
if (val == null) {
val = reference;
ref reference = ref val;
}
string text = reference.ToString(format2, CultureInfo.InvariantCulture);
int length = text.Length;
if (length > destination.Length) {
bytesWritten = 0;
return false;
}
for (int i = 0; i < length; i++) {
destination[i] = (byte)text[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(ref 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 = default(DecomposedGuid);
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, 255, 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, 65535, 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, 4294967295, 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) {
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 & (long)mask), format.Precision, true, destination, out bytesWritten);
case 'X':
return TryFormatUInt64X((ulong)(value & (long)mask), format.Precision, false, destination, out bytesWritten);
default:
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
}
}
return TryFormatInt64Default(value, destination, 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 < 10)
return TryFormatUInt32SingleDigit((uint)value, destination, out bytesWritten);
if (IntPtr.Size == 8)
return TryFormatInt64MultipleDigits(value, destination, out bytesWritten);
if (value <= 2147483647 && value >= -2147483648)
return TryFormatInt32MultipleDigits((int)value, destination, out bytesWritten);
if (value <= 4294967295000000000 && value >= -4294967295000000000) {
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 < 10)
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 / 1000000000;
uint value2 = (uint)(value - (long)(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) {
switch (format.Symbol) {
case 'G':
case 'g':
if (format.HasPrecision)
throw new NotSupportedException(System.SR.Argument_GWithPrecisionNotSupported);
return TryFormatUInt64D(value, format.Precision, destination, false, out bytesWritten);
case 'D':
case 'd':
return TryFormatUInt64D(value, format.Precision, destination, false, out bytesWritten);
case 'N':
case 'n':
return TryFormatUInt64N(value, format.Precision, destination, false, out bytesWritten);
case 'x':
return TryFormatUInt64X(value, format.Precision, true, destination, out bytesWritten);
case 'X':
return TryFormatUInt64X(value, format.Precision, false, destination, out bytesWritten);
default:
return System.ThrowHelper.TryFormatThrowFormatException(out bytesWritten);
}
}
return TryFormatUInt64Default(value, destination, 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 != 255) ? 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 <= 4294967295000000000)
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 == 255) ? 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 == 255) ? 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 & 15];
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(ref 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 = 4775808;
num2 = 922337203685;
goto IL_0082;
}
}
num2 = System.Buffers.Text.FormattingHelpers.DivMod((ulong)Math.Abs(value.Ticks), 10000000, out ulong 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 = 0;
ulong modulo2 = 0;
if (num2 != 0)
num4 = System.Buffers.Text.FormattingHelpers.DivMod(num2, 60, out modulo2);
ulong num5 = 0;
ulong modulo3 = 0;
if (num4 != 0)
num5 = System.Buffers.Text.FormattingHelpers.DivMod(num4, 60, out modulo3);
uint num6 = 0;
uint modulo4 = 0;
if (num5 != 0)
num6 = System.Buffers.Text.FormattingHelpers.DivMod((uint)num5, 24, 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;
}
}
}