using NModbus; using System.Xml.Linq; namespace ModbusSimulationProtocol.Data; public class PointSource : IPointSource { private readonly string _name; private readonly int _capacity; private readonly TPoint[] _points; private readonly object _lock = new(); /// /// The implementation to the register. /// /// The name of this register. /// A number between 1 and 65536 inclusive. public PointSource(string name, int capacity = 65536) { ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(capacity, ushort.MinValue, nameof(capacity)); ArgumentOutOfRangeException.ThrowIfGreaterThan(capacity, ushort.MaxValue + 1, nameof(capacity)); _name = name; _capacity = capacity; _points = new TPoint[_capacity]; } public TPoint[] ReadPoints(ushort startAddress, ushort numberOfPoints) { if (numberOfPoints == 0) return []; int start = startAddress; int count = numberOfPoints; ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(start, _capacity, nameof(start)); ArgumentOutOfRangeException.ThrowIfGreaterThan(start + count, _capacity, $"{start}+{count}"); lock (_lock) { TPoint[] snapshot = new TPoint[count]; Array.Copy(_points, start, snapshot, 0, count); return snapshot; } } public void WritePoints(ushort startAddress, TPoint[] points) { if (points.Length == 0) return; int start = startAddress; int count = points.Length; ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(start, _capacity, nameof(start)); ArgumentOutOfRangeException.ThrowIfGreaterThan(start + count, _capacity, $"{start}+{count}"); lock (_lock) { Array.Copy(points, 0, _points, start, count); } } }