Innovenergy_trunk/csharp/Lib/Protocols/Modbus/Tcp/ModbusTcpFrame.cs

64 lines
1.9 KiB
C#

using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames;
namespace InnovEnergy.Lib.Protocols.Modbus.Tcp;
internal static class ModbusTcpFrameExtensions
{
internal static ModbusTcpFrame ToModbusTcpFrame(this ModbusFrame frame, UInt16 transactionId)
{
var hdr = new MbapHeader(transactionId, frame.Data.Count);
return new ModbusTcpFrame(hdr, frame);
}
}
internal readonly struct ModbusTcpFrame
{
public MbapHeader Header => new MbapHeader(new ArraySegment<Byte>(_Data, 0, MbapHeader.Size));
public ModbusFrame Frame => new ModbusFrame(new ArraySegment<Byte>(_Data, MbapHeader.Size, _Data.Length - MbapHeader.Size));
public IReadOnlyList<Byte> Data => _Data;
private readonly Byte[] _Data;
public ModbusTcpFrame(MbapHeader header, ModbusFrame frame)
{
if (frame.Data.Count != header.FrameLength /* - 1*/) // TODO
throw new ArgumentException(nameof(header.FrameLength));
_Data = CreateData(header, frame);
}
public ModbusTcpFrame(Byte[] data)
{
_Data = data;
if (Frame.Data.Count != Header.FrameLength - 1)
throw new ArgumentException(nameof(Header.FrameLength));
}
private static Byte[] CreateData(MbapHeader header, ModbusFrame frame)
{
var hdl = header.Data.Count;
var fdl = frame.Data.Count;
var data = new Byte[hdl + fdl];
// TODO: avoid Array copy using ArraySegments?
Array.Copy(sourceArray: header.Data.Array!,
sourceIndex: header.Data.Offset,
destinationArray: data,
destinationIndex: 0,
length: hdl);
Array.Copy(sourceArray: frame.Data.Array!,
sourceIndex: frame.Data.Offset,
destinationArray: data,
destinationIndex: hdl,
length: fdl);
return data;
}
}