From a3735f2210bcfb55b3508e3d26639173a0483284 Mon Sep 17 00:00:00 2001 From: RogueException Date: Thu, 14 Jan 2016 08:08:49 -0400 Subject: [PATCH] Started adding ETF support --- src/Discord.Net/API/Client/ETFEncoder.cs | 132 ++++++++++++++++++++++++++++ src/Discord.Net/API/Client/ISerializable.cs | 9 ++ 2 files changed, 141 insertions(+) create mode 100644 src/Discord.Net/API/Client/ETFEncoder.cs create mode 100644 src/Discord.Net/API/Client/ISerializable.cs diff --git a/src/Discord.Net/API/Client/ETFEncoder.cs b/src/Discord.Net/API/Client/ETFEncoder.cs new file mode 100644 index 000000000..b63806f19 --- /dev/null +++ b/src/Discord.Net/API/Client/ETFEncoder.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Discord.API.Client +{ + //TODO: Floats, Atoms, Tuples, Lists, Dictionaries + + public 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[] { 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' }; + + 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); + public void Write(BinaryWriter writer, ushort value) => Write(writer, (ulong)value); + public void Write(BinaryWriter writer, short value) => Write(writer, (long)value); + public void Write(BinaryWriter writer, uint value) => Write(writer, (ulong)value); + public void Write(BinaryWriter writer, int value) => Write(writer, (long)value); + public void Write(BinaryWriter writer, ulong value) + { + if (value <= byte.MaxValue) + Append(writer, new byte[] { SMALL_INTEGER_EXT, (byte)value }); + else if (value <= int.MaxValue) + { + Append(writer, new byte[] + { + INTEGER_EXT, + (byte)((value >> 24) & 0xFF), + (byte)((value >> 16) & 0xFF), + (byte)((value >> 8) & 0xFF), + (byte)(value & 0xFF) + }); + } + else + { + var buffer = new byte[3 + 8]; + buffer[0] = SMALL_BIG_EXT; + //buffer[1] = 0; //Always positive + + byte bytes = 0; + while (value > 0) + { + buffer[3 + bytes] = (byte)(value & 0xFF); + value >>= 8; + bytes++; + } + buffer[1] = bytes; //Encoded bytes + + Append(writer, buffer, 3 + bytes); + } + } + public void Write(BinaryWriter writer, long value) + { + if (value >= byte.MinValue && value <= byte.MaxValue) + Append(writer, new byte[] { SMALL_INTEGER_EXT, (byte)value }); + else if (value >= int.MinValue && value <= int.MaxValue) + { + Append(writer, new byte[] + { + INTEGER_EXT, + (byte)((value >> 24) & 0xFF), + (byte)((value >> 16) & 0xFF), + (byte)((value >> 8) & 0xFF), + (byte)(value & 0xFF) + }); + } + else + { + var buffer = new byte[3 + 8]; + buffer[0] = SMALL_BIG_EXT; + if (value < 0) + { + buffer[2] = 1; //Is negative + value = -value; + } + + byte bytes = 0; + while (value > 0) + { + buffer[3 + bytes] = (byte)(value & 0xFF); + value >>= 8; + bytes++; + } + buffer[1] = bytes; //Encoded bytes + + Append(writer, buffer, 3 + bytes); + } + } + + //public void Write(BinaryWriter writer, double value) => Write(writer, (float)value); + public void Write(BinaryWriter writer, float value) + { + throw new NotImplementedException(); + } + + public void Write(BinaryWriter writer, byte[] value) + { + throw new NotImplementedException(); + } + public void Write(BinaryWriter writer, string value) + { + throw new NotImplementedException(); + } + + public void Write(BinaryWriter writer, T value) + where T : ISerializable + { + throw new NotImplementedException(); + } + public void Write(BinaryWriter writer, IEnumerable value) + where T : ISerializable + { + throw new NotImplementedException(); + } + + private void Append(BinaryWriter writer, byte[] data) => Append(writer, data, data.Length); + private void Append(BinaryWriter writer, byte[] data, int length) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Discord.Net/API/Client/ISerializable.cs b/src/Discord.Net/API/Client/ISerializable.cs new file mode 100644 index 000000000..d23dc3c6c --- /dev/null +++ b/src/Discord.Net/API/Client/ISerializable.cs @@ -0,0 +1,9 @@ +using System.IO; + +namespace Discord.API.Client +{ + public interface ISerializable + { + void Write(BinaryWriter writer); + } +}