|
|
@@ -2,23 +2,24 @@ |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.IO; |
|
|
|
|
|
|
|
namespace Discord.API.Client |
|
|
|
namespace Discord.ETF |
|
|
|
{ |
|
|
|
//TODO: Floats, Atoms, Tuples, Lists, Dictionaries |
|
|
|
|
|
|
|
public class ETFEncoder |
|
|
|
public unsafe class ETFEncoder |
|
|
|
{ |
|
|
|
private const byte SMALL_INTEGER_EXT = 97; |
|
|
|
private const byte INTEGER_EXT = 98; |
|
|
|
private const byte SMALL_BIG_EXT = 110; |
|
|
|
private const byte SMALL_ATOM_EXT = 115; |
|
|
|
private readonly static byte[] _nilBytes = new byte[] { (byte)ETFType.SMALL_ATOM_EXT, 3, (byte)'n', (byte)'i', (byte)'l' }; |
|
|
|
private readonly static byte[] _falseBytes = new byte[] { (byte)ETFType.SMALL_ATOM_EXT, 5, (byte)'f', (byte)'a', (byte)'l', (byte)'s', (byte)'e' }; |
|
|
|
private readonly static byte[] _trueBytes = new byte[] { (byte)ETFType.SMALL_ATOM_EXT, 4, (byte)'t', (byte)'r', (byte)'u', (byte)'e' }; |
|
|
|
private byte[] _writeBuffer; |
|
|
|
|
|
|
|
private readonly static byte[] nilBytes = new byte[] { SMALL_ATOM_EXT, 3, (byte)'n', (byte)'i', (byte)'l' }; |
|
|
|
private readonly static byte[] falseBytes = new byte[] { SMALL_ATOM_EXT, 5, (byte)'f', (byte)'a', (byte)'l', (byte)'s', (byte)'e' }; |
|
|
|
private readonly static byte[] trueBytes = new byte[] { SMALL_ATOM_EXT, 4, (byte)'t', (byte)'r', (byte)'u', (byte)'e' }; |
|
|
|
public ETFEncoder() |
|
|
|
{ |
|
|
|
_writeBuffer = new byte[11]; |
|
|
|
} |
|
|
|
|
|
|
|
private void WriteNil(BinaryWriter writer) => Append(writer, nilBytes); |
|
|
|
public void Write(BinaryWriter writer, bool value) => Append(writer, value ? trueBytes : falseBytes); |
|
|
|
private void WriteNil(BinaryWriter writer) => Append(writer, _nilBytes); |
|
|
|
public void Write(BinaryWriter writer, bool value) => Append(writer, value ? _trueBytes : _falseBytes); |
|
|
|
|
|
|
|
public void Write(BinaryWriter writer, byte value) => Write(writer, (ulong)value); |
|
|
|
public void Write(BinaryWriter writer, sbyte value) => Write(writer, (long)value); |
|
|
@@ -29,22 +30,19 @@ namespace Discord.API.Client |
|
|
|
public void Write(BinaryWriter writer, ulong value) |
|
|
|
{ |
|
|
|
if (value <= byte.MaxValue) |
|
|
|
Append(writer, new byte[] { SMALL_INTEGER_EXT, (byte)value }); |
|
|
|
Append(writer, new byte[] { (byte)ETFType.SMALL_INTEGER_EXT, (byte)value }); |
|
|
|
else if (value <= int.MaxValue) |
|
|
|
{ |
|
|
|
Append(writer, new byte[] |
|
|
|
{ |
|
|
|
INTEGER_EXT, |
|
|
|
Append(writer, (byte)ETFType.INTEGER_EXT, |
|
|
|
(byte)((value >> 24) & 0xFF), |
|
|
|
(byte)((value >> 16) & 0xFF), |
|
|
|
(byte)((value >> 8) & 0xFF), |
|
|
|
(byte)(value & 0xFF) |
|
|
|
}); |
|
|
|
(byte)(value & 0xFF)); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
var buffer = new byte[3 + 8]; |
|
|
|
buffer[0] = SMALL_BIG_EXT; |
|
|
|
buffer[0] = (byte)ETFType.SMALL_BIG_EXT; |
|
|
|
//buffer[1] = 0; //Always positive |
|
|
|
|
|
|
|
byte bytes = 0; |
|
|
@@ -62,22 +60,22 @@ namespace Discord.API.Client |
|
|
|
public void Write(BinaryWriter writer, long value) |
|
|
|
{ |
|
|
|
if (value >= byte.MinValue && value <= byte.MaxValue) |
|
|
|
Append(writer, new byte[] { SMALL_INTEGER_EXT, (byte)value }); |
|
|
|
{ |
|
|
|
Append(writer, (byte)ETFType.SMALL_INTEGER_EXT, |
|
|
|
(byte)value); |
|
|
|
} |
|
|
|
else if (value >= int.MinValue && value <= int.MaxValue) |
|
|
|
{ |
|
|
|
Append(writer, new byte[] |
|
|
|
{ |
|
|
|
INTEGER_EXT, |
|
|
|
Append(writer, (byte)ETFType.INTEGER_EXT, |
|
|
|
(byte)((value >> 24) & 0xFF), |
|
|
|
(byte)((value >> 16) & 0xFF), |
|
|
|
(byte)((value >> 8) & 0xFF), |
|
|
|
(byte)(value & 0xFF) |
|
|
|
}); |
|
|
|
(byte)(value & 0xFF)); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
var buffer = new byte[3 + 8]; |
|
|
|
buffer[0] = SMALL_BIG_EXT; |
|
|
|
buffer[0] = (byte)ETFType.SMALL_BIG_EXT; |
|
|
|
if (value < 0) |
|
|
|
{ |
|
|
|
buffer[2] = 1; //Is negative |
|
|
@@ -97,22 +95,37 @@ namespace Discord.API.Client |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//public void Write(BinaryWriter writer, double value) => Write(writer, (float)value); |
|
|
|
public void Write(BinaryWriter writer, float value) |
|
|
|
public void Write(BinaryWriter writer, float value) => Write(writer, (double)value); |
|
|
|
public void Write(BinaryWriter writer, double value) |
|
|
|
{ |
|
|
|
throw new NotImplementedException(); |
|
|
|
ulong value2 = *(ulong*)&value; |
|
|
|
Append(writer, (byte)ETFType.NEW_FLOAT_EXT, |
|
|
|
(byte)((value2 >> 56) & 0xFF), |
|
|
|
(byte)((value2 >> 48) & 0xFF), |
|
|
|
(byte)((value2 >> 40) & 0xFF), |
|
|
|
(byte)((value2 >> 32) & 0xFF), |
|
|
|
(byte)((value2 >> 24) & 0xFF), |
|
|
|
(byte)((value2 >> 16) & 0xFF), |
|
|
|
(byte)((value2 >> 8) & 0xFF), |
|
|
|
(byte)(value2 & 0xFF)); |
|
|
|
} |
|
|
|
|
|
|
|
public void Write(BinaryWriter writer, byte[] value) |
|
|
|
{ |
|
|
|
throw new NotImplementedException(); |
|
|
|
int count = value.Length; |
|
|
|
Append(writer, (byte)ETFType.BINARY_EXT, |
|
|
|
(byte)((count >> 24) & 0xFF), |
|
|
|
(byte)((count >> 16) & 0xFF), |
|
|
|
(byte)((count >> 8) & 0xFF), |
|
|
|
(byte)(count & 0xFF)); |
|
|
|
Append(writer, value); |
|
|
|
} |
|
|
|
public void Write(BinaryWriter writer, string value) |
|
|
|
{ |
|
|
|
throw new NotImplementedException(); |
|
|
|
} |
|
|
|
|
|
|
|
public void Write<T>(BinaryWriter writer, T value) |
|
|
|
/*public void Write<T>(BinaryWriter writer, T value) |
|
|
|
where T : ISerializable |
|
|
|
{ |
|
|
|
throw new NotImplementedException(); |
|
|
@@ -121,9 +134,9 @@ namespace Discord.API.Client |
|
|
|
where T : ISerializable |
|
|
|
{ |
|
|
|
throw new NotImplementedException(); |
|
|
|
} |
|
|
|
}*/ |
|
|
|
|
|
|
|
private void Append(BinaryWriter writer, byte[] data) => Append(writer, data, data.Length); |
|
|
|
private void Append(BinaryWriter writer, params byte[] data) => Append(writer, data, data.Length); |
|
|
|
private void Append(BinaryWriter writer, byte[] data, int length) |
|
|
|
{ |
|
|
|
throw new NotImplementedException(); |