FileRecordCollection.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using NModbus.Unme.Common;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.Diagnostics.CodeAnalysis;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Net;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. namespace NModbus.Data
  12. {
  13. public class FileRecordCollection : IModbusMessageDataCollection
  14. {
  15. [AllowNull]
  16. private IReadOnlyList<byte> networkBytes;
  17. [AllowNull]
  18. private IReadOnlyList<byte> dataBytes;
  19. public FileRecordCollection(ushort fileNumber, ushort startingAddress, byte[] data)
  20. {
  21. Build(fileNumber, startingAddress, data);
  22. FileNumber = fileNumber;
  23. StartingAddress = startingAddress;
  24. }
  25. public FileRecordCollection(byte[] messageFrame)
  26. {
  27. var fileNumber = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(messageFrame, 4));
  28. var startingAdress = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(messageFrame, 6));
  29. var count = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(messageFrame, 8));
  30. var data = messageFrame.Slice(10, count * 2).ToArray();
  31. Build(fileNumber, startingAdress, data);
  32. FileNumber = fileNumber;
  33. StartingAddress = startingAdress;
  34. }
  35. private void Build(ushort fileNumber, ushort startingAddress, byte[] data)
  36. {
  37. if (data.Length % 2 != 0)
  38. {
  39. throw new FormatException("Number of bytes has to be even");
  40. }
  41. var values = new List<byte>
  42. {
  43. 6, // Reference type, demanded by standard definition
  44. };
  45. void addAsBytes(int value)
  46. {
  47. values.AddRange(BitConverter.GetBytes((ushort)IPAddress.HostToNetworkOrder((short)value)));
  48. }
  49. addAsBytes(fileNumber);
  50. addAsBytes(startingAddress);
  51. addAsBytes(data.Length / 2);
  52. values.AddRange(data);
  53. dataBytes = data;
  54. networkBytes = values;
  55. }
  56. /// <summary>
  57. /// The Extended Memory file number
  58. /// </summary>
  59. public ushort FileNumber { get; }
  60. /// <summary>
  61. /// The starting register address within the file.
  62. /// </summary>
  63. public ushort StartingAddress { get; }
  64. /// <summary>
  65. /// The bytes written to the extended memory file.
  66. /// </summary>
  67. public IReadOnlyList<byte> DataBytes => dataBytes;
  68. public byte[] NetworkBytes => networkBytes.ToArray();
  69. /// <summary>
  70. /// Gets the byte count.
  71. /// </summary>
  72. public byte ByteCount => (byte)networkBytes.Count;
  73. /// <summary>
  74. /// Returns a <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
  75. /// </summary>
  76. /// <returns>
  77. /// A <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
  78. /// </returns>
  79. public override string ToString()
  80. {
  81. return string.Concat("{", string.Join(", ", this.networkBytes.Select(v => v.ToString()).ToArray()), "}");
  82. }
  83. }
  84. }