317 lines · 12.9 KB · C#
RawDownload
//******************************************************************************************************//  LogicalParser.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/03/2012 - Stephen C. Wills, Grid Protection Alliance//       Generated original version of source code.//  12/17/2012 - Starlynn Danyelle Gilliam//       Modified Header.////****************************************************************************************************** using System;using System.Collections.Generic;using System.ComponentModel;using System.IO;using GSF.PQDIF.Physical; namespace GSF.PQDIF.Logical{    /// <summary>    /// Represents a parser which parses the logical structure of a PQDIF file.    /// </summary>    /// <remarks>    /// <para>    /// This class makes the data from PQD files readily available to applications and defines several    /// redundant properties throughout the logical hierarchy of the PQDIF file to also facilitate    /// the association of definitions with instances within the logical structure. The following    /// list enumerates some of the more useful associations within the hierarchy.    /// </para>    ///    /// <list type="bullet">    /// <item><see cref="ObservationRecord.DataSource"/></item>    /// <item><see cref="ObservationRecord.Settings"/></item>    /// <item><see cref="SeriesDefinition.ChannelDefinition"/></item>    /// <item><see cref="ChannelInstance.Definition"/></item>    /// <item><see cref="SeriesInstance.Definition"/></item>    /// </list>    ///    /// <para>    /// Usage consists of iterating through observations (<see cref="ObservationRecord"/>) to    /// examine each of the the measurements recorded in the file. As was noted in the list above,    /// the data source (<see cref="DataSourceRecord"/>) and settings for the monitor    /// (<see cref="MonitorSettingsRecord"/>) associated with each observation is exposed as a    /// property on the observation record. Note that the same data source and monitor settings    /// records may be referenced by multiple observation records in the file.    /// </para>    ///    /// <para>    /// The following example demonstrates how to read all observation records from a PQDIF file    /// using the logical parser.    /// </para>    ///    /// <code><![CDATA[    /// ContainerRecord containerRecord;    /// List<ObservationRecord> observationRecords = new List<ObservationRecord>();    /// string fileName = args[0];    ///    /// using (LogicalParser parser = new LogicalParser(fileName))    /// {    ///     parser.Open();    ///     containerRecord = parser.ContainerRecord;    ///    ///     while (parser.HasNextObservationRecord())    ///         observationRecords.Add(parser.NextObservationRecord());    /// }    /// ]]></code>    /// </remarks>    public class LogicalParser : IDisposable    {        #region [ Members ]         // Fields        private readonly PhysicalParser m_physicalParser;        private ContainerRecord m_containerRecord;        private DataSourceRecord m_currentDataSourceRecord;        private MonitorSettingsRecord m_currentMonitorSettingsRecord;        private ObservationRecord m_nextObservationRecord;        private List<DataSourceRecord> m_allDataSourceRecords;         #endregion         #region [ Constructors ]         /// <summary>        /// Creates a new instance of the <see cref="LogicalParser"/> class.        /// </summary>        /// <param name="filePath">Path to the PQDIF file to be parsed.</param>        public LogicalParser(string filePath)        {            m_physicalParser = new PhysicalParser(filePath);            m_allDataSourceRecords = new List<DataSourceRecord>();        }         /// <summary>        /// Creates a new instance of the <see cref="LogicalParser"/> class.        /// </summary>        /// <param name="stream">The stream containing the PQDIF file data.</param>        /// <param name="leaveOpen">True if the stream should be closed when the parser is closed; false otherwise.</param>        /// <exception cref="ArgumentNullException"><paramref name="stream"/> is null.</exception>        /// <exception cref="InvalidOperationException"><paramref name="stream"/> is not both readable and seekable.</exception>        public LogicalParser(Stream stream, bool leaveOpen = false)        {            m_physicalParser = new PhysicalParser(null);            m_allDataSourceRecords = new List<DataSourceRecord>();            Open(stream, leaveOpen);        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets or sets the file path (not just the name) of the PQDIF file to be parsed.        /// Obsolete in favor of <see cref="FilePath"/>.        /// </summary>        [Obsolete("Property is deprecated. Please use FilePath instead.")]        [EditorBrowsable(EditorBrowsableState.Never)]        public string FileName        {            get            {                return m_physicalParser.FilePath;            }            set            {                m_physicalParser.FilePath = value;            }        }         /// <summary>        /// Gets or sets the file path of the PQDIF file to be parsed.        /// </summary>        public string FilePath        {            get            {                return m_physicalParser.FilePath;            }            set            {                m_physicalParser.FilePath = value;            }        }         /// <summary>        /// Gets the container record from the PQDIF file. This is        /// parsed as soon as the parser is <see cref="Open()"/>ed.        /// </summary>        public ContainerRecord ContainerRecord        {            get            {                return m_containerRecord;            }        }         /// <summary>        /// Gets a list of all DataSource records from the PQDIF file. This is        /// parsed when passing throug the observation records <see cref="NextObservationRecord()"/>ed.        /// </summary>        public List<DataSourceRecord> DataSourceRecords        {            get            {                return m_allDataSourceRecords;            }        }        #endregion         #region [ Methods ]         /// <summary>        /// Opens the parser and parses the <see cref="ContainerRecord"/>.        /// </summary>        /// <exception cref="InvalidOperationException"><see cref="FilePath"/> has not been defined.</exception>        /// <exception cref="NotSupportedException">An unsupported compression mode was defined in the PQDIF file.</exception>        public void Open()        {            m_physicalParser.Open();            m_containerRecord = ContainerRecord.CreateContainerRecord(m_physicalParser.NextRecord());            m_physicalParser.CompressionAlgorithm = m_containerRecord.CompressionAlgorithm;            m_physicalParser.CompressionStyle = m_containerRecord.CompressionStyle;        }         /// <summary>        /// Opens the parser and parses the <see cref="ContainerRecord"/>.        /// </summary>        /// <param name="stream">The stream containing the PQDIF file data.</param>        /// <param name="leaveOpen">True if the stream should be closed when the parser is closed; false otherwise.</param>        /// <exception cref="ArgumentNullException"><paramref name="stream"/> is null.</exception>        /// <exception cref="InvalidOperationException"><paramref name="stream"/> is not both readable and seekable.</exception>        /// <exception cref="NotSupportedException">An unsupported compression mode was defined in the PQDIF file.</exception>        public void Open(Stream stream, bool leaveOpen = false)        {            m_physicalParser.Open(stream, leaveOpen);            m_containerRecord = ContainerRecord.CreateContainerRecord(m_physicalParser.NextRecord());            m_physicalParser.CompressionAlgorithm = m_containerRecord.CompressionAlgorithm;            m_physicalParser.CompressionStyle = m_containerRecord.CompressionStyle;        }         /// <summary>        /// Determines whether there are any more        /// <see cref="ObservationRecord"/>s to be        /// read from the PQDIF file.        /// </summary>        /// <returns>true if there is another observation record to be read from PQDIF file; false otherwise</returns>        public bool HasNextObservationRecord()        {            Record physicalRecord;            RecordType recordType;             // Read records from the file until we encounter an observation record or end of file            while ((object)m_nextObservationRecord == null && m_physicalParser.HasNextRecord())            {                physicalRecord = m_physicalParser.NextRecord();                recordType = physicalRecord.Header.TypeOfRecord;                 switch (recordType)                {                    case RecordType.DataSource:                        // Keep track of the latest data source record in order to associate it with observation records                        m_currentDataSourceRecord = DataSourceRecord.CreateDataSourceRecord(physicalRecord);                        m_allDataSourceRecords.Add(m_currentDataSourceRecord);                        break;                     case RecordType.MonitorSettings:                        // Keep track of the latest monitor settings record in order to associate it with observation records                        m_currentMonitorSettingsRecord = MonitorSettingsRecord.CreateMonitorSettingsRecord(physicalRecord);                        break;                     case RecordType.Observation:                        // Found an observation record!                        m_nextObservationRecord = ObservationRecord.CreateObservationRecord(physicalRecord, m_currentDataSourceRecord, m_currentMonitorSettingsRecord);                        break;                     case RecordType.Container:                        // The container record is parsed when the file is opened; it should never be encountered here                        throw new InvalidOperationException("Found more than one container record in PQDIF file.");                     default:                        // Ignore unrecognized record types as the rest of the file might be valid.                        //throw new ArgumentOutOfRangeException(string.Format("Unknown record type: {0}", physicalRecord.Header.RecordTypeTag));                        break;                }            }             return (object)m_nextObservationRecord != null;        }         /// <summary>        /// Gets the next observation record from the PQDIF file.        /// </summary>        /// <returns>The next observation record.</returns>        public ObservationRecord NextObservationRecord()        {            ObservationRecord nextObservationRecord;             // Call this first to read ahead to the next            // observation record if we haven't already            HasNextObservationRecord();             // We need to set m_nextObservationRecord to null so that            // subsequent calls to HasNextObservationRecord() will            // continue to parse new records            nextObservationRecord = m_nextObservationRecord;            m_nextObservationRecord = null;             return nextObservationRecord;        }         /// <summary>        /// Resets the parser to the beginning of the PQDIF file.        /// </summary>        public void Reset()        {            m_currentDataSourceRecord = null;            m_currentMonitorSettingsRecord = null;            m_nextObservationRecord = null;            m_allDataSourceRecords = new List<DataSourceRecord>();             m_physicalParser.Reset();            m_physicalParser.NextRecord(); // skip container record        }         /// <summary>        /// Closes the PQDIF file.        /// </summary>        public void Close()        {            m_physicalParser.Close();        }         /// <summary>        /// Releases resources held by the parser.        /// </summary>        public void Dispose()        {            m_physicalParser.Dispose();        }         #endregion    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t