//****************************************************************************************************** // StateRecordDataPoint.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/04/2009 - Pinal C. Patel // Generated original version of code based on DatAWare system specifications by Brian B. Fox, GSF. // 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; namespace GSF.Historian.Files { /// /// Represents time-series data stored in . /// /// /// /// public class StateRecordDataPoint : ArchiveDataPoint { // ************************************************************************************************** // * Binary Structure * // ************************************************************************************************** // * # Of Bytes Byte Index Data Type Property Name * // * ---------- ---------- ---------- --------------------------------------------------------------* // * 8 0-7 Double Time * // * 4 8-11 Int32 Flags (Quality, TimeZoneIndex & DaylightSavingsTime) * // * 4 12-15 Single Value * // ************************************************************************************************** #region [ Members ] // Constants /// /// Specifies the number of bytes in the binary image of . /// public new const int FixedLength = 16; /// /// Specifies the bit-mask for stored in . /// protected const Bits TziMask = Bits.Bit05 | Bits.Bit06 | Bits.Bit07 | Bits.Bit08 | Bits.Bit09 | Bits.Bit10; /// /// Specifies the bit-mask for stored in . /// protected const Bits DstMask = Bits.Bit11; #endregion #region [ Constructors ] /// /// Initializes a new instance of the class. /// /// Historian identifier of . public StateRecordDataPoint(int historianID) : base(historianID) { } /// /// Initializes a new instance of the class. /// /// A time-series data point. public StateRecordDataPoint(IDataPoint dataPoint) : base(dataPoint) { } /// /// Initializes a new instance of the class. /// /// Historian identifier of . /// of . /// Floating-point value of . /// of . public StateRecordDataPoint(int historianID, TimeTag time, float value, Quality quality) : base(historianID, time, value, quality) { } /// /// Initializes a new instance of the class. /// /// Historian identifier of . /// Binary image to be used for initializing . /// 0-based starting index of initialization data in the . /// Valid number of bytes in from . public StateRecordDataPoint(int historianID, byte[] buffer, int startIndex, int length) : this(historianID) { ParseBinaryImage(buffer, startIndex, length); } #endregion #region [ Properties ] /// /// Gets or sets the 0-based index of the time-zone for the . /// /// The value being assigned is not positive or zero. public short TimeZoneIndex { get { return (short)(Flags.GetMaskedValue(TziMask) >> 5); } set { if (value < 0) throw new ArgumentException("Value must be positive or zero"); Flags = Flags.SetMaskedValue(TziMask, value << 5); } } /// /// Gets a boolean value that indicates whether daylight savings time is in effect. /// public bool DaylightSavingsTime { get { return Flags.CheckBits(DstMask); } set { Flags = value ? Flags.SetBits(DstMask) : Flags.ClearBits(DstMask); } } /// /// Gets or sets the of . /// /// The value being assigned is not between 01/01/1995 and 01/19/2063. public override TimeTag Time { get { return base.Time; } set { int flags = base.Flags; // Save existing flags. base.Time = value; // Update base time (modifies flags). base.Flags = flags; // Restore saved flags. } } /// /// Gets the length of the . /// public override 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 override int ParseBinaryImage(byte[] buffer, int startIndex, int length) { if (length >= FixedLength) { // Binary image has sufficient data. Time = new TimeTag((decimal)LittleEndian.ToDouble(buffer, startIndex)); Flags = LittleEndian.ToInt32(buffer, startIndex + 8); Value = LittleEndian.ToSingle(buffer, startIndex + 12); return FixedLength; } else { // 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 override int GenerateBinaryImage(byte[] buffer, int startIndex) { int length = BinaryLength; buffer.ValidateParameters(startIndex, length); LittleEndian.CopyBytes((double)Time.Value, buffer, startIndex); LittleEndian.CopyBytes(Flags, buffer, startIndex + 8); LittleEndian.CopyBytes(Value, buffer, startIndex + 12); return length; } #endregion } }