From cd3d90ea80bd948b47103e5ade7a858eedc827df Mon Sep 17 00:00:00 2001 From: Voltana Date: Mon, 16 May 2016 20:27:24 -0300 Subject: [PATCH] Added .Net Core RC2 Support --- global.json | 6 +- src/Discord.Net.Audio/Discord.Net.Audio.xproj | 6 +- src/Discord.Net.Audio/Net/VoiceSocket.cs | 13 +- src/Discord.Net.Audio/project.json | 32 +- .../Discord.Net.Commands.xproj | 6 +- src/Discord.Net.Commands/project.json | 30 +- src/Discord.Net.Modules/Discord.Net.Modules.xproj | 6 +- src/Discord.Net.Modules/project.json | 30 +- src/Discord.Net.Net45/Discord.Net.csproj | 3 - src/Discord.Net/Discord.Net.xproj | 6 +- src/Discord.Net/DiscordClient.cs | 15 +- src/Discord.Net/ETF/ETFReader.cs | 932 ++++++++++----------- src/Discord.Net/ETF/ETFWriter.cs | 894 ++++++++++---------- src/Discord.Net/Logging/ILogger.cs | 12 +- src/Discord.Net/Logging/LogManager.cs | 4 +- src/Discord.Net/Logging/Logger.cs | 2 +- src/Discord.Net/Net/Rest/BuiltInEngine.cs | 2 +- src/Discord.Net/Net/Rest/ETFRestClient.cs | 27 - src/Discord.Net/Net/Rest/RestClient.cs | 3 +- src/Discord.Net/Net/Rest/SharpRestEngine.cs | 2 +- src/Discord.Net/Net/WebSockets/BuiltInEngine.cs | 4 +- src/Discord.Net/Net/WebSockets/WS4NetEngine.cs | 2 +- src/Discord.Net/Net/WebSockets/WebSocket.cs | 2 +- src/Discord.Net/project.json | 86 +- test/Discord.Net.Tests/Discord.Net.Tests.csproj | 6 +- test/Discord.Net.Tests/Tests.cs | 2 +- 26 files changed, 1056 insertions(+), 1077 deletions(-) delete mode 100644 src/Discord.Net/Net/Rest/ETFRestClient.cs diff --git a/global.json b/global.json index 4357be0d5..17556ef1b 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "projects": [ "src" ], - "sdk": { - "version": "1.0.0-rc1-update1" - } + "sdk": { + "version": "1.0.0-preview1-002702" + } } \ No newline at end of file diff --git a/src/Discord.Net.Audio/Discord.Net.Audio.xproj b/src/Discord.Net.Audio/Discord.Net.Audio.xproj index 4eb480f88..c5a2a40f1 100644 --- a/src/Discord.Net.Audio/Discord.Net.Audio.xproj +++ b/src/Discord.Net.Audio/Discord.Net.Audio.xproj @@ -4,12 +4,12 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + dff7afe3-ca77-4109-bade-b4b49a4f6648 Discord.Audio ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ + .\bin\ 2.0 @@ -17,5 +17,5 @@ True - + \ No newline at end of file diff --git a/src/Discord.Net.Audio/Net/VoiceSocket.cs b/src/Discord.Net.Audio/Net/VoiceSocket.cs index 91f95890c..692cc4a5d 100644 --- a/src/Discord.Net.Audio/Net/VoiceSocket.cs +++ b/src/Discord.Net.Audio/Net/VoiceSocket.cs @@ -120,7 +120,7 @@ namespace Discord.Net.WebSockets SendIdentify(_userId.Value, _sessionId); -#if !DOTNET5_4 +#if !NETSTANDARD1_3 tasks.Add(WatcherAsync()); #endif tasks.AddRange(_engine.GetTasks(CancelToken)); @@ -178,7 +178,7 @@ namespace Discord.Net.WebSockets await Task.Delay(1).ConfigureAwait(false); if (_udp.Available > 0) { -#if !DOTNET5_4 +#if !NETSTANDARD1_3 packet = _udp.Receive(ref endpoint); #else //TODO: Is this really the only way to end a Receive call in DOTNET5_4? @@ -346,7 +346,7 @@ namespace Discord.Net.WebSockets { try { - _udp.Send(voicePacket, rtpPacketLength); + await _udp.SendAsync(voicePacket, rtpPacketLength, _endpoint).ConfigureAwait(false); } catch (SocketException ex) { @@ -371,7 +371,7 @@ namespace Discord.Net.WebSockets break; } } - await _udp.SendAsync(pingPacket, pingPacket.Length).ConfigureAwait(false); + await _udp.SendAsync(pingPacket, pingPacket.Length, _endpoint).ConfigureAwait(false); nextPingTicks = currentTicks + 5 * ticksPerSeconds; } } @@ -391,7 +391,7 @@ namespace Discord.Net.WebSockets catch (OperationCanceledException) { } catch (InvalidOperationException) { } //Includes ObjectDisposedException } -#if !DOTNET5_4 +#if !NETSTANDARD1_3 //Closes the UDP socket when _disconnectToken is triggered, since UDPClient doesn't allow passing a canceltoken private async Task WatcherAsync() { @@ -437,7 +437,6 @@ namespace Discord.Net.WebSockets _encryptionMode = UnencryptedMode; _isEncrypted = false; } - _udp.Connect(_endpoint); _sequence = 0;// (ushort)_rand.Next(0, ushort.MaxValue); //No thread issue here because SendAsync doesn't start until _isReady is true @@ -446,7 +445,7 @@ namespace Discord.Net.WebSockets packet[1] = (byte)(_ssrc >> 16); packet[2] = (byte)(_ssrc >> 8); packet[3] = (byte)(_ssrc >> 0); - await _udp.SendAsync(packet, 70).ConfigureAwait(false); + await _udp.SendAsync(packet, 70, _endpoint).ConfigureAwait(false); } } break; diff --git a/src/Discord.Net.Audio/project.json b/src/Discord.Net.Audio/project.json index f13c34ce4..67ab29949 100644 --- a/src/Discord.Net.Audio/project.json +++ b/src/Discord.Net.Audio/project.json @@ -2,26 +2,36 @@ "version": "0.9.1", "description": "A Discord.Net extension adding voice support.", "authors": [ "RogueException" ], - "tags": [ "discord", "discordapp" ], - "projectUrl": "https://github.com/RogueException/Discord.Net", - "licenseUrl": "http://opensource.org/licenses/MIT", - "repository": { - "type": "git", - "url": "git://github.com/RogueException/Discord.Net" + + "packOptions": { + "tags": [ "discord", "discordapp" ], + "projectUrl": "https://github.com/RogueException/Discord.Net", + "licenseUrl": "http://opensource.org/licenses/MIT", + "repository": { + "type": "git", + "url": "git://github.com/RogueException/Discord.Net" + }, + "contentFiles": [ "libsodium.dll", "opus.dll" ] }, - "compile": [ "**/*.cs", "../Discord.Net.Shared/*.cs" ], - "contentFiles": [ "libsodium.dll", "opus.dll" ], - "compilationOptions": { + "buildOptions": { + "compile": [ "**/*.cs", "../Discord.Net.Shared/*.cs" ], + "preserveCompilationContext": true, "allowUnsafe": true, "warningsAsErrors": true }, "dependencies": { + "NETStandard.Library": "1.5.0-rc2-24027", "Discord.Net": "0.9.1" }, "frameworks": { - "net45": { }, - "dotnet5.4": { } + "netstandard1.3": { + "imports": [ + "dotnet5.4", + "dnxcore50", + "portable-net45+win8" + ] + } } } diff --git a/src/Discord.Net.Commands/Discord.Net.Commands.xproj b/src/Discord.Net.Commands/Discord.Net.Commands.xproj index 6c0d0ca91..b6a050836 100644 --- a/src/Discord.Net.Commands/Discord.Net.Commands.xproj +++ b/src/Discord.Net.Commands/Discord.Net.Commands.xproj @@ -4,12 +4,12 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 19793545-ef89-48f4-8100-3ebaad0a9141 Discord.Commands ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ + .\bin\ 2.0 @@ -17,5 +17,5 @@ True - + \ No newline at end of file diff --git a/src/Discord.Net.Commands/project.json b/src/Discord.Net.Commands/project.json index 0351e03e1..6d4535c30 100644 --- a/src/Discord.Net.Commands/project.json +++ b/src/Discord.Net.Commands/project.json @@ -2,24 +2,34 @@ "version": "0.9.1", "description": "A Discord.Net extension adding basic command support.", "authors": [ "RogueException" ], - "tags": [ "discord", "discordapp" ], - "projectUrl": "https://github.com/RogueException/Discord.Net", - "licenseUrl": "http://opensource.org/licenses/MIT", - "repository": { - "type": "git", - "url": "git://github.com/RogueException/Discord.Net" + + "packOptions": { + "tags": [ "discord", "discordapp" ], + "projectUrl": "https://github.com/RogueException/Discord.Net", + "licenseUrl": "http://opensource.org/licenses/MIT", + "repository": { + "type": "git", + "url": "git://github.com/RogueException/Discord.Net" + } }, - "compile": [ "**/*.cs", "../Discord.Net.Shared/*.cs" ], - "compilationOptions": { + "buildOptions": { + "compile": [ "**/*.cs", "../Discord.Net.Shared/*.cs" ], + "preserveCompilationContext": true, "warningsAsErrors": true }, "dependencies": { + "NETStandard.Library": "1.5.0-rc2-24027", "Discord.Net": "0.9.1" }, "frameworks": { - "net45": { }, - "dotnet5.4": { } + "netstandard1.3": { + "imports": [ + "dotnet5.4", + "dnxcore50", + "portable-net45+win8" + ] + } } } diff --git a/src/Discord.Net.Modules/Discord.Net.Modules.xproj b/src/Discord.Net.Modules/Discord.Net.Modules.xproj index 77112cd5d..525fdd9e5 100644 --- a/src/Discord.Net.Modules/Discord.Net.Modules.xproj +++ b/src/Discord.Net.Modules/Discord.Net.Modules.xproj @@ -4,12 +4,12 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 01584e8a-78da-486f-9ef9-a894e435841b Discord.Modules ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ + .\bin\ 2.0 @@ -17,5 +17,5 @@ True - + \ No newline at end of file diff --git a/src/Discord.Net.Modules/project.json b/src/Discord.Net.Modules/project.json index f66dadedb..a7aab31c7 100644 --- a/src/Discord.Net.Modules/project.json +++ b/src/Discord.Net.Modules/project.json @@ -2,25 +2,35 @@ "version": "0.9.1", "description": "A Discord.Net extension adding basic plugin support.", "authors": [ "RogueException" ], - "tags": [ "discord", "discordapp" ], - "projectUrl": "https://github.com/RogueException/Discord.Net", - "licenseUrl": "http://opensource.org/licenses/MIT", - "repository": { - "type": "git", - "url": "git://github.com/RogueException/Discord.Net" + + "packOptions": { + "tags": [ "discord", "discordapp" ], + "projectUrl": "https://github.com/RogueException/Discord.Net", + "licenseUrl": "http://opensource.org/licenses/MIT", + "repository": { + "type": "git", + "url": "git://github.com/RogueException/Discord.Net" + } }, - "compile": [ "**/*.cs", "../Discord.Net.Shared/*.cs" ], - "compilationOptions": { + "buildOptions": { + "compile": [ "**/*.cs", "../Discord.Net.Shared/*.cs" ], + "preserveCompilationContext": true, "warningsAsErrors": true }, "dependencies": { + "NETStandard.Library": "1.5.0-rc2-24027", "Discord.Net": "0.9.1", "Discord.Net.Commands": "0.9.1" }, "frameworks": { - "net45": { }, - "dotnet5.4": { } + "netstandard1.3": { + "imports": [ + "dotnet5.4", + "dnxcore50", + "portable-net45+win8" + ] + } } } diff --git a/src/Discord.Net.Net45/Discord.Net.csproj b/src/Discord.Net.Net45/Discord.Net.csproj index 68b3adb16..35ac7701e 100644 --- a/src/Discord.Net.Net45/Discord.Net.csproj +++ b/src/Discord.Net.Net45/Discord.Net.csproj @@ -550,9 +550,6 @@ Net\Rest\CompletedRequestEventArgs.cs - - Net\Rest\ETFRestClient.cs - Net\Rest\IRestEngine.cs diff --git a/src/Discord.Net/Discord.Net.xproj b/src/Discord.Net/Discord.Net.xproj index be1dbc400..e26e53036 100644 --- a/src/Discord.Net/Discord.Net.xproj +++ b/src/Discord.Net/Discord.Net.xproj @@ -4,12 +4,12 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + acfb060b-ec8a-4926-b293-04c01e17ee23 Discord ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ + .\bin\ 2.0 @@ -17,5 +17,5 @@ True - + \ No newline at end of file diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index 47e85ae2a..7b67af4cf 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -243,12 +243,15 @@ namespace Discord } ClientAPI.Token = token; - var request = new LoginRequest() { Email = email, Password = password }; - var response = await ClientAPI.Send(request).ConfigureAwait(false); - token = response.Token; - if (Config.CacheDir != null && token != oldToken && tokenPath != null) - SaveToken(tokenPath, cacheKey, token); - ClientAPI.Token = token; + if (email != null && password != null) + { + var request = new LoginRequest() { Email = email, Password = password }; + var response = await ClientAPI.Send(request).ConfigureAwait(false); + token = response.Token; + if (Config.CacheDir != null && token != oldToken && tokenPath != null) + SaveToken(tokenPath, cacheKey, token); + ClientAPI.Token = token; + } //Cache other stuff var regionsResponse = (await ClientAPI.Send(new GetVoiceRegionsRequest()).ConfigureAwait(false)); diff --git a/src/Discord.Net/ETF/ETFReader.cs b/src/Discord.Net/ETF/ETFReader.cs index 9e1e4e8ef..600370ca5 100644 --- a/src/Discord.Net/ETF/ETFReader.cs +++ b/src/Discord.Net/ETF/ETFReader.cs @@ -1,491 +1,491 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; -using System.Text; +//using Newtonsoft.Json; +//using System; +//using System.Collections.Concurrent; +//using System.Collections.Generic; +//using System.IO; +//using System.Linq; +//using System.Reflection; +//using System.Reflection.Emit; +//using System.Text; -namespace Discord.ETF -{ - public class ETFReader : IDisposable - { - private static readonly ConcurrentDictionary _deserializers = new ConcurrentDictionary(); - private static readonly Dictionary _readMethods = GetPrimitiveReadMethods(); +//namespace Discord.ETF +//{ +// public class ETFReader : IDisposable +// { +// private static readonly ConcurrentDictionary _deserializers = new ConcurrentDictionary(); +// private static readonly Dictionary _readMethods = GetPrimitiveReadMethods(); - private readonly Stream _stream; - private readonly byte[] _buffer; - private readonly bool _leaveOpen; - private readonly Encoding _encoding; +// private readonly Stream _stream; +// private readonly byte[] _buffer; +// private readonly bool _leaveOpen; +// private readonly Encoding _encoding; - public ETFReader(Stream stream, bool leaveOpen = false) - { - if (stream == null) throw new ArgumentNullException(nameof(stream)); +// public ETFReader(Stream stream, bool leaveOpen = false) +// { +// if (stream == null) throw new ArgumentNullException(nameof(stream)); - _stream = stream; - _leaveOpen = leaveOpen; - _buffer = new byte[11]; - _encoding = Encoding.UTF8; - } +// _stream = stream; +// _leaveOpen = leaveOpen; +// _buffer = new byte[11]; +// _encoding = Encoding.UTF8; +// } - public bool ReadBool() - { - _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(); - } - 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() +// { +// _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(); +// } +// 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 int ReadSByte() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - return (sbyte)ReadLongInternal(type); - } - public uint ReadByte() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - return (byte)ReadLongInternal(type); - } - public int ReadShort() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - return (short)ReadLongInternal(type); - } - public uint ReadUShort() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - return (ushort)ReadLongInternal(type); - } - public int ReadInt() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - return (int)ReadLongInternal(type); - } - public uint ReadUInt() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - return (uint)ReadLongInternal(type); - } - public long ReadLong() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - return ReadLongInternal(type); - } - public ulong ReadULong() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - return (ulong)ReadLongInternal(type); - } - public long ReadLongInternal(ETFType type) - { - switch (type) - { - case ETFType.SMALL_INTEGER_EXT: - _stream.Read(_buffer, 0, 1); - return _buffer[0]; - case ETFType.INTEGER_EXT: - _stream.Read(_buffer, 0, 4); - return (_buffer[0] << 24) | (_buffer[1] << 16) | (_buffer[2] << 8) | (_buffer[3]); - case ETFType.SMALL_BIG_EXT: - _stream.Read(_buffer, 0, 2); - bool isPositive = _buffer[0] == 0; - byte count = _buffer[1]; +// public int ReadSByte() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// return (sbyte)ReadLongInternal(type); +// } +// public uint ReadByte() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// return (byte)ReadLongInternal(type); +// } +// public int ReadShort() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// return (short)ReadLongInternal(type); +// } +// public uint ReadUShort() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// return (ushort)ReadLongInternal(type); +// } +// public int ReadInt() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// return (int)ReadLongInternal(type); +// } +// public uint ReadUInt() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// return (uint)ReadLongInternal(type); +// } +// public long ReadLong() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// return ReadLongInternal(type); +// } +// public ulong ReadULong() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// return (ulong)ReadLongInternal(type); +// } +// public long ReadLongInternal(ETFType type) +// { +// switch (type) +// { +// case ETFType.SMALL_INTEGER_EXT: +// _stream.Read(_buffer, 0, 1); +// return _buffer[0]; +// case ETFType.INTEGER_EXT: +// _stream.Read(_buffer, 0, 4); +// return (_buffer[0] << 24) | (_buffer[1] << 16) | (_buffer[2] << 8) | (_buffer[3]); +// case ETFType.SMALL_BIG_EXT: +// _stream.Read(_buffer, 0, 2); +// bool isPositive = _buffer[0] == 0; +// byte count = _buffer[1]; - int shiftValue = (count - 1) * 8; - ulong value = 0; - _stream.Read(_buffer, 0, count); - for (int i = 0; i < count; i++, shiftValue -= 8) - value = value + _buffer[i] << shiftValue; - if (!isPositive) - return -(long)value; - else - return (long)value; - } - throw new InvalidDataException(); - } +// int shiftValue = (count - 1) * 8; +// ulong value = 0; +// _stream.Read(_buffer, 0, count); +// for (int i = 0; i < count; i++, shiftValue -= 8) +// value = value + _buffer[i] << shiftValue; +// if (!isPositive) +// return -(long)value; +// else +// return (long)value; +// } +// throw new InvalidDataException(); +// } - public float ReadSingle() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - return (float)ReadDoubleInternal(type); - } - public double ReadDouble() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - return ReadDoubleInternal(type); - } - public double ReadDoubleInternal(ETFType type) - { - throw new NotImplementedException(); - } +// public float ReadSingle() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// return (float)ReadDoubleInternal(type); +// } +// public double ReadDouble() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// return ReadDoubleInternal(type); +// } +// public double ReadDoubleInternal(ETFType type) +// { +// 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() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; - return (sbyte)ReadLongInternal(type); - } - public uint? ReadNullableByte() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; - return (byte)ReadLongInternal(type); - } - public int? ReadNullableShort() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; - return (short)ReadLongInternal(type); - } - public uint? ReadNullableUShort() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; - return (ushort)ReadLongInternal(type); - } - public int? ReadNullableInt() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; - return (int)ReadLongInternal(type); - } - public uint? ReadNullableUInt() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; - return (uint)ReadLongInternal(type); - } - public long? ReadNullableLong() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; - return ReadLongInternal(type); - } - public ulong? ReadNullableULong() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; - return (ulong)ReadLongInternal(type); - } - public float? ReadNullableSingle() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; - return (float)ReadDoubleInternal(type); - } - public double? ReadNullableDouble() - { - _stream.Read(_buffer, 0, 1); - ETFType type = (ETFType)_buffer[0]; - if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; - return ReadDoubleInternal(type); - } +// 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() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; +// return (sbyte)ReadLongInternal(type); +// } +// public uint? ReadNullableByte() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; +// return (byte)ReadLongInternal(type); +// } +// public int? ReadNullableShort() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; +// return (short)ReadLongInternal(type); +// } +// public uint? ReadNullableUShort() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; +// return (ushort)ReadLongInternal(type); +// } +// public int? ReadNullableInt() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; +// return (int)ReadLongInternal(type); +// } +// public uint? ReadNullableUInt() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; +// return (uint)ReadLongInternal(type); +// } +// public long? ReadNullableLong() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; +// return ReadLongInternal(type); +// } +// public ulong? ReadNullableULong() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; +// return (ulong)ReadLongInternal(type); +// } +// public float? ReadNullableSingle() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; +// return (float)ReadDoubleInternal(type); +// } +// public double? ReadNullableDouble() +// { +// _stream.Read(_buffer, 0, 1); +// ETFType type = (ETFType)_buffer[0]; +// if (type == ETFType.SMALL_ATOM_EXT && ReadNil()) return null; +// return ReadDoubleInternal(type); +// } - public string ReadString() - { - throw new NotImplementedException(); - } - public byte[] ReadByteArray() - { - throw new NotImplementedException(); - } +// public string ReadString() +// { +// throw new NotImplementedException(); +// } +// public byte[] ReadByteArray() +// { +// throw new NotImplementedException(); +// } - public T Read() - where T : new() - { - var type = typeof(T); - var typeInfo = type.GetTypeInfo(); - var action = _deserializers.GetOrAdd(type, _ => CreateDeserializer(type, typeInfo)) as Func; - return action(this); - } - /*public void Read() - where T : Nullable - where U : struct, new() - { - }*/ - public T[] ReadArray() - { - throw new NotImplementedException(); - } - public IDictionary ReadDictionary() - { - throw new NotImplementedException(); - } - /*public object Read(object obj) - { - throw new NotImplementedException(); - }*/ +// public T Read() +// where T : new() +// { +// var type = typeof(T); +// var typeInfo = type.GetTypeInfo(); +// var action = _deserializers.GetOrAdd(type, _ => CreateDeserializer(type, typeInfo)) as Func; +// return action(this); +// } +// /*public void Read() +// where T : Nullable +// where U : struct, new() +// { +// }*/ +// public T[] ReadArray() +// { +// throw new NotImplementedException(); +// } +// public IDictionary ReadDictionary() +// { +// 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; - } +// 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; +// _stream.Read(_buffer, 0, 3); +// if (_buffer[0] == 'n' && _buffer[1] == 'i' && _buffer[2] == 'l') +// return true; - return false; - } +// return false; +// } - #region Emit - private static Func CreateDeserializer(Type type, TypeInfo typeInfo) - where T : new() - { - var method = new DynamicMethod("DeserializeETF", type, new[] { typeof(ETFReader) }, true); - var generator = method.GetILGenerator(); +// #region Emit +// private static Func CreateDeserializer(Type type, TypeInfo typeInfo) +// where T : new() +// { +// var method = new DynamicMethod("DeserializeETF", type, new[] { typeof(ETFReader) }, true); +// var generator = method.GetILGenerator(); - generator.Emit(OpCodes.Ldarg_0); //ETFReader(this) - EmitReadValue(generator, type, typeInfo, true); +// generator.Emit(OpCodes.Ldarg_0); //ETFReader(this) +// EmitReadValue(generator, type, typeInfo, true); - generator.Emit(OpCodes.Ret); - return method.CreateDelegate(typeof(Func)) as Func; - } - private static void EmitReadValue(ILGenerator generator, Type type, TypeInfo typeInfo, bool isTop) - { - //Convert enum types to their base type - if (typeInfo.IsEnum) - { - type = Enum.GetUnderlyingType(type); - typeInfo = type.GetTypeInfo(); - } - //Primitives/Enums - if (!typeInfo.IsEnum && IsType(type, typeof(sbyte), typeof(byte), typeof(short), - typeof(ushort), typeof(int), typeof(uint), typeof(long), - typeof(ulong), typeof(double), typeof(bool), typeof(string), - typeof(sbyte?), typeof(byte?), typeof(short?), typeof(ushort?), - typeof(int?), typeof(uint?), typeof(long?), typeof(ulong?), - typeof(bool?), typeof(float?), typeof(double?) - /*typeof(object), typeof(DateTime)*/)) - { - //No conversion needed - generator.EmitCall(OpCodes.Call, GetReadMethod(type), null); - } - //Dictionaries - /*else if (!typeInfo.IsValueType && typeInfo.ImplementedInterfaces - .Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(IDictionary<,>))) - { - generator.EmitCall(OpCodes.Call, _writeDictionaryTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); - } - //Enumerable - else if (!typeInfo.IsValueType && typeInfo.ImplementedInterfaces - .Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>))) - { - generator.EmitCall(OpCodes.Call, _writeEnumerableTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); - } - //Nullable Structs - else if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>) && - typeInfo.GenericTypeParameters[0].GetTypeInfo().IsValueType) - { - generator.EmitCall(OpCodes.Call, _writeNullableTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); - } - //Structs/Classes - else if (typeInfo.IsClass || (typeInfo.IsValueType && !typeInfo.IsPrimitive)) - { - if (isTop) - { - typeInfo.ForEachField(f => - { - string name; - if (!f.IsPublic || !IsETFProperty(f, out name)) return; +// generator.Emit(OpCodes.Ret); +// return method.CreateDelegate(typeof(Func)) as Func; +// } +// private static void EmitReadValue(ILGenerator generator, Type type, TypeInfo typeInfo, bool isTop) +// { +// //Convert enum types to their base type +// if (typeInfo.IsEnum) +// { +// type = Enum.GetUnderlyingType(type); +// typeInfo = type.GetTypeInfo(); +// } +// //Primitives/Enums +// if (!typeInfo.IsEnum && IsType(type, typeof(sbyte), typeof(byte), typeof(short), +// typeof(ushort), typeof(int), typeof(uint), typeof(long), +// typeof(ulong), typeof(double), typeof(bool), typeof(string), +// typeof(sbyte?), typeof(byte?), typeof(short?), typeof(ushort?), +// typeof(int?), typeof(uint?), typeof(long?), typeof(ulong?), +// typeof(bool?), typeof(float?), typeof(double?) +// /*typeof(object), typeof(DateTime)*/)) +// { +// //No conversion needed +// generator.EmitCall(OpCodes.Call, GetReadMethod(type), null); +// } +// //Dictionaries +// /*else if (!typeInfo.IsValueType && typeInfo.ImplementedInterfaces +// .Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(IDictionary<,>))) +// { +// generator.EmitCall(OpCodes.Call, _writeDictionaryTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); +// } +// //Enumerable +// else if (!typeInfo.IsValueType && typeInfo.ImplementedInterfaces +// .Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>))) +// { +// generator.EmitCall(OpCodes.Call, _writeEnumerableTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); +// } +// //Nullable Structs +// else if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>) && +// typeInfo.GenericTypeParameters[0].GetTypeInfo().IsValueType) +// { +// generator.EmitCall(OpCodes.Call, _writeNullableTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); +// } +// //Structs/Classes +// else if (typeInfo.IsClass || (typeInfo.IsValueType && !typeInfo.IsPrimitive)) +// { +// if (isTop) +// { +// typeInfo.ForEachField(f => +// { +// string name; +// if (!f.IsPublic || !IsETFProperty(f, out name)) return; - generator.Emit(OpCodes.Ldarg_0); //ETFReader(this) - generator.Emit(OpCodes.Ldstr, name); //ETFReader(this), name - generator.EmitCall(OpCodes.Call, GetWriteMethod(typeof(string)), null); - generator.Emit(OpCodes.Ldarg_0); //ETFReader(this) - generator.Emit(OpCodes.Ldarg_1); //ETFReader(this), obj - generator.Emit(OpCodes.Ldfld, f); //ETFReader(this), obj.fieldValue - EmitWriteValue(generator, f.FieldType, f.FieldType.GetTypeInfo(), false); - }); +// generator.Emit(OpCodes.Ldarg_0); //ETFReader(this) +// generator.Emit(OpCodes.Ldstr, name); //ETFReader(this), name +// generator.EmitCall(OpCodes.Call, GetWriteMethod(typeof(string)), null); +// generator.Emit(OpCodes.Ldarg_0); //ETFReader(this) +// generator.Emit(OpCodes.Ldarg_1); //ETFReader(this), obj +// generator.Emit(OpCodes.Ldfld, f); //ETFReader(this), obj.fieldValue +// EmitWriteValue(generator, f.FieldType, f.FieldType.GetTypeInfo(), false); +// }); - typeInfo.ForEachProperty(p => - { - string name; - if (!p.CanRead || !p.GetMethod.IsPublic || !IsETFProperty(p, out name)) return; +// typeInfo.ForEachProperty(p => +// { +// string name; +// if (!p.CanRead || !p.GetMethod.IsPublic || !IsETFProperty(p, out name)) return; - generator.Emit(OpCodes.Ldarg_0); //ETFReader(this) - generator.Emit(OpCodes.Ldstr, name); //ETFReader(this), name - generator.EmitCall(OpCodes.Call, GetWriteMethod(typeof(string)), null); - generator.Emit(OpCodes.Ldarg_0); //ETFReader(this) - generator.Emit(OpCodes.Ldarg_1); //ETFReader(this), obj - generator.EmitCall(OpCodes.Callvirt, p.GetMethod, null); //ETFReader(this), obj.propValue - EmitWriteValue(generator, p.PropertyType, p.PropertyType.GetTypeInfo(), false); - }); - } - else - { - //While we could drill deeper and make a large serializer that also serializes all subclasses, - //it's more efficient to serialize on a per-type basis via another Write call. - generator.EmitCall(OpCodes.Call, _writeTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); - } - }*/ - //Unsupported (decimal, char) - else - throw new InvalidOperationException($"Deserializing {type.Name} is not supported."); - } +// generator.Emit(OpCodes.Ldarg_0); //ETFReader(this) +// generator.Emit(OpCodes.Ldstr, name); //ETFReader(this), name +// generator.EmitCall(OpCodes.Call, GetWriteMethod(typeof(string)), null); +// generator.Emit(OpCodes.Ldarg_0); //ETFReader(this) +// generator.Emit(OpCodes.Ldarg_1); //ETFReader(this), obj +// generator.EmitCall(OpCodes.Callvirt, p.GetMethod, null); //ETFReader(this), obj.propValue +// EmitWriteValue(generator, p.PropertyType, p.PropertyType.GetTypeInfo(), false); +// }); +// } +// else +// { +// //While we could drill deeper and make a large serializer that also serializes all subclasses, +// //it's more efficient to serialize on a per-type basis via another Write call. +// generator.EmitCall(OpCodes.Call, _writeTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); +// } +// }*/ +// //Unsupported (decimal, char) +// else +// throw new InvalidOperationException($"Deserializing {type.Name} is not supported."); +// } - private static bool IsType(Type type, params Type[] types) - { - for (int i = 0; i < types.Length; i++) - { - if (type == types[i]) - return true; - } - return false; - } - private static bool IsETFProperty(FieldInfo f, out string name) - { - var attrib = f.CustomAttributes.Where(x => x.AttributeType == typeof(JsonPropertyAttribute)).FirstOrDefault(); - if (attrib != null) - { - name = attrib.ConstructorArguments.FirstOrDefault().Value as string ?? f.Name; - return true; - } - name = null; - return false; - } - private static bool IsETFProperty(PropertyInfo p, out string name) - { - var attrib = p.CustomAttributes.Where(x => x.AttributeType == typeof(JsonPropertyAttribute)).FirstOrDefault(); - if (attrib != null) - { - name = attrib.ConstructorArguments.FirstOrDefault().Value as string ?? p.Name; - return true; - } - name = null; - return false; - } +// private static bool IsType(Type type, params Type[] types) +// { +// for (int i = 0; i < types.Length; i++) +// { +// if (type == types[i]) +// return true; +// } +// return false; +// } +// private static bool IsETFProperty(FieldInfo f, out string name) +// { +// var attrib = f.CustomAttributes.Where(x => x.AttributeType == typeof(JsonPropertyAttribute)).FirstOrDefault(); +// if (attrib != null) +// { +// name = attrib.ConstructorArguments.FirstOrDefault().Value as string ?? f.Name; +// return true; +// } +// name = null; +// return false; +// } +// private static bool IsETFProperty(PropertyInfo p, out string name) +// { +// var attrib = p.CustomAttributes.Where(x => x.AttributeType == typeof(JsonPropertyAttribute)).FirstOrDefault(); +// if (attrib != null) +// { +// name = attrib.ConstructorArguments.FirstOrDefault().Value as string ?? p.Name; +// return true; +// } +// name = null; +// return false; +// } - private static MethodInfo GetReadMethod(string name) - => typeof(ETFReader).GetTypeInfo().GetDeclaredMethods(name).Single(); - private static MethodInfo GetReadMethod(Type type) - { - MethodInfo method; - if (_readMethods.TryGetValue(type, out method)) - return method; - return null; - } - private static Dictionary GetPrimitiveReadMethods() - { - return new Dictionary - { - { typeof(bool), GetReadMethod(nameof(ReadBool)) }, - { typeof(bool?), GetReadMethod(nameof(ReadNullableBool)) }, - { typeof(byte), GetReadMethod(nameof(ReadByte)) }, - { typeof(byte?), GetReadMethod(nameof(ReadNullableByte)) }, - { typeof(sbyte), GetReadMethod(nameof(ReadSByte)) }, - { typeof(sbyte?), GetReadMethod(nameof(ReadNullableSByte)) }, - { typeof(short), GetReadMethod(nameof(ReadShort)) }, - { typeof(short?), GetReadMethod(nameof(ReadNullableShort)) }, - { typeof(ushort), GetReadMethod(nameof(ReadUShort)) }, - { typeof(ushort?), GetReadMethod(nameof(ReadNullableUShort)) }, - { typeof(int), GetReadMethod(nameof(ReadInt)) }, - { typeof(int?), GetReadMethod(nameof(ReadNullableInt)) }, - { typeof(uint), GetReadMethod(nameof(ReadUInt)) }, - { typeof(uint?), GetReadMethod(nameof(ReadNullableUInt)) }, - { typeof(long), GetReadMethod(nameof(ReadLong)) }, - { typeof(long?), GetReadMethod(nameof(ReadNullableLong)) }, - { typeof(ulong), GetReadMethod(nameof(ReadULong)) }, - { typeof(ulong?), GetReadMethod(nameof(ReadNullableULong)) }, - { typeof(float), GetReadMethod(nameof(ReadSingle)) }, - { typeof(float?), GetReadMethod(nameof(ReadNullableSingle)) }, - { typeof(double), GetReadMethod(nameof(ReadDouble)) }, - { typeof(double?), GetReadMethod(nameof(ReadNullableDouble)) }, - }; - } - #endregion +// private static MethodInfo GetReadMethod(string name) +// => typeof(ETFReader).GetTypeInfo().GetDeclaredMethods(name).Single(); +// private static MethodInfo GetReadMethod(Type type) +// { +// MethodInfo method; +// if (_readMethods.TryGetValue(type, out method)) +// return method; +// return null; +// } +// private static Dictionary GetPrimitiveReadMethods() +// { +// return new Dictionary +// { +// { typeof(bool), GetReadMethod(nameof(ReadBool)) }, +// { typeof(bool?), GetReadMethod(nameof(ReadNullableBool)) }, +// { typeof(byte), GetReadMethod(nameof(ReadByte)) }, +// { typeof(byte?), GetReadMethod(nameof(ReadNullableByte)) }, +// { typeof(sbyte), GetReadMethod(nameof(ReadSByte)) }, +// { typeof(sbyte?), GetReadMethod(nameof(ReadNullableSByte)) }, +// { typeof(short), GetReadMethod(nameof(ReadShort)) }, +// { typeof(short?), GetReadMethod(nameof(ReadNullableShort)) }, +// { typeof(ushort), GetReadMethod(nameof(ReadUShort)) }, +// { typeof(ushort?), GetReadMethod(nameof(ReadNullableUShort)) }, +// { typeof(int), GetReadMethod(nameof(ReadInt)) }, +// { typeof(int?), GetReadMethod(nameof(ReadNullableInt)) }, +// { typeof(uint), GetReadMethod(nameof(ReadUInt)) }, +// { typeof(uint?), GetReadMethod(nameof(ReadNullableUInt)) }, +// { typeof(long), GetReadMethod(nameof(ReadLong)) }, +// { typeof(long?), GetReadMethod(nameof(ReadNullableLong)) }, +// { typeof(ulong), GetReadMethod(nameof(ReadULong)) }, +// { typeof(ulong?), GetReadMethod(nameof(ReadNullableULong)) }, +// { typeof(float), GetReadMethod(nameof(ReadSingle)) }, +// { typeof(float?), GetReadMethod(nameof(ReadNullableSingle)) }, +// { typeof(double), GetReadMethod(nameof(ReadDouble)) }, +// { typeof(double?), GetReadMethod(nameof(ReadNullableDouble)) }, +// }; +// } +// #endregion - #region IDisposable - private bool _isDisposed = false; +// #region IDisposable +// private bool _isDisposed = false; - protected virtual void Dispose(bool disposing) - { - if (!_isDisposed) - { - if (disposing) - { - if (_leaveOpen) - _stream.Flush(); - else - _stream.Dispose(); - } - _isDisposed = true; - } - } +// protected virtual void Dispose(bool disposing) +// { +// if (!_isDisposed) +// { +// if (disposing) +// { +// if (_leaveOpen) +// _stream.Flush(); +// else +// _stream.Dispose(); +// } +// _isDisposed = true; +// } +// } - public void Dispose() => Dispose(true); - #endregion - } -} \ No newline at end of file +// public void Dispose() => Dispose(true); +// #endregion +// } +//} \ No newline at end of file diff --git a/src/Discord.Net/ETF/ETFWriter.cs b/src/Discord.Net/ETF/ETFWriter.cs index 37d1553db..cae365d7f 100644 --- a/src/Discord.Net/ETF/ETFWriter.cs +++ b/src/Discord.Net/ETF/ETFWriter.cs @@ -1,482 +1,482 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; -using System.Text; +//using Newtonsoft.Json; +//using System; +//using System.Collections.Concurrent; +//using System.Collections.Generic; +//using System.IO; +//using System.Linq; +//using System.Reflection; +//using System.Reflection.Emit; +//using System.Text; -namespace Discord.ETF -{ - public unsafe class ETFWriter : IDisposable - { - private static readonly ConcurrentDictionary _serializers = new ConcurrentDictionary(); - private static readonly ConcurrentDictionary _indirectSerializers = new ConcurrentDictionary(); +//namespace Discord.ETF +//{ +// public unsafe class ETFWriter : IDisposable +// { +// private static readonly ConcurrentDictionary _serializers = new ConcurrentDictionary(); +// private static readonly ConcurrentDictionary _indirectSerializers = new ConcurrentDictionary(); - private static readonly byte[] _nilBytes = new byte[] { (byte)ETFType.SMALL_ATOM_EXT, 3, (byte)'n', (byte)'i', (byte)'l' }; - private static readonly byte[] _falseBytes = new byte[] { (byte)ETFType.SMALL_ATOM_EXT, 5, (byte)'f', (byte)'a', (byte)'l', (byte)'s', (byte)'e' }; - private static readonly byte[] _trueBytes = new byte[] { (byte)ETFType.SMALL_ATOM_EXT, 4, (byte)'t', (byte)'r', (byte)'u', (byte)'e' }; +// private static readonly byte[] _nilBytes = new byte[] { (byte)ETFType.SMALL_ATOM_EXT, 3, (byte)'n', (byte)'i', (byte)'l' }; +// private static readonly byte[] _falseBytes = new byte[] { (byte)ETFType.SMALL_ATOM_EXT, 5, (byte)'f', (byte)'a', (byte)'l', (byte)'s', (byte)'e' }; +// private static readonly byte[] _trueBytes = new byte[] { (byte)ETFType.SMALL_ATOM_EXT, 4, (byte)'t', (byte)'r', (byte)'u', (byte)'e' }; - private static readonly MethodInfo _writeTMethod = GetGenericWriteMethod(null); - private static readonly MethodInfo _writeNullableTMethod = GetGenericWriteMethod(typeof(Nullable<>)); - private static readonly MethodInfo _writeDictionaryTMethod = GetGenericWriteMethod(typeof(IDictionary<,>)); - private static readonly MethodInfo _writeEnumerableTMethod = GetGenericWriteMethod(typeof(IEnumerable<>)); - private static readonly DateTime _epochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); +// private static readonly MethodInfo _writeTMethod = GetGenericWriteMethod(null); +// private static readonly MethodInfo _writeNullableTMethod = GetGenericWriteMethod(typeof(Nullable<>)); +// private static readonly MethodInfo _writeDictionaryTMethod = GetGenericWriteMethod(typeof(IDictionary<,>)); +// private static readonly MethodInfo _writeEnumerableTMethod = GetGenericWriteMethod(typeof(IEnumerable<>)); +// private static readonly DateTime _epochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - private readonly Stream _stream; - private readonly byte[] _buffer; - private readonly bool _leaveOpen; - private readonly Encoding _encoding; +// private readonly Stream _stream; +// private readonly byte[] _buffer; +// private readonly bool _leaveOpen; +// private readonly Encoding _encoding; - public virtual Stream BaseStream - { - get - { - Flush(); - return _stream; - } - } +// public virtual Stream BaseStream +// { +// get +// { +// Flush(); +// return _stream; +// } +// } - public ETFWriter(Stream stream, bool leaveOpen = false) - { - if (stream == null) throw new ArgumentNullException(nameof(stream)); +// public ETFWriter(Stream stream, bool leaveOpen = false) +// { +// if (stream == null) throw new ArgumentNullException(nameof(stream)); - _stream = stream; - _leaveOpen = leaveOpen; - _buffer = new byte[11]; - _encoding = Encoding.UTF8; - } +// _stream = stream; +// _leaveOpen = leaveOpen; +// _buffer = new byte[11]; +// _encoding = Encoding.UTF8; +// } - public void Write(bool value) - { - if (value) - _stream.Write(_trueBytes, 0, _trueBytes.Length); - else - _stream.Write(_falseBytes, 0, _falseBytes.Length); - } - 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) - { - //TODO: Does this encode negatives correctly? - _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; - } +// public void Write(bool value) +// { +// if (value) +// _stream.Write(_trueBytes, 0, _trueBytes.Length); +// else +// _stream.Write(_falseBytes, 0, _falseBytes.Length); +// } +// 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) +// { +// //TODO: Does this encode negatives correctly? +// _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 +// 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 +// _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 +// byte bytes = 0; +// while (value > 0) +// _buffer[3 + bytes++] = (byte)(value >>= 8); +// _buffer[1] = bytes; //Encoded bytes - _stream.Write(_buffer, 0, 3 + bytes); - } - } +// _stream.Write(_buffer, 0, 3 + bytes); +// } +// } - public void Write(float value) => Write((double)value); - public 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(float value) => Write((double)value); +// public 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)); +// public void Write(DateTime value) => Write((ulong)((value.Ticks - _epochTime.Ticks) / TimeSpan.TicksPerSecond)); - public void Write(bool? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } - public void Write(sbyte? value) { if (value.HasValue) Write((long)value.Value); else WriteNil(); } - public void Write(byte? value) { if (value.HasValue) Write((ulong)value.Value); else WriteNil(); } - public void Write(short? value) { if (value.HasValue) Write((long)value.Value); else WriteNil(); } - public void Write(ushort? value) { if (value.HasValue) Write((ulong)value.Value); else WriteNil(); } - public void Write(int? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } - public void Write(uint? value) { if (value.HasValue) Write((ulong)value.Value); else WriteNil(); } - public void Write(long? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } - public void Write(ulong? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } - public void Write(double? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } - public void Write(float? value) { if (value.HasValue) Write((double)value.Value); else WriteNil(); } - public void Write(DateTime? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } +// public void Write(bool? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } +// public void Write(sbyte? value) { if (value.HasValue) Write((long)value.Value); else WriteNil(); } +// public void Write(byte? value) { if (value.HasValue) Write((ulong)value.Value); else WriteNil(); } +// public void Write(short? value) { if (value.HasValue) Write((long)value.Value); else WriteNil(); } +// public void Write(ushort? value) { if (value.HasValue) Write((ulong)value.Value); else WriteNil(); } +// public void Write(int? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } +// public void Write(uint? value) { if (value.HasValue) Write((ulong)value.Value); else WriteNil(); } +// public void Write(long? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } +// public void Write(ulong? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } +// public void Write(double? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } +// public void Write(float? value) { if (value.HasValue) Write((double)value.Value); else WriteNil(); } +// public void Write(DateTime? value) { if (value.HasValue) Write(value.Value); else WriteNil(); } - public void Write(string value) - { - if (value != null) - { - var bytes = _encoding.GetBytes(value); - int count = bytes.Length; - _buffer[0] = (byte)ETFType.BINARY_EXT; - _buffer[1] = (byte)(count >> 24); - _buffer[2] = (byte)(count >> 16); - _buffer[3] = (byte)(count >> 8); - _buffer[4] = (byte)count; - _stream.Write(_buffer, 0, 5); - _stream.Write(bytes, 0, bytes.Length); - } - else - WriteNil(); - } - public void Write(byte[] value) - { - if (value != null) - { - int count = value.Length; - _buffer[0] = (byte)ETFType.BINARY_EXT; - _buffer[1] = (byte)(count >> 24); - _buffer[2] = (byte)(count >> 16); - _buffer[3] = (byte)(count >> 8); - _buffer[4] = (byte)count; - _stream.Write(_buffer, 0, 5); - _stream.Write(value, 0, value.Length); - } - else - WriteNil(); - } +// public void Write(string value) +// { +// if (value != null) +// { +// var bytes = _encoding.GetBytes(value); +// int count = bytes.Length; +// _buffer[0] = (byte)ETFType.BINARY_EXT; +// _buffer[1] = (byte)(count >> 24); +// _buffer[2] = (byte)(count >> 16); +// _buffer[3] = (byte)(count >> 8); +// _buffer[4] = (byte)count; +// _stream.Write(_buffer, 0, 5); +// _stream.Write(bytes, 0, bytes.Length); +// } +// else +// WriteNil(); +// } +// public void Write(byte[] value) +// { +// if (value != null) +// { +// int count = value.Length; +// _buffer[0] = (byte)ETFType.BINARY_EXT; +// _buffer[1] = (byte)(count >> 24); +// _buffer[2] = (byte)(count >> 16); +// _buffer[3] = (byte)(count >> 8); +// _buffer[4] = (byte)count; +// _stream.Write(_buffer, 0, 5); +// _stream.Write(value, 0, value.Length); +// } +// else +// WriteNil(); +// } - public void Write(T obj) - { - var type = typeof(T); - var typeInfo = type.GetTypeInfo(); - var action = _serializers.GetOrAdd(type, _ => CreateSerializer(type, typeInfo, false)) as Action; - action(this, obj); - } - public void Write(T? obj) - where T : struct - { - if (obj != null) - Write(obj.Value); - else - WriteNil(); - } - public void Write(IEnumerable obj) - { - if (obj != null) - { - var array = obj.ToArray(); - int length = array.Length; - _buffer[0] = (byte)ETFType.LIST_EXT; - _buffer[1] = (byte)(length >> 24); - _buffer[2] = (byte)(length >> 16); - _buffer[3] = (byte)(length >> 8); - _buffer[4] = (byte)length; - _stream.Write(_buffer, 0, 5); +// public void Write(T obj) +// { +// var type = typeof(T); +// var typeInfo = type.GetTypeInfo(); +// var action = _serializers.GetOrAdd(type, _ => CreateSerializer(type, typeInfo, false)) as Action; +// action(this, obj); +// } +// public void Write(T? obj) +// where T : struct +// { +// if (obj != null) +// Write(obj.Value); +// else +// WriteNil(); +// } +// public void Write(IEnumerable obj) +// { +// if (obj != null) +// { +// var array = obj.ToArray(); +// int length = array.Length; +// _buffer[0] = (byte)ETFType.LIST_EXT; +// _buffer[1] = (byte)(length >> 24); +// _buffer[2] = (byte)(length >> 16); +// _buffer[3] = (byte)(length >> 8); +// _buffer[4] = (byte)length; +// _stream.Write(_buffer, 0, 5); - for (int i = 0; i < array.Length; i++) - Write(array[i]); +// for (int i = 0; i < array.Length; i++) +// Write(array[i]); - _buffer[0] = (byte)ETFType.NIL_EXT; - _stream.Write(_buffer, 0, 1); - } - else - WriteNil(); - } - public void Write(IDictionary obj) - { - if (obj != null) - { - int length = obj.Count; - _buffer[0] = (byte)ETFType.MAP_EXT; - _buffer[1] = (byte)(length >> 24); - _buffer[2] = (byte)(length >> 16); - _buffer[3] = (byte)(length >> 8); - _buffer[4] = (byte)length; - _stream.Write(_buffer, 0, 5); +// _buffer[0] = (byte)ETFType.NIL_EXT; +// _stream.Write(_buffer, 0, 1); +// } +// else +// WriteNil(); +// } +// public void Write(IDictionary obj) +// { +// if (obj != null) +// { +// int length = obj.Count; +// _buffer[0] = (byte)ETFType.MAP_EXT; +// _buffer[1] = (byte)(length >> 24); +// _buffer[2] = (byte)(length >> 16); +// _buffer[3] = (byte)(length >> 8); +// _buffer[4] = (byte)length; +// _stream.Write(_buffer, 0, 5); - foreach (var pair in obj) - { - Write(pair.Key); - Write(pair.Value); - } - } - else - WriteNil(); - } - public void Write(object obj) - { - if (obj != null) - { - var type = obj.GetType(); - var typeInfo = type.GetTypeInfo(); - var action = _indirectSerializers.GetOrAdd(type, _ => CreateSerializer(type, typeInfo, true)) as Action; - action(this, obj); - } - else - WriteNil(); - } +// foreach (var pair in obj) +// { +// Write(pair.Key); +// Write(pair.Value); +// } +// } +// else +// WriteNil(); +// } +// public void Write(object obj) +// { +// if (obj != null) +// { +// var type = obj.GetType(); +// var typeInfo = type.GetTypeInfo(); +// var action = _indirectSerializers.GetOrAdd(type, _ => CreateSerializer(type, typeInfo, true)) as Action; +// action(this, obj); +// } +// else +// WriteNil(); +// } - private void WriteNil() => _stream.Write(_nilBytes, 0, _nilBytes.Length); +// private void WriteNil() => _stream.Write(_nilBytes, 0, _nilBytes.Length); - public virtual void Flush() => _stream.Flush(); - public virtual long Seek(int offset, SeekOrigin origin) => _stream.Seek(offset, origin); +// public virtual void Flush() => _stream.Flush(); +// public virtual long Seek(int offset, SeekOrigin origin) => _stream.Seek(offset, origin); - #region Emit - private static Action CreateSerializer(Type type, TypeInfo typeInfo, bool isDirect) - { - var method = new DynamicMethod(isDirect ? "SerializeETF" : "SerializeIndirectETF", - null, new[] { typeof(ETFWriter), isDirect ? type : typeof(object) }, true); - var generator = method.GetILGenerator(); +// #region Emit +// private static Action CreateSerializer(Type type, TypeInfo typeInfo, bool isDirect) +// { +// var method = new DynamicMethod(isDirect ? "SerializeETF" : "SerializeIndirectETF", +// null, new[] { typeof(ETFWriter), isDirect ? type : typeof(object) }, true); +// var generator = method.GetILGenerator(); - generator.Emit(OpCodes.Ldarg_0); //ETFWriter(this) - generator.Emit(OpCodes.Ldarg_1); //ETFWriter(this), value - if (!isDirect) - { - if (typeInfo.IsValueType) //Unbox value types - generator.Emit(OpCodes.Unbox_Any, type); //ETFWriter(this), real_value - else //Cast reference types - generator.Emit(OpCodes.Castclass, type); //ETFWriter(this), real_value - generator.EmitCall(OpCodes.Call, _writeTMethod.MakeGenericMethod(type), null); //Call generic version - } - else - EmitWriteValue(generator, type, typeInfo, true); +// generator.Emit(OpCodes.Ldarg_0); //ETFWriter(this) +// generator.Emit(OpCodes.Ldarg_1); //ETFWriter(this), value +// if (!isDirect) +// { +// if (typeInfo.IsValueType) //Unbox value types +// generator.Emit(OpCodes.Unbox_Any, type); //ETFWriter(this), real_value +// else //Cast reference types +// generator.Emit(OpCodes.Castclass, type); //ETFWriter(this), real_value +// generator.EmitCall(OpCodes.Call, _writeTMethod.MakeGenericMethod(type), null); //Call generic version +// } +// else +// EmitWriteValue(generator, type, typeInfo, true); - generator.Emit(OpCodes.Ret); - return method.CreateDelegate(typeof(Action)) as Action; - } - private static void EmitWriteValue(ILGenerator generator, Type type, TypeInfo typeInfo, bool isTop) - { - //Convert enum types to their base type - if (typeInfo.IsEnum) - { - type = Enum.GetUnderlyingType(type); - typeInfo = type.GetTypeInfo(); - } +// generator.Emit(OpCodes.Ret); +// return method.CreateDelegate(typeof(Action)) as Action; +// } +// private static void EmitWriteValue(ILGenerator generator, Type type, TypeInfo typeInfo, bool isTop) +// { +// //Convert enum types to their base type +// if (typeInfo.IsEnum) +// { +// type = Enum.GetUnderlyingType(type); +// typeInfo = type.GetTypeInfo(); +// } - //Primitives/Enums - Type targetType = null; - if (!typeInfo.IsEnum && IsType(type, typeof(long), typeof(ulong), typeof(double), typeof(bool), typeof(string), - typeof(sbyte?), typeof(byte?), typeof(short?), typeof(ushort?), - typeof(int?), typeof(uint?), typeof(long?), typeof(ulong?), - typeof(bool?), typeof(float?), typeof(double?), - typeof(object), typeof(DateTime))) - { - //No conversion needed - targetType = type; - } - else if (IsType(type, typeof(sbyte), typeof(short), typeof(int))) - { - //Convert to long - generator.Emit(OpCodes.Conv_I8); - targetType = typeof(long); - } - else if (IsType(type, typeof(byte), typeof(ushort), typeof(uint))) - { - //Convert to ulong - generator.Emit(OpCodes.Conv_U8); - targetType = typeof(ulong); - } - else if (IsType(type, typeof(float))) - { - //Convert to double - generator.Emit(OpCodes.Conv_R8); - targetType = typeof(double); - } - if (targetType != null) - generator.EmitCall(OpCodes.Call, GetWriteMethod(targetType), null); +// //Primitives/Enums +// Type targetType = null; +// if (!typeInfo.IsEnum && IsType(type, typeof(long), typeof(ulong), typeof(double), typeof(bool), typeof(string), +// typeof(sbyte?), typeof(byte?), typeof(short?), typeof(ushort?), +// typeof(int?), typeof(uint?), typeof(long?), typeof(ulong?), +// typeof(bool?), typeof(float?), typeof(double?), +// typeof(object), typeof(DateTime))) +// { +// //No conversion needed +// targetType = type; +// } +// else if (IsType(type, typeof(sbyte), typeof(short), typeof(int))) +// { +// //Convert to long +// generator.Emit(OpCodes.Conv_I8); +// targetType = typeof(long); +// } +// else if (IsType(type, typeof(byte), typeof(ushort), typeof(uint))) +// { +// //Convert to ulong +// generator.Emit(OpCodes.Conv_U8); +// targetType = typeof(ulong); +// } +// else if (IsType(type, typeof(float))) +// { +// //Convert to double +// generator.Emit(OpCodes.Conv_R8); +// targetType = typeof(double); +// } +// if (targetType != null) +// generator.EmitCall(OpCodes.Call, GetWriteMethod(targetType), null); - //Dictionaries - else if (!typeInfo.IsValueType && typeInfo.ImplementedInterfaces - .Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(IDictionary<,>))) - { - generator.EmitCall(OpCodes.Call, _writeDictionaryTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); - } - //Enumerable - else if (!typeInfo.IsValueType && typeInfo.ImplementedInterfaces - .Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>))) - { - generator.EmitCall(OpCodes.Call, _writeEnumerableTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); - } - //Nullable Structs - else if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>) && - typeInfo.GenericTypeParameters[0].GetTypeInfo().IsValueType) - { - generator.EmitCall(OpCodes.Call, _writeNullableTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); - } - //Structs/Classes - else if (typeInfo.IsClass || (typeInfo.IsValueType && !typeInfo.IsPrimitive)) - { - if (isTop) - { - typeInfo.ForEachField(f => - { - string name; - if (!f.IsPublic || !IsETFProperty(f, out name)) return; +// //Dictionaries +// else if (!typeInfo.IsValueType && typeInfo.ImplementedInterfaces +// .Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(IDictionary<,>))) +// { +// generator.EmitCall(OpCodes.Call, _writeDictionaryTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); +// } +// //Enumerable +// else if (!typeInfo.IsValueType && typeInfo.ImplementedInterfaces +// .Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(IEnumerable<>))) +// { +// generator.EmitCall(OpCodes.Call, _writeEnumerableTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); +// } +// //Nullable Structs +// else if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>) && +// typeInfo.GenericTypeParameters[0].GetTypeInfo().IsValueType) +// { +// generator.EmitCall(OpCodes.Call, _writeNullableTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); +// } +// //Structs/Classes +// else if (typeInfo.IsClass || (typeInfo.IsValueType && !typeInfo.IsPrimitive)) +// { +// if (isTop) +// { +// typeInfo.ForEachField(f => +// { +// string name; +// if (!f.IsPublic || !IsETFProperty(f, out name)) return; - generator.Emit(OpCodes.Ldarg_0); //ETFWriter(this) - generator.Emit(OpCodes.Ldstr, name); //ETFWriter(this), name - generator.EmitCall(OpCodes.Call, GetWriteMethod(typeof(string)), null); - generator.Emit(OpCodes.Ldarg_0); //ETFWriter(this) - generator.Emit(OpCodes.Ldarg_1); //ETFWriter(this), obj - generator.Emit(OpCodes.Ldfld, f); //ETFWriter(this), obj.fieldValue - EmitWriteValue(generator, f.FieldType, f.FieldType.GetTypeInfo(), false); - }); +// generator.Emit(OpCodes.Ldarg_0); //ETFWriter(this) +// generator.Emit(OpCodes.Ldstr, name); //ETFWriter(this), name +// generator.EmitCall(OpCodes.Call, GetWriteMethod(typeof(string)), null); +// generator.Emit(OpCodes.Ldarg_0); //ETFWriter(this) +// generator.Emit(OpCodes.Ldarg_1); //ETFWriter(this), obj +// generator.Emit(OpCodes.Ldfld, f); //ETFWriter(this), obj.fieldValue +// EmitWriteValue(generator, f.FieldType, f.FieldType.GetTypeInfo(), false); +// }); - typeInfo.ForEachProperty(p => - { - string name; - if (!p.CanRead || !p.GetMethod.IsPublic || !IsETFProperty(p, out name)) return; +// typeInfo.ForEachProperty(p => +// { +// string name; +// if (!p.CanRead || !p.GetMethod.IsPublic || !IsETFProperty(p, out name)) return; - generator.Emit(OpCodes.Ldarg_0); //ETFWriter(this) - generator.Emit(OpCodes.Ldstr, name); //ETFWriter(this), name - generator.EmitCall(OpCodes.Call, GetWriteMethod(typeof(string)), null); - generator.Emit(OpCodes.Ldarg_0); //ETFWriter(this) - generator.Emit(OpCodes.Ldarg_1); //ETFWriter(this), obj - generator.EmitCall(OpCodes.Callvirt, p.GetMethod, null); //ETFWriter(this), obj.propValue - EmitWriteValue(generator, p.PropertyType, p.PropertyType.GetTypeInfo(), false); - }); - } - else - { - //While we could drill deeper and make a large serializer that also serializes all subclasses, - //it's more efficient to serialize on a per-type basis via another Write call. - generator.EmitCall(OpCodes.Call, _writeTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); - } - } - //Unsupported (decimal, char) - else - throw new InvalidOperationException($"Serializing {type.Name} is not supported."); - } +// generator.Emit(OpCodes.Ldarg_0); //ETFWriter(this) +// generator.Emit(OpCodes.Ldstr, name); //ETFWriter(this), name +// generator.EmitCall(OpCodes.Call, GetWriteMethod(typeof(string)), null); +// generator.Emit(OpCodes.Ldarg_0); //ETFWriter(this) +// generator.Emit(OpCodes.Ldarg_1); //ETFWriter(this), obj +// generator.EmitCall(OpCodes.Callvirt, p.GetMethod, null); //ETFWriter(this), obj.propValue +// EmitWriteValue(generator, p.PropertyType, p.PropertyType.GetTypeInfo(), false); +// }); +// } +// else +// { +// //While we could drill deeper and make a large serializer that also serializes all subclasses, +// //it's more efficient to serialize on a per-type basis via another Write call. +// generator.EmitCall(OpCodes.Call, _writeTMethod.MakeGenericMethod(typeInfo.GenericTypeParameters), null); +// } +// } +// //Unsupported (decimal, char) +// else +// throw new InvalidOperationException($"Serializing {type.Name} is not supported."); +// } - private static bool IsType(Type type, params Type[] types) - { - for (int i = 0; i < types.Length; i++) - { - if (type == types[i]) - return true; - } - return false; - } - private static bool IsETFProperty(FieldInfo f, out string name) - { - var attrib = f.CustomAttributes.Where(x => x.AttributeType == typeof(JsonPropertyAttribute)).FirstOrDefault(); - if (attrib != null) - { - name = attrib.ConstructorArguments.FirstOrDefault().Value as string ?? f.Name; - return true; - } - name = null; - return false; - } - private static bool IsETFProperty(PropertyInfo p, out string name) - { - var attrib = p.CustomAttributes.Where(x => x.AttributeType == typeof(JsonPropertyAttribute)).FirstOrDefault(); - if (attrib != null) - { - name = attrib.ConstructorArguments.FirstOrDefault().Value as string ?? p.Name; - return true; - } - name = null; - return false; - } +// private static bool IsType(Type type, params Type[] types) +// { +// for (int i = 0; i < types.Length; i++) +// { +// if (type == types[i]) +// return true; +// } +// return false; +// } +// private static bool IsETFProperty(FieldInfo f, out string name) +// { +// var attrib = f.CustomAttributes.Where(x => x.AttributeType == typeof(JsonPropertyAttribute)).FirstOrDefault(); +// if (attrib != null) +// { +// name = attrib.ConstructorArguments.FirstOrDefault().Value as string ?? f.Name; +// return true; +// } +// name = null; +// return false; +// } +// private static bool IsETFProperty(PropertyInfo p, out string name) +// { +// var attrib = p.CustomAttributes.Where(x => x.AttributeType == typeof(JsonPropertyAttribute)).FirstOrDefault(); +// if (attrib != null) +// { +// name = attrib.ConstructorArguments.FirstOrDefault().Value as string ?? p.Name; +// return true; +// } +// name = null; +// return false; +// } - private static MethodInfo GetWriteMethod(Type paramType) - { - return typeof(ETFWriter).GetTypeInfo().GetDeclaredMethods(nameof(Write)) - .Where(x => x.GetParameters()[0].ParameterType == paramType) - .Single(); - } - private static MethodInfo GetGenericWriteMethod(Type genericType) - { - if (genericType == null) - { - return typeof(ETFWriter).GetTypeInfo() - .GetDeclaredMethods(nameof(Write)) - .Where(x => x.IsGenericMethodDefinition && x.GetParameters()[0].ParameterType == x.GetGenericArguments()[0]) - .Single(); - } - else - { - return typeof(ETFWriter).GetTypeInfo() - .GetDeclaredMethods(nameof(Write)) - .Where(x => - { - if (!x.IsGenericMethodDefinition) return false; - var p = x.GetParameters()[0].ParameterType.GetTypeInfo(); - return p.IsGenericType && p.GetGenericTypeDefinition() == genericType; - }) - .Single(); - } - } - #endregion +// private static MethodInfo GetWriteMethod(Type paramType) +// { +// return typeof(ETFWriter).GetTypeInfo().GetDeclaredMethods(nameof(Write)) +// .Where(x => x.GetParameters()[0].ParameterType == paramType) +// .Single(); +// } +// private static MethodInfo GetGenericWriteMethod(Type genericType) +// { +// if (genericType == null) +// { +// return typeof(ETFWriter).GetTypeInfo() +// .GetDeclaredMethods(nameof(Write)) +// .Where(x => x.IsGenericMethodDefinition && x.GetParameters()[0].ParameterType == x.GetGenericArguments()[0]) +// .Single(); +// } +// else +// { +// return typeof(ETFWriter).GetTypeInfo() +// .GetDeclaredMethods(nameof(Write)) +// .Where(x => +// { +// if (!x.IsGenericMethodDefinition) return false; +// var p = x.GetParameters()[0].ParameterType.GetTypeInfo(); +// return p.IsGenericType && p.GetGenericTypeDefinition() == genericType; +// }) +// .Single(); +// } +// } +// #endregion - #region IDisposable - private bool _isDisposed = false; +// #region IDisposable +// private bool _isDisposed = false; - protected virtual void Dispose(bool disposing) - { - if (!_isDisposed) - { - if (disposing) - { - if (_leaveOpen) - _stream.Flush(); - else - _stream.Dispose(); - } - _isDisposed = true; - } - } +// protected virtual void Dispose(bool disposing) +// { +// if (!_isDisposed) +// { +// if (disposing) +// { +// if (_leaveOpen) +// _stream.Flush(); +// else +// _stream.Dispose(); +// } +// _isDisposed = true; +// } +// } - public void Dispose() => Dispose(true); - #endregion - } -} +// public void Dispose() => Dispose(true); +// #endregion +// } +//} diff --git a/src/Discord.Net/Logging/ILogger.cs b/src/Discord.Net/Logging/ILogger.cs index abc713cc2..3282c80fa 100644 --- a/src/Discord.Net/Logging/ILogger.cs +++ b/src/Discord.Net/Logging/ILogger.cs @@ -7,36 +7,36 @@ namespace Discord.Logging LogSeverity Level { get; } void Log(LogSeverity severity, string message, Exception exception = null); -#if DOTNET5_4 +#if NETSTANDARD1_3 void Log(LogSeverity severity, FormattableString message, Exception exception = null); #endif void Error(string message, Exception exception = null); -#if DOTNET5_4 +#if NETSTANDARD1_3 void Error(FormattableString message, Exception exception = null); #endif void Error(Exception exception); void Warning(string message, Exception exception = null); -#if DOTNET5_4 +#if NETSTANDARD1_3 void Warning(FormattableString message, Exception exception = null); #endif void Warning(Exception exception); void Info(string message, Exception exception = null); -#if DOTNET5_4 +#if NETSTANDARD1_3 void Info(FormattableString message, Exception exception = null); #endif void Info(Exception exception); void Verbose(string message, Exception exception = null); -#if DOTNET5_4 +#if NETSTANDARD1_3 void Verbose(FormattableString message, Exception exception = null); #endif void Verbose(Exception exception); void Debug(string message, Exception exception = null); -#if DOTNET5_4 +#if NETSTANDARD1_3 void Debug(FormattableString message, Exception exception = null); #endif void Debug(Exception exception); diff --git a/src/Discord.Net/Logging/LogManager.cs b/src/Discord.Net/Logging/LogManager.cs index 2abc4f10d..3688ca29b 100644 --- a/src/Discord.Net/Logging/LogManager.cs +++ b/src/Discord.Net/Logging/LogManager.cs @@ -25,7 +25,7 @@ namespace Discord.Logging } } -#if DOTNET5_4 +#if NETSTANDARD1_3 public void Log(LogSeverity severity, string source, FormattableString message, Exception exception = null) { if (severity <= Level) @@ -57,7 +57,7 @@ namespace Discord.Logging public void Debug(string source, Exception ex) => Log(LogSeverity.Debug, source, (string)null, ex); -#if DOTNET5_4 +#if NETSTANDARD1_3 public void Error(string source, FormattableString message, Exception ex = null) => Log(LogSeverity.Error, source, message, ex); public void Warning(string source, FormattableString message, Exception ex = null) diff --git a/src/Discord.Net/Logging/Logger.cs b/src/Discord.Net/Logging/Logger.cs index 59d591163..5d5b041f9 100644 --- a/src/Discord.Net/Logging/Logger.cs +++ b/src/Discord.Net/Logging/Logger.cs @@ -38,7 +38,7 @@ namespace Discord.Logging public void Debug(Exception exception) => _manager.Debug(Name, exception); -#if DOTNET5_4 +#if NETSTANDARD1_3 public void Log(LogSeverity severity, FormattableString message, Exception exception = null) => _manager.Log(severity, Name, message, exception); public void Error(FormattableString message, Exception exception = null) diff --git a/src/Discord.Net/Net/Rest/BuiltInEngine.cs b/src/Discord.Net/Net/Rest/BuiltInEngine.cs index 83d12ec50..71a4d09d6 100644 --- a/src/Discord.Net/Net/Rest/BuiltInEngine.cs +++ b/src/Discord.Net/Net/Rest/BuiltInEngine.cs @@ -1,4 +1,4 @@ -#if DOTNET5_4 +#if NETSTANDARD1_3 using Discord.Logging; using System; using System.IO; diff --git a/src/Discord.Net/Net/Rest/ETFRestClient.cs b/src/Discord.Net/Net/Rest/ETFRestClient.cs deleted file mode 100644 index 5a2620e89..000000000 --- a/src/Discord.Net/Net/Rest/ETFRestClient.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Discord.ETF; -using System.IO; -using System; -using Discord.Logging; - -namespace Discord.Net.Rest -{ - public class ETFRestClient : RestClient - { - private readonly ETFWriter _serializer; - - public ETFRestClient(DiscordConfig config, string baseUrl, ILogger logger = null) - : base(config, baseUrl, logger) - { - _serializer = new ETFWriter(new MemoryStream()); - } - - protected override string Serialize(T obj) - { - throw new NotImplementedException(); - } - protected override T Deserialize(string json) - { - throw new NotImplementedException(); - } - } -} diff --git a/src/Discord.Net/Net/Rest/RestClient.cs b/src/Discord.Net/Net/Rest/RestClient.cs index 47853f8a4..f5e1a6471 100644 --- a/src/Discord.Net/Net/Rest/RestClient.cs +++ b/src/Discord.Net/Net/Rest/RestClient.cs @@ -36,7 +36,6 @@ namespace Discord.Net.Rest private readonly DiscordConfig _config; private readonly IRestEngine _engine; - private readonly ETFWriter _serializer; private readonly ILogger _logger; private string _token; @@ -57,7 +56,7 @@ namespace Discord.Net.Rest _config = config; _logger = logger; -#if !DOTNET5_4 +#if !NETSTANDARD1_3 _engine = new RestSharpEngine(config, baseUrl, logger); #else _engine = new BuiltInEngine(config, baseUrl, logger); diff --git a/src/Discord.Net/Net/Rest/SharpRestEngine.cs b/src/Discord.Net/Net/Rest/SharpRestEngine.cs index f9c54064b..dda6e40e2 100644 --- a/src/Discord.Net/Net/Rest/SharpRestEngine.cs +++ b/src/Discord.Net/Net/Rest/SharpRestEngine.cs @@ -1,4 +1,4 @@ -#if !DOTNET5_4 +#if !NETSTANDARD1_3 using Discord.Logging; using Nito.AsyncEx; using RestSharp; diff --git a/src/Discord.Net/Net/WebSockets/BuiltInEngine.cs b/src/Discord.Net/Net/WebSockets/BuiltInEngine.cs index bda5ccb15..460e608eb 100644 --- a/src/Discord.Net/Net/WebSockets/BuiltInEngine.cs +++ b/src/Discord.Net/Net/WebSockets/BuiltInEngine.cs @@ -1,4 +1,4 @@ -#if DOTNET5_4 +#if NETSTANDARD1_3 using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -89,7 +89,7 @@ namespace Discord.Net.WebSockets if (result.MessageType == WebSocketMessageType.Close) throw new WebSocketException((int)result.CloseStatus.Value, result.CloseStatusDescription); else - stream.Write(buffer.Array, buffer.Offset, buffer.Count); + stream.Write(buffer.Array, 0, result.Count); } while (result == null || !result.EndOfMessage); diff --git a/src/Discord.Net/Net/WebSockets/WS4NetEngine.cs b/src/Discord.Net/Net/WebSockets/WS4NetEngine.cs index 420299d6b..d72e59168 100644 --- a/src/Discord.Net/Net/WebSockets/WS4NetEngine.cs +++ b/src/Discord.Net/Net/WebSockets/WS4NetEngine.cs @@ -1,4 +1,4 @@ -#if !DOTNET5_4 +#if !NETSTANDARD1_3 using SuperSocket.ClientEngine; using System; using System.Collections.Concurrent; diff --git a/src/Discord.Net/Net/WebSockets/WebSocket.cs b/src/Discord.Net/Net/WebSockets/WebSocket.cs index d3f70f14c..5bb4208e5 100644 --- a/src/Discord.Net/Net/WebSockets/WebSocket.cs +++ b/src/Discord.Net/Net/WebSockets/WebSocket.cs @@ -49,7 +49,7 @@ namespace Discord.Net.WebSockets CancelToken = new CancellationToken(true); _connectedEvent = new ManualResetEventSlim(false); -#if !DOTNET5_4 +#if !NETSTANDARD1_3 _engine = new WS4NetEngine(config, _taskManager); #else _engine = new BuiltInEngine(config); diff --git a/src/Discord.Net/project.json b/src/Discord.Net/project.json index fd8ac91ed..de0e79a5d 100644 --- a/src/Discord.Net/project.json +++ b/src/Discord.Net/project.json @@ -1,29 +1,31 @@ { "version": "0.9.1", "description": "An unofficial .Net API wrapper for the Discord client.", - "authors": [ - "RogueException" - ], - "tags": [ - "discord", - "discordapp" - ], - "projectUrl": "https://github.com/RogueException/Discord.Net", - "licenseUrl": "http://opensource.org/licenses/MIT", - "repository": { - "type": "git", - "url": "git://github.com/RogueException/Discord.Net" + "authors": [ "RogueException" ], + + "packOptions": { + "tags": [ + "discord", + "discordapp" + ], + "projectUrl": "https://github.com/RogueException/Discord.Net", + "licenseUrl": "http://opensource.org/licenses/MIT", + "repository": { + "type": "git", + "url": "git://github.com/RogueException/Discord.Net" + } }, - "compile": [ "**/*.cs", "../Discord.Net.Shared/*.cs" ], - "compilationOptions": { + "buildOptions": { + "compile": [ "**/*.cs", "../Discord.Net.Shared/*.cs" ], + "preserveCompilationContext": true, "allowUnsafe": true, "warningsAsErrors": true }, "configurations": { "TestResponses": { - "compilationOptions": { + "buildOptions": { "define": [ "DEBUG", "TRACE", @@ -34,48 +36,24 @@ }, "dependencies": { - "Newtonsoft.Json": "8.0.1", - "Nito.AsyncEx": "3.0.1" + "NETStandard.Library": "1.5.0-rc2-24027", + "Newtonsoft.Json": "8.0.3", + "Nito.AsyncEx": "3.0.1", + "System.Net.Requests": "4.0.11-rc2-24027", + "System.Net.Websockets.Client": "4.0.0-rc2-24027", + "System.Reflection.Emit.Lightweight": "4.0.1-rc2-24027", + "System.Runtime.Serialization.Primitives": "4.1.1-rc2-24027", + "System.Security.Cryptography.Algorithms": "4.1.0-rc2-24027", + "System.Net.NameResolution": "4.0.0-rc2-24027" }, "frameworks": { - "dotnet5.4": { - "dependencies": { - "System.Collections": "4.0.11-beta-23516", - "System.Collections.Concurrent": "4.0.11-beta-23516", - "System.Dynamic.Runtime": "4.0.11-beta-23516", - "System.IO.FileSystem": "4.0.1-beta-23516", - "System.IO.Compression": "4.1.0-beta-23516", - "System.Linq": "4.0.1-beta-23516", - "System.Net.Http": "4.0.1-beta-23516", - "System.Net.NameResolution": "4.0.0-beta-23516", - "System.Net.Sockets": "4.1.0-beta-23409", - "System.Net.Requests": "4.0.11-beta-23516", - "System.Net.WebSockets.Client": "4.0.0-beta-23516", - "System.Reflection": "4.1.0-beta-23516", - "System.Reflection.Emit.Lightweight": "4.0.1-beta-23516", - "System.Runtime.InteropServices": "4.0.21-beta-23516", - "System.Runtime.Serialization.Primitives": "4.1.0-beta-23516", - "System.Security.Cryptography.Algorithms": "4.0.0-beta-23516", - "System.Text.RegularExpressions": "4.0.11-beta-23516", - "System.Threading": "4.0.11-beta-23516" - } - }, - "net45": { - "frameworkAssemblies": { - "System.Runtime": { - "type": "build", - "version": "" - }, - "System.Threading.Tasks": { - "type": "build", - "version": "" - } - }, - "dependencies": { - "WebSocket4Net": "0.14.1", - "RestSharp": "105.2.3" - } + "netstandard1.3": { + "imports": [ + "dotnet5.4", + "dnxcore50", + "portable-net45+win8" + ] } } } \ No newline at end of file diff --git a/test/Discord.Net.Tests/Discord.Net.Tests.csproj b/test/Discord.Net.Tests/Discord.Net.Tests.csproj index 0136c7ea9..dd0e3f165 100644 --- a/test/Discord.Net.Tests/Discord.Net.Tests.csproj +++ b/test/Discord.Net.Tests/Discord.Net.Tests.csproj @@ -59,14 +59,14 @@ + + + {8d71a857-879a-4a10-859e-5ff824ed6688} Discord.Net - - - diff --git a/test/Discord.Net.Tests/Tests.cs b/test/Discord.Net.Tests/Tests.cs index 5bc5bd1eb..64425221d 100644 --- a/test/Discord.Net.Tests/Tests.cs +++ b/test/Discord.Net.Tests/Tests.cs @@ -334,7 +334,7 @@ namespace Discord.Tests async () => await SetGame(_targetBot, "test game"), x => _observerBot.UserUpdated += x, x => _observerBot.UserUpdated -= x, - (s, e) => _targetBot.CurrentGame == "test game"); + (s, e) => _targetBot.CurrentGame.Name == "test game"); } private async Task SetGame(DiscordClient _client, string game)