// 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
            }
        }