Small .NET optimizations
This commit is contained in:
@@ -10,6 +10,22 @@ namespace AMWD.Protocols.Modbus.Common.Protocols
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class RtuProtocol : IModbusProtocol
|
public class RtuProtocol : IModbusProtocol
|
||||||
{
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
private static readonly byte[] _readFunctionCodes = [
|
||||||
|
(byte)ModbusFunctionCode.ReadCoils,
|
||||||
|
(byte)ModbusFunctionCode.ReadDiscreteInputs,
|
||||||
|
(byte)ModbusFunctionCode.ReadHoldingRegisters,
|
||||||
|
(byte)ModbusFunctionCode.ReadInputRegisters];
|
||||||
|
|
||||||
|
private static readonly byte[] _writeFunctionCodes = [
|
||||||
|
(byte)ModbusFunctionCode.WriteSingleCoil,
|
||||||
|
(byte)ModbusFunctionCode.WriteSingleRegister,
|
||||||
|
(byte)ModbusFunctionCode.WriteMultipleCoils,
|
||||||
|
(byte)ModbusFunctionCode.WriteMultipleRegisters];
|
||||||
|
|
||||||
|
#endregion Fields
|
||||||
|
|
||||||
#region Constants
|
#region Constants
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -627,7 +643,7 @@ namespace AMWD.Protocols.Modbus.Common.Protocols
|
|||||||
// - 0x03 Read Holding Registers
|
// - 0x03 Read Holding Registers
|
||||||
// - 0x04 Read Input Registers
|
// - 0x04 Read Input Registers
|
||||||
// do have a "following bytes" at position 3
|
// do have a "following bytes" at position 3
|
||||||
if (new[] { 0x01, 0x02, 0x03, 0x04 }.Contains(responseBytes[1]))
|
if (_readFunctionCodes.Contains(responseBytes[1]))
|
||||||
{
|
{
|
||||||
// Unit ID, Function Code, ByteCount, 2x CRC and length of ByteCount
|
// Unit ID, Function Code, ByteCount, 2x CRC and length of ByteCount
|
||||||
if (responseBytes.Count < 5 + responseBytes[2])
|
if (responseBytes.Count < 5 + responseBytes[2])
|
||||||
@@ -638,7 +654,7 @@ namespace AMWD.Protocols.Modbus.Common.Protocols
|
|||||||
// - 0x06 Write Single Register
|
// - 0x06 Write Single Register
|
||||||
// - 0x0F Write Multiple Coils
|
// - 0x0F Write Multiple Coils
|
||||||
// - 0x10 Write Multiple Registers
|
// - 0x10 Write Multiple Registers
|
||||||
if (new[] { 0x05, 0x06, 0x0F, 0x10 }.Contains(responseBytes[1]))
|
if (_writeFunctionCodes.Contains(responseBytes[1]))
|
||||||
{
|
{
|
||||||
// Write Single => Unit ID, Function code, 2x Address, 2x Value, 2x CRC
|
// Write Single => Unit ID, Function code, 2x Address, 2x Value, 2x CRC
|
||||||
// Write Multi => Unit ID, Function code, 2x Address, 2x QuantityWritten, 2x CRC
|
// Write Multi => Unit ID, Function code, 2x Address, 2x QuantityWritten, 2x CRC
|
||||||
@@ -715,13 +731,13 @@ namespace AMWD.Protocols.Modbus.Common.Protocols
|
|||||||
if (isError)
|
if (isError)
|
||||||
throw new ModbusException("Remote Error") { ErrorCode = (ModbusErrorCode)response[2] };
|
throw new ModbusException("Remote Error") { ErrorCode = (ModbusErrorCode)response[2] };
|
||||||
|
|
||||||
if (new[] { 0x01, 0x02, 0x03, 0x04 }.Contains(fnCode))
|
if (_readFunctionCodes.Contains(fnCode))
|
||||||
{
|
{
|
||||||
if (response.Count != 5 + response[2])
|
if (response.Count != 5 + response[2])
|
||||||
throw new ModbusException("Number of following bytes does not match.");
|
throw new ModbusException("Number of following bytes does not match.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new[] { 0x05, 0x06, 0x0F, 0x10 }.Contains(fnCode))
|
if (_writeFunctionCodes.Contains(fnCode))
|
||||||
{
|
{
|
||||||
if (response.Count != 8)
|
if (response.Count != 8)
|
||||||
throw new ModbusException("Number of bytes does not match.");
|
throw new ModbusException("Number of bytes does not match.");
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ namespace AMWD.Protocols.Modbus.Common.Protocols
|
|||||||
|
|
||||||
public DeviceIdentificationRaw DeserializeReadDeviceIdentification(IReadOnlyList<byte> response)
|
public DeviceIdentificationRaw DeserializeReadDeviceIdentification(IReadOnlyList<byte> response)
|
||||||
{
|
{
|
||||||
if (!_devices.TryGetValue(response[0], out var device))
|
if (!_devices.TryGetValue(response[0], out var _))
|
||||||
throw new TimeoutException("Device not found.");
|
throw new TimeoutException("Device not found.");
|
||||||
|
|
||||||
var result = new DeviceIdentificationRaw
|
var result = new DeviceIdentificationRaw
|
||||||
|
|||||||
@@ -65,8 +65,12 @@ namespace AMWD.Protocols.Modbus.Tcp
|
|||||||
get => _readTimeout;
|
get => _readTimeout;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
#if NET8_0_OR_GREATER
|
||||||
|
ArgumentOutOfRangeException.ThrowIfLessThan(value, TimeSpan.Zero);
|
||||||
|
#else
|
||||||
if (value < TimeSpan.Zero)
|
if (value < TimeSpan.Zero)
|
||||||
throw new ArgumentOutOfRangeException(nameof(value));
|
throw new ArgumentOutOfRangeException(nameof(value));
|
||||||
|
#endif
|
||||||
|
|
||||||
_readTimeout = value;
|
_readTimeout = value;
|
||||||
|
|
||||||
@@ -81,8 +85,12 @@ namespace AMWD.Protocols.Modbus.Tcp
|
|||||||
get => _writeTimeout;
|
get => _writeTimeout;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
#if NET8_0_OR_GREATER
|
||||||
|
ArgumentOutOfRangeException.ThrowIfLessThan(value, TimeSpan.Zero);
|
||||||
|
#else
|
||||||
if (value < TimeSpan.Zero)
|
if (value < TimeSpan.Zero)
|
||||||
throw new ArgumentOutOfRangeException(nameof(value));
|
throw new ArgumentOutOfRangeException(nameof(value));
|
||||||
|
#endif
|
||||||
|
|
||||||
_writeTimeout = value;
|
_writeTimeout = value;
|
||||||
|
|
||||||
@@ -376,10 +384,9 @@ namespace AMWD.Protocols.Modbus.Tcp
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Dns.GetHostAddresses(hostname)
|
return [.. Dns.GetHostAddresses(hostname)
|
||||||
.Where(a => a.AddressFamily == AddressFamily.InterNetwork || a.AddressFamily == AddressFamily.InterNetworkV6)
|
.Where(a => a.AddressFamily == AddressFamily.InterNetwork || a.AddressFamily == AddressFamily.InterNetworkV6)
|
||||||
.OrderBy(a => a.AddressFamily) // prefer IPv4
|
.OrderBy(a => a.AddressFamily)]; // prefer IPv4
|
||||||
.ToArray();
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
namespace AMWD.Protocols.Modbus.Tcp.Utils
|
namespace AMWD.Protocols.Modbus.Tcp.Utils
|
||||||
{
|
{
|
||||||
internal class IPEndPointWrapper
|
/// <inheritdoc cref="IPEndPoint" />
|
||||||
|
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||||
|
internal class IPEndPointWrapper(EndPoint endPoint)
|
||||||
{
|
{
|
||||||
private IPEndPoint _ipEndPoint;
|
private readonly IPEndPoint _ipEndPoint = (IPEndPoint)endPoint;
|
||||||
|
|
||||||
public IPEndPointWrapper(EndPoint endPoint)
|
|
||||||
{
|
|
||||||
_ipEndPoint = (IPEndPoint)endPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,9 @@ namespace AMWD.Protocols.Modbus.Tcp.Utils
|
|||||||
{
|
{
|
||||||
/// <inheritdoc cref="NetworkStream" />
|
/// <inheritdoc cref="NetworkStream" />
|
||||||
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||||
internal class NetworkStreamWrapper : IDisposable
|
internal class NetworkStreamWrapper(NetworkStream stream) : IDisposable
|
||||||
{
|
{
|
||||||
private readonly NetworkStream _stream;
|
private readonly NetworkStream _stream = stream;
|
||||||
|
|
||||||
public NetworkStreamWrapper(NetworkStream stream)
|
|
||||||
{
|
|
||||||
_stream = stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="NetworkStream.Dispose" />
|
/// <inheritdoc cref="NetworkStream.Dispose" />
|
||||||
public virtual void Dispose()
|
public virtual void Dispose()
|
||||||
|
|||||||
@@ -3,14 +3,11 @@ using System.Net.Sockets;
|
|||||||
|
|
||||||
namespace AMWD.Protocols.Modbus.Tcp.Utils
|
namespace AMWD.Protocols.Modbus.Tcp.Utils
|
||||||
{
|
{
|
||||||
internal class SocketWrapper : IDisposable
|
/// <inheritdoc cref="Socket" />
|
||||||
|
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||||
|
internal class SocketWrapper(Socket socket) : IDisposable
|
||||||
{
|
{
|
||||||
private Socket _socket;
|
private readonly Socket _socket = socket;
|
||||||
|
|
||||||
public SocketWrapper(Socket socket)
|
|
||||||
{
|
|
||||||
_socket = socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Socket.DualMode" />
|
/// <inheritdoc cref="Socket.DualMode" />
|
||||||
public virtual bool DualMode
|
public virtual bool DualMode
|
||||||
|
|||||||
@@ -6,22 +6,18 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace AMWD.Protocols.Modbus.Tcp.Utils
|
namespace AMWD.Protocols.Modbus.Tcp.Utils
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc cref="TcpListener" />
|
||||||
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
|
||||||
internal class TcpListenerWrapper : IDisposable
|
internal class TcpListenerWrapper(IPAddress localaddr, int port) : IDisposable
|
||||||
{
|
{
|
||||||
#region Fields
|
#region Fields
|
||||||
|
|
||||||
private TcpListener _tcpListener;
|
private readonly TcpListener _tcpListener = new(localaddr, port);
|
||||||
|
|
||||||
#endregion Fields
|
#endregion Fields
|
||||||
|
|
||||||
#region Constructor
|
#region Constructor
|
||||||
|
|
||||||
public TcpListenerWrapper(IPAddress localaddr, int port)
|
|
||||||
{
|
|
||||||
_tcpListener = new TcpListener(localaddr, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructor
|
#endregion Constructor
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|||||||
Reference in New Issue
Block a user