/* Test.Module.Channel.DataArray.cs Copyright © 2009 Diversified Technical Systems, Inc. All Rights Reserved */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Text; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; using DTS.Utilities; using DTS.Utilities.DotNetProgrammingConstructs; using DTS.Utilities.Xml; namespace DTS.Serialization { // *** see Test.cs *** public partial class Test { // *** see Test.Module.cs *** public partial class Module { // *** see Test.Module.Channel.cs *** public partial class Channel { /// /// Representation of serializable channel data. /// /// /// /// The actual type of this channel data's datum. /// /// public class DataArray : Exceptional, IXmlSerializable { private readonly string DataXmlTag = "Data"; private readonly string DataLengthXmlTag = "Length"; private readonly string DataTypeXmlTag = "Type"; private readonly string DatumXmlTag = "Datum"; private readonly string DatumValueXmlTag = "Value"; private readonly string DataAdcToMvScaleFactorTag = "ScaleFactorMv"; private readonly string DataMvPerEuTag = "SensitivityMvEu"; /// /// Method for converting a of the generic data type to /// a DataArray. /// /// /// /// The of the generic data type to be converted into a /// DataArray. /// /// /// /// A DataArray containing the specified values. /// /// public static implicit operator DataArray( List dataList ) { return new DataArray( dataList.ToArray( ) ); } /// /// Method for converting a DataArray of the generic data type to a /// of the generic data type. /// /// /// /// The DataArray of the specified generic type to be converted into a . /// /// /// /// A of the specified generic type. /// /// public static implicit operator List( DataArray dataArray ) { return new List( dataArray.Values ); } /// /// Initialize an instance of the Data class. /// public DataArray( ) { } /// /// Initialize an instance of the Data class. /// /// /// /// The values with which to initialize this data collection. /// /// public DataArray( DataType[] values ) { try { this.Values = values; } catch ( System.Exception ex ) { throw new Exception( "encountered problem constructing Test.Module.Channel.DataArray", ex ); } } /// /// Get all of the data values in an array. /// public DataType[] Values { //get { return _Values.Value; } get { if (!_Values.IsInitialized || null == _Values.Value) { return new DataType[0]; } else { return _Values.Value; } } set { _Values.Value = value; } } private Property _Values = new Property( typeof( DataArray ).Namespace + ".Test.Module.Channel.DataArray.Values", null, false ); /// /// Get/set the ADC->MV scale factor for this data. /// public double ScaleFactorMv { get { return _ScaleFactorMv.Value; } set { _ScaleFactorMv.Value = value; } } private Property _ScaleFactorMv = new Property( typeof( DataArray ).Namespace + ".Test.Module.Channel.DataArray.ScaleFactorMv", 0.0, false ); public double ScaleFactorEU { get { return _ScaleFactorEU.Value; } set { _ScaleFactorEU.Value = value; } } private Property _ScaleFactorEU = new Property( typeof(DataArray).Namespace + ".Test.Module.Channel.DataArray.ScaleFactorEU", 0.0, false ); public bool UseTDASScaleFactors { get { return _UseTDASScaleFactors.Value; } set { _UseTDASScaleFactors.Value = value; } } private Property _UseTDASScaleFactors = new Property( typeof(DataArray).Namespace + ".Test.Module.Channel.DataArray.UseTDASScaleFactors", false, true ); public short DataZeroLevel { get { return _DataZeroLevel.Value; } set { _DataZeroLevel.Value = value; } } private Property _DataZeroLevel = new Property( typeof(DataArray).Namespace + ".Test.Module.Channel.DataArray.DataZeroLevel", 0, false ); /// /// Get/set the Unit Conversion for this data. /// public double UnitConversion { get { return _UnitConversion.Value; } set { _UnitConversion.Value = value; } } private Property _UnitConversion = new Property( typeof(DataArray).Namespace + ".Test.Module.Channel.DataArray.UnitConversion", 1.0, true ); /// /// Get/set the Multiplier for this data. /// public double Multiplier { get { return _Multiplier.Value; } set { _Multiplier.Value = value; } } private Property _Multiplier = new Property( typeof(DataArray).Namespace + ".Test.Module.Channel.DataArray.Multiplier", 1.0, true ); /// /// Get/set the Modify Offset for this data. /// public double UserOffsetEU { get { return _UserOffsetEU.Value; } set { _UserOffsetEU.Value = value; } } private Property _UserOffsetEU = new Property( typeof(DataArray).Namespace + ".Test.Module.Channel.DataArray.UserOffsetEU", 0.0, true ); /// /// Get/set the ADC->EU scale factor for this data. /// public double MvPerEu { get { return _MvPerEu.Value; } set { _MvPerEu.Value = value; } } private Property _MvPerEu = new Property( typeof( DataArray ).Namespace + ".Test.Module.Channel.DataArray.MvPerEu", 0.0, false ); /// /// Write XML serialization for this object to the specified writer. /// /// /// /// The to which this object's XML serialization /// will be written. /// /// public void WriteXml( XmlWriter writer ) { try { var cult = new System.Globalization.CultureInfo(""); int dataLength = Values.Length; writer.WriteStartElement( DataXmlTag ); writer.WriteAttributeString( DataLengthXmlTag, dataLength.ToString(cult) ); writer.WriteAttributeString( DataTypeXmlTag, typeof( DataType ).FullName ); writer.WriteAttributeString( DataAdcToMvScaleFactorTag, ScaleFactorMv.ToString(cult) ); writer.WriteAttributeString( DataMvPerEuTag, MvPerEu.ToString(cult) ); for ( int i=0; i /// Read XML serialization for this object from the specified reader. /// /// /// /// The from which this object's XML serialization /// will be read. /// /// public void ReadXml( XmlReader reader ) { try { var cult = new System.Globalization.CultureInfo(""); reader.MoveToContent(); Type dataType = null; int dataLength; try { string scaleFactorMvString = null; try { scaleFactorMvString = reader.GetAttribute( DataAdcToMvScaleFactorTag ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem extracting ADC->MV scaling factor from XML", ex ); } string mvPerEuString = null; try { mvPerEuString = reader.GetAttribute( DataMvPerEuTag ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem extracting sensitivity MV/EU factor from XML", ex ); } string dataTypeString = null; try { dataTypeString = reader.GetAttribute( DataTypeXmlTag ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem extracting data type name from XML", ex ); } dataType = null; try { dataType = Type.GetType( dataTypeString ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem instantiating type " + ( null != dataTypeString ? "\"" + dataTypeString + "\"" : "<>" ), ex ); } string dataLengthString = null; try { dataLengthString = reader.GetAttribute( DataLengthXmlTag ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem extracting data length string representation from XML", ex ); } dataLength = 0; try { dataLength = int.Parse( dataLengthString, cult ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem parsing data length from string representation " + ( null != dataLengthString ? "\"" + dataLengthString + "\"" : "<>" ), ex ); } Array dataArray = null; try { dataArray = Array.CreateInstance( dataType, dataLength ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem creating data array of type " + ( null != dataType ? "\"" + dataType.FullName + "\"" : "<>" ) + " and length " + dataLength.ToString( ) , ex ); } try { this.Values = (DataType[])dataArray; } catch ( System.Exception ex ) { throw new Exception( "encountered problem assigning data array dynamically created from XML to Data.Values", ex ); } } catch ( System.Exception ex ) { throw new Exception( "encountered problem creating data array from XML", ex ); } try { this.ScaleFactorMv = double.Parse( reader.GetAttribute( DataAdcToMvScaleFactorTag ), cult ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem parsing ADC->MV scaling factor property", ex ); } try { this.MvPerEu = double.Parse( reader.GetAttribute( DataMvPerEuTag ), cult ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem parsing MV/EU sensitivity factor property", ex ); } MemberInfo[] dataTypeMembers = typeof( DataType ).GetMember( "Parse" ); if ( null == dataTypeMembers || dataTypeMembers.Length < 1 ) throw new Exception( "data type does not contain a \"Parse\" method" ); else if ( dataLength > 0 ) { Object dataTypeObject = null; try { dataTypeObject = Activator.CreateInstance( dataType ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem creating an instance of type " + ( null != dataType ? typeof( DataType ).FullName : "<>" ), ex ); } Type[] paramTypes = new Type[ 1 ]; paramTypes[ 0 ] = Type.GetType( "System.String" ); MethodInfo parseMethodInfo = null; try { parseMethodInfo = dataType.GetMethod( "Parse", paramTypes ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem getting \"Parse\" method information from data type " + dataType.FullName, ex ); } for ( int i=0; i < this.Values.Length; i++ ) { reader.Read( ); reader.MoveToContent( ); string datumValueString = null; try { datumValueString = reader.GetAttribute( DatumValueXmlTag ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem extracting datum value string representation from XML", ex ); } Object[] parameters = new Object[ 1 ]; parameters[ 0 ] = datumValueString; DataType parseResult; try { parseResult = (DataType)parseMethodInfo.Invoke( dataTypeObject, parameters ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem invoking \"Parse\" method on string representation " + ( null != datumValueString ? datumValueString : "<>" ), ex ); } try { this.Values[ i ] = parseResult; } catch ( System.Exception ex ) { throw new Exception( "encountered problem inserting parse result " + ( null != parseResult ? parseResult.ToString( ) : "<>" ) + " into collection of data values", ex ); } } } reader.Read( ); reader.MoveToContent( ); if ( reader.Name.Equals( DataXmlTag, StringComparison.OrdinalIgnoreCase ) ) { // // This needs to be conditional in case we get inline data of length // zero. Though this probably will only ever happen under unit test. // reader.ReadEndElement( ); // consume attribute end tag. reader.MoveToContent( ); } } catch ( System.Exception ex ) { throw new Exception( "encountered problem converting XML to DTS.Serialization.Test.Module.Channel.Data object", ex ); } } /// /// Should normally return a schema representing the form of the XML /// generated/consumed by WriteXml/ReadXml, but it never called during /// the serialization process so ours just returns null. /// /// /// /// Null reference, always. /// /// public XmlSchema GetSchema( ) { // This method is never invoked during XML object serialization. return null; } /// /// Test the specified object for equality with this object. /// /// /// /// The to be tested for equality. /// /// /// /// true if the specified object has memeberwise equality with /// this object; false otherwise. /// /// public override bool Equals( object obj ) { DataArray that = obj as DataArray; try { return (null != that) && this.ScaleFactorMv.Equals( that.ScaleFactorMv ) && this.MvPerEu.Equals( that.MvPerEu ) && (this.Values.Length == that.Values.Length) && this.ValuesEquals( that.Values ); } catch ( System.Exception ex ) { throw new Exception( "encountered problem equality-testing object " + ( null != obj ? "\"" + obj.ToString( )+ "\"" : "<>" ), ex ); } } /// /// Test the specified object's module list for equality with this object's /// data list. /// /// /// /// The of object to be /// compared for equality with this test's equivalent. /// /// /// /// true if the two lists contain equivalent-valued members; /// false otherwise. /// /// private bool ValuesEquals( DataType[] thoseValues ) { try { if ( null == thoseValues || this.Values.Length != thoseValues.Length ) return false; else for ( int i=0; i < this.Values.Length; i++ ) if ( !this.Values[ i ].Equals( thoseValues[ i ] ) ) return false; return true; } catch ( System.Exception ex ) { throw new Exception( "encountered problem equality testing value array", ex ); } } /// /// Return the hash code for this object. /// /// /// /// The hash code for this object. /// /// public override int GetHashCode( ) { return base.GetHashCode( ); } } } } } }