// attrData, index (stride count), and length (in words) are provided by the caller public Section(Modbus MB, AttrData BaseAttr, int index, int Len, bool load) { this.MB = MB; // Save Modbus I/O object this.attr = (T)(object)BaseAttr.Val; // Reverse lookup AttrData => Attr this.Index = index; // For repeated structures this.BaseAttr = BaseAttr; // Need the stride for indexing this.Len = Len; // Save for section write message this.Load = load; // False => already already cleared to 0's byte[] t; // Used in case I/O fails string idx = string.Empty; if (BaseAttr.Count > 1) { idx = $"[{index}]"; } MB.LogIt($"\nAllocating Section {MB.GetAttributeName(BaseAttr.Class, BaseAttr.Val)}{idx} Length = {Len}, PreLoad = {load}"); if (load) // Load if previous contents needed { b = new byte[Len * 2]; // Big enough for all reads if (Len <= MaxWordSize) // If only one read needed, read it directly { t = MB.GetAttributeBlock(BaseAttr, index, Len); // Buffer.BlockCopy(t, 0, b, 0, t.Length); // save away the bytes } else // Otherwise, read it in block size chunks { int wordsRead = 0; // Words read so far int wordsToRead = Len; // Words needed while (wordsToRead > 0) // Until all have been read { t = MB.GetAttributeBlock(BaseAttr, index, Math.Min(wordsToRead, MaxWordSize), wordsRead); Buffer.BlockCopy(t, 0, b, wordsRead * 2, t.Length); // save away the bytes wordsRead += MaxWordSize; // Update words read wordsToRead -= MaxWordSize; // Update words remaining (OK if it goes negative) } } } else { b = new byte[Len * 2]; // Empty array big enough for all data } }