Started work on ETFReader
This commit is contained in:
@@ -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<Type, Delegate> _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));
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user