//****************************************************************************************************** // MetadataRecordDigitalFields.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: // ---------------------------------------------------------------------------------------------------- // 02/21/2007 - Pinal C. Patel // Generated original version of code based on DatAWare system specifications by Brian B. Fox, GSF. // 01/23/2008 - Pinal C. Patel // Added AlarmDelay property to expose delay in sending alarm notification. // 04/20/2009 - Pinal C. Patel // Converted to C#. // 09/15/2009 - Stephen C. Wills // Added new header and license agreement. // 10/11/2010 - Mihir Brahmbhatt // Updated header and license agreement. // 11/30/2011 - J. Ritchie Carroll // Modified to support buffer optimized ISupportBinaryImage. // 12/14/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.IO; using System.Text; using GSF.Parsing; namespace GSF.Historian.Files { /// /// Defines specific fields for s that are of type . /// /// public class MetadataRecordDigitalFields : ISupportBinaryImage { // ************************************************************************************************** // * Binary Structure * // ************************************************************************************************** // * # Of Bytes Byte Index Data Type Property Name * // * ---------- ---------- ---------- --------------------------------------------------------------* // * 24 0-23 Char(24) SetDescription * // * 24 24-47 Char(24) ClearDescription * // * 4 48-51 Int32 AlarmState * // * 4 52-55 Single AlarmDelay * // ************************************************************************************************** #region [ Members ] // Constants /// /// Specifies the number of bytes in the binary image of . /// public const int FixedLength = 56; // Fields private string m_setDescription; private string m_clearDescription; private int m_alarmState; private float m_alarmDelay; private readonly MetadataFileLegacyMode m_legacyMode; #endregion #region [ Constructors ] /// /// Initializes a new instance of the class. /// /// Legacy mode of . internal MetadataRecordDigitalFields(MetadataFileLegacyMode legacyMode) { m_setDescription = string.Empty; m_clearDescription = string.Empty; m_legacyMode = legacyMode; } internal MetadataRecordDigitalFields(BinaryReader reader) { m_legacyMode = MetadataFileLegacyMode.Disabled; m_setDescription = reader.ReadString(); m_clearDescription = reader.ReadString(); m_alarmState = reader.ReadInt32(); m_alarmDelay = reader.ReadSingle(); } #endregion #region [ Properties ] /// /// Gets or sets the text description of the data value for the when it is 1. /// /// /// Maximum length for is 24 characters. /// public string SetDescription { get { return m_setDescription; } set { if ((object)value == null) throw new ArgumentNullException(nameof(value)); if (m_legacyMode == MetadataFileLegacyMode.Enabled) m_setDescription = value.TruncateRight(24); else m_setDescription = value; } } /// /// Gets or sets the text description of the data value for the when it is 0. /// /// /// Maximum length for is 24 characters. /// public string ClearDescription { get { return m_clearDescription; } set { if ((object)value == null) throw new ArgumentNullException(nameof(value)); if (m_legacyMode == MetadataFileLegacyMode.Enabled) m_clearDescription = value.TruncateRight(24); else m_clearDescription = value; } } /// /// Gets or sets the value (0 or 1) that indicates alarm state for the . /// /// A value of -1 indicates no alarm state. /// The value being assigned is not -1, 0 or 1. public int AlarmState { get { return m_alarmState; } set { if (value < -1 || value > 1) throw new ArgumentException("Value must be either -1, 0 or 1"); m_alarmState = value; } } /// /// Gets or sets the time (in seconds) to wait before consecutive alarm notifications are sent for the . /// public float AlarmDelay { get { return m_alarmDelay; } set { m_alarmDelay = value; } } /// /// Gets the length of the . /// public int BinaryLength { get { return FixedLength; } } #endregion #region [ Methods ] /// /// Initializes from the specified . /// /// Binary image to be used for initializing . /// 0-based starting index of initialization data in the . /// Valid number of bytes in from . /// Number of bytes used from the for initializing . public int ParseBinaryImage(byte[] buffer, int startIndex, int length) { if (length >= FixedLength) { // Binary image has sufficient data. SetDescription = Encoding.ASCII.GetString(buffer, startIndex, 24).Trim(); ClearDescription = Encoding.ASCII.GetString(buffer, startIndex + 24, 24).Trim(); AlarmState = LittleEndian.ToInt32(buffer, startIndex + 48); AlarmDelay = LittleEndian.ToSingle(buffer, startIndex + 52); return FixedLength; } // Binary image does not have sufficient data. return 0; } /// /// Generates binary image of the and copies it into the given buffer, for bytes. /// /// Buffer used to hold generated binary image of the source object. /// 0-based starting index in the to start writing. /// The number of bytes written to the . /// is null. /// /// or is less than 0 -or- /// and will exceed length. /// public virtual int GenerateBinaryImage(byte[] buffer, int startIndex) { int length = BinaryLength; buffer.ValidateParameters(startIndex, length); Buffer.BlockCopy(Encoding.ASCII.GetBytes(m_setDescription.PadRight(24).TruncateRight(24)), 0, buffer, startIndex, 24); Buffer.BlockCopy(Encoding.ASCII.GetBytes(m_clearDescription.PadRight(24).TruncateRight(24)), 0, buffer, startIndex + 24, 24); Buffer.BlockCopy(LittleEndian.GetBytes(m_alarmState), 0, buffer, startIndex + 48, 4); Buffer.BlockCopy(LittleEndian.GetBytes(m_alarmDelay), 0, buffer, startIndex + 52, 4); return length; } internal void WriteImage(BinaryWriter writer) { writer.Write(m_setDescription); writer.Write(m_clearDescription); writer.Write(m_alarmState); writer.Write(m_alarmDelay); } #endregion } }