//****************************************************************************************************** // CollectionElement.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: // ---------------------------------------------------------------------------------------------------- // 05/02/2012 - Stephen C. Wills, Grid Protection Alliance // Generated original version of source code. // 12/17/2012 - Starlynn Danyelle Gilliam // Modified Header. // 06/09/2016 - Stephen Jenks, Grid Protection Alliance // Added readSize member // //****************************************************************************************************** using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace GSF.PQDIF.Physical { /// /// Represents an which is a collection of other /// elements. Collection elements are part of the physical structure of /// a PQDIF file. They exist within the body of a . /// public class CollectionElement : Element { #region [ Members ] // Fields private readonly IList m_elements; private int m_readSize; // In case the actual size differs from the read size. #endregion #region [ Constructors ] /// /// Creates a new instance of the class. /// public CollectionElement() { m_elements = new List(); } #endregion #region [ Properties ] /// /// Gets or sets the number of elements in the collection. /// public int Size { get { return m_elements.Count; } } /// /// Gets or sets the size that the file says the collection is. /// This may differ from the actual size if, upon parsing the /// file the end of file is reached before the collection becomes /// as large as the read size. /// public int ReadSize { get { return m_readSize; } set { m_readSize = value; } } /// /// Gets the type of the element. /// Returns . /// public override ElementType TypeOfElement { get { return ElementType.Collection; } } /// /// Gets a list of the element in this collection. /// public IList Elements { get { return m_elements; } } #endregion #region [ Methods ] /// /// Adds the given element to the collection. /// /// The element to be added. public void AddElement(Element element) { m_elements.Add(element); } /// /// Removes the given element from the collection. /// /// The element to be removed. public void RemoveElement(Element element) { m_elements.Remove(element); } /// /// Removes all elements identified by the given tag from the collection. /// /// The tag of the elements to be removed. public void RemoveElementsByTag(Guid tag) { for (int i = m_elements.Count - 1; i >= 0; i--) { if (m_elements[i].TagOfElement == tag) m_elements.RemoveAt(i); } } /// /// Gets the elements whose tag matches the one given as a parameter. /// /// The tag of the elements to be retrieved. /// /// An of s /// identified by the given . /// public IEnumerable GetElementsByTag(Guid tag) { return m_elements.Where(element => element.TagOfElement == tag); } /// /// Gets the element whose tag matches the one given as a /// parameter, type cast to . /// /// The tag to search by. /// The element whose tag matches the one given, or null if no matching collection element exists. public CollectionElement GetCollectionByTag(Guid tag) { return m_elements.SingleOrDefault(element => element.TagOfElement == tag) as CollectionElement; } /// /// Gets the element whose tag matches the one given as a /// parameter, type cast to . /// /// The tag to search by. /// The element whose tag matches the one given, or null if no matching scalar element exists. public ScalarElement GetScalarByTag(Guid tag) { return m_elements.SingleOrDefault(element => element.TagOfElement == tag) as ScalarElement; } /// /// Gets the element whose tag matches the one given as a /// parameter, type cast to . /// /// The tag to search by. /// The element whose tag matches the one given, or null if no matching vector element exists. public VectorElement GetVectorByTag(Guid tag) { return m_elements.SingleOrDefault(element => element.TagOfElement == tag) as VectorElement; } /// /// Gets the scalar element identified by the given tag /// or adds a new scalar element if one does not already exist. /// /// The tag which identifies the scalar element to be retrieved. /// The scalar element identified by the tag, or a new scalar element if one did not already exist. public ScalarElement GetOrAddScalar(Guid tag) { ScalarElement scalarElement = GetScalarByTag(tag); if ((object)scalarElement == null) { scalarElement = new ScalarElement() { TagOfElement = tag }; AddElement(scalarElement); } return scalarElement; } /// /// Gets the vector element identified by the given tag /// or adds a new vector element if one does not already exist. /// /// The tag which identifies the vector element to be retrieved. /// The vector element identified by the tag, or a new vector element if one did not already exist. public VectorElement GetOrAddVector(Guid tag) { VectorElement vectorElement = GetVectorByTag(tag); if ((object)vectorElement == null) { vectorElement = new VectorElement() { TagOfElement = tag }; AddElement(vectorElement); } return vectorElement; } /// /// Updates the value of the scalar element identified by the given tag /// or adds a new scalar element if one does not already exist. /// /// The tag which identifies the scalar element to be updated. /// The physical type of the value contained in the scalar element. /// The value to be entered into the scalar element. /// The scalar element which was updated, or a new scalar element if one did not already exist. public ScalarElement AddOrUpdateScalar(Guid tag, PhysicalType type, byte[] bytes) { ScalarElement scalarElement = GetOrAddScalar(tag); scalarElement.TypeOfValue = type; scalarElement.SetValue(bytes, 0); return scalarElement; } /// /// Updates the values contained by the vector element identified by the given tag /// or adds a new vector element if one does not already exist. /// /// The tag which identifies the vector element to be updated. /// The physical type of the values contained in the vector element. /// The values to be entered into the vector element. /// The vector element which was updated, or a new vector element if one did not already exist. public VectorElement AddOrUpdateVector(Guid tag, PhysicalType type, byte[] bytes) { VectorElement vectorElement = GetOrAddVector(tag); vectorElement.TypeOfValue = type; vectorElement.Size = bytes.Length / type.GetByteSize(); vectorElement.SetValues(bytes, 0); return vectorElement; } /// /// Returns a string that represents the collection. /// /// A string that represents the collection. public override string ToString() { StringBuilder builder = new StringBuilder(); string[] lines; builder.AppendFormat("Collection -- Size: {0}, Tag: {1}", Size, TagOfElement); foreach (Element element in m_elements) { lines = element.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None); foreach (string line in lines) { builder.AppendLine(); builder.AppendFormat(" {0}", line); } } return builder.ToString(); } #endregion } }