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