DiscreteCollection.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. namespace NModbus.Data
  7. {
  8. /// <summary>
  9. /// Collection of discrete values.
  10. /// </summary>
  11. public class DiscreteCollection : Collection<bool>, IModbusMessageDataCollection
  12. {
  13. /// <summary>
  14. /// Number of bits per byte.
  15. /// </summary>
  16. private const int BitsPerByte = 8;
  17. private readonly List<bool> _discretes;
  18. /// <summary>
  19. /// Initializes a new instance of the <see cref="DiscreteCollection" /> class.
  20. /// </summary>
  21. public DiscreteCollection()
  22. : this(new List<bool>())
  23. {
  24. }
  25. /// <summary>
  26. /// Initializes a new instance of the <see cref="DiscreteCollection" /> class.
  27. /// </summary>
  28. /// <param name="bits">Array for discrete collection.</param>
  29. public DiscreteCollection(params bool[] bits)
  30. : this((IList<bool>)bits)
  31. {
  32. }
  33. /// <summary>
  34. /// Initializes a new instance of the <see cref="DiscreteCollection" /> class.
  35. /// </summary>
  36. /// <param name="bytes">Array for discrete collection.</param>
  37. public DiscreteCollection(params byte[] bytes)
  38. : this()
  39. {
  40. if (bytes == null)
  41. {
  42. throw new ArgumentNullException(nameof(bytes));
  43. }
  44. _discretes.Capacity = bytes.Length * BitsPerByte;
  45. foreach (byte b in bytes)
  46. {
  47. _discretes.Add((b & 1) == 1);
  48. _discretes.Add((b & 2) == 2);
  49. _discretes.Add((b & 4) == 4);
  50. _discretes.Add((b & 8) == 8);
  51. _discretes.Add((b & 16) == 16);
  52. _discretes.Add((b & 32) == 32);
  53. _discretes.Add((b & 64) == 64);
  54. _discretes.Add((b & 128) == 128);
  55. }
  56. }
  57. /// <summary>
  58. /// Initializes a new instance of the <see cref="DiscreteCollection" /> class.
  59. /// </summary>
  60. /// <param name="bits">List for discrete collection.</param>
  61. public DiscreteCollection(IList<bool> bits)
  62. : this(new List<bool>(bits))
  63. {
  64. }
  65. /// <summary>
  66. /// Initializes a new instance of the <see cref="DiscreteCollection" /> class.
  67. /// </summary>
  68. /// <param name="bits">List for discrete collection.</param>
  69. internal DiscreteCollection(List<bool> bits)
  70. : base(bits)
  71. {
  72. Debug.Assert(bits != null, "Discrete bits is null.");
  73. _discretes = bits;
  74. }
  75. /// <summary>
  76. /// Gets the network bytes.
  77. /// </summary>
  78. public byte[] NetworkBytes
  79. {
  80. get
  81. {
  82. byte[] bytes = new byte[ByteCount];
  83. for (int index = 0; index < _discretes.Count; index++)
  84. {
  85. if (_discretes[index])
  86. {
  87. bytes[index / BitsPerByte] |= (byte)(1 << (index % BitsPerByte));
  88. }
  89. }
  90. return bytes;
  91. }
  92. }
  93. /// <summary>
  94. /// Gets the byte count.
  95. /// </summary>
  96. public byte ByteCount => (byte)((Count + 7) / 8);
  97. /// <summary>
  98. /// Returns a <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
  99. /// </summary>
  100. /// <returns>
  101. /// A <see cref="T:System.String" /> that represents the current <see cref="T:System.Object" />.
  102. /// </returns>
  103. public override string ToString()
  104. {
  105. return string.Concat("{", string.Join(", ", this.Select(discrete => discrete ? "1" : "0").ToArray()), "}");
  106. }
  107. }
  108. }