diff --git a/ExchangeSharp.sln b/ExchangeSharp.sln
index 43bd812c..47af431e 100644
--- a/ExchangeSharp.sln
+++ b/ExchangeSharp.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.27130.2027
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29318.209
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExchangeSharp", "ExchangeSharp\ExchangeSharp.csproj", "{B4ADDAEF-95BF-4FDA-8B2F-8B899EDA3F45}"
EndProject
diff --git a/ExchangeSharp/API/Common/APIRequestMaker.cs b/ExchangeSharp/API/Common/APIRequestMaker.cs
index 04bb7fae..297ec641 100644
--- a/ExchangeSharp/API/Common/APIRequestMaker.cs
+++ b/ExchangeSharp/API/Common/APIRequestMaker.cs
@@ -1,4 +1,4 @@
-/*
+/*
MIT LICENSE
Copyright 2017 Digital Ruby, LLC - http://www.digitalruby.com
@@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
+#nullable enable
using System;
using System.Collections.Generic;
using System.IO;
@@ -33,7 +33,7 @@ private class InternalHttpWebRequest : IHttpWebRequest
public InternalHttpWebRequest(Uri fullUri)
{
- request = HttpWebRequest.Create(fullUri) as HttpWebRequest;
+ request = (HttpWebRequest.Create(fullUri) as HttpWebRequest ?? throw new NullReferenceException("Failed to create HttpWebRequest"));
request.KeepAlive = false;
}
@@ -145,22 +145,18 @@ public APIRequestMaker(IAPIRequestHandler api)
/// The encoding of payload is API dependant but is typically json.
/// Request method or null for default. Example: 'GET' or 'POST'.
/// Raw response
- public async Task MakeRequestAsync(string url, string baseUrl = null, Dictionary payload = null, string method = null)
+ public async Task MakeRequestAsync(string url, string? baseUrl = null, Dictionary? payload = null, string? method = null)
{
await new SynchronizationContextRemover();
-
await api.RateLimit.WaitToProceedAsync();
- if (string.IsNullOrWhiteSpace(url))
- {
- return null;
- }
- else if (url[0] != '/')
+
+ if (url[0] != '/')
{
url = "/" + url;
}
string fullUrl = (baseUrl ?? api.BaseUrl) + url;
- method = method ?? api.RequestMethod;
+ method ??= api.RequestMethod;
Uri uri = api.ProcessRequestUrl(new UriBuilder(fullUrl), payload, method);
InternalHttpWebRequest request = new InternalHttpWebRequest(uri)
{
@@ -171,8 +167,8 @@ public async Task MakeRequestAsync(string url, string baseUrl = null, Di
request.AddHeader("user-agent", BaseAPI.RequestUserAgent);
request.Timeout = request.ReadWriteTimeout = (int)api.RequestTimeout.TotalMilliseconds;
await api.ProcessRequestAsync(request, payload);
- HttpWebResponse response = null;
- string responseString = null;
+ HttpWebResponse? response = null;
+ string responseString;
try
{
@@ -194,21 +190,19 @@ public async Task MakeRequestAsync(string url, string baseUrl = null, Di
}
}
using (Stream responseStream = response.GetResponseStream())
+ using (StreamReader responseStreamReader = new StreamReader(responseStream))
+ responseString = responseStreamReader.ReadToEnd();
+ if (response.StatusCode != HttpStatusCode.OK)
{
- responseString = new StreamReader(responseStream).ReadToEnd();
- if (response.StatusCode != HttpStatusCode.OK)
+ // 404 maybe return empty responseString
+ if (string.IsNullOrWhiteSpace(responseString))
{
- // 404 maybe return empty responseString
- if (string.IsNullOrWhiteSpace(responseString))
- {
- throw new APIException(string.Format("{0} - {1}",
- response.StatusCode.ConvertInvariant(), response.StatusCode));
- }
- throw new APIException(responseString);
+ throw new APIException(string.Format("{0} - {1}", response.StatusCode.ConvertInvariant(), response.StatusCode));
}
- api.ProcessResponse(new InternalHttpWebResponse(response));
- RequestStateChanged?.Invoke(this, RequestMakerState.Finished, responseString);
+ throw new APIException(responseString);
}
+ api.ProcessResponse(new InternalHttpWebResponse(response));
+ RequestStateChanged?.Invoke(this, RequestMakerState.Finished, responseString);
}
catch (Exception ex)
{
@@ -225,6 +219,6 @@ public async Task MakeRequestAsync(string url, string baseUrl = null, Di
///
/// An action to execute when a request has been made (this request and state and object (response or exception))
///
- public Action RequestStateChanged { get; set; }
+ public Action? RequestStateChanged { get; set; }
}
}
diff --git a/ExchangeSharp/API/Common/BaseAPI.cs b/ExchangeSharp/API/Common/BaseAPI.cs
index 2eddc013..b5ef8dba 100644
--- a/ExchangeSharp/API/Common/BaseAPI.cs
+++ b/ExchangeSharp/API/Common/BaseAPI.cs
@@ -1,4 +1,4 @@
-/*
+/*
MIT LICENSE
Copyright 2017 Digital Ruby, LLC - http://www.digitalruby.com
@@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
+#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -148,28 +148,28 @@ public IAPIRequestMaker RequestMaker
///
/// Base URL for the API for web sockets
///
- public virtual string BaseUrlWebSocket { get; set; }
+ public virtual string BaseUrlWebSocket { get; set; } = string.Empty;
///
/// Gets the name of the API
///
- public virtual string Name { get; private set; }
+ public virtual string Name { get; private set; } = string.Empty;
///
/// Public API key - only needs to be set if you are using private authenticated end points. Please use CryptoUtility.SaveUnprotectedStringsToFile to store your API keys, never store them in plain text!
///
- public System.Security.SecureString PublicApiKey { get; set; }
+ public System.Security.SecureString? PublicApiKey { get; set; }
///
/// Private API key - only needs to be set if you are using private authenticated end points. Please use CryptoUtility.SaveUnprotectedStringsToFile to store your API keys, never store them in plain text!
///
- public System.Security.SecureString PrivateApiKey { get; set; }
+ public System.Security.SecureString? PrivateApiKey { get; set; }
///
/// Pass phrase API key - only needs to be set if you are using private authenticated end points. Please use CryptoUtility.SaveUnprotectedStringsToFile to store your API keys, never store them in plain text!
/// Most services do not require this, but Coinbase is an example of one that does
///
- public System.Security.SecureString Passphrase { get; set; }
+ public System.Security.SecureString? Passphrase { get; set; }
///
/// Rate limiter - set this to a new limit if you are seeing your ip get blocked by the API
@@ -209,12 +209,12 @@ public IAPIRequestMaker RequestMaker
///
/// The nonce end point for pulling down a server timestamp - override OnGetNonceOffset if you need custom handling
///
- public string NonceEndPoint { get; protected set; }
+ public string? NonceEndPoint { get; protected set; }
///
/// The field in the json returned by the nonce end point to parse out - override OnGetNonceOffset if you need custom handling
///
- public string NonceEndPointField { get; protected set; }
+ public string? NonceEndPointField { get; protected set; }
///
/// The type of value in the nonce end point field - override OnGetNonceOffset if you need custom handling.
@@ -297,7 +297,7 @@ public BaseAPI()
}
else
{
- Name = (nameAttributes[0] as ApiNameAttribute).Name;
+ Name = (nameAttributes[0] as ApiNameAttribute)?.Name ?? string.Empty;
}
}
@@ -376,7 +376,7 @@ public async Task
/// Symbol
/// Normalized symbol
- public virtual string NormalizeMarketSymbol(string marketSymbol)
+ public virtual string NormalizeMarketSymbol(string? marketSymbol)
{
marketSymbol = (marketSymbol ?? string.Empty).Trim();
marketSymbol = marketSymbol.Replace("-", MarketSymbolSeparator)
@@ -529,7 +534,7 @@ public virtual async Task> GetMarketSymbolsMetadataA
///
/// The market symbol. Ex. ADA/BTC. This is assumed to be normalized and already correct for the exchange.
/// The ExchangeMarket or null if it doesn't exist in the cache or there was an error
- public virtual async Task GetExchangeMarketFromCacheAsync(string marketSymbol)
+ public virtual async Task GetExchangeMarketFromCacheAsync(string marketSymbol)
{
try
{
@@ -733,7 +738,7 @@ public virtual async Task PlaceOrdersAsync(params Exchang
/// Order id to get details for
/// Symbol of order (most exchanges do not require this)
/// Order details
- public virtual async Task GetOrderDetailsAsync(string orderId, string marketSymbol = null)
+ public virtual async Task GetOrderDetailsAsync(string orderId, string? marketSymbol = null)
{
marketSymbol = NormalizeMarketSymbol(marketSymbol);
return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetOrderDetailsAsync(orderId, marketSymbol), nameof(GetOrderDetailsAsync), nameof(orderId), orderId, nameof(marketSymbol), marketSymbol);
@@ -744,7 +749,7 @@ public virtual async Task GetOrderDetailsAsync(string order
///
/// Symbol to get open orders for or null for all
/// All open order details
- public virtual async Task> GetOpenOrderDetailsAsync(string marketSymbol = null)
+ public virtual async Task> GetOpenOrderDetailsAsync(string? marketSymbol = null)
{
marketSymbol = NormalizeMarketSymbol(marketSymbol);
return await Cache.CacheMethod(MethodCachePolicy, async () => await OnGetOpenOrderDetailsAsync(marketSymbol), nameof(GetOpenOrderDetailsAsync), nameof(marketSymbol), marketSymbol);
@@ -756,7 +761,7 @@ public virtual async Task> GetOpenOrderDetailsA
/// Symbol to get completed orders for or null for all
/// Only returns orders on or after the specified date/time
/// All completed order details for the specified symbol, or all if null symbol
- public virtual async Task> GetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null)
+ public virtual async Task> GetCompletedOrderDetailsAsync(string? marketSymbol = null, DateTime? afterDate = null)
{
marketSymbol = NormalizeMarketSymbol(marketSymbol);
return await Cache.CacheMethod(MethodCachePolicy, async () => (await OnGetCompletedOrderDetailsAsync(marketSymbol, afterDate)).ToArray(), nameof(GetCompletedOrderDetailsAsync),
@@ -768,7 +773,7 @@ public virtual async Task> GetCompletedOrderDet
///
/// Order id of the order to cancel
/// Symbol of order (most exchanges do not require this)
- public virtual async Task CancelOrderAsync(string orderId, string marketSymbol = null)
+ public virtual async Task CancelOrderAsync(string orderId, string? marketSymbol = null)
{
// *NOTE* do not wrap in CacheMethodCall
await new SynchronizationContextRemover();
diff --git a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs
index c395fdaf..5c74a48a 100644
--- a/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs
+++ b/ExchangeSharp/API/Exchanges/_Base/ExchangeAPIExtensions.cs
@@ -1,4 +1,4 @@
-/*
+/*
MIT LICENSE
Copyright 2017 Digital Ruby, LLC - http://www.digitalruby.com
@@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
+#nullable enable
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -50,7 +50,7 @@ public static async Task GetFullOrderBookWebSocketAsync(this IOrderB
ConcurrentDictionary fullBooks = new ConcurrentDictionary();
Dictionary> partialOrderBookQueues = new Dictionary>();
- void applyDelta(SortedDictionary deltaValues, SortedDictionary bookToEdit)
+ static void applyDelta(SortedDictionary deltaValues, SortedDictionary bookToEdit)
{
foreach (ExchangeOrderPrice record in deltaValues.Values)
{
@@ -65,7 +65,7 @@ void applyDelta(SortedDictionary deltaValues, Sorte
}
}
- void updateOrderBook(ExchangeOrderBook fullOrderBook, ExchangeOrderBook freshBook)
+ static void updateOrderBook(ExchangeOrderBook fullOrderBook, ExchangeOrderBook freshBook)
{
lock (fullOrderBook)
{
@@ -443,8 +443,8 @@ internal static ExchangeOrderBook ParseOrderBookFromJTokenDictionaries
/// ExchangeTicker
internal static async Task ParseTickerAsync(this ExchangeAPI api, JToken token, string marketSymbol,
object askKey, object bidKey, object lastKey, object baseVolumeKey,
- object quoteVolumeKey = null, object timestampKey = null, TimestampType timestampType = TimestampType.None,
- object baseCurrencyKey = null, object quoteCurrencyKey = null, object idKey = null)
+ object? quoteVolumeKey = null, object? timestampKey = null, TimestampType timestampType = TimestampType.None,
+ object? baseCurrencyKey = null, object? quoteCurrencyKey = null, object? idKey = null)
{
if (token == null || !token.HasValues)
{
@@ -632,7 +632,7 @@ internal static T ParseTradeComponents(this JToken token, object amountKey, o
/// Last volume value
/// Receive base currency volume
/// Receive quote currency volume
- internal static void ParseVolumes(this JToken token, object baseVolumeKey, object quoteVolumeKey, decimal last, out decimal baseCurrencyVolume, out decimal quoteCurrencyVolume)
+ internal static void ParseVolumes(this JToken token, object baseVolumeKey, object? quoteVolumeKey, decimal last, out decimal baseCurrencyVolume, out decimal quoteCurrencyVolume)
{
// parse out volumes, handle cases where one or both do not exist
if (baseVolumeKey == null)
@@ -679,7 +679,7 @@ internal static void ParseVolumes(this JToken token, object baseVolumeKey, objec
/// Weighted average key
/// MarketCandle
internal static MarketCandle ParseCandle(this INamed named, JToken token, string marketSymbol, int periodSeconds, object openKey, object highKey, object lowKey,
- object closeKey, object timestampKey, TimestampType timestampType, object baseVolumeKey, object quoteVolumeKey = null, object weightedAverageKey = null)
+ object closeKey, object timestampKey, TimestampType timestampType, object baseVolumeKey, object? quoteVolumeKey = null, object? weightedAverageKey = null)
{
MarketCandle candle = new MarketCandle
{
@@ -703,4 +703,4 @@ internal static MarketCandle ParseCandle(this INamed named, JToken token, string
return candle;
}
}
-}
\ No newline at end of file
+}
diff --git a/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs b/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs
index dab28e57..0dc7ebaf 100644
--- a/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs
+++ b/ExchangeSharp/API/Exchanges/_Base/IExchangeAPI.cs
@@ -1,4 +1,4 @@
-/*
+/*
MIT LICENSE
Copyright 2017 Digital Ruby, LLC - http://www.digitalruby.com
@@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
+#nullable enable
using System;
using System.Collections.Generic;
using System.Security;
@@ -164,14 +164,14 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider
/// order id
/// Market Symbol
/// Order details
- Task GetOrderDetailsAsync(string orderId, string marketSymbol = null);
+ Task GetOrderDetailsAsync(string orderId, string? marketSymbol = null);
///
/// Get the details of all open orders
///
/// Market symbol to get open orders for or null for all
/// All open order details for the specified symbol
- Task> GetOpenOrderDetailsAsync(string marketSymbol = null);
+ Task> GetOpenOrderDetailsAsync(string? marketSymbol = null);
///
/// Get the details of all completed orders
@@ -179,14 +179,14 @@ public interface IExchangeAPI : IDisposable, IBaseAPI, IOrderBookProvider
/// Market symbol to get completed orders for or null for all
/// Only returns orders on or after the specified date/time
/// All completed order details for the specified symbol, or all if null symbol
- Task> GetCompletedOrderDetailsAsync(string marketSymbol = null, DateTime? afterDate = null);
+ Task> GetCompletedOrderDetailsAsync(string? marketSymbol = null, DateTime? afterDate = null);
///
/// Cancel an order, an exception is thrown if failure
///
/// Order id of the order to cancel
/// Market symbol of the order to cancel (not required for most exchanges)
- Task CancelOrderAsync(string orderId, string marketSymbol = null);
+ Task CancelOrderAsync(string orderId, string? marketSymbol = null);
///
/// Get margin amounts available to trade, symbol / amount dictionary
diff --git a/ExchangeSharp/ExchangeSharp.csproj b/ExchangeSharp/ExchangeSharp.csproj
index b1fa9c5a..2ca23093 100644
--- a/ExchangeSharp/ExchangeSharp.csproj
+++ b/ExchangeSharp/ExchangeSharp.csproj
@@ -1,7 +1,7 @@
- net472;netstandard2.0;netcoreapp2.2
+ net472;netstandard2.0;netstandard2.1Copyright 2017, Digital Ruby, LLC - www.digitalruby.comfalsetrue
diff --git a/ExchangeSharp/Utility/CryptoUtility.cs b/ExchangeSharp/Utility/CryptoUtility.cs
index 490da8d8..dc51cb84 100644
--- a/ExchangeSharp/Utility/CryptoUtility.cs
+++ b/ExchangeSharp/Utility/CryptoUtility.cs
@@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
+#nullable enable
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
@@ -72,7 +72,7 @@ public static void SetDateTimeUtcNowFunc(Func utcNowFunc)
/// Object
/// Parameter name
/// Message
- public static void ThrowIfNull(this object obj, string name, string message = null)
+ public static void ThrowIfNull(this object obj, string? name, string? message = null)
{
if (obj == null)
{
@@ -86,7 +86,7 @@ public static void ThrowIfNull(this object obj, string name, string message = nu
/// Object
/// Parameter name
/// Message
- public static void ThrowIfNullOrWhitespace(this string obj, string name, string message = null)
+ public static void ThrowIfNullOrWhitespace(this string obj, string name, string? message = null)
{
if (string.IsNullOrWhiteSpace(obj))
{
@@ -193,7 +193,7 @@ public static DateTime ToDateTimeInvariant(this object obj, DateTime defaultValu
{
return defaultValue;
}
- JValue jValue = obj as JValue;
+ JValue? jValue = obj as JValue;
if (jValue != null && jValue.Value == null)
{
return defaultValue;
@@ -215,7 +215,7 @@ public static T ConvertInvariant(this object obj, T defaultValue = default)
{
return defaultValue;
}
- JValue jValue = obj as JValue;
+ JValue? jValue = obj as JValue;
if (jValue != null && jValue.Value == null)
{
return defaultValue;
@@ -289,7 +289,7 @@ public static string ToUnsecureString(this SecureString s)
///
/// SecureString
/// Binary data
- public static byte[] ToUnsecureBytesUTF8(this SecureString s)
+ public static byte[]? ToUnsecureBytesUTF8(this SecureString? s)
{
if (s == null)
{
@@ -303,7 +303,7 @@ public static byte[] ToUnsecureBytesUTF8(this SecureString s)
///
/// SecureString in base64 format
/// Binary data
- public static byte[] ToBytesBase64Decode(this SecureString s)
+ public static byte[]? ToBytesBase64Decode(this SecureString? s)
{
if (s == null)
{
@@ -1075,37 +1075,39 @@ public static byte[] AesEncryption(byte[] input, byte[] password, byte[] salt)
/// Password
/// Salt
/// Decrypted data
- public static byte[] AesDecryption(byte[] input, byte[] password, byte[] salt)
+ public static byte[]? AesDecryption(byte[] input, byte[] password, byte[] salt)
{
if (input == null || input.Length == 0 || password == null || password.Length == 0 || salt == null || salt.Length == 0)
{
return null;
}
MemoryStream decrypted = new MemoryStream();
- var AES = new RijndaelManaged()
+ using (RijndaelManaged AES = new RijndaelManaged()
{
KeySize = 256,
BlockSize = 128,
Padding = PaddingMode.PKCS7,
- };
- var key = new Rfc2898DeriveBytes(password, salt, 1024);
- AES.Key = key.GetBytes(AES.KeySize / 8);
- AES.IV = key.GetBytes(AES.BlockSize / 8);
- AES.Mode = CipherMode.CBC;
- MemoryStream encrypted = new MemoryStream(input);
- byte[] saltMatch = new byte[salt.Length];
- if (encrypted.Read(saltMatch, 0, saltMatch.Length) != salt.Length || !salt.SequenceEqual(saltMatch))
- {
- throw new InvalidOperationException("Invalid salt");
- }
- var cs = new CryptoStream(encrypted, AES.CreateDecryptor(), CryptoStreamMode.Read);
- byte[] buffer = new byte[8192];
- int count;
- while ((count = cs.Read(buffer, 0, buffer.Length)) > 0)
- {
- decrypted.Write(buffer, 0, count);
+ })
+ {
+ var key = new Rfc2898DeriveBytes(password, salt, 1024);
+ AES.Key = key.GetBytes(AES.KeySize / 8);
+ AES.IV = key.GetBytes(AES.BlockSize / 8);
+ AES.Mode = CipherMode.CBC;
+ MemoryStream encrypted = new MemoryStream(input);
+ byte[] saltMatch = new byte[salt.Length];
+ if (encrypted.Read(saltMatch, 0, saltMatch.Length) != salt.Length || !salt.SequenceEqual(saltMatch))
+ {
+ throw new InvalidOperationException("Invalid salt");
+ }
+ var cs = new CryptoStream(encrypted, AES.CreateDecryptor(), CryptoStreamMode.Read);
+ byte[] buffer = new byte[8192];
+ int count;
+ while ((count = cs.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ decrypted.Write(buffer, 0, count);
+ }
+ return decrypted.ToArray();
}
- return decrypted.ToArray();
}
///
@@ -1362,7 +1364,7 @@ public static T Sync(this Task task)
/// Method implementation
/// Function arguments - function name and then param name, value, name, value, etc.
///
- public static async Task CacheMethod(this ICache cache, Dictionary methodCachePolicy, Func> method, params object[] arguments) where T : class
+ public static async Task CacheMethod(this ICache cache, Dictionary methodCachePolicy, Func> method, params object?[] arguments) where T : class
{
await new SynchronizationContextRemover();
methodCachePolicy.ThrowIfNull(nameof(methodCachePolicy));
@@ -1370,11 +1372,11 @@ public static async Task CacheMethod(this ICache cache, Dictionary
/// Data to protect
/// Protected data
- public static byte[] Protect(byte[] data, byte[] optionalEntropy = null, DataProtectionScope scope = DataProtectionScope.CurrentUser)
+ public static byte[] Protect(byte[] data, byte[]? optionalEntropy = null, DataProtectionScope scope = DataProtectionScope.CurrentUser)
{
if (CryptoUtility.IsWindows)
{
@@ -520,7 +517,7 @@ public static byte[] Protect(byte[] data, byte[] optionalEntropy = null, DataPro
///
/// Data to unprotect
/// Unprotected data
- public static byte[] Unprotect(byte[] data, byte[] optionalEntropy = null, DataProtectionScope scope = DataProtectionScope.CurrentUser)
+ public static byte[] Unprotect(byte[] data, byte[]? optionalEntropy = null, DataProtectionScope scope = DataProtectionScope.CurrentUser)
{
if (CryptoUtility.IsWindows)
{
diff --git a/ExchangeSharp/Utility/SignalrManager.cs b/ExchangeSharp/Utility/SignalrManager.cs
index 814da484..0494f36e 100644
--- a/ExchangeSharp/Utility/SignalrManager.cs
+++ b/ExchangeSharp/Utility/SignalrManager.cs
@@ -1,4 +1,4 @@
-/*
+/*
MIT LICENSE
Copyright 2017 Digital Ruby, LLC - http://www.digitalruby.com
@@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
+#nullable enable
#define HAS_SIGNALR
#if HAS_SIGNALR
@@ -103,14 +103,14 @@ public SignalrSocketConnection(SignalrManager manager)
/// Delay after invoking each object[] in param, used if the server will disconnect you for too many invoke too fast
/// End point parameters, each array of strings is a separate call to the end point function. For no parameters, pass null.
/// Connection
- public async Task OpenAsync(string functionName, Func callback, int delayMilliseconds = 0, object[][] param = null)
+ public async Task OpenAsync(string functionName, Func callback, int delayMilliseconds = 0, object[][]? param = null)
{
callback.ThrowIfNull(nameof(callback), "Callback must not be null");
SignalrManager _manager = this.manager;
_manager.ThrowIfNull(nameof(manager), "Manager is null");
- Exception ex = null;
+ Exception? ex = null;
param = (param ?? new object[][] { new object[0] });
string functionFullName = _manager.GetFunctionFullName(functionName);
this.functionFullName = functionFullName;
@@ -257,9 +257,9 @@ public sealed class WebsocketCustomTransport : ClientTransportBase
public WebsocketCustomTransport(IHttpClient client, TimeSpan connectInterval, TimeSpan keepAlive)
: base(client, "webSockets")
{
- this.connectInterval = connectInterval;
- this.keepAlive = keepAlive;
WebSocket = new ExchangeSharp.ClientWebSocket();
+ this.connectInterval = connectInterval;
+ this.keepAlive = keepAlive;
}
~WebsocketCustomTransport()
@@ -326,9 +326,9 @@ protected override void Dispose(bool disposing)
private void DisposeWebSocket()
{
WebSocket.Dispose();
- WebSocket = null;
}
+ /*
private void WebSocketOnClosed()
{
connection.Stop();
@@ -338,6 +338,7 @@ private void WebSocketOnError(Exception e)
{
connection.OnError(e);
}
+ */
private Task WebSocketOnBinaryMessageReceived(IWebSocket socket, byte[] data)
{
@@ -365,9 +366,9 @@ private class HubListener
private readonly List sockets = new List();
private readonly SemaphoreSlim reconnectLock = new SemaphoreSlim(1);
- private WebsocketCustomTransport customTransport;
- private HubConnection hubConnection;
- private IHubProxy hubProxy;
+ private WebsocketCustomTransport? customTransport;
+ private HubConnection? hubConnection;
+ private IHubProxy? hubProxy;
private bool disposed;
private TimeSpan _connectInterval = TimeSpan.FromHours(1.0);