diff --git a/src/Discord.Net/ETF/ETFReader.cs b/src/Discord.Net/ETF/ETFReader.cs index d2f33dcbc..e8ef4ca0e 100644 --- a/src/Discord.Net/ETF/ETFReader.cs +++ b/src/Discord.Net/ETF/ETFReader.cs @@ -1,9 +1,173 @@ using System; +using System.Collections.Concurrent; using System.IO; +using System.Linq; +using System.Text; namespace Discord.ETF { public class ETFReader { + /* + private readonly Stream _stream; + private readonly byte[] _buffer; + private readonly bool _leaveOpen; + private readonly Encoding _encoding; + private readonly ConcurrentDictionary _serializers, _indirectSerializers; + + private void ReadNil(bool allow) + { + if (!allow) throw new InvalidDataException(); + _stream.Read(_buffer, 0, 3); + if (_buffer[0] != 'n' || _buffer[1] != 'i' || _buffer[2] != 'l') + throw new InvalidDataException(); + } + private void ReadTrue() + { + _stream.Read(_buffer, 0, 4); + if (_buffer[0] != 't' || _buffer[1] != 'r' || _buffer[2] != 'u' || _buffer[3] != 'e') + throw new InvalidDataException(); + } + private void ReadFalse() + { + _stream.Read(_buffer, 0, 5); + if (_buffer[0] != 'f' || _buffer[1] != 'a' || _buffer[2] != 'l' || _buffer[3] != 's' || _buffer[4] != 'e') + throw new InvalidDataException(); + } + + public bool? ReadBool(bool allowNil) + { + _stream.Read(_buffer, 0, 2); + switch ((ETFType)_buffer[0]) + { + case ETFType.SMALL_ATOM_EXT: + switch (_buffer[1]) //Length + { + case 3: + ReadNil(allowNil); + return null; + case 4: + ReadTrue(); + return true; + case 5: + ReadFalse(); + return false; + } + break; + } + throw new InvalidDataException(); + } + + public long? ReadInteger(bool allowNil) + { + _stream.Read(_buffer, 0, 1); + ETFType type = (ETFType)reader.ReadByte(); + switch (type) + { + case ETFType.SMALL_ATOM_EXT: + ReadNil(allowNil); + return null; + case ETFType.SMALL_INTEGER_EXT: + _stream.Read(_buffer, 0, 1); + return (_buffer[0] << 24) | (_buffer[1] << 16) | + (_buffer[2] << 8) | (_buffer[3]); + case ETFType.INTEGER_EXT: + _stream.Read(_buffer, 0, 4); + return ??; + case ETFType.SMALL_BIG_EXT: + return ??; + } + throw new InvalidDataException(); + } + + public void Write(sbyte value) => Write((long)value); + public void Write(byte value) => Write((ulong)value); + public void Write(short value) => Write((long)value); + public void Write(ushort value) => Write((ulong)value); + public void Write(int value) => Write((long)value); + public void Write(uint value) => Write((ulong)value); + public void Write(long value) + { + if (value >= byte.MinValue && value <= byte.MaxValue) + { + _buffer[0] = (byte)ETFType.SMALL_INTEGER_EXT; + _buffer[1] = (byte)value; + _stream.Write(_buffer, 0, 2); + } + else if (value >= int.MinValue && value <= int.MaxValue) + { + _buffer[0] = (byte)ETFType.INTEGER_EXT; + _buffer[1] = (byte)(value >> 24); + _buffer[2] = (byte)(value >> 16); + _buffer[3] = (byte)(value >> 8); + _buffer[4] = (byte)value; + _stream.Write(_buffer, 0, 5); + } + else + { + _buffer[0] = (byte)ETFType.SMALL_BIG_EXT; + if (value < 0) + { + _buffer[2] = 1; //Is negative + value = -value; + } + + byte bytes = 0; + while (value > 0) + _buffer[3 + bytes++] = (byte)(value >>= 8); + _buffer[1] = bytes; //Encoded bytes + + _stream.Write(_buffer, 0, 3 + bytes); + } + } + public void Write(ulong value) + { + if (value <= byte.MaxValue) + { + _buffer[0] = (byte)ETFType.SMALL_INTEGER_EXT; + _buffer[1] = (byte)value; + _stream.Write(_buffer, 0, 2); + } + else if (value <= int.MaxValue) + { + _buffer[0] = (byte)ETFType.INTEGER_EXT; + _buffer[1] = (byte)(value >> 24); + _buffer[2] = (byte)(value >> 16); + _buffer[3] = (byte)(value >> 8); + _buffer[4] = (byte)value; + _stream.Write(_buffer, 0, 5); + } + else + { + _buffer[0] = (byte)ETFType.SMALL_BIG_EXT; + _buffer[2] = 0; //Always positive + + byte bytes = 0; + while (value > 0) + _buffer[3 + bytes++] = (byte)(value >>= 8); + _buffer[1] = bytes; //Encoded bytes + + _stream.Write(_buffer, 0, 3 + bytes); + } + } + + public void Write(float value) => Write((double)value); + public unsafe void Write(double value) + { + ulong value2 = *(ulong*)&value; + _buffer[0] = (byte)ETFType.NEW_FLOAT_EXT; + _buffer[1] = (byte)(value2 >> 56); + _buffer[2] = (byte)(value2 >> 48); + _buffer[3] = (byte)(value2 >> 40); + _buffer[4] = (byte)(value2 >> 32); + _buffer[5] = (byte)(value2 >> 24); + _buffer[6] = (byte)(value2 >> 16); + _buffer[7] = (byte)(value2 >> 8); + _buffer[8] = (byte)value2; + _stream.Write(_buffer, 0, 9); + } + + public void Write(DateTime value) => Write((ulong)((value.Ticks - _epochTime.Ticks) / TimeSpan.TicksPerSecond)); +*/ } -} +} \ No newline at end of file