PointSource.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using NModbus;
  2. using System.Xml.Linq;
  3. namespace ModbusSimulationProtocol.Data;
  4. public class PointSource<TPoint> : IPointSource<TPoint>
  5. {
  6. private readonly string _name;
  7. private readonly int _capacity;
  8. private readonly TPoint[] _points;
  9. private readonly object _lock = new();
  10. /// <summary>
  11. /// The implementation to the <typeparamref name="TPoint"/> register.
  12. /// </summary>
  13. /// <param name="name">The name of this register.</param>
  14. /// <param name="capacity">A number between 1 and 65536 inclusive.</param>
  15. public PointSource(string name, int capacity = 65536)
  16. {
  17. ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(capacity, ushort.MinValue, nameof(capacity));
  18. ArgumentOutOfRangeException.ThrowIfGreaterThan(capacity, ushort.MaxValue + 1, nameof(capacity));
  19. _name = name;
  20. _capacity = capacity;
  21. _points = new TPoint[_capacity];
  22. }
  23. public TPoint[] ReadPoints(ushort startAddress, ushort numberOfPoints)
  24. {
  25. if (numberOfPoints == 0) return [];
  26. int start = startAddress;
  27. int count = numberOfPoints;
  28. ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(start, _capacity, nameof(start));
  29. ArgumentOutOfRangeException.ThrowIfGreaterThan(start + count, _capacity, $"{start}+{count}");
  30. lock (_lock)
  31. {
  32. TPoint[] snapshot = new TPoint[count];
  33. Array.Copy(_points, start, snapshot, 0, count);
  34. return snapshot;
  35. }
  36. }
  37. public void WritePoints(ushort startAddress, TPoint[] points)
  38. {
  39. if (points.Length == 0) return;
  40. int start = startAddress;
  41. int count = points.Length;
  42. ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(start, _capacity, nameof(start));
  43. ArgumentOutOfRangeException.ThrowIfGreaterThan(start + count, _capacity, $"{start}+{count}");
  44. lock (_lock)
  45. {
  46. Array.Copy(points, 0, _points, start, count);
  47. }
  48. }
  49. }