From ffb82f82864eab35f91aab0f7159a58e8132675b Mon Sep 17 00:00:00 2001 From: wherewhere Date: Tue, 10 Oct 2023 23:30:37 +0800 Subject: [PATCH] Improve DeviceMonitor Add AggressiveInlining on single line methods Use HashCode to create hash code --- .../DeviceMonitorTests.Async.cs | 27 +- .../DeviceMonitorTests.cs | 26 +- .../Dummys/DeviceMonitorSink.cs | 10 +- AdvancedSharpAdbClient/AdbClient.Async.cs | 2 + AdvancedSharpAdbClient/AdbClient.cs | 5 + .../AdbCommandLineClient.cs | 3 + AdvancedSharpAdbClient/AdbServer.Async.cs | 2 + AdvancedSharpAdbClient/AdbSocket.Async.cs | 5 + AdvancedSharpAdbClient/AdbSocket.cs | 9 + .../DeviceCommands/DeviceExtensions.Async.cs | 3 + .../DeviceCommands/DeviceExtensions.cs | 12 + .../DeviceCommands/LinuxPath.cs | 9 +- .../DeviceCommands/Models/AndroidProcess.cs | 6 + .../DeviceCommands/PackageManager.Async.cs | 3 + .../DeviceCommands/PackageManager.cs | 3 + .../Receivers/EnvironmentVariablesReceiver.cs | 2 + .../Receivers/GetPropReceiver.cs | 2 + .../Receivers/InfoOutputReceiver.cs | 4 + .../Receivers/InstallOutputReceiver.cs | 8 +- .../Receivers/VersionInfoReceiver.cs | 2 + AdvancedSharpAdbClient/DeviceMonitor.cs | 73 ++- .../Exceptions/JavaException.cs | 3 + .../Extensions/AdbClientExtensions.Async.cs | 25 + .../Extensions/AdbClientExtensions.cs | 20 + .../Extensions/DateTimeExtensions.cs | 3 + .../Extensions/ExceptionExtensions.cs | 5 + .../Extensions/Extensions.cs | 12 + .../Extensions/LoggerExtensions.cs | 62 +- .../Extensions/SocketExtensions.cs | 6 + .../Extensions/StreamExtensions.cs | 9 + .../Extensions/StringExtensions.cs | 6 + .../Interfaces/IDeviceMonitor.cs | 5 + .../Logs/AndroidLogEntry.cs | 2 + AdvancedSharpAdbClient/Logs/LoggerProvider.cs | 5 + AdvancedSharpAdbClient/Models/AdbResponse.cs | 13 +- AdvancedSharpAdbClient/Models/Area.cs | 25 +- AdvancedSharpAdbClient/Models/Cords.cs | 22 +- AdvancedSharpAdbClient/Models/DeviceData.cs | 38 +- AdvancedSharpAdbClient/Models/DnsEndPoint.cs | 1 - AdvancedSharpAdbClient/Models/Element.cs | 24 +- .../Models/FileStatistics.cs | 16 +- AdvancedSharpAdbClient/Models/ForwardData.cs | 19 +- AdvancedSharpAdbClient/Models/ForwardSpec.cs | 12 +- AdvancedSharpAdbClient/Models/Framebuffer.cs | 2 + .../Models/FramebufferHeader.cs | 2 + AdvancedSharpAdbClient/Models/HashCode.cs | 562 ++++++++++++++++++ AdvancedSharpAdbClient/Models/ShellStream.cs | 5 + .../Receivers/ConsoleOutputReceiver.cs | 8 +- .../Receivers/MultilineReceiver.cs | 2 + AdvancedSharpAdbClient/SyncService.Async.cs | 1 + AdvancedSharpAdbClient/SyncService.cs | 2 + AdvancedSharpAdbClient/TcpSocket.Async.cs | 13 + AdvancedSharpAdbClient/TcpSocket.cs | 12 + 53 files changed, 1030 insertions(+), 128 deletions(-) create mode 100644 AdvancedSharpAdbClient/Models/HashCode.cs diff --git a/AdvancedSharpAdbClient.Tests/DeviceMonitorTests.Async.cs b/AdvancedSharpAdbClient.Tests/DeviceMonitorTests.Async.cs index ae5aa157..de5c5372 100644 --- a/AdvancedSharpAdbClient.Tests/DeviceMonitorTests.Async.cs +++ b/AdvancedSharpAdbClient.Tests/DeviceMonitorTests.Async.cs @@ -27,12 +27,15 @@ await RunTestAsync( Assert.Single(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); Socket.ResponseMessages.Clear(); Socket.Responses.Clear(); Socket.Requests.Clear(); + sink.ResetSignals(); + // Device disconnects ManualResetEvent eventWaiter = sink.CreateEventSignal(); @@ -43,9 +46,10 @@ await RunTestAsync( () => _ = eventWaiter.WaitOne(1000)); Assert.Empty(monitor.Devices); - Assert.Single(sink.ConnectedEvents); + Assert.Empty(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Single(sink.DisconnectedEvents); Assert.Equal("169.254.109.177:5555", sink.DisconnectedEvents[0].Device.Serial); } @@ -70,13 +74,16 @@ await RunTestAsync( Assert.Empty(monitor.Devices); Assert.Empty(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); - Assert.Empty(sink.NotifiedEvents); + Assert.Single(sink.NotifiedEvents); + Assert.Empty(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); Socket.ResponseMessages.Clear(); Socket.Responses.Clear(); Socket.Requests.Clear(); + sink.ResetSignals(); + // Device disconnects ManualResetEvent eventWaiter = sink.CreateEventSignal(); @@ -90,6 +97,7 @@ await RunTestAsync( Assert.Single(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); Assert.Equal("169.254.109.177:5555", sink.ConnectedEvents[0].Device.Serial); } @@ -114,16 +122,17 @@ await RunTestAsync( () => monitor.StartAsync()); Assert.Single(monitor.Devices); - Assert.Equal("169.254.109.177:5555", monitor.Devices.ElementAt(0).Serial); + Assert.Equal("169.254.109.177:5555", monitor.Devices[0].Serial); Assert.Single(sink.ConnectedEvents); Assert.Equal("169.254.109.177:5555", sink.ConnectedEvents[0].Device.Serial); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); } [Fact] - public async void DeviceChanged_TriggeredWhenStatusChangedAsyncTest() + public async void TriggeredWhenStatusChangedAsyncTest() { Socket.WaitForNewData = true; @@ -140,10 +149,11 @@ await RunTestAsync( () => monitor.StartAsync()); Assert.Single(monitor.Devices); - Assert.Equal(DeviceState.Offline, monitor.Devices.ElementAt(0).State); + Assert.Equal(DeviceState.Offline, monitor.Devices[0].State); Assert.Single(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); Socket.ResponseMessages.Clear(); @@ -162,16 +172,17 @@ await RunTestAsync( () => eventWaiter.WaitOne(1000)); Assert.Single(monitor.Devices); - Assert.Equal(DeviceState.Online, monitor.Devices.ElementAt(0).State); + Assert.Equal(DeviceState.Online, monitor.Devices[0].State); Assert.Empty(sink.ConnectedEvents); Assert.Single(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); Assert.Equal("169.254.109.177:5555", sink.ChangedEvents[0].Device.Serial); } [Fact] - public async void DeviceChanged_NoTriggerIfStatusIsSameAsyncTest() + public async void NoTriggerIfStatusIsSameAsyncTest() { Socket.WaitForNewData = true; @@ -192,6 +203,7 @@ await RunTestAsync( Assert.Single(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); Socket.ResponseMessages.Clear(); @@ -214,6 +226,7 @@ await RunTestAsync( Assert.Empty(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Empty(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); } diff --git a/AdvancedSharpAdbClient.Tests/DeviceMonitorTests.cs b/AdvancedSharpAdbClient.Tests/DeviceMonitorTests.cs index f19882cc..20fabbcf 100644 --- a/AdvancedSharpAdbClient.Tests/DeviceMonitorTests.cs +++ b/AdvancedSharpAdbClient.Tests/DeviceMonitorTests.cs @@ -1,5 +1,6 @@ using AdvancedSharpAdbClient.Logs; using System; +using System.Linq; using System.Threading; using Xunit; @@ -58,8 +59,11 @@ public void DeviceDisconnectedTest() Assert.Single(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); + sink.ResetSignals(); + Socket.ResponseMessages.Clear(); Socket.Responses.Clear(); Socket.Requests.Clear(); @@ -74,9 +78,10 @@ public void DeviceDisconnectedTest() () => eventWaiter.WaitOne(1000)); Assert.Empty(monitor.Devices); - Assert.Single(sink.ConnectedEvents); + Assert.Empty(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Single(sink.DisconnectedEvents); Assert.Equal("169.254.109.177:5555", sink.DisconnectedEvents[0].Device.Serial); } @@ -101,13 +106,16 @@ public void DeviceConnectedTest() Assert.Empty(monitor.Devices); Assert.Empty(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); - Assert.Empty(sink.NotifiedEvents); + Assert.Single(sink.NotifiedEvents); + Assert.Empty(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); Socket.ResponseMessages.Clear(); Socket.Responses.Clear(); Socket.Requests.Clear(); + sink.ResetSignals(); + // Device disconnects ManualResetEvent eventWaiter = sink.CreateEventSignal(); @@ -121,6 +129,7 @@ public void DeviceConnectedTest() Assert.Single(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); Assert.Equal("169.254.109.177:5555", sink.ConnectedEvents[0].Device.Serial); } @@ -150,11 +159,12 @@ public void StartInitialDeviceListTest() Assert.Equal("169.254.109.177:5555", sink.ConnectedEvents[0].Device.Serial); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); } [Fact] - public void DeviceChanged_TriggeredWhenStatusChangedTest() + public void TriggeredWhenStatusChangedTest() { Socket.WaitForNewData = true; @@ -175,6 +185,7 @@ public void DeviceChanged_TriggeredWhenStatusChangedTest() Assert.Single(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); Socket.ResponseMessages.Clear(); @@ -197,12 +208,13 @@ public void DeviceChanged_TriggeredWhenStatusChangedTest() Assert.Empty(sink.ConnectedEvents); Assert.Single(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); Assert.Equal("169.254.109.177:5555", sink.ChangedEvents[0].Device.Serial); } [Fact] - public void DeviceChanged_NoTriggerIfStatusIsSameTest() + public void NoTriggerIfStatusIsSameTest() { Socket.WaitForNewData = true; @@ -219,10 +231,11 @@ public void DeviceChanged_NoTriggerIfStatusIsSameTest() monitor.Start); Assert.Single(monitor.Devices); - Assert.Equal(DeviceState.Offline, monitor.Devices[0].State); + Assert.Equal(DeviceState.Offline, monitor.Devices.ElementAt(0).State); Assert.Single(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Single(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); Socket.ResponseMessages.Clear(); @@ -241,10 +254,11 @@ public void DeviceChanged_NoTriggerIfStatusIsSameTest() () => eventWaiter.WaitOne(1000)); Assert.Single(monitor.Devices); - Assert.Equal(DeviceState.Offline, monitor.Devices[0].State); + Assert.Equal(DeviceState.Offline, monitor.Devices.ElementAt(0).State); Assert.Empty(sink.ConnectedEvents); Assert.Empty(sink.ChangedEvents); Assert.Single(sink.NotifiedEvents); + Assert.Empty(sink.ListChangedEvents); Assert.Empty(sink.DisconnectedEvents); } diff --git a/AdvancedSharpAdbClient.Tests/Dummys/DeviceMonitorSink.cs b/AdvancedSharpAdbClient.Tests/Dummys/DeviceMonitorSink.cs index 0dc88c0d..78ca3a29 100644 --- a/AdvancedSharpAdbClient.Tests/Dummys/DeviceMonitorSink.cs +++ b/AdvancedSharpAdbClient.Tests/Dummys/DeviceMonitorSink.cs @@ -12,11 +12,13 @@ public DeviceMonitorSink(DeviceMonitor monitor) Monitor.DeviceChanged += OnDeviceChanged; Monitor.DeviceNotified += OnDeviceNotified; Monitor.DeviceConnected += OnDeviceConnected; + Monitor.DeviceListChanged += OnDeviceListChanged; Monitor.DeviceDisconnected += OnDeviceDisconnected; ChangedEvents = []; NotifiedEvents = []; ConnectedEvents = []; + ListChangedEvents = []; DisconnectedEvents = []; } @@ -25,13 +27,16 @@ public void ResetSignals() ChangedEvents.Clear(); NotifiedEvents.Clear(); ConnectedEvents.Clear(); + ListChangedEvents.Clear(); DisconnectedEvents.Clear(); } public List DisconnectedEvents { get; init; } - public List ConnectedEvents { get; init; } + public List ListChangedEvents { get; init; } + public List ConnectedEvents { get; init; } + public List NotifiedEvents { get; init; } public List ChangedEvents { get; init; } @@ -42,12 +47,13 @@ public ManualResetEvent CreateEventSignal() { ManualResetEvent signal = new(false); Monitor.DeviceNotified += (sender, e) => signal.Set(); - Monitor.DeviceDisconnected += (sender, e) => signal.Set(); return signal; } protected virtual void OnDeviceDisconnected(object sender, DeviceDataConnectEventArgs e) => DisconnectedEvents.Add(e); + protected virtual void OnDeviceListChanged(object sender, DeviceDataNotifyEventArgs e) => ListChangedEvents.Add(e); + protected virtual void OnDeviceConnected(object sender, DeviceDataConnectEventArgs e) => ConnectedEvents.Add(e); protected virtual void OnDeviceNotified(object sender, DeviceDataNotifyEventArgs e) => NotifiedEvents.Add(e); diff --git a/AdvancedSharpAdbClient/AdbClient.Async.cs b/AdvancedSharpAdbClient/AdbClient.Async.cs index 94a301ff..d891047a 100644 --- a/AdvancedSharpAdbClient/AdbClient.Async.cs +++ b/AdvancedSharpAdbClient/AdbClient.Async.cs @@ -378,9 +378,11 @@ public async Task DisconnectAsync(DnsEndPoint endpoint, CancellationToke } /// + [MethodImpl((MethodImplOptions)256)] public Task RootAsync(DeviceData device, CancellationToken cancellationToken = default) => RootAsync("root:", device, cancellationToken); /// + [MethodImpl((MethodImplOptions)256)] public Task UnrootAsync(DeviceData device, CancellationToken cancellationToken = default) => RootAsync("unroot:", device, cancellationToken); /// diff --git a/AdvancedSharpAdbClient/AdbClient.cs b/AdvancedSharpAdbClient/AdbClient.cs index 33177cb4..0b57413d 100644 --- a/AdvancedSharpAdbClient/AdbClient.cs +++ b/AdvancedSharpAdbClient/AdbClient.cs @@ -11,6 +11,7 @@ using System.IO; using System.Linq; using System.Net; +using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; @@ -520,9 +521,11 @@ public string Disconnect(DnsEndPoint endpoint) } /// + [MethodImpl((MethodImplOptions)256)] public void Root(DeviceData device) => Root("root:", device); /// + [MethodImpl((MethodImplOptions)256)] public void Unroot(DeviceData device) => Root("unroot:", device); /// @@ -1129,6 +1132,7 @@ public void StopApp(DeviceData device, string packageName) /// Sets default encoding (default - UTF8). /// /// The to set. + [MethodImpl((MethodImplOptions)256)] public static void SetEncoding(Encoding encoding) => Encoding = encoding; /// @@ -1151,6 +1155,7 @@ protected static void EnsureDevice(DeviceData device) [GeneratedRegex("<\\?xml(.?)*")] private static partial Regex GetXmlRegex(); #else + [MethodImpl((MethodImplOptions)256)] private static Regex GetXmlRegex() => new("<\\?xml(.?)*"); #endif } diff --git a/AdvancedSharpAdbClient/AdbCommandLineClient.cs b/AdvancedSharpAdbClient/AdbCommandLineClient.cs index 57e177af..fd54209e 100644 --- a/AdvancedSharpAdbClient/AdbCommandLineClient.cs +++ b/AdvancedSharpAdbClient/AdbCommandLineClient.cs @@ -9,6 +9,7 @@ using System.ComponentModel; using System.Diagnostics; using System.IO; +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; namespace AdvancedSharpAdbClient @@ -128,6 +129,7 @@ public virtual void StartServer() } /// + [MethodImpl((MethodImplOptions)256)] public virtual bool CheckFileExists(string adbPath) => Factories.CheckFileExists(adbPath); /// @@ -272,6 +274,7 @@ protected virtual int RunProcess(string filename, string command, ICollection new(AdbVersionPattern); #endif } diff --git a/AdvancedSharpAdbClient/AdbServer.Async.cs b/AdvancedSharpAdbClient/AdbServer.Async.cs index 70221dc3..7d1275e1 100644 --- a/AdvancedSharpAdbClient/AdbServer.Async.cs +++ b/AdvancedSharpAdbClient/AdbServer.Async.cs @@ -6,6 +6,7 @@ using AdvancedSharpAdbClient.Exceptions; using System; using System.Net.Sockets; +using System.Runtime.CompilerServices; using System.Threading; namespace AdvancedSharpAdbClient @@ -61,6 +62,7 @@ public virtual async Task StartServerAsync(string adbPath, bo } /// + [MethodImpl((MethodImplOptions)256)] public Task RestartServerAsync(CancellationToken cancellationToken = default) => RestartServerAsync(null, cancellationToken); /// diff --git a/AdvancedSharpAdbClient/AdbSocket.Async.cs b/AdvancedSharpAdbClient/AdbSocket.Async.cs index 72e0020a..54ae917f 100644 --- a/AdvancedSharpAdbClient/AdbSocket.Async.cs +++ b/AdvancedSharpAdbClient/AdbSocket.Async.cs @@ -8,6 +8,7 @@ using System.Globalization; using System.IO; using System.Net.Sockets; +using System.Runtime.CompilerServices; using System.Threading; namespace AdvancedSharpAdbClient @@ -16,6 +17,7 @@ public partial class AdbSocket { #if NET6_0_OR_GREATER /// + [MethodImpl((MethodImplOptions)256)] public virtual ValueTask ReconnectAsync(CancellationToken cancellationToken = default) => socket.ReconnectAsync(cancellationToken); #endif @@ -66,6 +68,7 @@ public virtual async Task SendAsync(byte[] data, int offset, int length, Cancell } /// + [MethodImpl((MethodImplOptions)256)] public Task SendSyncRequestAsync(SyncCommand command, string path, int permissions, CancellationToken cancellationToken = default) => SendSyncRequestAsync(command, $"{path},{permissions}", cancellationToken); @@ -112,6 +115,7 @@ public virtual async Task SendAdbRequestAsync(string request, CancellationToken } /// + [MethodImpl((MethodImplOptions)256)] public virtual Task ReadAsync(byte[] data, int length, CancellationToken cancellationToken = default) => ReadAsync(data, 0, length, cancellationToken); @@ -338,6 +342,7 @@ public virtual async Task SendAsync(byte[] data, CancellationToken cancellationT } /// + [MethodImpl((MethodImplOptions)256)] public virtual Task ReadAsync(byte[] data, CancellationToken cancellationToken = default) => ReadAsync(data, 0, data.Length, cancellationToken); #endif diff --git a/AdvancedSharpAdbClient/AdbSocket.cs b/AdvancedSharpAdbClient/AdbSocket.cs index bc5817ec..8af12525 100644 --- a/AdvancedSharpAdbClient/AdbSocket.cs +++ b/AdvancedSharpAdbClient/AdbSocket.cs @@ -9,6 +9,7 @@ using System.IO; using System.Net; using System.Net.Sockets; +using System.Runtime.CompilerServices; using System.Text; namespace AdvancedSharpAdbClient @@ -99,6 +100,7 @@ public AdbSocket(ITcpSocket socket, ILogger logger = null) /// /// The reply. /// if the specified reply is okay; otherwise, . + [MethodImpl((MethodImplOptions)256)] #if HAS_BUFFERS public static bool IsOkay(ReadOnlySpan reply) => AdbClient.Encoding.GetString(reply).Equals("OKAY"); #else @@ -109,6 +111,7 @@ public AdbSocket(ITcpSocket socket, ILogger logger = null) public bool Connected => socket.Connected; /// + [MethodImpl((MethodImplOptions)256)] public virtual void Reconnect() => socket.Reconnect(); /// @@ -158,6 +161,7 @@ public virtual void Send(byte[] data, int offset, int length) } /// + [MethodImpl((MethodImplOptions)256)] public void SendSyncRequest(SyncCommand command, string path, int permissions) => SendSyncRequest(command, $"{path},{permissions}"); @@ -204,6 +208,7 @@ public virtual void SendAdbRequest(string request) } /// + [MethodImpl((MethodImplOptions)256)] public virtual int Read(byte[] data, int length) => Read(data, 0, length); /// @@ -402,10 +407,12 @@ public virtual void Send(byte[] data) } /// + [MethodImpl((MethodImplOptions)256)] public virtual int Read(byte[] data) => Read(data, 0, data.Length); #endif /// + [MethodImpl((MethodImplOptions)256)] public virtual Stream GetShellStream() { Stream stream = socket.GetStream(); @@ -512,6 +519,7 @@ protected virtual string ReplyToString(byte[] reply) /// /// Releases all resources used by the current instance of the class. /// + [MethodImpl((MethodImplOptions)256)] protected virtual void Dispose(bool disposing) { if (disposing) @@ -528,6 +536,7 @@ public void Dispose() } /// + [MethodImpl((MethodImplOptions)256)] public virtual void Close() => socket.Dispose(); } } diff --git a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs index 5d395bf7..39c0b64e 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.Async.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; @@ -22,6 +23,7 @@ public static partial class DeviceExtensions /// The command to execute. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task ExecuteShellCommandAsync(this IAdbClient client, DeviceData device, string command, CancellationToken cancellationToken = default) => client.ExecuteRemoteCommandAsync(command, device, AdbClient.Encoding, cancellationToken); @@ -34,6 +36,7 @@ public static Task ExecuteShellCommandAsync(this IAdbClient client, DeviceData d /// Optionally, a that processes the command output. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task ExecuteShellCommandAsync(this IAdbClient client, DeviceData device, string command, IShellOutputReceiver receiver, CancellationToken cancellationToken = default) => client.ExecuteRemoteCommandAsync(command, device, receiver, AdbClient.Encoding, cancellationToken); diff --git a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs index 16a1722d..55785d48 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/DeviceExtensions.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; namespace AdvancedSharpAdbClient.DeviceCommands @@ -22,6 +23,7 @@ public static partial class DeviceExtensions /// The to use when executing the command. /// The device on which to run the command. /// The command to execute. + [MethodImpl((MethodImplOptions)256)] public static void ExecuteShellCommand(this IAdbClient client, DeviceData device, string command) => client.ExecuteRemoteCommand(command, device, AdbClient.Encoding); @@ -32,6 +34,7 @@ public static void ExecuteShellCommand(this IAdbClient client, DeviceData device /// The device on which to run the command. /// The command to execute. /// Optionally, a that processes the command output. + [MethodImpl((MethodImplOptions)256)] public static void ExecuteShellCommand(this IAdbClient client, DeviceData device, string command, IShellOutputReceiver receiver) => client.ExecuteRemoteCommand(command, device, receiver, AdbClient.Encoding); @@ -42,6 +45,7 @@ public static void ExecuteShellCommand(this IAdbClient client, DeviceData device /// The device on which to look for the file. /// The path to the file. /// A object that represents the file. + [MethodImpl((MethodImplOptions)256)] public static FileStatistics Stat(this IAdbClient client, DeviceData device, string path) { using ISyncService service = Factories.SyncServiceFactory(client, device); @@ -55,6 +59,7 @@ public static FileStatistics Stat(this IAdbClient client, DeviceData device, str /// The device on which to list the directory. /// The path to the directory on the device. /// For each child item of the directory, a object with information of the item. + [MethodImpl((MethodImplOptions)256)] public static IEnumerable List(this IAdbClient client, DeviceData device, string remotePath) { using ISyncService service = Factories.SyncServiceFactory(client, device); @@ -71,6 +76,7 @@ public static IEnumerable List(this IAdbClient client, DeviceDat /// An optional handler for the event. /// An optional parameter which, when specified, returns progress notifications. The progress is reported as a value between 0 and 100, representing the percentage of the file which has been transferred. /// A that can be used to cancel the task. + [MethodImpl((MethodImplOptions)256)] public static void Pull(this IAdbClient client, DeviceData device, string remotePath, Stream stream, EventHandler syncProgressEventHandler = null, @@ -97,6 +103,7 @@ public static void Pull(this IAdbClient client, DeviceData device, /// An optional handler for the event. /// An optional parameter which, when specified, returns progress notifications. The progress is reported as a value between 0 and 100, representing the percentage of the file which has been transferred. /// A that can be used to cancel the task. + [MethodImpl((MethodImplOptions)256)] public static void Push(this IAdbClient client, DeviceData device, string remotePath, Stream stream, int permissions, DateTimeOffset timestamp, EventHandler syncProgressEventHandler = null, @@ -118,6 +125,7 @@ public static void Push(this IAdbClient client, DeviceData device, /// The device for which to get the property. /// The name of property which to get. /// The value of the property on the device. + [MethodImpl((MethodImplOptions)256)] public static string GetProperty(this IAdbClient client, DeviceData device, string property) { ConsoleOutputReceiver receiver = new(); @@ -131,6 +139,7 @@ public static string GetProperty(this IAdbClient client, DeviceData device, stri /// The connection to the adb server. /// The device for which to list the properties. /// A dictionary containing the properties of the device, and their values. + [MethodImpl((MethodImplOptions)256)] public static Dictionary GetProperties(this IAdbClient client, DeviceData device) { GetPropReceiver receiver = new(); @@ -144,6 +153,7 @@ public static Dictionary GetProperties(this IAdbClient client, D /// The connection to the adb server. /// The device for which to list the environment variables. /// A dictionary containing the environment variables of the device, and their values. + [MethodImpl((MethodImplOptions)256)] public static Dictionary GetEnvironmentVariables(this IAdbClient client, DeviceData device) { EnvironmentVariablesReceiver receiver = new(); @@ -157,6 +167,7 @@ public static Dictionary GetEnvironmentVariables(this IAdbClient /// The connection to the adb server. /// The device on which to uninstall the package. /// The name of the package to uninstall. + [MethodImpl((MethodImplOptions)256)] public static void UninstallPackage(this IAdbClient client, DeviceData device, string packageName) { PackageManager manager = new(client, device); @@ -169,6 +180,7 @@ public static void UninstallPackage(this IAdbClient client, DeviceData device, s /// The connection to the adb server. /// The device on which to uninstall the package. /// The name of the package from which to get the application version. + [MethodImpl((MethodImplOptions)256)] public static VersionInfo GetPackageVersion(this IAdbClient client, DeviceData device, string packageName) { PackageManager manager = new(client, device); diff --git a/AdvancedSharpAdbClient/DeviceCommands/LinuxPath.cs b/AdvancedSharpAdbClient/DeviceCommands/LinuxPath.cs index 87d32e60..e86591b6 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/LinuxPath.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/LinuxPath.cs @@ -5,6 +5,7 @@ using System; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; @@ -139,7 +140,9 @@ public static string GetDirectoryName(string path) return null; } - /// Returns the file name and extension of the specified path string. + /// + /// Returns the file name and extension of the specified path string. + /// /// A consisting of the characters after the last directory character in path. /// If the last character of path is a directory or volume separator character, /// this method returns . If path is null, this method returns null. @@ -196,6 +199,7 @@ public static bool IsPathRooted(string path) /// /// The path. /// The entry name. + [MethodImpl((MethodImplOptions)256)] public static string Escape(string path) => EscapeRegex().Replace(path, new MatchEvaluator(m => m.Result("\\\\$1"))); /// @@ -203,12 +207,14 @@ public static bool IsPathRooted(string path) /// /// The path. /// The quoted path. + [MethodImpl((MethodImplOptions)256)] public static string Quote(string path) => path.Contains(' ') ? $"\"{path}\"" : path; /// /// Checks the invalid path chars. /// /// The path. + [MethodImpl((MethodImplOptions)256)] internal static void CheckInvalidPathChars(string path) { ExceptionExtensions.ThrowIfNull(path); @@ -247,6 +253,7 @@ private static string FixupPath(string path) [GeneratedRegex(EscapePattern)] private static partial Regex EscapeRegex(); #else + [MethodImpl((MethodImplOptions)256)] private static Regex EscapeRegex() => new(EscapePattern); #endif } diff --git a/AdvancedSharpAdbClient/DeviceCommands/Models/AndroidProcess.cs b/AdvancedSharpAdbClient/DeviceCommands/Models/AndroidProcess.cs index 1efe67d9..64e0a972 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/Models/AndroidProcess.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/Models/AndroidProcess.cs @@ -3,6 +3,7 @@ // using System; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient.DeviceCommands { @@ -601,6 +602,7 @@ public AndroidProcess(string line, bool cmdLinePrefix = false) /// A value indicating whether the output of /proc/{pid}/stat is prefixed with /proc/{pid}/cmdline or not. /// Because stat does not contain the full process name, this can be useful. /// The equivalent . + [MethodImpl((MethodImplOptions)256)] public static AndroidProcess Parse(string line, bool cmdLinePrefix = false) => new(line, cmdLinePrefix); /// @@ -610,12 +612,16 @@ public AndroidProcess(string line, bool cmdLinePrefix = false) /// A that represents this . public override string ToString() => $"{Name} ({ProcessId})"; + [MethodImpl((MethodImplOptions)256)] private static int ParseInt(string value) => value == "-" ? 0 : int.Parse(value); + [MethodImpl((MethodImplOptions)256)] private static uint ParseUInt(string value) => value == "-" ? 0 : uint.Parse(value); + [MethodImpl((MethodImplOptions)256)] private static long ParseLong(string value) => value == "-" ? 0 : long.Parse(value); + [MethodImpl((MethodImplOptions)256)] private static ulong ParseULong(string value) => value == "-" ? 0 : ulong.Parse(value); } } diff --git a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs index dfa02a54..706ec496 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.Async.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Threading; namespace AdvancedSharpAdbClient.DeviceCommands @@ -51,6 +52,7 @@ public virtual async Task InstallPackageAsync(string packageFilePath, bool reins InstallProgressChanged?.Invoke(this, new InstallProgressEventArgs(PackageInstallProgressState.Finished)); + [MethodImpl((MethodImplOptions)256)] void OnSyncProgressChanged(object sender, SyncProgressChangedEventArgs args) => InstallProgressChanged?.Invoke(this, new InstallProgressEventArgs(sender is true ? 1 : 0, 1, args.ProgressPercentage)); } @@ -92,6 +94,7 @@ public virtual async Task InstallMultiplePackageAsync(string basePackageFilePath { ValidateDevice(); + [MethodImpl((MethodImplOptions)256)] void OnMainSyncProgressChanged(object sender, SyncProgressChangedEventArgs args) => InstallProgressChanged?.Invoke(this, new InstallProgressEventArgs(sender is true ? 1 : 0, splitPackageFilePaths.Count + 1, args.ProgressPercentage / 2)); diff --git a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs index 26ad4a5c..bd8161a5 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/PackageManager.cs @@ -9,6 +9,7 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient.DeviceCommands { @@ -139,6 +140,7 @@ public virtual void InstallPackage(string packageFilePath, bool reinstall) InstallProgressChanged?.Invoke(this, new InstallProgressEventArgs(PackageInstallProgressState.Finished)); + [MethodImpl((MethodImplOptions)256)] void OnSyncProgressChanged(object sender, SyncProgressChangedEventArgs args) => InstallProgressChanged?.Invoke(this, new InstallProgressEventArgs(sender is true ? 1 : 0, 1, args.ProgressPercentage)); } @@ -176,6 +178,7 @@ public virtual void InstallMultiplePackage(string basePackageFilePath, IList InstallProgressChanged?.Invoke(this, new InstallProgressEventArgs(sender is true ? 1 : 0, splitPackageFilePaths.Count + 1, args.ProgressPercentage / 2)); diff --git a/AdvancedSharpAdbClient/DeviceCommands/Receivers/EnvironmentVariablesReceiver.cs b/AdvancedSharpAdbClient/DeviceCommands/Receivers/EnvironmentVariablesReceiver.cs index 0ae04fc1..cb6e735e 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/Receivers/EnvironmentVariablesReceiver.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/Receivers/EnvironmentVariablesReceiver.cs @@ -3,6 +3,7 @@ // using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; namespace AdvancedSharpAdbClient.DeviceCommands @@ -64,6 +65,7 @@ protected override void ProcessNewLines(IEnumerable lines) [GeneratedRegex(EnvPattern)] private static partial Regex EnvRegex(); #else + [MethodImpl((MethodImplOptions)256)] private static Regex EnvRegex() => new(EnvPattern); #endif } diff --git a/AdvancedSharpAdbClient/DeviceCommands/Receivers/GetPropReceiver.cs b/AdvancedSharpAdbClient/DeviceCommands/Receivers/GetPropReceiver.cs index 799f9492..534b7aca 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/Receivers/GetPropReceiver.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/Receivers/GetPropReceiver.cs @@ -3,6 +3,7 @@ // using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; namespace AdvancedSharpAdbClient.DeviceCommands @@ -68,6 +69,7 @@ protected override void ProcessNewLines(IEnumerable lines) [GeneratedRegex(GetPropPattern)] private static partial Regex GetPropRegex(); #else + [MethodImpl((MethodImplOptions)256)] private static Regex GetPropRegex() => new(GetPropPattern); #endif } diff --git a/AdvancedSharpAdbClient/DeviceCommands/Receivers/InfoOutputReceiver.cs b/AdvancedSharpAdbClient/DeviceCommands/Receivers/InfoOutputReceiver.cs index 714b8a4e..58a09b0a 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/Receivers/InfoOutputReceiver.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/Receivers/InfoOutputReceiver.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient.DeviceCommands { @@ -34,6 +35,7 @@ public InfoOutputReceiver() { } /// /// The name of the property. /// The received value + [MethodImpl((MethodImplOptions)256)] public object GetPropertyValue(string propertyName) => Properties.TryGetValue(propertyName, out object property) ? property : null; /// @@ -43,6 +45,7 @@ public InfoOutputReceiver() { } /// The type of the property /// The name of the property. /// The received value. + [MethodImpl((MethodImplOptions)256)] public T GetPropertyValue(string propertyName) => Properties.TryGetValue(propertyName, out object property) && property is T value ? value : default; /// @@ -52,6 +55,7 @@ public InfoOutputReceiver() { } /// /// The property corresponding with the parser. /// Function parsing one string and returning the property value if possible. + [MethodImpl((MethodImplOptions)256)] public void AddPropertyParser(string property, Func parser) => PropertyParsers[property] = parser; /// diff --git a/AdvancedSharpAdbClient/DeviceCommands/Receivers/InstallOutputReceiver.cs b/AdvancedSharpAdbClient/DeviceCommands/Receivers/InstallOutputReceiver.cs index ba306688..0dbcf1b9 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/Receivers/InstallOutputReceiver.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/Receivers/InstallOutputReceiver.cs @@ -3,6 +3,7 @@ // using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; namespace AdvancedSharpAdbClient.DeviceCommands @@ -138,10 +139,13 @@ protected override void ProcessNewLines(IEnumerable lines) [GeneratedRegex(ErrorPattern, RegexOptions.IgnoreCase)] private static partial Regex ErrorRegex(); #else + [MethodImpl((MethodImplOptions)256)] private static Regex SuccessRegex() => new(SuccessPattern, RegexOptions.IgnoreCase); - + + [MethodImpl((MethodImplOptions)256)] private static Regex FailureRegex() => new(FailurePattern, RegexOptions.IgnoreCase); - + + [MethodImpl((MethodImplOptions)256)] private static Regex ErrorRegex() => new(ErrorPattern, RegexOptions.IgnoreCase); #endif } diff --git a/AdvancedSharpAdbClient/DeviceCommands/Receivers/VersionInfoReceiver.cs b/AdvancedSharpAdbClient/DeviceCommands/Receivers/VersionInfoReceiver.cs index c1416fe8..6200c5bd 100644 --- a/AdvancedSharpAdbClient/DeviceCommands/Receivers/VersionInfoReceiver.cs +++ b/AdvancedSharpAdbClient/DeviceCommands/Receivers/VersionInfoReceiver.cs @@ -3,6 +3,7 @@ // using System; +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; namespace AdvancedSharpAdbClient.DeviceCommands @@ -120,6 +121,7 @@ internal object GetVersionCode(string line) [GeneratedRegex(VersionCodePattern)] private static partial Regex VersionCodeRegex(); #else + [MethodImpl((MethodImplOptions)256)] private static Regex VersionCodeRegex() => new(VersionCodePattern); #endif } diff --git a/AdvancedSharpAdbClient/DeviceMonitor.cs b/AdvancedSharpAdbClient/DeviceMonitor.cs index 67273cc6..887c8ae4 100644 --- a/AdvancedSharpAdbClient/DeviceMonitor.cs +++ b/AdvancedSharpAdbClient/DeviceMonitor.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using System.Runtime.CompilerServices; using System.Threading; namespace AdvancedSharpAdbClient @@ -76,6 +77,9 @@ public partial class DeviceMonitor : IDeviceMonitor /// public event EventHandler DeviceConnected; + /// + public event EventHandler DeviceListChanged; + /// public event EventHandler DeviceDisconnected; @@ -202,24 +206,35 @@ public void Dispose() /// Raises the event. /// /// The instance containing the event data. + [MethodImpl((MethodImplOptions)256)] protected void OnDeviceChanged(DeviceDataChangeEventArgs e) => DeviceChanged?.Invoke(this, e); /// /// Raises the event. /// - /// The instance containing the event data. + /// The instance containing the event data. + [MethodImpl((MethodImplOptions)256)] protected void OnDeviceNotified(DeviceDataNotifyEventArgs e) => DeviceNotified?.Invoke(this, e); /// /// Raises the event. /// /// The instance containing the event data. + [MethodImpl((MethodImplOptions)256)] protected void OnDeviceConnected(DeviceDataConnectEventArgs e) => DeviceConnected?.Invoke(this, e); + /// + /// Raises the event. + /// + /// The instance containing the event data. + [MethodImpl((MethodImplOptions)256)] + protected void OnDeviceListChanged(DeviceDataNotifyEventArgs e) => DeviceListChanged?.Invoke(this, e); + /// /// Raises the event. /// /// The instance containing the event data. + [MethodImpl((MethodImplOptions)256)] protected void OnDeviceDisconnected(DeviceDataConnectEventArgs e) => DeviceDisconnected?.Invoke(this, e); #if !HAS_TASK @@ -278,14 +293,15 @@ private void ProcessIncomingDeviceData(string result) IEnumerable currentDevices = deviceValues.Select(x => new DeviceData(x)); UpdateDevices(currentDevices); + OnDeviceNotified(new DeviceDataNotifyEventArgs(currentDevices)); } /// /// Processes the incoming . /// - protected virtual void UpdateDevices(IEnumerable devices) + protected virtual void UpdateDevices(IEnumerable collection) { - lock (this.devices) + lock (devices) { // For each device in the current list, we look for a matching the new list. // * if we find it, we update the current object with whatever new information @@ -297,41 +313,48 @@ protected virtual void UpdateDevices(IEnumerable devices) // add them to the list, and start monitoring them. // Add or update existing devices - foreach (DeviceData device in devices) - { - DeviceData existingDevice = this.devices.SingleOrDefault(d => d.Serial == device.Serial); - if (existingDevice == null) + bool isChanged = false; + int length = this.devices.Count; + List devices = collection.ToList(); + for (int i = 0; i < length;) + { + DeviceData currentDevice = this.devices[i]; + int index = devices.FindIndex(d => d.Serial == currentDevice.Serial); + if (index == -1) { - this.devices.Add(device); - OnDeviceConnected(new DeviceDataConnectEventArgs(device, true)); + this.devices.RemoveAt(i); + OnDeviceDisconnected(new DeviceDataConnectEventArgs(currentDevice, false)); + isChanged = true; + length--; } - else if (existingDevice.State != device.State) + else { - DeviceState oldState = existingDevice.State; - int index = this.devices.IndexOf(existingDevice); - if (index != -1) - { - this.devices[index] = device; - } - else + DeviceData device = devices[index]; + if (currentDevice.State != device.State) { - this.devices.Add(device); + this.devices[i] = device; + OnDeviceChanged(new DeviceDataChangeEventArgs(device, device.State, currentDevice.State)); + isChanged = true; } - OnDeviceChanged(new DeviceDataChangeEventArgs(device, device.State, oldState)); + devices.RemoveAt(index); + i++; } } - // Remove devices - foreach (DeviceData device in this.devices.Where(d => !devices.Any(e => e.Serial == d.Serial)).ToArray()) + if (devices.Count > 0) { - this.devices.Remove(device); - OnDeviceDisconnected(new DeviceDataConnectEventArgs(device, false)); + foreach (DeviceData device in devices) + { + this.devices.Add(device); + OnDeviceConnected(new DeviceDataConnectEventArgs(device, false)); + } + isChanged = true; } - if (devices.Any()) + if (isChanged) { - OnDeviceNotified(new DeviceDataNotifyEventArgs(devices)); + OnDeviceListChanged(new DeviceDataNotifyEventArgs(devices)); } } } diff --git a/AdvancedSharpAdbClient/Exceptions/JavaException.cs b/AdvancedSharpAdbClient/Exceptions/JavaException.cs index daa16843..6070cfe4 100644 --- a/AdvancedSharpAdbClient/Exceptions/JavaException.cs +++ b/AdvancedSharpAdbClient/Exceptions/JavaException.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; @@ -82,6 +83,7 @@ public JavaException(string name, string message, string stackTrace, Exception i /// /// A which represents a . /// The equivalent . + [MethodImpl((MethodImplOptions)256)] public static JavaException Parse(string line) => Parse(line.Split(separator, StringSplitOptions.RemoveEmptyEntries)); @@ -125,6 +127,7 @@ public static JavaException Parse(IEnumerable lines) [GeneratedRegex(ExceptionPattern, RegexOptions.IgnoreCase)] private static partial Regex ExceptionRegex(); #else + [MethodImpl((MethodImplOptions)256)] private static Regex ExceptionRegex() => new(ExceptionPattern, RegexOptions.IgnoreCase); #endif } diff --git a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs index 6f67facf..7e88c483 100644 --- a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs +++ b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.Async.cs @@ -10,6 +10,7 @@ using System.IO; using System.Linq; using System.Net; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; @@ -31,6 +32,7 @@ public static partial class AdbClientExtensions /// A which represents the asynchronous operation. /// If your requested to start forwarding to local port TCP:0, the port number of the TCP port /// which has been opened. In all other cases, 0. + [MethodImpl((MethodImplOptions)256)] public static Task CreateForwardAsync(this IAdbClient client, DeviceData device, ForwardSpec local, ForwardSpec remote, bool allowRebind, CancellationToken cancellationToken = default) => client.CreateForwardAsync(device, local?.ToString(), remote?.ToString(), allowRebind, cancellationToken); @@ -46,6 +48,7 @@ public static Task CreateForwardAsync(this IAdbClient client, DeviceData de /// If your requested to start forwarding to local port TCP:0, the port number of the TCP port /// which has been opened. In all other cases, 0. /// Failed to submit the forward command. Or Device rejected command: + resp.Message. + [MethodImpl((MethodImplOptions)256)] public static Task CreateForwardAsync(this IAdbClient client, DeviceData device, int localPort, int remotePort, CancellationToken cancellationToken = default) => client.CreateForwardAsync(device, $"tcp:{localPort}", $"tcp:{remotePort}", true, cancellationToken); @@ -62,6 +65,7 @@ public static Task CreateForwardAsync(this IAdbClient client, DeviceData de /// which has been opened. In all other cases, 0. /// The client failed to submit the forward command. /// The device rejected command. The error message will include the error message provided by the device. + [MethodImpl((MethodImplOptions)256)] public static Task CreateForwardAsync(this IAdbClient client, DeviceData device, int localPort, string remoteSocket, CancellationToken cancellationToken = default) => client.CreateForwardAsync(device, $"tcp:{localPort}", $"local:{remoteSocket}", true, cancellationToken); @@ -79,6 +83,7 @@ public static Task CreateForwardAsync(this IAdbClient client, DeviceData de /// A which represents the asynchronous operation. /// If your requested to start reverse to remote port TCP:0, the port number of the TCP port /// which has been opened. In all other cases, 0. + [MethodImpl((MethodImplOptions)256)] public static Task CreateReverseForwardAsync(this IAdbClient client, DeviceData device, ForwardSpec remote, ForwardSpec local, bool allowRebind, CancellationToken cancellationToken = default) => client.CreateReverseForwardAsync(device, remote?.ToString(), local?.ToString(), allowRebind, cancellationToken); @@ -90,6 +95,7 @@ public static Task CreateReverseForwardAsync(this IAdbClient client, Device /// Specification of the remote that was forwarded /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task RemoveReverseForwardAsync(this IAdbClient client, DeviceData device, ForwardSpec remote, CancellationToken cancellationToken = default) => client.RemoveReverseForwardAsync(device, remote?.ToString(), cancellationToken); @@ -103,6 +109,7 @@ public static Task RemoveReverseForwardAsync(this IAdbClient client, DeviceData /// Optionally, a that processes the command output. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task ExecuteServerCommandAsync(this IAdbClient client, string target, string command, IShellOutputReceiver receiver, CancellationToken cancellationToken = default) => client.ExecuteServerCommandAsync(target, command, receiver, AdbClient.Encoding, cancellationToken); @@ -116,6 +123,7 @@ public static Task ExecuteServerCommandAsync(this IAdbClient client, string targ /// The to send command. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task ExecuteServerCommandAsync(this IAdbClient client, string target, string command, IAdbSocket socket, CancellationToken cancellationToken = default) => client.ExecuteServerCommandAsync(target, command, socket, AdbClient.Encoding, cancellationToken); @@ -127,6 +135,7 @@ public static Task ExecuteServerCommandAsync(this IAdbClient client, string targ /// The device on which to run the command. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task ExecuteRemoteCommandAsync(this IAdbClient client, string command, DeviceData device, CancellationToken cancellationToken = default) => client.ExecuteRemoteCommandAsync(command, device, AdbClient.Encoding, cancellationToken); @@ -139,6 +148,7 @@ public static Task ExecuteRemoteCommandAsync(this IAdbClient client, string comm /// The command to execute. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task ExecuteServerCommandAsync(this IAdbClient client, string target, string command, CancellationToken cancellationToken = default) => client.ExecuteServerCommandAsync(target, command, AdbClient.Encoding, cancellationToken); @@ -153,6 +163,7 @@ public static Task ExecuteServerCommandAsync(this IAdbClient client, string targ /// Optionally, a that processes the command output. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task ExecuteServerCommandAsync(this IAdbClient client, string target, string command, IAdbSocket socket, IShellOutputReceiver receiver, CancellationToken cancellationToken = default) => client.ExecuteServerCommandAsync(target, command, socket, receiver, AdbClient.Encoding, cancellationToken); @@ -165,6 +176,7 @@ public static Task ExecuteServerCommandAsync(this IAdbClient client, string targ /// Optionally, a that processes the command output. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task ExecuteRemoteCommandAsync(this IAdbClient client, string command, DeviceData device, IShellOutputReceiver receiver, CancellationToken cancellationToken = default) => client.ExecuteRemoteCommandAsync(command, device, receiver, AdbClient.Encoding, cancellationToken); @@ -176,6 +188,7 @@ public static Task ExecuteRemoteCommandAsync(this IAdbClient client, string comm /// A callback which will receive the event log messages as they are received. /// Optionally, the names of the logs to receive. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task RunLogServiceAsync(this IAdbClient client, DeviceData device, Action messageSink, params LogId[] logNames) => client.RunLogServiceAsync(device, messageSink, default, logNames); @@ -186,6 +199,7 @@ public static Task RunLogServiceAsync(this IAdbClient client, DeviceData device, /// The device. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task RebootAsync(this IAdbClient client, DeviceData device, CancellationToken cancellationToken = default) => client.RebootAsync(string.Empty, device, cancellationToken); /// @@ -196,6 +210,7 @@ public static Task RunLogServiceAsync(this IAdbClient client, DeviceData device, /// The pairing code. /// A which can be used to cancel the asynchronous operation. /// The results from adb. + [MethodImpl((MethodImplOptions)256)] public static Task PairAsync(this IAdbClient client, IPAddress address, string code, CancellationToken cancellationToken = default) => address == null ? throw new ArgumentNullException(nameof(address)) @@ -209,6 +224,7 @@ public static Task PairAsync(this IAdbClient client, IPAddress address, /// The pairing code. /// A which can be used to cancel the asynchronous operation. /// The results from adb. + [MethodImpl((MethodImplOptions)256)] public static Task PairAsync(this IAdbClient client, IPEndPoint endpoint, string code, CancellationToken cancellationToken = default) => endpoint == null ? throw new ArgumentNullException(nameof(endpoint)) @@ -266,6 +282,7 @@ public static Task PairAsync(this IAdbClient client, string host, int po /// The IP address of the remote device. /// A which can be used to cancel the asynchronous operation. /// A which return the results from adb. + [MethodImpl((MethodImplOptions)256)] public static Task ConnectAsync(this IAdbClient client, IPAddress address, CancellationToken cancellationToken = default) => address == null ? throw new ArgumentNullException(nameof(address)) @@ -278,6 +295,7 @@ public static Task ConnectAsync(this IAdbClient client, IPAddress addres /// The IP endpoint at which the adb server on the device is running. /// A which can be used to cancel the asynchronous operation. /// A which return the results from adb. + [MethodImpl((MethodImplOptions)256)] public static Task ConnectAsync(this IAdbClient client, IPEndPoint endpoint, CancellationToken cancellationToken = default) => endpoint == null ? throw new ArgumentNullException(nameof(endpoint)) @@ -313,6 +331,7 @@ public static Task ConnectAsync(this IAdbClient client, string host, int /// A which represents the application to install. /// The arguments to pass to adb install. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task InstallAsync(this IAdbClient client, DeviceData device, Stream apk, params string[] arguments) => client.InstallAsync(device, apk, default, arguments); /// @@ -324,6 +343,7 @@ public static Task ConnectAsync(this IAdbClient client, string host, int /// The package name of the base APK to install. /// The arguments to pass to adb install-create. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task InstallMultipleAsync(this IAdbClient client, DeviceData device, IEnumerable splitAPKs, string packageName, params string[] arguments) => client.InstallMultipleAsync(device, splitAPKs, packageName, default, arguments); @@ -336,6 +356,7 @@ public static Task InstallMultipleAsync(this IAdbClient client, DeviceData devic /// s which represents the split APKs to install. /// The arguments to pass to adb install-create. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task InstallMultipleAsync(this IAdbClient client, DeviceData device, Stream baseAPK, IEnumerable splitAPKs, params string[] arguments) => client.InstallMultipleAsync(device, baseAPK, splitAPKs, default, arguments); @@ -347,6 +368,7 @@ public static Task InstallMultipleAsync(this IAdbClient client, DeviceData devic /// The package name of the baseAPK to install. /// The arguments to pass to adb install-create. /// A which return the session ID + [MethodImpl((MethodImplOptions)256)] public static Task InstallCreateAsync(this IAdbClient client, DeviceData device, string packageName = null, params string[] arguments) => client.InstallCreateAsync(device, packageName, default, arguments); @@ -358,6 +380,7 @@ public static Task InstallCreateAsync(this IAdbClient client, DeviceData /// The length of text to clear. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static async Task ClearInputAsync(this IAdbClient client, DeviceData device, int charCount, CancellationToken cancellationToken = default) { await client.SendKeyEventAsync(device, "KEYCODE_MOVE_END", cancellationToken).ConfigureAwait(false); @@ -371,6 +394,7 @@ public static async Task ClearInputAsync(this IAdbClient client, DeviceData devi /// The device on which to click BACK button. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task ClickBackButtonAsync(this IAdbClient client, DeviceData device, CancellationToken cancellationToken = default) => client.SendKeyEventAsync(device, "KEYCODE_BACK", cancellationToken); /// @@ -380,6 +404,7 @@ public static async Task ClearInputAsync(this IAdbClient client, DeviceData devi /// The device on which to click HOME button. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public static Task ClickHomeButtonAsync(this IAdbClient client, DeviceData device, CancellationToken cancellationToken = default) => client.SendKeyEventAsync(device, "KEYCODE_HOME", cancellationToken); } } diff --git a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs index 71a85734..9a8411fd 100644 --- a/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs +++ b/AdvancedSharpAdbClient/Extensions/AdbClientExtensions.cs @@ -6,6 +6,7 @@ using System; using System.Linq; using System.Net; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient { @@ -26,6 +27,7 @@ public static partial class AdbClientExtensions /// connection from . /// If your requested to start forwarding to local port TCP:0, the port number of the TCP port /// which has been opened. In all other cases, 0. + [MethodImpl((MethodImplOptions)256)] public static int CreateForward(this IAdbClient client, DeviceData device, ForwardSpec local, ForwardSpec remote, bool allowRebind) => client.CreateForward(device, local?.ToString(), remote?.ToString(), allowRebind); @@ -41,6 +43,7 @@ public static int CreateForward(this IAdbClient client, DeviceData device, Forwa /// is already bound through a previous reverse command. /// If your requested to start reverse to remote port TCP:0, the port number of the TCP port /// which has been opened. In all other cases, 0. + [MethodImpl((MethodImplOptions)256)] public static int CreateReverseForward(this IAdbClient client, DeviceData device, ForwardSpec remote, ForwardSpec local, bool allowRebind) => client.CreateReverseForward(device, remote?.ToString(), local?.ToString(), allowRebind); @@ -50,6 +53,7 @@ public static int CreateReverseForward(this IAdbClient client, DeviceData device /// An instance of a class that implements the interface. /// The device on which to remove the reverse port forwarding /// Specification of the remote that was forwarded + [MethodImpl((MethodImplOptions)256)] public static void RemoveReverseForward(this IAdbClient client, DeviceData device, string remote) => client.RemoveReverseForward(device, remote); @@ -60,6 +64,7 @@ public static void RemoveReverseForward(this IAdbClient client, DeviceData devic /// The target of command, such as shell, remount, dev, tcp, local, /// localreserved, localabstract, jdwp, track-jdwp, sync, reverse and so on. /// The command to execute. + [MethodImpl((MethodImplOptions)256)] public static void ExecuteServerCommand(this IAdbClient client, string target, string command) => client.ExecuteServerCommand(target, command, AdbClient.Encoding); @@ -71,6 +76,7 @@ public static void ExecuteServerCommand(this IAdbClient client, string target, s /// localreserved, localabstract, jdwp, track-jdwp, sync, reverse and so on. /// The command to execute. /// The to send command. + [MethodImpl((MethodImplOptions)256)] public static void ExecuteServerCommand(this IAdbClient client, string target, string command, IAdbSocket socket) => client.ExecuteServerCommand(target, command, socket, AdbClient.Encoding); @@ -80,6 +86,7 @@ public static void ExecuteServerCommand(this IAdbClient client, string target, s /// An instance of a class that implements the interface. /// The command to execute. /// The device on which to run the command. + [MethodImpl((MethodImplOptions)256)] public static void ExecuteRemoteCommand(this IAdbClient client, string command, DeviceData device) => client.ExecuteRemoteCommand(command, device, AdbClient.Encoding); @@ -91,6 +98,7 @@ public static void ExecuteRemoteCommand(this IAdbClient client, string command, /// localreserved, localabstract, jdwp, track-jdwp, sync, reverse and so on. /// The command to execute. /// Optionally, a that processes the command output. + [MethodImpl((MethodImplOptions)256)] public static void ExecuteServerCommand(this IAdbClient client, string target, string command, IShellOutputReceiver receiver) => client.ExecuteServerCommand(target, command, receiver, AdbClient.Encoding); @@ -103,6 +111,7 @@ public static void ExecuteServerCommand(this IAdbClient client, string target, s /// The command to execute. /// The to send command. /// Optionally, a that processes the command output. + [MethodImpl((MethodImplOptions)256)] public static void ExecuteServerCommand(this IAdbClient client, string target, string command, IAdbSocket socket, IShellOutputReceiver receiver) => client.ExecuteServerCommand(target, command, socket, receiver, AdbClient.Encoding); @@ -113,6 +122,7 @@ public static void ExecuteServerCommand(this IAdbClient client, string target, s /// The command to execute. /// The device on which to run the command. /// Optionally, a that processes the command output. + [MethodImpl((MethodImplOptions)256)] public static void ExecuteRemoteCommand(this IAdbClient client, string command, DeviceData device, IShellOutputReceiver receiver) => client.ExecuteRemoteCommand(command, device, receiver, AdbClient.Encoding); @@ -126,6 +136,7 @@ public static void ExecuteRemoteCommand(this IAdbClient client, string command, /// If your requested to start forwarding to local port TCP:0, the port number of the TCP port /// which has been opened. In all other cases, 0. /// Failed to submit the forward command. Or Device rejected command: + resp.Message. + [MethodImpl((MethodImplOptions)256)] public static int CreateForward(this IAdbClient client, DeviceData device, int localPort, int remotePort) => client.CreateForward(device, $"tcp:{localPort}", $"tcp:{remotePort}", true); @@ -140,6 +151,7 @@ public static int CreateForward(this IAdbClient client, DeviceData device, int l /// which has been opened. In all other cases, 0. /// The client failed to submit the forward command. /// The device rejected command. The error message will include the error message provided by the device. + [MethodImpl((MethodImplOptions)256)] public static int CreateForward(this IAdbClient client, DeviceData device, int localPort, string remoteSocket) => client.CreateForward(device, $"tcp:{localPort}", $"local:{remoteSocket}", true); @@ -148,6 +160,7 @@ public static int CreateForward(this IAdbClient client, DeviceData device, int l /// /// An instance of a class that implements the interface. /// The device. + [MethodImpl((MethodImplOptions)256)] public static void Reboot(this IAdbClient client, DeviceData device) => client.Reboot(string.Empty, device); /// @@ -157,6 +170,7 @@ public static int CreateForward(this IAdbClient client, DeviceData device, int l /// The IP address of the remote device. /// The pairing code. /// The results from adb. + [MethodImpl((MethodImplOptions)256)] public static string Pair(this IAdbClient client, IPAddress address, string code) => address == null ? throw new ArgumentNullException(nameof(address)) @@ -169,6 +183,7 @@ public static string Pair(this IAdbClient client, IPAddress address, string code /// The DNS endpoint at which the adb server on the device is running. /// The pairing code. /// The results from adb. + [MethodImpl((MethodImplOptions)256)] public static string Pair(this IAdbClient client, IPEndPoint endpoint, string code) => endpoint == null ? throw new ArgumentNullException(nameof(endpoint)) @@ -223,6 +238,7 @@ public static string Pair(this IAdbClient client, string host, int port, string /// An instance of a class that implements the interface. /// The IP address of the remote device. /// The results from adb. + [MethodImpl((MethodImplOptions)256)] public static string Connect(this IAdbClient client, IPAddress address) => address == null ? throw new ArgumentNullException(nameof(address)) @@ -234,6 +250,7 @@ public static string Connect(this IAdbClient client, IPAddress address) => /// An instance of a class that implements the interface. /// The IP endpoint at which the adb server on the device is running. /// The results from adb. + [MethodImpl((MethodImplOptions)256)] public static string Connect(this IAdbClient client, IPEndPoint endpoint) => endpoint == null ? throw new ArgumentNullException(nameof(endpoint)) @@ -266,6 +283,7 @@ public static string Connect(this IAdbClient client, string host, int port = Adb /// An instance of a class that implements the interface. /// The device on which to clear the input text. /// The length of text to clear. + [MethodImpl((MethodImplOptions)256)] public static void ClearInput(this IAdbClient client, DeviceData device, int charCount) { client.SendKeyEvent(device, "KEYCODE_MOVE_END"); @@ -277,6 +295,7 @@ public static void ClearInput(this IAdbClient client, DeviceData device, int cha /// /// An instance of a class that implements the interface. /// The device on which to click BACK button. + [MethodImpl((MethodImplOptions)256)] public static void ClickBackButton(this IAdbClient client, DeviceData device) => client.SendKeyEvent(device, "KEYCODE_BACK"); /// @@ -284,6 +303,7 @@ public static void ClearInput(this IAdbClient client, DeviceData device, int cha /// /// An instance of a class that implements the interface. /// The device on which to click HOME button. + [MethodImpl((MethodImplOptions)256)] public static void ClickHomeButton(this IAdbClient client, DeviceData device) => client.SendKeyEvent(device, "KEYCODE_HOME"); } } diff --git a/AdvancedSharpAdbClient/Extensions/DateTimeExtensions.cs b/AdvancedSharpAdbClient/Extensions/DateTimeExtensions.cs index c38fecab..5b9fb133 100644 --- a/AdvancedSharpAdbClient/Extensions/DateTimeExtensions.cs +++ b/AdvancedSharpAdbClient/Extensions/DateTimeExtensions.cs @@ -3,6 +3,7 @@ // using System; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient { @@ -106,6 +107,7 @@ public static long ToUnixTimeSeconds(this DateTimeOffset dateTimeOffset) /// /// The Unix equivalent to convert to the date. /// A that represents the date. + [MethodImpl((MethodImplOptions)256)] public static DateTime FromUnixEpoch(long time) => Epoch.Add(new TimeSpan(time * 1000_0000)); /// @@ -113,6 +115,7 @@ public static long ToUnixTimeSeconds(this DateTimeOffset dateTimeOffset) /// /// The date to convert to the Unix format. /// A that represents the date, in Unix format. + [MethodImpl((MethodImplOptions)256)] public static long ToUnixEpoch(this DateTime date) => (long)Math.Round(date.ToUniversalTime().Subtract(Epoch).TotalSeconds); } } diff --git a/AdvancedSharpAdbClient/Extensions/ExceptionExtensions.cs b/AdvancedSharpAdbClient/Extensions/ExceptionExtensions.cs index 4ab9d9f9..e214480c 100644 --- a/AdvancedSharpAdbClient/Extensions/ExceptionExtensions.cs +++ b/AdvancedSharpAdbClient/Extensions/ExceptionExtensions.cs @@ -12,6 +12,7 @@ internal static class ExceptionExtensions /// /// The reference type argument to validate as non-null. /// The name of the parameter with which corresponds. + [MethodImpl((MethodImplOptions)256)] public static void ThrowIfNull(object argument, [CallerArgumentExpression(nameof(argument))] string paramName = null) { #if NET6_0_OR_GREATER @@ -30,6 +31,7 @@ public static void ThrowIfNull(object argument, [CallerArgumentExpression(nameof /// The argument to validate as less or equal than . /// The value to compare with . /// The name of the parameter with which corresponds. + [MethodImpl((MethodImplOptions)256)] public static void ThrowIfGreaterThan(T value, T other, [CallerArgumentExpression(nameof(value))] string paramName = null) where T : IComparable { @@ -49,6 +51,7 @@ public static void ThrowIfGreaterThan(T value, T other, [CallerArgumentExpres /// The argument to validate as greater than or equal than . /// The value to compare with . /// The name of the parameter with which corresponds. + [MethodImpl((MethodImplOptions)256)] public static void ThrowIfLessThan(T value, T other, [CallerArgumentExpression(nameof(value))] string paramName = null) where T : IComparable { @@ -67,6 +70,7 @@ public static void ThrowIfLessThan(T value, T other, [CallerArgumentExpressio /// /// The argument to validate as non-negative. /// The name of the parameter with which corresponds. + [MethodImpl((MethodImplOptions)256)] #if NET8_0_OR_GREATER public static void ThrowIfNegative(T value, [CallerArgumentExpression(nameof(value))] string paramName = null) where T : INumberBase @@ -89,6 +93,7 @@ public static void ThrowIfNegative(int value, [CallerArgumentExpression(nameof(v /// The object whose type's full name should be included in any resulting . /// The is . [StackTraceHidden] + [MethodImpl((MethodImplOptions)256)] public static void ThrowIf( #if HAS_INDEXRANGE [DoesNotReturnIf(true)] diff --git a/AdvancedSharpAdbClient/Extensions/Extensions.cs b/AdvancedSharpAdbClient/Extensions/Extensions.cs index 114c7e1d..def5e5ca 100644 --- a/AdvancedSharpAdbClient/Extensions/Extensions.cs +++ b/AdvancedSharpAdbClient/Extensions/Extensions.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading; @@ -120,6 +121,7 @@ public static void Dispose(this WaitHandle waitHandle) /// The type of the elements of . /// An to create an array from. /// An array that contains the elements from the input sequence. + [MethodImpl((MethodImplOptions)256)] public static Task ToArrayAsync(this Task> source) => source.ContinueWith(x => x.Result.ToArray()); @@ -129,6 +131,7 @@ public static Task ToArrayAsync(this TaskThe type of the elements of . /// An to create an array from. /// An array that contains the elements from the input sequence. + [MethodImpl((MethodImplOptions)256)] public static Task ToArrayAsync(this IEnumerable> source) => WhenAll(source); /// @@ -138,6 +141,7 @@ public static Task ToArrayAsync(this TaskA cancellation token to observe while waiting for the task to complete. /// A task that represents the time delay. /// The argument is less than -1. + [MethodImpl((MethodImplOptions)256)] public static Task Delay(int dueTime, CancellationToken cancellationToken = default) => #if NETFRAMEWORK && !NET45_OR_GREATER TaskEx @@ -154,6 +158,7 @@ public static Task Delay(int dueTime, CancellationToken cancellationToken = defa /// A task that represents a proxy for the task returned by . /// The parameter was . /// For information on handling exceptions thrown by task operations, see Exception Handling. + [MethodImpl((MethodImplOptions)256)] public static Task Run(Action function, CancellationToken cancellationToken = default) => #if NETFRAMEWORK && !NET45_OR_GREATER TaskEx @@ -172,6 +177,7 @@ public static Task Run(Action function, CancellationToken cancellationToken = de /// A that represents a proxy for the /// returned by . /// The parameter was . + [MethodImpl((MethodImplOptions)256)] public static Task Run(Func function, CancellationToken cancellationToken = default) => #if NETFRAMEWORK && !NET45_OR_GREATER TaskEx @@ -185,6 +191,7 @@ public static Task Run(Func function, CancellationTok /// /// The tasks to wait on for completion. /// A task that represents the completion of all of the supplied tasks. + [MethodImpl((MethodImplOptions)256)] public static Task WhenAll(IEnumerable tasks) => #if NETFRAMEWORK && !NET45_OR_GREATER TaskEx @@ -199,6 +206,7 @@ public static Task WhenAll(IEnumerable tasks) => /// The type of the completed task. /// The tasks to wait on for completion. /// A task that represents the completion of all of the supplied tasks. + [MethodImpl((MethodImplOptions)256)] public static Task WhenAll(IEnumerable> tasks) => #if NETFRAMEWORK && !NET45_OR_GREATER TaskEx @@ -216,6 +224,7 @@ public static Task WhenAll(IEnumerable> tasks) /// A value task that represents the asynchronous read operation. The value of the /// TResult parameter contains the next line from the text reader, or is null if /// all of the characters have been read. + [MethodImpl((MethodImplOptions)256)] public static Task ReadLineAsync(this TextReader reader, CancellationToken cancellationToken) => #if !NET35 reader.ReadLineAsync(); @@ -231,6 +240,7 @@ public static Task ReadLineAsync(this TextReader reader, CancellationTok /// A task that represents the asynchronous read operation. The value of the TResult /// parameter contains a string with the characters from the current position to /// the end of the stream. + [MethodImpl((MethodImplOptions)256)] public static Task ReadToEndAsync(this TextReader reader, CancellationToken cancellationToken) => #if !NET35 reader.ReadToEndAsync(); @@ -240,6 +250,7 @@ public static Task ReadToEndAsync(this TextReader reader, CancellationTo #endif #endif + [MethodImpl((MethodImplOptions)256)] public static bool IsWindowsPlatform() => #if HAS_RUNTIMEINFORMATION RuntimeInformation.IsOSPlatform(OSPlatform.Windows); @@ -254,6 +265,7 @@ or PlatformID.WinCE or PlatformID.Xbox; #endif + [MethodImpl((MethodImplOptions)256)] public static bool IsUnixPlatform() => #if HAS_RUNTIMEINFORMATION RuntimeInformation.IsOSPlatform(OSPlatform.Linux) diff --git a/AdvancedSharpAdbClient/Extensions/LoggerExtensions.cs b/AdvancedSharpAdbClient/Extensions/LoggerExtensions.cs index 69fb4c58..f4def657 100644 --- a/AdvancedSharpAdbClient/Extensions/LoggerExtensions.cs +++ b/AdvancedSharpAdbClient/Extensions/LoggerExtensions.cs @@ -4,6 +4,7 @@ using AdvancedSharpAdbClient.Logs; using System; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient { @@ -22,10 +23,9 @@ public static class LoggerExtensions /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogDebug(exception, "Error while processing request from {Address}", address) - public static void LogDebug(this ILogger logger, Exception exception, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogDebug(this ILogger logger, Exception exception, string message, params object[] args) => logger.Log(LogLevel.Debug, exception, message, args); - } /// /// Formats and writes a debug log message. @@ -34,10 +34,9 @@ public static void LogDebug(this ILogger logger, Exception exception, string mes /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogDebug("Processing request from {Address}", address) - public static void LogDebug(this ILogger logger, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogDebug(this ILogger logger, string message, params object[] args) => logger.Log(LogLevel.Debug, message, args); - } //------------------------------------------TRACE------------------------------------------// @@ -49,10 +48,9 @@ public static void LogDebug(this ILogger logger, string message, params object[] /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogTrace(exception, "Error while processing request from {Address}", address) - public static void LogTrace(this ILogger logger, Exception exception, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogTrace(this ILogger logger, Exception exception, string message, params object[] args) => logger.Log(LogLevel.Trace, exception, message, args); - } /// /// Formats and writes a trace log message. @@ -61,10 +59,9 @@ public static void LogTrace(this ILogger logger, Exception exception, string mes /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogTrace("Processing request from {Address}", address) - public static void LogTrace(this ILogger logger, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogTrace(this ILogger logger, string message, params object[] args) => logger.Log(LogLevel.Trace, message, args); - } //------------------------------------------INFORMATION------------------------------------------// @@ -76,10 +73,9 @@ public static void LogTrace(this ILogger logger, string message, params object[] /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogInformation(exception, "Error while processing request from {Address}", address) - public static void LogInformation(this ILogger logger, Exception exception, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogInformation(this ILogger logger, Exception exception, string message, params object[] args) => logger.Log(LogLevel.Information, exception, message, args); - } /// /// Formats and writes an informational log message. @@ -88,10 +84,9 @@ public static void LogInformation(this ILogger logger, Exception exception, stri /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogInformation("Processing request from {Address}", address) - public static void LogInformation(this ILogger logger, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogInformation(this ILogger logger, string message, params object[] args) => logger.Log(LogLevel.Information, message, args); - } //------------------------------------------WARNING------------------------------------------// @@ -103,10 +98,9 @@ public static void LogInformation(this ILogger logger, string message, params ob /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogWarning(exception, "Error while processing request from {Address}", address) - public static void LogWarning(this ILogger logger, Exception exception, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogWarning(this ILogger logger, Exception exception, string message, params object[] args) => logger.Log(LogLevel.Warning, exception, message, args); - } /// /// Formats and writes a warning log message. @@ -115,10 +109,9 @@ public static void LogWarning(this ILogger logger, Exception exception, string m /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogWarning("Processing request from {Address}", address) - public static void LogWarning(this ILogger logger, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogWarning(this ILogger logger, string message, params object[] args) => logger.Log(LogLevel.Warning, message, args); - } //------------------------------------------ERROR------------------------------------------// @@ -130,10 +123,9 @@ public static void LogWarning(this ILogger logger, string message, params object /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogError(exception, "Error while processing request from {Address}", address) - public static void LogError(this ILogger logger, Exception exception, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogError(this ILogger logger, Exception exception, string message, params object[] args) => logger.Log(LogLevel.Error, exception, message, args); - } /// /// Formats and writes an error log message. @@ -142,10 +134,9 @@ public static void LogError(this ILogger logger, Exception exception, string mes /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogError("Processing request from {Address}", address) - public static void LogError(this ILogger logger, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogError(this ILogger logger, string message, params object[] args) => logger.Log(LogLevel.Error, message, args); - } //------------------------------------------CRITICAL------------------------------------------// @@ -157,10 +148,9 @@ public static void LogError(this ILogger logger, string message, params object[] /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogCritical(exception, "Error while processing request from {Address}", address) - public static void LogCritical(this ILogger logger, Exception exception, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogCritical(this ILogger logger, Exception exception, string message, params object[] args) => logger.Log(LogLevel.Critical, exception, message, args); - } /// /// Formats and writes a critical log message. @@ -169,10 +159,9 @@ public static void LogCritical(this ILogger logger, Exception exception, string /// Format string of the log message in message template format. Example: "User {User} logged in from {Address}" /// An object array that contains zero or more objects to format. /// logger.LogCritical("Processing request from {Address}", address) - public static void LogCritical(this ILogger logger, string message, params object[] args) - { + [MethodImpl((MethodImplOptions)256)] + public static void LogCritical(this ILogger logger, string message, params object[] args) => logger.Log(LogLevel.Critical, message, args); - } /// /// Formats and writes a log message at the specified log level. @@ -181,6 +170,7 @@ public static void LogCritical(this ILogger logger, string message, params objec /// Entry will be written on this level. /// Format string of the log message. /// An object array that contains zero or more objects to format. + [MethodImpl((MethodImplOptions)256)] public static void Log(this ILogger logger, LogLevel logLevel, string message, params object[] args) => logger.Log(logLevel, null, message, args); } diff --git a/AdvancedSharpAdbClient/Extensions/SocketExtensions.cs b/AdvancedSharpAdbClient/Extensions/SocketExtensions.cs index b53f0ee4..401d96bc 100644 --- a/AdvancedSharpAdbClient/Extensions/SocketExtensions.cs +++ b/AdvancedSharpAdbClient/Extensions/SocketExtensions.cs @@ -4,6 +4,7 @@ using System; using System.Net.Sockets; +using System.Runtime.CompilerServices; using System.Threading; namespace AdvancedSharpAdbClient @@ -24,6 +25,7 @@ public static class SocketExtensions /// A which can be used to cancel the asynchronous task. /// Cancelling the task will also close the socket. /// The number of bytes received. + [MethodImpl((MethodImplOptions)256)] public static Task ReceiveAsync(this Socket socket, byte[] buffer, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.ReceiveAsync(buffer, 0, buffer.Length, socketFlags, cancellationToken); #endif @@ -38,6 +40,7 @@ public static Task ReceiveAsync(this Socket socket, byte[] buffer, SocketFl /// A which can be used to cancel the asynchronous task. /// Cancelling the task will also close the socket. /// The number of bytes received. + [MethodImpl((MethodImplOptions)256)] public static Task ReceiveAsync(this Socket socket, byte[] buffer, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) #if HAS_BUFFERS => socket.ReceiveAsync(buffer.AsMemory(0, size), socketFlags, cancellationToken).AsTask(); @@ -110,6 +113,7 @@ public static Task ReceiveAsync(this Socket socket, byte[] buffer, int offs /// A which can be used to cancel the asynchronous task. /// Cancelling the task will also close the socket. /// The number of bytes received. + [MethodImpl((MethodImplOptions)256)] public static Task SendAsync(this Socket socket, byte[] buffer, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.SendAsync(buffer, 0, buffer.Length, socketFlags, cancellationToken); #endif @@ -124,6 +128,7 @@ public static Task SendAsync(this Socket socket, byte[] buffer, SocketFlags /// A which can be used to cancel the asynchronous task. /// Cancelling the task will also close the socket. /// The number of bytes received. + [MethodImpl((MethodImplOptions)256)] public static Task SendAsync(this Socket socket, byte[] buffer, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) #if HAS_BUFFERS => socket.SendAsync(buffer.AsMemory(0, size), socketFlags, cancellationToken).AsTask(); @@ -191,6 +196,7 @@ public static Task SendAsync(this Socket socket, byte[] buffer, int offset, /// Closes the connection and releases all associated resources. /// /// The to release. + [MethodImpl((MethodImplOptions)256)] public static void Close(this Socket socket) => socket.Dispose(); #endif diff --git a/AdvancedSharpAdbClient/Extensions/StreamExtensions.cs b/AdvancedSharpAdbClient/Extensions/StreamExtensions.cs index 54e837d8..828ae748 100644 --- a/AdvancedSharpAdbClient/Extensions/StreamExtensions.cs +++ b/AdvancedSharpAdbClient/Extensions/StreamExtensions.cs @@ -4,6 +4,7 @@ using System; using System.IO; +using System.Runtime.CompilerServices; using System.Threading; namespace AdvancedSharpAdbClient @@ -21,6 +22,7 @@ public static class StreamExtensions /// An array of bytes. When this method returns, the contents of this region are replaced by the bytes read from the current source. /// The total number of bytes read into the buffer. This can be less than the size of the buffer if that many bytes are not currently available, /// or zero (0) if the buffer's length is zero or the end of the stream has been reached. + [MethodImpl((MethodImplOptions)256)] public static int Read(this Stream stream, byte[] buffer) => stream.Read(buffer, 0, buffer.Length); @@ -29,6 +31,7 @@ public static int Read(this Stream stream, byte[] buffer) => /// /// The stream from which to read data. /// An array of bytes. This method copies the contents of this region to the current stream. + [MethodImpl((MethodImplOptions)256)] public static void Write(this Stream stream, byte[] buffer) => stream.Write(buffer, 0, buffer.Length); @@ -44,6 +47,7 @@ public static void Write(this Stream stream, byte[] buffer) => /// of bytes requested if the number of bytes currently available is less than the requested number, /// or it can be 0 (zero) if length of the buffer is 0 or if the end of the stream has been reached. /// Cancelling the task will also close the stream. + [MethodImpl((MethodImplOptions)256)] public static Task ReadAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default) => stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken); @@ -55,6 +59,7 @@ public static Task ReadAsync(this Stream stream, byte[] buffer, Cancellatio /// The token to monitor for cancellation requests. The default value is . /// A task that represents the asynchronous write operation. /// Cancelling the task will also close the stream. + [MethodImpl((MethodImplOptions)256)] public static Task WriteAsync(this Stream stream, byte[] buffer, CancellationToken cancellationToken = default) => stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken); #endif @@ -68,6 +73,7 @@ public static Task WriteAsync(this Stream stream, byte[] buffer, CancellationTok /// The maximum number of bytes to read. /// The total number of bytes read into the buffer. This can be less than the size of the buffer if that many bytes are not currently available, /// or zero (0) if the buffer's length is zero or the end of the stream has been reached. + [MethodImpl((MethodImplOptions)256)] public static int Read(this Stream stream, byte[] buffer, int count) => stream.Read(buffer, 0, count); @@ -77,6 +83,7 @@ public static int Read(this Stream stream, byte[] buffer, int count) => /// The stream from which to read data. /// An array of bytes. This method copies bytes from buffer to the current stream. /// The number of bytes to be written to the current stream. + [MethodImpl((MethodImplOptions)256)] public static void Write(this Stream stream, byte[] buffer, int count) => stream.Write(buffer, 0, count); @@ -94,6 +101,7 @@ public static void Write(this Stream stream, byte[] buffer, int count) => /// of bytes requested if the number of bytes currently available is less than the requested number, /// or it can be 0 (zero) if is 0 or if the end of the stream has been reached. /// Cancelling the task will also close the stream. + [MethodImpl((MethodImplOptions)256)] public static Task ReadAsync(this Stream stream, byte[] buffer, int count, CancellationToken cancellationToken = default) => stream.ReadAsync(buffer, 0, count, cancellationToken); @@ -107,6 +115,7 @@ public static Task ReadAsync(this Stream stream, byte[] buffer, int count, /// The token to monitor for cancellation requests. The default value is . /// A task that represents the asynchronous write operation. /// Cancelling the task will also close the stream. + [MethodImpl((MethodImplOptions)256)] public static Task WriteAsync(this Stream stream, byte[] buffer, int count, CancellationToken cancellationToken = default) => stream.WriteAsync(buffer, 0, count, cancellationToken); diff --git a/AdvancedSharpAdbClient/Extensions/StringExtensions.cs b/AdvancedSharpAdbClient/Extensions/StringExtensions.cs index b2fec310..693d82f7 100644 --- a/AdvancedSharpAdbClient/Extensions/StringExtensions.cs +++ b/AdvancedSharpAdbClient/Extensions/StringExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Text; namespace AdvancedSharpAdbClient @@ -46,6 +47,7 @@ public static bool IsNullOrWhiteSpace(string value) /// One of the enumeration values that specifies the rules to use in the comparison. /// if the parameter occurs within this string, /// or if is the empty string (""); otherwise, . + [MethodImpl((MethodImplOptions)256)] public static bool Contains(this string text, string value, StringComparison comparisonType) => text.IndexOf(value, comparisonType) != -1; @@ -56,6 +58,7 @@ public static bool Contains(this string text, string value, StringComparison com /// A character that delimits the substrings in this string. /// A bitwise combination of the enumeration values that specifies whether to trim substrings and include empty substrings. /// An array whose elements contain the substrings from this instance that are delimited by . + [MethodImpl((MethodImplOptions)256)] public static string[] Split(this string text, char separator, StringSplitOptions options = StringSplitOptions.None) => text.Split(new[] { separator }, options); @@ -70,6 +73,7 @@ public static string[] Split(this string text, char separator, StringSplitOption /// The maximum number of elements expected in the array. /// A bitwise combination of the enumeration values that specifies whether to trim substrings and include empty substrings. /// An array that contains at most count substrings from this instance that are delimited by . + [MethodImpl((MethodImplOptions)256)] public static string[] Split(this string text, char separator, int count, StringSplitOptions options = StringSplitOptions.None) => text.Split(new[] { separator }, count, options); @@ -79,6 +83,7 @@ public static string[] Split(this string text, char separator, int count, String /// A sequence in which to locate a value. /// The character to compare. /// if matches the beginning of this string; otherwise, . + [MethodImpl((MethodImplOptions)256)] public static bool StartsWith(this string text, char value) => text.StartsWith(new string([value])); /// @@ -87,6 +92,7 @@ public static string[] Split(this string text, char separator, int count, String /// A sequence in which to locate a value. /// The character to compare to the character at the end of this instance. /// if matches the end of this instance; otherwise, . + [MethodImpl((MethodImplOptions)256)] public static bool EndsWith(this string text, char value) => text.EndsWith(new string([value])); #endif diff --git a/AdvancedSharpAdbClient/Interfaces/IDeviceMonitor.cs b/AdvancedSharpAdbClient/Interfaces/IDeviceMonitor.cs index 15072324..1a84a083 100644 --- a/AdvancedSharpAdbClient/Interfaces/IDeviceMonitor.cs +++ b/AdvancedSharpAdbClient/Interfaces/IDeviceMonitor.cs @@ -30,6 +30,11 @@ public partial interface IDeviceMonitor : IDisposable /// event EventHandler DeviceConnected; + /// + /// Occurs when the list of the connected devices has changed. + /// + event EventHandler DeviceListChanged; + /// /// Occurs when a device has disconnected from the Android Debug Bridge. /// diff --git a/AdvancedSharpAdbClient/Logs/AndroidLogEntry.cs b/AdvancedSharpAdbClient/Logs/AndroidLogEntry.cs index 8a5dfcf7..d85ed6e5 100644 --- a/AdvancedSharpAdbClient/Logs/AndroidLogEntry.cs +++ b/AdvancedSharpAdbClient/Logs/AndroidLogEntry.cs @@ -3,6 +3,7 @@ // using System.Collections.Generic; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient.Logs { @@ -55,6 +56,7 @@ public override string ToString() => /// /// The value to convert. /// A that represents in the system log. + [MethodImpl((MethodImplOptions)256)] private static char FormatPriority(Priority value) => PriorityFormatters?.TryGetValue(value, out char result) == true ? result : '?'; } diff --git a/AdvancedSharpAdbClient/Logs/LoggerProvider.cs b/AdvancedSharpAdbClient/Logs/LoggerProvider.cs index f2bc3026..bb7eb0b4 100644 --- a/AdvancedSharpAdbClient/Logs/LoggerProvider.cs +++ b/AdvancedSharpAdbClient/Logs/LoggerProvider.cs @@ -2,6 +2,8 @@ // Copyright (c) The Android Open Source Project, Ryan Conrad, Quamotion, yungd1plomat, wherewhere. All rights reserved. // +using System.Runtime.CompilerServices; + namespace AdvancedSharpAdbClient.Logs { /// @@ -15,6 +17,7 @@ public static class LoggerProvider /// Sets the current log provider based on logger factory. /// /// The logger factory. + [MethodImpl((MethodImplOptions)256)] public static void SetLogProvider(ILoggerFactory loggerFactory) => _loggerFactory = loggerFactory; /// @@ -22,6 +25,7 @@ public static class LoggerProvider /// /// The category name for messages produced by the logger. /// A new instance. + [MethodImpl((MethodImplOptions)256)] public static ILogger CreateLogger(string category) => _loggerFactory == null ? NullLogger.Instance : _loggerFactory.CreateLogger(category); /// @@ -29,6 +33,7 @@ public static class LoggerProvider /// /// The type. /// The that was created + [MethodImpl((MethodImplOptions)256)] public static ILogger CreateLogger() => _loggerFactory == null ? NullLogger.Instance : _loggerFactory.CreateLogger(); } } diff --git a/AdvancedSharpAdbClient/Models/AdbResponse.cs b/AdvancedSharpAdbClient/Models/AdbResponse.cs index f693c3ea..beb30138 100644 --- a/AdvancedSharpAdbClient/Models/AdbResponse.cs +++ b/AdvancedSharpAdbClient/Models/AdbResponse.cs @@ -3,6 +3,7 @@ // using System; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient { @@ -62,6 +63,7 @@ namespace AdvancedSharpAdbClient /// /// The error message returned by adb. /// A new object that represents the error. + [MethodImpl((MethodImplOptions)256)] public static AdbResponse FromError(string message) => new(message) { IOSuccess = true, @@ -91,16 +93,7 @@ public readonly bool Equals(AdbResponse other) => /// Gets the hash code for the current . /// /// A hash code for the current . - public override readonly int GetHashCode() - { - int hash = 17; - hash = (hash * 23) + IOSuccess.GetHashCode(); - hash = (hash * 23) + Message == null ? 0 : Message.GetHashCode(); - hash = (hash * 23) + Okay.GetHashCode(); - hash = (hash * 23) + Timeout.GetHashCode(); - - return hash; - } + public override readonly int GetHashCode() => HashCode.Combine(IOSuccess, Message, Okay, Timeout); /// /// Returns a that represents the current . diff --git a/AdvancedSharpAdbClient/Models/Area.cs b/AdvancedSharpAdbClient/Models/Area.cs index 1fc55e52..c69345ae 100644 --- a/AdvancedSharpAdbClient/Models/Area.cs +++ b/AdvancedSharpAdbClient/Models/Area.cs @@ -1,4 +1,5 @@ using System; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient { @@ -123,6 +124,7 @@ public Area(Windows.Foundation.Point location, Windows.Foundation.Size size) /// The x-coordinate of the lower-right corner of this structure. /// The y-coordinate of the lower-right corner of this structure. /// The new that this method creates. + [MethodImpl((MethodImplOptions)256)] public static Area FromLTRB(int left, int top, int right, int bottom) => new(left, top, unchecked(right - left), unchecked(bottom - top)); @@ -322,6 +324,7 @@ public int Height /// Converts a to a by performing a ceiling operation on all the coordinates. /// /// The structure to be converted. + [MethodImpl((MethodImplOptions)256)] public static Area Ceiling(RectangleF value) { unchecked @@ -338,6 +341,7 @@ public static Area Ceiling(RectangleF value) /// Converts a to a by performing a truncate operation on all the coordinates. /// /// The structure to be converted. + [MethodImpl((MethodImplOptions)256)] public static Area Truncate(RectangleF value) { unchecked @@ -354,6 +358,7 @@ public static Area Truncate(RectangleF value) /// Converts a to a by performing a round operation on all the coordinates. /// /// The structure to be converted. + [MethodImpl((MethodImplOptions)256)] public static Area Round(RectangleF value) { unchecked @@ -373,6 +378,7 @@ public static Area Round(RectangleF value) /// Converts a to a by performing a ceiling operation on all the coordinates. /// /// The structure to be converted. + [MethodImpl((MethodImplOptions)256)] public static Area Ceiling(Rect value) { unchecked @@ -389,6 +395,7 @@ public static Area Ceiling(Rect value) /// Converts a to a by performing a truncate operation on all the coordinates. /// /// The structure to be converted. + [MethodImpl((MethodImplOptions)256)] public static Area Truncate(Rect value) { unchecked @@ -405,6 +412,7 @@ public static Area Truncate(Rect value) /// Converts a to a by performing a round operation on all the coordinates. /// /// The structure to be converted. + [MethodImpl((MethodImplOptions)256)] public static Area Round(Rect value) { unchecked @@ -427,6 +435,7 @@ public static Area Round(Rect value) /// The y-coordinate of the point to test. /// This method returns if the point defined by and /// is contained within this structure; otherwise . + [MethodImpl((MethodImplOptions)256)] public readonly bool Contains(int x, int y) => X <= x && x < X + Width && Y <= y && y < Y + Height; /// @@ -436,6 +445,7 @@ public static Area Round(Rect value) /// The to test. /// This method returns if the point represented by /// is contained within this structure; otherwise . + [MethodImpl((MethodImplOptions)256)] public readonly bool Contains(Cords pt) => Contains(pt.X, pt.Y); /// @@ -445,6 +455,7 @@ public static Area Round(Rect value) /// The to test. /// This method returns if the rectangular region represented by /// is entirely contained within this structure; otherwise . + [MethodImpl((MethodImplOptions)256)] public readonly bool Contains(Area rect) => (X <= rect.X) && (rect.X + rect.Width <= X + Width) && (Y <= rect.Y) && (rect.Y + rect.Height <= Y + Height); @@ -453,18 +464,14 @@ public readonly bool Contains(Area rect) => /// Returns the hash code for this structure. /// /// An integer that represents the hash code for this rectangle. - public override readonly int GetHashCode() => -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - HashCode.Combine(X, Y, Width, Height); -#else - X ^ Y ^ Width ^ Height; -#endif + public override readonly int GetHashCode() => HashCode.Combine(X, Y, Width, Height); /// /// Inflates this by the specified amount. /// /// The amount to inflate this horizontally. /// The amount to inflate this vertically. + [MethodImpl((MethodImplOptions)256)] public void Inflate(int width, int height) { unchecked @@ -482,6 +489,7 @@ public void Inflate(int width, int height) /// Inflates this by the specified amount. /// /// The amount to inflate this rectangle. + [MethodImpl((MethodImplOptions)256)] public void Inflate(System.Drawing.Size size) => Inflate(size.Width, size.Height); #endif @@ -490,6 +498,7 @@ public void Inflate(int width, int height) /// Inflates this by the specified amount. /// /// The amount to inflate this rectangle. + [MethodImpl((MethodImplOptions)256)] public void Inflate(Windows.Foundation.Size size) => Inflate(unchecked((int)size.Width), unchecked((int)size.Height)); #endif @@ -499,6 +508,7 @@ public void Inflate(int width, int height) /// The with which to start. This rectangle is not modified. /// The amount to inflate this horizontally. /// The amount to inflate this vertically. + [MethodImpl((MethodImplOptions)256)] public static Area Inflate(Area rect, int x, int y) { Area r = rect; @@ -542,6 +552,7 @@ public static Area Intersect(Area a, Area b) /// /// The rectangle to test. /// This method returns if there is any intersection, otherwise . + [MethodImpl((MethodImplOptions)256)] public readonly bool IntersectsWith(Area rect) => (rect.X < X + Width) && (X < rect.X + rect.Width) && (rect.Y < Y + Height) && (Y < rect.Y + rect.Height); @@ -566,6 +577,7 @@ public static Area Union(Area a, Area b) /// Adjusts the location of this rectangle by the specified amount. /// /// Amount to offset the location. + [MethodImpl((MethodImplOptions)256)] public void Offset(Cords pos) => Offset(pos.X, pos.Y); /// @@ -573,6 +585,7 @@ public static Area Union(Area a, Area b) /// /// The horizontal offset. /// The vertical offset. + [MethodImpl((MethodImplOptions)256)] public void Offset(int x, int y) { unchecked diff --git a/AdvancedSharpAdbClient/Models/Cords.cs b/AdvancedSharpAdbClient/Models/Cords.cs index 14b0869a..37c9e3e2 100644 --- a/AdvancedSharpAdbClient/Models/Cords.cs +++ b/AdvancedSharpAdbClient/Models/Cords.cs @@ -3,6 +3,7 @@ // using System; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient { @@ -227,6 +228,7 @@ public Cords(Windows.Foundation.Size sz) /// The to add. /// The to add. /// The that is the result of the addition operation. + [MethodImpl((MethodImplOptions)256)] public static Cords Add(Cords pt, System.Drawing.Size sz) => new(unchecked(pt.X + sz.Width), unchecked(pt.Y + sz.Height)); /// @@ -235,6 +237,7 @@ public Cords(Windows.Foundation.Size sz) /// The to be subtracted from. /// The to subtract from the Point. /// The that is the result of the subtraction operation. + [MethodImpl((MethodImplOptions)256)] public static Cords Subtract(Cords pt, System.Drawing.Size sz) => new(unchecked(pt.X - sz.Width), unchecked(pt.Y - sz.Height)); /// @@ -242,6 +245,7 @@ public Cords(Windows.Foundation.Size sz) /// /// The to convert. /// The this method converts to. + [MethodImpl((MethodImplOptions)256)] public static Cords Ceiling(System.Drawing.PointF value) => new(unchecked((int)Math.Ceiling(value.X)), unchecked((int)Math.Ceiling(value.Y))); /// @@ -249,6 +253,7 @@ public Cords(Windows.Foundation.Size sz) /// /// The to convert. /// The this method converts to. + [MethodImpl((MethodImplOptions)256)] public static Cords Truncate(System.Drawing.PointF value) => new(unchecked((int)value.X), unchecked((int)value.Y)); /// @@ -256,6 +261,7 @@ public Cords(Windows.Foundation.Size sz) /// /// The to convert. /// The this method converts to. + [MethodImpl((MethodImplOptions)256)] public static Cords Round(System.Drawing.PointF value) => new(unchecked((int)Math.Round(value.X)), unchecked((int)Math.Round(value.Y))); #endif @@ -267,6 +273,7 @@ public Cords(Windows.Foundation.Size sz) /// The to add. /// The to add. /// The that is the result of the addition operation. + [MethodImpl((MethodImplOptions)256)] public static Cords Add(Cords pt, Windows.Foundation.Size sz) => new(unchecked((int)(pt.X + sz.Width)), unchecked((int)(pt.Y + sz.Height))); /// @@ -275,6 +282,7 @@ public Cords(Windows.Foundation.Size sz) /// The to be subtracted from. /// The to subtract from the Point. /// The that is the result of the subtraction operation. + [MethodImpl((MethodImplOptions)256)] public static Cords Subtract(Cords pt, Windows.Foundation.Size sz) => new(unchecked((int)(pt.X - sz.Width)), unchecked((int)(pt.Y - sz.Height))); /// @@ -282,6 +290,7 @@ public Cords(Windows.Foundation.Size sz) /// /// The to convert. /// The this method converts to. + [MethodImpl((MethodImplOptions)256)] public static Cords Ceiling(Windows.Foundation.Point value) => new(unchecked((int)Math.Ceiling(value.X)), unchecked((int)Math.Ceiling(value.Y))); /// @@ -289,6 +298,7 @@ public Cords(Windows.Foundation.Size sz) /// /// The to convert. /// The this method converts to. + [MethodImpl((MethodImplOptions)256)] public static Cords Truncate(Windows.Foundation.Point value) => new(unchecked((int)value.X), unchecked((int)value.Y)); /// @@ -296,6 +306,7 @@ public Cords(Windows.Foundation.Size sz) /// /// The to convert. /// The this method converts to. + [MethodImpl((MethodImplOptions)256)] public static Cords Round(Windows.Foundation.Point value) => new(unchecked((int)Math.Round(value.X)), unchecked((int)Math.Round(value.Y))); #pragma warning restore CS0419 // cref 特性中有不明确的引用 #endif @@ -320,18 +331,14 @@ public Cords(Windows.Foundation.Size sz) /// Returns a hash code for this . /// /// An integer value that specifies a hash value for this . - public override readonly int GetHashCode() => -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - HashCode.Combine(X, Y); -#else - X ^ Y; -#endif + public override readonly int GetHashCode() => HashCode.Combine(X, Y); /// /// Translates this by the specified amount. /// /// The amount to offset the x-coordinate. /// The amount to offset the y-coordinate. + [MethodImpl((MethodImplOptions)256)] public void Offset(int dx, int dy) { unchecked @@ -345,6 +352,7 @@ public void Offset(int dx, int dy) /// Translates this by the specified amount. /// /// The used offset this . + [MethodImpl((MethodImplOptions)256)] public void Offset(Cords p) => Offset(p.X, p.Y); /// @@ -364,8 +372,10 @@ public readonly void Deconstruct(out int cx, out int cy) cy = Y; } + [MethodImpl((MethodImplOptions)256)] private static short HighInt16(int n) => unchecked((short)((n >> 16) & 0xffff)); + [MethodImpl((MethodImplOptions)256)] private static short LowInt16(int n) => unchecked((short)(n & 0xffff)); } } diff --git a/AdvancedSharpAdbClient/Models/DeviceData.cs b/AdvancedSharpAdbClient/Models/DeviceData.cs index 6a510c5f..75c99d1a 100644 --- a/AdvancedSharpAdbClient/Models/DeviceData.cs +++ b/AdvancedSharpAdbClient/Models/DeviceData.cs @@ -3,6 +3,8 @@ // using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; namespace AdvancedSharpAdbClient @@ -10,7 +12,7 @@ namespace AdvancedSharpAdbClient /// /// Represents a device that is connected to the Android Debug Bridge. /// - public partial class DeviceData + public partial class DeviceData : IEquatable { /// /// A regular expression that can be used to parse the device information that is returned by the Android Debut Bridge. @@ -104,8 +106,41 @@ public DeviceData(string data) /// /// The data retrieved from the Android Debug Bridge that represents a device. /// A object that represents the device. + [MethodImpl((MethodImplOptions)256)] public static DeviceData CreateFromAdbData(string data) => new(data); + /// + public override bool Equals(object obj) => Equals(obj as DeviceData); + + /// + public bool Equals(DeviceData other) => + other is not null + && Serial == other.Serial + && State == other.State + && Model == other.Model + && Product == other.Product + && Name == other.Name + && Features == other.Features + && Usb == other.Usb + && TransportId == other.TransportId + && Message == other.Message; + + /// + public override int GetHashCode() + { + HashCode hash = new(); + hash.Add(Serial); + hash.Add(State); + hash.Add(Model); + hash.Add(Product); + hash.Add(Name); + hash.Add(Features); + hash.Add(Usb); + hash.Add(TransportId); + hash.Add(Message); + return hash.ToHashCode(); + } + /// public override string ToString() => Serial; @@ -145,6 +180,7 @@ internal static DeviceState GetStateFromString(string state) [GeneratedRegex(DeviceDataRegexString, RegexOptions.IgnoreCase)] private static partial Regex DeviceDataRegex(); #else + [MethodImpl((MethodImplOptions)256)] private static Regex DeviceDataRegex() => new(DeviceDataRegexString, RegexOptions.IgnoreCase); #endif } diff --git a/AdvancedSharpAdbClient/Models/DnsEndPoint.cs b/AdvancedSharpAdbClient/Models/DnsEndPoint.cs index 9bd51f32..da375e03 100644 --- a/AdvancedSharpAdbClient/Models/DnsEndPoint.cs +++ b/AdvancedSharpAdbClient/Models/DnsEndPoint.cs @@ -1,5 +1,4 @@ #if NETFRAMEWORK && !NET40_OR_GREATER -using AdvancedSharpAdbClient.Exceptions; using System; using System.Net; using System.Net.Sockets; diff --git a/AdvancedSharpAdbClient/Models/Element.cs b/AdvancedSharpAdbClient/Models/Element.cs index 74029e3c..1ea53d1d 100644 --- a/AdvancedSharpAdbClient/Models/Element.cs +++ b/AdvancedSharpAdbClient/Models/Element.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Threading; using System.Xml; @@ -191,6 +192,7 @@ IEnumerable FindElements() /// The current device containing the element. /// The of the element. /// The new that this method creates. + [MethodImpl((MethodImplOptions)256)] public static Element FromXmlNode(IAdbClient client, DeviceData device, XmlNode xmlNode) => xmlNode.Attributes["bounds"] != null ? new Element(client, device, xmlNode) : null; @@ -202,6 +204,7 @@ public static Element FromXmlNode(IAdbClient client, DeviceData device, XmlNode /// The current device containing the element. /// The of the element. /// The new that this method creates. + [MethodImpl((MethodImplOptions)256)] public static Element FromIXmlNode(IAdbClient client, DeviceData device, Windows.Data.Xml.Dom.IXmlNode xmlNode) => xmlNode.Attributes?.GetNamedItem("bounds") != null ? new Element(client, device, xmlNode) : null; #endif @@ -209,11 +212,13 @@ public static Element FromIXmlNode(IAdbClient client, DeviceData device, Windows /// /// Gets the count of in this element. /// + [MethodImpl((MethodImplOptions)256)] public virtual int GetChildCount() => Children.Count() + Children.Select(x => x.GetChildCount()).Sum(); /// /// Clicks on this coordinates. /// + [MethodImpl((MethodImplOptions)256)] public void Click() => Client.Click(Device, Center); /// @@ -229,6 +234,7 @@ public void SendText(string text) /// /// Clear the input text. Use if the element is focused. /// + [MethodImpl((MethodImplOptions)256)] public void ClearInput() => ClearInput(Text.Length); /// @@ -246,6 +252,7 @@ public void ClearInput(int charCount) /// Clicks on this coordinates. /// /// A which can be used to cancel the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public Task ClickAsync(CancellationToken cancellationToken = default) => Client.ClickAsync(Device, Center, cancellationToken); @@ -266,6 +273,7 @@ public async Task SendTextAsync(string text, CancellationToken cancellationToken /// /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public Task ClearInputAsync(CancellationToken cancellationToken = default) => ClearInputAsync(Text.Length, cancellationToken); @@ -312,6 +320,7 @@ public Element FindDescendant(Func predicate) /// /// The predicatee to use to match the descendant nodes. /// The descendant (or self) that was found, or . + [MethodImpl((MethodImplOptions)256)] public Element FindDescendantOrSelf(Func predicate) => predicate(this) ? this : FindDescendant(predicate); @@ -354,18 +363,9 @@ other is not null /// public override int GetHashCode() => -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - HashCode.Combine(Client, Device, Node == null ? HashCode.Combine(Bounds, Attributes) : Node.GetHashCode()); -#else - Client.GetHashCode() - ^ Device.GetHashCode() - ^ (Node == null - ? Bounds.GetHashCode() - ^ (Attributes == null - ? 1 - : Attributes.GetHashCode()) - : Node.GetHashCode()); -#endif + Node == null + ? HashCode.Combine(Client, Device, Bounds, Attributes) + : HashCode.Combine(Client, Device, Node); /// public override string ToString() => diff --git a/AdvancedSharpAdbClient/Models/FileStatistics.cs b/AdvancedSharpAdbClient/Models/FileStatistics.cs index 88a38419..8822925e 100644 --- a/AdvancedSharpAdbClient/Models/FileStatistics.cs +++ b/AdvancedSharpAdbClient/Models/FileStatistics.cs @@ -9,7 +9,7 @@ namespace AdvancedSharpAdbClient /// /// Contains information about a file on the remote device. /// - public class FileStatistics + public class FileStatistics : IEquatable { /// /// Initializes a new instance of the class. @@ -41,5 +41,19 @@ public FileStatistics() { } /// /// The of the current object. public override string ToString() => Path; + + /// + public override bool Equals(object obj) => Equals(obj as FileStatistics); + + /// + public bool Equals(FileStatistics other) => + other is not null + && Path == other.Path + && FileType == other.FileType + && Size == other.Size + && Time == other.Time; + + /// + public override int GetHashCode() => HashCode.Combine(Path, FileType, Size, Time); } } diff --git a/AdvancedSharpAdbClient/Models/ForwardData.cs b/AdvancedSharpAdbClient/Models/ForwardData.cs index 0bc64481..019928fc 100644 --- a/AdvancedSharpAdbClient/Models/ForwardData.cs +++ b/AdvancedSharpAdbClient/Models/ForwardData.cs @@ -2,12 +2,15 @@ // Copyright (c) The Android Open Source Project, Ryan Conrad, Quamotion, yungd1plomat, wherewhere. All rights reserved. // +using System; +using System.Runtime.CompilerServices; + namespace AdvancedSharpAdbClient { /// /// Contains information about port forwarding configured by the Android Debug Bridge. /// - public class ForwardData + public class ForwardData : IEquatable { /// /// Initializes a new instance of the class. @@ -69,8 +72,22 @@ public ForwardData(string value) /// /// The value to parse. /// A object that represents the port forwarding information contained in . + [MethodImpl((MethodImplOptions)256)] public static ForwardData FromString(string value) => value == null ? null : new ForwardData(value); + /// + public override bool Equals(object obj) => Equals(obj as ForwardData); + + /// + public bool Equals(ForwardData other) => + other is not null + && SerialNumber == other.SerialNumber + && Local == other.Local + && Remote == other.Remote; + + /// + public override int GetHashCode() => HashCode.Combine(SerialNumber, Local, Remote); + /// public override string ToString() => $"{SerialNumber} {Local} {Remote}"; } diff --git a/AdvancedSharpAdbClient/Models/ForwardSpec.cs b/AdvancedSharpAdbClient/Models/ForwardSpec.cs index 5eb4aa55..2d860c9a 100644 --- a/AdvancedSharpAdbClient/Models/ForwardSpec.cs +++ b/AdvancedSharpAdbClient/Models/ForwardSpec.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient { @@ -116,6 +117,7 @@ or ForwardProtocol.LocalReserved /// /// A which represents a . /// A which represents . + [MethodImpl((MethodImplOptions)256)] public static ForwardSpec Parse(string spec) => new(spec); /// @@ -136,15 +138,7 @@ or ForwardProtocol.LocalReserved } /// - public override int GetHashCode() => -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - HashCode.Combine((int)Protocol, Port, ProcessId, SocketName == null ? 1 : SocketName.GetHashCode()); -#else - (int)Protocol - ^ Port - ^ ProcessId - ^ (SocketName == null ? 1 : SocketName.GetHashCode()); -#endif + public override int GetHashCode() => HashCode.Combine(Protocol, Port, ProcessId, SocketName); /// public override bool Equals(object obj) => Equals(obj as ForwardSpec); diff --git a/AdvancedSharpAdbClient/Models/Framebuffer.cs b/AdvancedSharpAdbClient/Models/Framebuffer.cs index 8f43f88c..7d8b8398 100644 --- a/AdvancedSharpAdbClient/Models/Framebuffer.cs +++ b/AdvancedSharpAdbClient/Models/Framebuffer.cs @@ -4,6 +4,7 @@ using System; using System.Net; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; @@ -270,6 +271,7 @@ public void Dispose() /// /// Throws an exception if this has been disposed. /// + [MethodImpl((MethodImplOptions)256)] protected virtual void EnsureNotDisposed() => ExceptionExtensions.ThrowIf(disposed, this); } } diff --git a/AdvancedSharpAdbClient/Models/FramebufferHeader.cs b/AdvancedSharpAdbClient/Models/FramebufferHeader.cs index 7376a64a..04214d76 100644 --- a/AdvancedSharpAdbClient/Models/FramebufferHeader.cs +++ b/AdvancedSharpAdbClient/Models/FramebufferHeader.cs @@ -4,6 +4,7 @@ using System; using System.IO; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -130,6 +131,7 @@ public FramebufferHeader(byte[] data) /// /// The data that feeds the struct. /// A new object. + [MethodImpl((MethodImplOptions)256)] public static FramebufferHeader Read(byte[] data) => new(data); #if HAS_DRAWING diff --git a/AdvancedSharpAdbClient/Models/HashCode.cs b/AdvancedSharpAdbClient/Models/HashCode.cs new file mode 100644 index 00000000..ebad20d2 --- /dev/null +++ b/AdvancedSharpAdbClient/Models/HashCode.cs @@ -0,0 +1,562 @@ +#if !NETCOREAPP2_1_OR_GREATER && !NETSTANDARD2_1_OR_GREATER +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/* + +The xxHash32 implementation is based on the code published by Yann Collet: +https://raw.githubusercontent.com/Cyan4973/xxHash/5c174cfa4e45a42f94082dc0d4539b39696afea1/xxhash.c + + xxHash - Fast Hash algorithm + Copyright (C) 2012-2016, Yann Collet + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - xxHash homepage: http://www.xxhash.com + - xxHash source repository : https://github.com/Cyan4973/xxHash + +*/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace AdvancedSharpAdbClient +{ + // xxHash32 is used for the hash code. + // https://github.com/Cyan4973/xxHash + + /// + /// Combines the hash code for multiple values into a single hash code. + /// + public struct HashCode + { + private static readonly uint s_seed = GenerateGlobalSeed(); + + private const uint Prime1 = 2654435761U; + private const uint Prime2 = 2246822519U; + private const uint Prime3 = 3266489917U; + private const uint Prime4 = 668265263U; + private const uint Prime5 = 374761393U; + + private uint _v1, _v2, _v3, _v4; + private uint _queue1, _queue2, _queue3; + private uint _length; + + [MethodImpl((MethodImplOptions)256)] + private static uint GenerateGlobalSeed() => (uint)new Random().Next(int.MinValue, int.MaxValue); + + /// + /// Diffuses the hash code returned by the specified value. + /// + /// The type of the value to add the hash code. + /// The value to add to the hash code. + /// The hash code that represents the single value. + public static int Combine(T1 value1) + { + // Provide a way of diffusing bits from something with a limited + // input hash space. For example, many enums only have a few + // possible hashes, only using the bottom few bits of the code. Some + // collections are built on the assumption that hashes are spread + // over a larger space, so diffusing the bits may help the + // collection work more efficiently. + + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + + uint hash = MixEmptyState(); + hash += 4; + + hash = QueueRound(hash, hc1); + + hash = MixFinal(hash); + return (int)hash; + } + + /// + /// Combines two values into a hash code. + /// + /// The type of the first value to combine into the hash code. + /// The type of the second value to combine into the hash code. + /// The first value to combine into the hash code. + /// The second value to combine into the hash code. + /// The hash code that represents the two values. + public static int Combine(T1 value1, T2 value2) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + + uint hash = MixEmptyState(); + hash += 8; + + hash = QueueRound(hash, hc1); + hash = QueueRound(hash, hc2); + + hash = MixFinal(hash); + return (int)hash; + } + + /// + /// Combines three values into a hash code. + /// + /// The type of the first value to combine into the hash code. + /// The type of the second value to combine into the hash code. + /// The type of the third value to combine into the hash code. + /// The first value to combine into the hash code. + /// The second value to combine into the hash code. + /// The third value to combine into the hash code. + /// The hash code that represents the three values. + public static int Combine(T1 value1, T2 value2, T3 value3) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + + uint hash = MixEmptyState(); + hash += 12; + + hash = QueueRound(hash, hc1); + hash = QueueRound(hash, hc2); + hash = QueueRound(hash, hc3); + + hash = MixFinal(hash); + return (int)hash; + } + + /// + /// Combines four values into a hash code. + /// + /// The type of the first value to combine into the hash code. + /// The type of the second value to combine into the hash code. + /// The type of the third value to combine into the hash code. + /// The type of the fourth value to combine into the hash code. + /// The first value to combine into the hash code. + /// The second value to combine into the hash code. + /// The third value to combine into the hash code. + /// The fourth value to combine into the hash code. + /// The hash code that represents the four values. + public static int Combine(T1 value1, T2 value2, T3 value3, T4 value4) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + uint hc4 = (uint)(value4?.GetHashCode() ?? 0); + + Initialize(out uint v1, out uint v2, out uint v3, out uint v4); + + v1 = Round(v1, hc1); + v2 = Round(v2, hc2); + v3 = Round(v3, hc3); + v4 = Round(v4, hc4); + + uint hash = MixState(v1, v2, v3, v4); + hash += 16; + + hash = MixFinal(hash); + return (int)hash; + } + + /// + /// Combines five values into a hash code. + /// + /// The type of the first value to combine into the hash code. + /// The type of the second value to combine into the hash code. + /// The type of the third value to combine into the hash code. + /// The type of the fourth value to combine into the hash code. + /// The type of the fifth value to combine into the hash code. + /// The first value to combine into the hash code. + /// The second value to combine into the hash code. + /// The third value to combine into the hash code. + /// The fourth value to combine into the hash code. + /// The fifth value to combine into the hash code. + /// The hash code that represents the five values. + public static int Combine(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + uint hc4 = (uint)(value4?.GetHashCode() ?? 0); + uint hc5 = (uint)(value5?.GetHashCode() ?? 0); + + Initialize(out uint v1, out uint v2, out uint v3, out uint v4); + + v1 = Round(v1, hc1); + v2 = Round(v2, hc2); + v3 = Round(v3, hc3); + v4 = Round(v4, hc4); + + uint hash = MixState(v1, v2, v3, v4); + hash += 20; + + hash = QueueRound(hash, hc5); + + hash = MixFinal(hash); + return (int)hash; + } + + /// + /// Combines six values into a hash code. + /// + /// The type of the first value to combine into the hash code. + /// The type of the second value to combine into the hash code. + /// The type of the third value to combine into the hash code. + /// The type of the fourth value to combine into the hash code. + /// The type of the fifth value to combine into the hash code. + /// The type of the sixth value to combine into the hash code. + /// The first value to combine into the hash code. + /// The second value to combine into the hash code. + /// The third value to combine into the hash code. + /// The fourth value to combine into the hash code. + /// The fifth value to combine into the hash code. + /// The sixth value to combine into the hash code. + /// The hash code that represents the six values. + public static int Combine(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + uint hc4 = (uint)(value4?.GetHashCode() ?? 0); + uint hc5 = (uint)(value5?.GetHashCode() ?? 0); + uint hc6 = (uint)(value6?.GetHashCode() ?? 0); + + Initialize(out uint v1, out uint v2, out uint v3, out uint v4); + + v1 = Round(v1, hc1); + v2 = Round(v2, hc2); + v3 = Round(v3, hc3); + v4 = Round(v4, hc4); + + uint hash = MixState(v1, v2, v3, v4); + hash += 24; + + hash = QueueRound(hash, hc5); + hash = QueueRound(hash, hc6); + + hash = MixFinal(hash); + return (int)hash; + } + + /// + /// Combines seven values into a hash code. + /// + /// The type of the first value to combine into the hash code. + /// The type of the second value to combine into the hash code. + /// The type of the third value to combine into the hash code. + /// The type of the fourth value to combine into the hash code. + /// The type of the fifth value to combine into the hash code. + /// The type of the sixth value to combine into the hash code. + /// The type of the seventh value to combine into the hash code. + /// The first value to combine into the hash code. + /// The second value to combine into the hash code. + /// The third value to combine into the hash code. + /// The fourth value to combine into the hash code. + /// The fifth value to combine into the hash code. + /// The sixth value to combine into the hash code. + /// The seventh value to combine into the hash code. + /// The hash code that represents the seven values. + public static int Combine(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + uint hc4 = (uint)(value4?.GetHashCode() ?? 0); + uint hc5 = (uint)(value5?.GetHashCode() ?? 0); + uint hc6 = (uint)(value6?.GetHashCode() ?? 0); + uint hc7 = (uint)(value7?.GetHashCode() ?? 0); + + Initialize(out uint v1, out uint v2, out uint v3, out uint v4); + + v1 = Round(v1, hc1); + v2 = Round(v2, hc2); + v3 = Round(v3, hc3); + v4 = Round(v4, hc4); + + uint hash = MixState(v1, v2, v3, v4); + hash += 28; + + hash = QueueRound(hash, hc5); + hash = QueueRound(hash, hc6); + hash = QueueRound(hash, hc7); + + hash = MixFinal(hash); + return (int)hash; + } + + /// + /// Combines eight values into a hash code. + /// + /// The type of the first value to combine into the hash code. + /// The type of the second value to combine into the hash code. + /// The type of the third value to combine into the hash code. + /// The type of the fourth value to combine into the hash code. + /// The type of the fifth value to combine into the hash code. + /// The type of the sixth value to combine into the hash code. + /// The type of the seventh value to combine into the hash code. + /// The type of the eighth value to combine into the hash code. + /// The first value to combine into the hash code. + /// The second value to combine into the hash code. + /// The third value to combine into the hash code. + /// The fourth value to combine into the hash code. + /// The fifth value to combine into the hash code. + /// The sixth value to combine into the hash code. + /// The seventh value to combine into the hash code. + /// The eighth value to combine into the hash code. + /// The hash code that represents the eight values. + public static int Combine(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5, T6 value6, T7 value7, T8 value8) + { + uint hc1 = (uint)(value1?.GetHashCode() ?? 0); + uint hc2 = (uint)(value2?.GetHashCode() ?? 0); + uint hc3 = (uint)(value3?.GetHashCode() ?? 0); + uint hc4 = (uint)(value4?.GetHashCode() ?? 0); + uint hc5 = (uint)(value5?.GetHashCode() ?? 0); + uint hc6 = (uint)(value6?.GetHashCode() ?? 0); + uint hc7 = (uint)(value7?.GetHashCode() ?? 0); + uint hc8 = (uint)(value8?.GetHashCode() ?? 0); + + Initialize(out uint v1, out uint v2, out uint v3, out uint v4); + + v1 = Round(v1, hc1); + v2 = Round(v2, hc2); + v3 = Round(v3, hc3); + v4 = Round(v4, hc4); + + v1 = Round(v1, hc5); + v2 = Round(v2, hc6); + v3 = Round(v3, hc7); + v4 = Round(v4, hc8); + + uint hash = MixState(v1, v2, v3, v4); + hash += 32; + + hash = MixFinal(hash); + return (int)hash; + } + + [MethodImpl((MethodImplOptions)256)] + private static void Initialize(out uint v1, out uint v2, out uint v3, out uint v4) + { + v1 = s_seed + Prime1 + Prime2; + v2 = s_seed + Prime2; + v3 = s_seed; + v4 = s_seed - Prime1; + } + + [MethodImpl((MethodImplOptions)256)] + private static uint Round(uint hash, uint input) + { + return RotateLeft(hash + input * Prime2, 13) * Prime1; + } + + [MethodImpl((MethodImplOptions)256)] + private static uint QueueRound(uint hash, uint queuedValue) + { + return RotateLeft(hash + queuedValue * Prime3, 17) * Prime4; + } + + [MethodImpl((MethodImplOptions)256)] + private static uint MixState(uint v1, uint v2, uint v3, uint v4) + { + return RotateLeft(v1, 1) + RotateLeft(v2, 7) + RotateLeft(v3, 12) + RotateLeft(v4, 18); + } + + private static uint MixEmptyState() + { + return s_seed + Prime5; + } + + [MethodImpl((MethodImplOptions)256)] + private static uint MixFinal(uint hash) + { + hash ^= hash >> 15; + hash *= Prime2; + hash ^= hash >> 13; + hash *= Prime3; + hash ^= hash >> 16; + return hash; + } + + /// + /// Rotates the specified value left by the specified number of bits. + /// Similar in behavior to the x86 instruction ROL. + /// + /// The value to rotate. + /// The number of bits to rotate by. + /// Any value outside the range [0..31] is treated as congruent mod 32. + /// The rotated value. + [MethodImpl((MethodImplOptions)256)] + private static uint RotateLeft(uint value, int offset) + => (value << offset) | (value >> (32 - offset)); + + /// + /// Adds a single value to the hash code. + /// + /// The type of the value to add to the hash code. + /// The value to add to the hash code. + public void Add(T value) + { + Add(value?.GetHashCode() ?? 0); + } + + /// + /// Adds a single value to the hash code, specifying the type that provides the hash code function. + /// + /// The type of the value to add to the hash code. + /// The value to add to the hash code. + /// The to use to calculate the hash code. This value can be a null reference (Nothing in Visual Basic), which will use the default equality comparer for . + public void Add(T value, IEqualityComparer comparer) + { + Add(value is null ? 0 : (comparer?.GetHashCode(value) ?? value.GetHashCode())); + } + + private void Add(int value) + { + // The original xxHash works as follows: + // 0. Initialize immediately. We can't do this in a struct (no + // default ctor). + // 1. Accumulate blocks of length 16 (4 uints) into 4 accumulators. + // 2. Accumulate remaining blocks of length 4 (1 uint) into the + // hash. + // 3. Accumulate remaining blocks of length 1 into the hash. + + // There is no need for #3 as this type only accepts ints. _queue1, + // _queue2 and _queue3 are basically a buffer so that when + // ToHashCode is called we can execute #2 correctly. + + // We need to initialize the xxHash32 state (_v1 to _v4) lazily (see + // #0) nd the last place that can be done if you look at the + // original code is just before the first block of 16 bytes is mixed + // in. The xxHash32 state is never used for streams containing fewer + // than 16 bytes. + + // To see what's really going on here, have a look at the Combine + // methods. + + uint val = (uint)value; + + // Storing the value of _length locally shaves of quite a few bytes + // in the resulting machine code. + uint previousLength = _length++; + uint position = previousLength % 4; + + // Switch can't be inlined. + + if (position == 0) + _queue1 = val; + else if (position == 1) + _queue2 = val; + else if (position == 2) + _queue3 = val; + else // position == 3 + { + if (previousLength == 3) + Initialize(out _v1, out _v2, out _v3, out _v4); + + _v1 = Round(_v1, _queue1); + _v2 = Round(_v2, _queue2); + _v3 = Round(_v3, _queue3); + _v4 = Round(_v4, val); + } + } + + /// + /// Calculates the final hash code after consecutive invocations. + /// + /// The calculated hash code. + public readonly int ToHashCode() + { + // Storing the value of _length locally shaves of quite a few bytes + // in the resulting machine code. + uint length = _length; + + // position refers to the *next* queue position in this method, so + // position == 1 means that _queue1 is populated; _queue2 would have + // been populated on the next call to Add. + uint position = length % 4; + + // If the length is less than 4, _v1 to _v4 don't contain anything + // yet. xxHash32 treats this differently. + + uint hash = length < 4 ? MixEmptyState() : MixState(_v1, _v2, _v3, _v4); + + // _length is incremented once per Add(Int32) and is therefore 4 + // times too small (xxHash length is in bytes, not ints). + + hash += length * 4; + + // Mix what remains in the queue + + // Switch can't be inlined right now, so use as few branches as + // possible by manually excluding impossible scenarios (position > 1 + // is always false if position is not > 0). + if (position > 0) + { + hash = QueueRound(hash, _queue1); + if (position > 1) + { + hash = QueueRound(hash, _queue2); + if (position > 2) + hash = QueueRound(hash, _queue3); + } + } + + hash = MixFinal(hash); + return (int)hash; + } + +#pragma warning disable 0809 + // Obsolete member 'memberA' overrides non-obsolete member 'memberB'. + // Disallowing GetHashCode and Equals is by design + + // * We decided to not override GetHashCode() to produce the hash code + // as this would be weird, both naming-wise as well as from a + // behavioral standpoint (GetHashCode() should return the object's + // hash code, not the one being computed). + + // * Even though ToHashCode() can be called safely multiple times on + // this implementation, it is not part of the contract. If the + // implementation has to change in the future we don't want to worry + // about people who might have incorrectly used this type. + + /// + [Obsolete("HashCode is a mutable struct and should not be compared with other HashCodes. Use ToHashCode to retrieve the computed hash code.", error: true)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly int GetHashCode() => throw new NotSupportedException("HashCode is a mutable struct and should not be compared with other HashCodes. Use ToHashCode to retrieve the computed hash code."); + + /// + [Obsolete("HashCode is a mutable struct and should not be compared with other HashCodes.", error: true)] + [EditorBrowsable(EditorBrowsableState.Never)] + public override readonly bool Equals(object obj) => throw new NotSupportedException("HashCode is a mutable struct and should not be compared with other HashCodes."); + + /// + public static bool operator ==(HashCode left, HashCode right) => left.Equals(right); + + /// + public static bool operator !=(HashCode left, HashCode right) => !(left == right); +#pragma warning restore 0809 + } +} +#endif \ No newline at end of file diff --git a/AdvancedSharpAdbClient/Models/ShellStream.cs b/AdvancedSharpAdbClient/Models/ShellStream.cs index 2ae4bc74..09a99668 100644 --- a/AdvancedSharpAdbClient/Models/ShellStream.cs +++ b/AdvancedSharpAdbClient/Models/ShellStream.cs @@ -4,6 +4,7 @@ using System; using System.IO; +using System.Runtime.CompilerServices; using System.Threading; namespace AdvancedSharpAdbClient @@ -485,15 +486,19 @@ async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToke #endif /// + [MethodImpl((MethodImplOptions)256)] public override void Flush() => throw new NotImplementedException(); /// + [MethodImpl((MethodImplOptions)256)] public override long Seek(long offset, SeekOrigin origin) => throw new NotImplementedException(); /// + [MethodImpl((MethodImplOptions)256)] public override void SetLength(long value) => throw new NotImplementedException(); /// + [MethodImpl((MethodImplOptions)256)] public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException(); /// diff --git a/AdvancedSharpAdbClient/Receivers/ConsoleOutputReceiver.cs b/AdvancedSharpAdbClient/Receivers/ConsoleOutputReceiver.cs index 97082d73..02fc8e16 100644 --- a/AdvancedSharpAdbClient/Receivers/ConsoleOutputReceiver.cs +++ b/AdvancedSharpAdbClient/Receivers/ConsoleOutputReceiver.cs @@ -6,6 +6,7 @@ using AdvancedSharpAdbClient.Logs; using System.Collections.Generic; using System.IO; +using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; @@ -118,10 +119,13 @@ protected override void ProcessNewLines(IEnumerable lines) [GeneratedRegex("(permission|access) denied$", DefaultRegexOptions)] private static partial Regex DeniedRegex(); #else + [MethodImpl((MethodImplOptions)256)] private static Regex AbortingRegex() => new("Aborting.$", DefaultRegexOptions); - + + [MethodImpl((MethodImplOptions)256)] private static Regex AppletRegex() => new("applet not found$", DefaultRegexOptions); - + + [MethodImpl((MethodImplOptions)256)] private static Regex DeniedRegex() => new("(permission|access) denied$", DefaultRegexOptions); #endif } diff --git a/AdvancedSharpAdbClient/Receivers/MultilineReceiver.cs b/AdvancedSharpAdbClient/Receivers/MultilineReceiver.cs index 095a797f..c36e84d9 100644 --- a/AdvancedSharpAdbClient/Receivers/MultilineReceiver.cs +++ b/AdvancedSharpAdbClient/Receivers/MultilineReceiver.cs @@ -3,6 +3,7 @@ // using System.Collections.Generic; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient { @@ -42,6 +43,7 @@ public abstract class MultiLineReceiver : IShellOutputReceiver /// Adds a line to the output. /// /// The line to add to the output. + [MethodImpl((MethodImplOptions)256)] public virtual void AddOutput(string line) => Lines.Add(line); /// diff --git a/AdvancedSharpAdbClient/SyncService.Async.cs b/AdvancedSharpAdbClient/SyncService.Async.cs index d0db5934..9827ea68 100644 --- a/AdvancedSharpAdbClient/SyncService.Async.cs +++ b/AdvancedSharpAdbClient/SyncService.Async.cs @@ -47,6 +47,7 @@ public virtual Task ReopenAsync(IAdbSocket socket, CancellationToken cancellatio /// A connection to an adb server. /// A which can be used to cancel the asynchronous operation. /// A which represents the asynchronous operation. + [MethodImpl((MethodImplOptions)256)] public Task ReopenAsync(IAdbClient client, CancellationToken cancellationToken = default) => ReopenAsync(Factories.AdbSocketFactory(client.EndPoint), cancellationToken); /// diff --git a/AdvancedSharpAdbClient/SyncService.cs b/AdvancedSharpAdbClient/SyncService.cs index 9b59eb37..136b20f8 100644 --- a/AdvancedSharpAdbClient/SyncService.cs +++ b/AdvancedSharpAdbClient/SyncService.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient { @@ -118,6 +119,7 @@ public virtual void Reopen(IAdbSocket socket) /// Reopen this connection. /// /// A connection to an adb server. + [MethodImpl((MethodImplOptions)256)] public void Reopen(IAdbClient client) => Reopen(Factories.AdbSocketFactory(client.EndPoint)); /// diff --git a/AdvancedSharpAdbClient/TcpSocket.Async.cs b/AdvancedSharpAdbClient/TcpSocket.Async.cs index 8eeba38d..1938b9c6 100644 --- a/AdvancedSharpAdbClient/TcpSocket.Async.cs +++ b/AdvancedSharpAdbClient/TcpSocket.Async.cs @@ -6,6 +6,7 @@ using System; using System.Net; using System.Net.Sockets; +using System.Runtime.CompilerServices; using System.Threading; namespace AdvancedSharpAdbClient @@ -45,50 +46,62 @@ public virtual ValueTask ReconnectAsync(CancellationToken cancellationToken = de #if HAS_BUFFERS /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual Task SendAsync(byte[] buffer, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.SendAsync(buffer.AsMemory(0, size), socketFlags, cancellationToken).AsTask(); /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual Task SendAsync(byte[] buffer, int offset, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.SendAsync(buffer.AsMemory(offset, size), socketFlags, cancellationToken).AsTask(); /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public ValueTask SendAsync(ReadOnlyMemory buffer, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.SendAsync(buffer, socketFlags, cancellationToken); /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual Task ReceiveAsync(byte[] buffer, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.ReceiveAsync(buffer.AsMemory(0, size), socketFlags, cancellationToken).AsTask(); /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual Task ReceiveAsync(byte[] buffer, int offset, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.ReceiveAsync(buffer.AsMemory(offset, size), socketFlags, cancellationToken).AsTask(); /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public ValueTask ReceiveAsync(Memory buffer, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.ReceiveAsync(buffer, socketFlags, cancellationToken); #else /// + [MethodImpl((MethodImplOptions)256)] public virtual Task SendAsync(byte[] buffer, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.SendAsync(buffer, socketFlags, cancellationToken); /// + [MethodImpl((MethodImplOptions)256)] public virtual Task SendAsync(byte[] buffer, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.SendAsync(buffer, size, socketFlags, cancellationToken); /// + [MethodImpl((MethodImplOptions)256)] public virtual Task SendAsync(byte[] buffer, int offset, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.SendAsync(buffer, offset, size, socketFlags, cancellationToken); /// + [MethodImpl((MethodImplOptions)256)] public virtual Task ReceiveAsync(byte[] buffer, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.ReceiveAsync(buffer, socketFlags, cancellationToken); /// + [MethodImpl((MethodImplOptions)256)] public virtual Task ReceiveAsync(byte[] buffer, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.ReceiveAsync(buffer, size, socketFlags, cancellationToken); /// + [MethodImpl((MethodImplOptions)256)] public virtual Task ReceiveAsync(byte[] buffer, int offset, int size, SocketFlags socketFlags, CancellationToken cancellationToken = default) => socket.ReceiveAsync(buffer, offset, size, socketFlags, cancellationToken); #endif diff --git a/AdvancedSharpAdbClient/TcpSocket.cs b/AdvancedSharpAdbClient/TcpSocket.cs index 2beb4bc2..8c529157 100644 --- a/AdvancedSharpAdbClient/TcpSocket.cs +++ b/AdvancedSharpAdbClient/TcpSocket.cs @@ -6,6 +6,7 @@ using System.IO; using System.Net; using System.Net.Sockets; +using System.Runtime.CompilerServices; namespace AdvancedSharpAdbClient { @@ -69,6 +70,7 @@ public virtual void Reconnect() } /// + [MethodImpl((MethodImplOptions)256)] protected virtual void Dispose(bool disposing) { if (disposing) @@ -85,9 +87,11 @@ public void Dispose() } /// + [MethodImpl((MethodImplOptions)256)] public virtual void Close() => socket.Close(); /// + [MethodImpl((MethodImplOptions)256)] public virtual int Send(byte[] buffer, int size, SocketFlags socketFlags) => #if HAS_BUFFERS socket.Send(buffer.AsSpan(0, size), socketFlags); @@ -96,6 +100,7 @@ public virtual int Send(byte[] buffer, int size, SocketFlags socketFlags) => #endif /// + [MethodImpl((MethodImplOptions)256)] public virtual int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags) => #if HAS_BUFFERS socket.Send(buffer.AsSpan(offset, size), socketFlags); @@ -104,6 +109,7 @@ public virtual int Send(byte[] buffer, int offset, int size, SocketFlags socketF #endif /// + [MethodImpl((MethodImplOptions)256)] public virtual int Receive(byte[] buffer, int size, SocketFlags socketFlags) => #if HAS_BUFFERS socket.Receive(buffer.AsSpan(0, size), socketFlags); @@ -112,6 +118,7 @@ public virtual int Receive(byte[] buffer, int size, SocketFlags socketFlags) => #endif /// + [MethodImpl((MethodImplOptions)256)] public virtual int Receive(byte[] buffer, int offset, int size, SocketFlags socketFlags) => #if HAS_BUFFERS socket.Send(buffer.AsSpan(offset, size), socketFlags); @@ -121,23 +128,28 @@ public virtual int Receive(byte[] buffer, int offset, int size, SocketFlags sock #if HAS_BUFFERS /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual int Send(ReadOnlySpan buffer, SocketFlags socketFlags) => socket.Send(buffer, socketFlags); /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual int Receive(Span buffer, SocketFlags socketFlags) => socket.Receive(buffer, socketFlags); #else /// + [MethodImpl((MethodImplOptions)256)] public virtual int Send(byte[] buffer, SocketFlags socketFlags) => socket.Send(buffer, socketFlags); /// + [MethodImpl((MethodImplOptions)256)] public virtual int Receive(byte[] buffer, SocketFlags socketFlags) => socket.Receive(buffer, socketFlags); #endif /// + [MethodImpl((MethodImplOptions)256)] public virtual Stream GetStream() => new NetworkStream(socket); } }