//****************************************************************************************************** // ChannelValueCollectionBase.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 03/07/2005 - J. Ritchie Carroll // Generated original version of source code. // 09/15/2009 - Stephen C. Wills // Added new header and license agreement. // 10/5/2012 - Gavin E. Holden // Added new header and license agreement. // 12/17/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Runtime.Serialization; namespace GSF.PhasorProtocols { /// /// Represents a protocol independent collection of objects. /// /// Specific type that the references. /// Specific type that the contains. [Serializable] public abstract class ChannelValueCollectionBase : ChannelCollectionBase where TDefinition : IChannelDefinition where TValue : IChannelValue { #region [ Members ] // Fields private int m_fixedCount; private int m_floatCount; #endregion #region [ Constructors ] /// /// Creates a new using specified . /// /// Last valid index for the collection (i.e., maximum count - 1). /// /// is used instead of maximum count so that maximum type values may /// be specified as needed. For example, if the protocol specifies a collection with a signed 16-bit /// maximum length you can specify (i.e., 32,767) as the last valid index /// for the collection since total number of items supported would be 32,768. /// protected ChannelValueCollectionBase(int lastValidIndex) : base(lastValidIndex, true) { } /// /// Creates a new from serialization parameters. /// /// The with populated with data. /// The source for this deserialization. protected ChannelValueCollectionBase(SerializationInfo info, StreamingContext context) : base(info, context) { // Deserialize extra elements m_fixedCount = info.GetInt32("fixedCount"); m_floatCount = info.GetInt32("floatCount"); } #endregion #region [ Properties ] /// /// Gets the length of the . /// public override int BinaryLength { get { // Cells will be constant length, so we can quickly calculate lengths if (m_fixedCount == 0 || m_floatCount == 0) return base.BinaryLength; // Cells will be different lengths, so we must manually sum lengths return this.Sum(frame => frame.BinaryLength); } } /// /// Gets a boolean value indicating if all of the composite values have been assigned a value. /// /// true, if all composite values have been assigned a value; otherwise, false. public virtual bool AllValuesAssigned => this.All(item => !item.IsEmpty); /// /// Gets a of string based property names and values for this object. /// public override Dictionary Attributes { get { Dictionary baseAttributes = base.Attributes; baseAttributes.Add("Fixed Count", m_fixedCount.ToString()); baseAttributes.Add("Float Count", m_floatCount.ToString()); baseAttributes.Add("All Values Assigned", AllValuesAssigned.ToString()); return baseAttributes; } } #endregion #region [ Methods ] /// /// Populates a with the data needed to serialize the target object. /// /// The to populate with data. /// The destination for this serialization. public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); // Serialize extra elements info.AddValue("fixedCount", m_fixedCount); info.AddValue("floatCount", m_floatCount); } // In typical usage, all channel values will be of the same data type - but we can't anticipate all // possible uses of collection, so we track totals of each data type so we can quickly ascertain if // all the items in the collection are of the same data type /// /// Inserts an element into the at the specified index. /// /// The zero-based index at which item should be inserted. /// The object to insert. protected override void InsertItem(int index, TValue item) { if (item?.DataFormat == DataFormat.FixedInteger) m_fixedCount++; else m_floatCount++; base.InsertItem(index, item); } /// /// Replaces the element at the specified index. /// /// The zero-based index of the element to replace. /// The new value for the element at the specified index. The value can be null for reference types. /// /// is less than zero. -or- is greater than . /// protected override void SetItem(int index, TValue item) { if (this[index].DataFormat == DataFormat.FixedInteger) m_fixedCount--; else m_floatCount--; if (item?.DataFormat == DataFormat.FixedInteger) m_fixedCount++; else m_floatCount++; base.SetItem(index, item); } /// /// Removes the element at the specified index of the . /// /// The zero-based index of the element to remove. /// /// is less than zero. -or- is equal to or greater than . /// protected override void RemoveItem(int index) { if (this[index].DataFormat == DataFormat.FixedInteger) m_fixedCount--; else m_floatCount--; base.RemoveItem(index); } /// /// Removes all elements from the . /// protected override void ClearItems() { m_fixedCount = 0; m_floatCount = 0; base.ClearItems(); } #endregion } }