| @@ -29,36 +29,8 @@ namespace Discord.ETF | |||||
| _buffer = new byte[11]; | _buffer = new byte[11]; | ||||
| _encoding = Encoding.UTF8; | _encoding = Encoding.UTF8; | ||||
| } | } | ||||
| private bool ReadNil(bool ignoreLength = false) | |||||
| { | |||||
| if (!ignoreLength) | |||||
| { | |||||
| _stream.Read(_buffer, 0, 1); | |||||
| byte length = _buffer[0]; | |||||
| if (length != 3) return false; | |||||
| } | |||||
| _stream.Read(_buffer, 0, 3); | |||||
| if (_buffer[0] == 'n' && _buffer[1] == 'i' && _buffer[2] == 'l') | |||||
| return true; | |||||
| return false; | |||||
| } | |||||
| 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? ReadNullableBool() | |||||
| public bool ReadBool() | |||||
| { | { | ||||
| _stream.Read(_buffer, 0, 1); | _stream.Read(_buffer, 0, 1); | ||||
| ETFType type = (ETFType)_buffer[0]; | ETFType type = (ETFType)_buffer[0]; | ||||
| @@ -67,10 +39,6 @@ namespace Discord.ETF | |||||
| _stream.Read(_buffer, 0, 1); | _stream.Read(_buffer, 0, 1); | ||||
| switch (_buffer[0]) //Length | switch (_buffer[0]) //Length | ||||
| { | { | ||||
| case 3: | |||||
| if (ReadNil()) | |||||
| return null; | |||||
| break; | |||||
| case 4: | case 4: | ||||
| ReadTrue(); | ReadTrue(); | ||||
| return true; | return true; | ||||
| @@ -81,24 +49,17 @@ namespace Discord.ETF | |||||
| } | } | ||||
| throw new InvalidDataException(); | throw new InvalidDataException(); | ||||
| } | } | ||||
| public bool ReadBool() | |||||
| private void ReadTrue() | |||||
| { | { | ||||
| _stream.Read(_buffer, 0, 1); | |||||
| ETFType type = (ETFType)_buffer[0]; | |||||
| if (type == ETFType.SMALL_ATOM_EXT) | |||||
| { | |||||
| _stream.Read(_buffer, 0, 1); | |||||
| switch (_buffer[0]) //Length | |||||
| { | |||||
| case 4: | |||||
| ReadTrue(); | |||||
| return true; | |||||
| case 5: | |||||
| ReadFalse(); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| throw new InvalidDataException(); | |||||
| _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 int ReadSByte() | public int ReadSByte() | ||||
| @@ -194,6 +155,29 @@ namespace Discord.ETF | |||||
| throw new NotImplementedException(); | throw new NotImplementedException(); | ||||
| } | } | ||||
| public bool? ReadNullableBool() | |||||
| { | |||||
| _stream.Read(_buffer, 0, 1); | |||||
| ETFType type = (ETFType)_buffer[0]; | |||||
| if (type == ETFType.SMALL_ATOM_EXT) | |||||
| { | |||||
| _stream.Read(_buffer, 0, 1); | |||||
| switch (_buffer[0]) //Length | |||||
| { | |||||
| case 3: | |||||
| if (ReadNil()) | |||||
| return null; | |||||
| break; | |||||
| case 4: | |||||
| ReadTrue(); | |||||
| return true; | |||||
| case 5: | |||||
| ReadFalse(); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| throw new InvalidDataException(); | |||||
| } | |||||
| public int? ReadNullableSByte() | public int? ReadNullableSByte() | ||||
| { | { | ||||
| _stream.Read(_buffer, 0, 1); | _stream.Read(_buffer, 0, 1); | ||||
| @@ -274,6 +258,48 @@ namespace Discord.ETF | |||||
| throw new NotImplementedException(); | throw new NotImplementedException(); | ||||
| } | } | ||||
| public T Read<T>() | |||||
| where T : new() | |||||
| { | |||||
| var type = typeof(T); | |||||
| var typeInfo = type.GetTypeInfo(); | |||||
| var action = _deserializers.GetOrAdd(type, _ => CreateDeserializer<T>(type, typeInfo)) as Func<ETFReader, T>; | |||||
| return action(this); | |||||
| } | |||||
| /*public void Read<T, U>() | |||||
| where T : Nullable<T> | |||||
| where U : struct, new() | |||||
| { | |||||
| }*/ | |||||
| public T[] ReadArray<T>() | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| public IDictionary<TKey, TValue> ReadDictionary<TKey, TValue>() | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| /*public object Read(object obj) | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| }*/ | |||||
| private bool ReadNil(bool ignoreLength = false) | |||||
| { | |||||
| if (!ignoreLength) | |||||
| { | |||||
| _stream.Read(_buffer, 0, 1); | |||||
| byte length = _buffer[0]; | |||||
| if (length != 3) return false; | |||||
| } | |||||
| _stream.Read(_buffer, 0, 3); | |||||
| if (_buffer[0] == 'n' && _buffer[1] == 'i' && _buffer[2] == 'l') | |||||
| return true; | |||||
| return false; | |||||
| } | |||||
| #region Emit | #region Emit | ||||
| private static Func<ETFReader, T> CreateDeserializer<T>(Type type, TypeInfo typeInfo) | private static Func<ETFReader, T> CreateDeserializer<T>(Type type, TypeInfo typeInfo) | ||||
| where T : new() | where T : new() | ||||