public static bool TryWrite(ref ResizableMemory <byte> writer, bool value, StandardFormat standardFormat) { if (standardFormat.IsDefault) { if (value) { _trueValue.Span.CopyTo(writer.RequestSpan(6)); writer.Advance(6); } else { _falseValue.Span.CopyTo(writer.RequestSpan(7)); writer.Advance(7); } } else { int start = writer.Length; writer.Push((byte)EtfTokenType.Binary); writer.Advance(4); if (!Utf8Writer.TryWrite(ref writer, value, standardFormat)) { return(false); } int length = writer.Length - start - 5; writer.Array[start + 1] = (byte)(length >> 24); writer.Array[start + 2] = (byte)(length >> 16); writer.Array[start + 3] = (byte)(length >> 8); writer.Array[start + 4] = (byte)length; } return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, long value, StandardFormat standardFormat) { if (standardFormat.IsDefault) { if (value <= byte.MaxValue && value >= byte.MinValue) { return(TryWrite(ref writer, (byte)value, standardFormat)); } if (value <= int.MaxValue && value >= int.MinValue) { return(TryWrite(ref writer, (int)value, standardFormat)); } writer.Push((byte)EtfTokenType.SmallBig); writer.Push(8); if (value >= 0) { writer.Push(0); BinaryPrimitives.WriteUInt64LittleEndian(writer.RequestSpan(8), (ulong)value); } else { writer.Push(1); if (value == long.MinValue) { BinaryPrimitives.WriteUInt64LittleEndian(writer.RequestSpan(8), 9223372036854775808); } else { BinaryPrimitives.WriteUInt64LittleEndian(writer.RequestSpan(8), (ulong)-value); } } writer.Advance(8); } else { int start = writer.Length; writer.Push((byte)EtfTokenType.Binary); writer.Advance(4); if (!Utf8Writer.TryWrite(ref writer, value, standardFormat)) { return(false); } int length = writer.Length - start - 5; writer.Array[start + 1] = (byte)(length >> 24); writer.Array[start + 2] = (byte)(length >> 16); writer.Array[start + 3] = (byte)(length >> 8); writer.Array[start + 4] = (byte)length; } return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, int value, StandardFormat standardFormat) { if (standardFormat.IsDefault) { if (value <= byte.MaxValue && value >= byte.MinValue) { return(TryWrite(ref writer, (byte)value, standardFormat)); } writer.Push((byte)EtfTokenType.Integer); BinaryPrimitives.WriteInt32BigEndian(writer.RequestSpan(4), value); writer.Advance(4); } else { int start = writer.Length; writer.Push((byte)EtfTokenType.Binary); writer.Advance(4); if (!Utf8Writer.TryWrite(ref writer, value, standardFormat)) { return(false); } int length = writer.Length - start - 5; writer.Array[start + 1] = (byte)(length >> 24); writer.Array[start + 2] = (byte)(length >> 16); writer.Array[start + 3] = (byte)(length >> 8); writer.Array[start + 4] = (byte)length; } return(true); }
public static bool TryWriteString(ref ResizableMemory <byte> writer, ReadOnlySpan <byte> value) { var dstSpan = writer.RequestSpan(value.Length); value.CopyTo(dstSpan); writer.Advance(value.Length); return(true); }
public static bool TryWriteNull(ref ResizableMemory <byte> writer) { var data = writer.RequestSpan(4); // null const uint nullValue = ('n' << 24) + ('u' << 16) + ('l' << 8) + ('l' << 0); BinaryPrimitives.WriteUInt32BigEndian(data, nullValue); writer.Advance(4); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, ulong value, StandardFormat standardFormat) { var data = writer.RequestSpan(29); // 18,446,744,073,709,551,615.00 if (!Utf8Formatter.TryFormat(value, data, out int bytesWritten, standardFormat)) { return(false); } writer.Advance(bytesWritten); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, uint value, StandardFormat standardFormat) { var data = writer.RequestSpan(16); // 4,294,967,295.00 if (!Utf8Formatter.TryFormat(value, data, out int bytesWritten, standardFormat)) { return(false); } writer.Advance(bytesWritten); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, long value, StandardFormat standardFormat) { var data = writer.RequestSpan(29); // -9,223,372,036,854,775,808.00 if (!Utf8Formatter.TryFormat(value, data, out int bytesWritten, standardFormat)) { return(false); } writer.Advance(bytesWritten); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, Guid value, StandardFormat standardFormat) { var data = writer.RequestSpan(38); // {ABCDEFGH-ABCD-ABCD-ABCD-ABCDEFGHIJKL} if (!Utf8Formatter.TryFormat(value, data, out int bytesWritten, standardFormat)) { return(false); } writer.Advance(bytesWritten); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, DateTimeOffset value, StandardFormat standardFormat) { var data = writer.RequestSpan(33); // 9999-12-31T11:59:59.999999+00:00 if (!Utf8Formatter.TryFormat(value, data, out int bytesWritten, standardFormat)) { return(false); } writer.Advance(bytesWritten); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, TimeSpan value, StandardFormat standardFormat) { var data = writer.RequestSpan(26); // -10675199.02:48:05.4775808 if (!Utf8Formatter.TryFormat(value, data, out int bytesWritten, standardFormat)) { return(false); } writer.Advance(bytesWritten); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, float value, StandardFormat standardFormat) { var data = writer.RequestSpan(14); // -3.402823E+038 if (!Utf8Formatter.TryFormat(value, data, out int bytesWritten, standardFormat)) { return(false); } writer.Advance(bytesWritten); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, double value, StandardFormat standardFormat) { var data = writer.RequestSpan(22); // -1.79769313486232E+308 if (!Utf8Formatter.TryFormat(value, data, out int bytesWritten, standardFormat)) { return(false); } writer.Advance(bytesWritten); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, decimal value, StandardFormat standardFormat) { var data = writer.RequestSpan(30); // -79228162514264337593543950336 if (!Utf8Formatter.TryFormat(value, data, out int bytesWritten, standardFormat)) { return(false); } writer.Advance(bytesWritten); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, DateTime value, StandardFormat standardFormat) { // TODO: Will this break in other locales? var data = writer.RequestSpan(31); // Fri, 31 Dec 9999 11:59:59 ACWST if (!Utf8Formatter.TryFormat(value, data, out int bytesWritten, standardFormat)) { return(false); } writer.Advance(bytesWritten); return(true); }
public static bool TryWriteUtf8Bytes(ref ResizableMemory <byte> writer, ReadOnlySpan <byte> value) { if (value.Length > ushort.MaxValue) { return(false); } writer.Push((byte)EtfTokenType.Binary); BinaryPrimitives.WriteUInt32BigEndian(writer.RequestSpan(4), (uint)value.Length); writer.Advance(4); if (!Utf8Writer.TryWriteString(ref writer, value)) { return(false); } return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, string value) { var valueBytes = MemoryMarshal.AsBytes(value.AsSpan()); if (Encodings.Utf16.ToUtf8Length(valueBytes, out var length) != OperationStatus.Done) { return(false); } var data = writer.RequestSpan(length); if (Encodings.Utf16.ToUtf8(valueBytes, data, out _, out _) != OperationStatus.Done) { return(false); } writer.Advance(length); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, char value) { ReadOnlySpan <char> chars = stackalloc char[] { value }; var valueBytes = MemoryMarshal.AsBytes(chars); if (Encodings.Utf16.ToUtf8Length(valueBytes, out var length) != OperationStatus.Done) { return(false); } var data = writer.RequestSpan(length); if (Encodings.Utf16.ToUtf8(valueBytes, data, out _, out _) != OperationStatus.Done) { return(false); } writer.Advance(length); return(true); }
public static bool TryWrite(ref ResizableMemory <byte> writer, float value, StandardFormat standardFormat) { // TODO: Untested, does Discord have any endpoints that accept floats? if (standardFormat.IsDefault) { writer.Push((byte)EtfTokenType.NewFloat); // Swap endian Span <double> src = stackalloc double[] { value }; var srcBytes = MemoryMarshal.AsBytes(src); var dst = writer.RequestSpan(8); dst[0] = srcBytes[7]; dst[1] = srcBytes[6]; dst[2] = srcBytes[5]; dst[3] = srcBytes[4]; dst[4] = srcBytes[3]; dst[5] = srcBytes[2]; dst[6] = srcBytes[1]; dst[7] = srcBytes[0]; writer.Advance(8); } else { int start = writer.Length; writer.Push((byte)EtfTokenType.Binary); writer.Advance(4); if (!Utf8Writer.TryWrite(ref writer, value, standardFormat)) { return(false); } int length = writer.Length - start - 5; writer.Array[start + 1] = (byte)(length >> 24); writer.Array[start + 2] = (byte)(length >> 16); writer.Array[start + 3] = (byte)(length >> 8); writer.Array[start + 4] = (byte)length; } return(true); }
public static bool TryWriteNull(ref ResizableMemory <byte> writer) { _nilValue.Span.CopyTo(writer.RequestSpan(5)); writer.Advance(5); return(true); }
public static bool TryWriteUtf8Bytes(ref ResizableMemory <byte> writer, ReadOnlySpan <byte> value) { int i = 0; int start = 0; for (; i < value.Length; i++) { byte b = value[i]; // Special chars switch (b) { case (byte)'"': case (byte)'\\': //case (byte)'/': if (i != start) { int bytes = i - start; var buffer = writer.RequestSpan(bytes); value.Slice(start, bytes).CopyTo(buffer); writer.Advance(bytes); } writer.Push((byte)'\\'); writer.Push(b); start = i + 1; continue; } if (b < 32) // Control codes { if (i != start) { int bytes = i - start; var buffer = writer.RequestSpan(bytes); value.Slice(start, bytes).CopyTo(buffer); writer.Advance(bytes); } switch (b) { case (byte)'\b': writer.Push((byte)'\\'); writer.Push((byte)'b'); break; case (byte)'\f': writer.Push((byte)'\\'); writer.Push((byte)'f'); break; case (byte)'\n': writer.Push((byte)'\\'); writer.Push((byte)'n'); break; case (byte)'\r': writer.Push((byte)'\\'); writer.Push((byte)'r'); break; case (byte)'\t': writer.Push((byte)'\\'); writer.Push((byte)'t'); break; default: var escape = writer.RequestSpan(6); escape[0] = (byte)'\\'; escape[1] = (byte)'u'; escape[2] = (byte)'0'; escape[3] = (byte)'0'; escape[4] = ToHex((byte)(b >> 4)); escape[5] = ToHex((byte)(b & 0xF)); writer.Advance(6); break; } start = i + 1; } else if (b >= 192) // Multi-byte chars { if (i != start) { int bytes = i - start; var buffer = writer.RequestSpan(bytes); value.Slice(start, i - start).CopyTo(buffer); writer.Advance(bytes); } int seqStart = i; int length = 1; for (; length < 4 && i < value.Length - 1 && value[i + 1] >= 128; length++, i++) { } Span <ushort> utf16Value = stackalloc ushort[2]; if (Encodings.Utf8.ToUtf16(value.Slice(seqStart, length), MemoryMarshal.AsBytes(utf16Value), out _, out int bytesWritten) != OperationStatus.Done) { return(false); } for (int j = 0; j < bytesWritten / 2; j++) { var buffer2 = writer.RequestSpan(6); buffer2[0] = (byte)'\\'; buffer2[1] = (byte)'u'; buffer2[2] = ToHex((byte)((utf16Value[j] >> 12) & 0xF)); buffer2[3] = ToHex((byte)((utf16Value[j] >> 8) & 0xF)); buffer2[4] = ToHex((byte)((utf16Value[j] >> 4) & 0xF)); buffer2[5] = ToHex((byte)(utf16Value[j] & 0xF)); writer.Advance(6); } start = i + 1; } else if (b >= 128) // Multi-byte chars out of sequence { return(false); } } // Append last part to builder if (i != start) { int bytes = i - start; var buffer = writer.RequestSpan(bytes); value.Slice(start, bytes).CopyTo(buffer); writer.Advance(bytes); } return(true); }