/* SliceRaw.File.Writer.cs Copyright © 2009 Diversified Technical Systems, Inc. All Rights Reserved */ using System; using System.IO; using System.Linq; using System.Text; using System.Xml.Serialization; using DTS.Common.Utilities.Logging; namespace DTS.Serialization.SliceRaw { // *** see SliceRaw.File.cs *** public partial class File { /// /// /// Utility object for serializing s to disk /// in the SliceRaw format. /// /// public class Writer : Writer, IWriter { /// /// /// Initialize an instance of the SliceRaw.File.Writer class. /// /// /// /// The -type this serializer is associated with. /// /// public Writer(File fileType, int encoding) : base(fileType, encoding) { } public delegate void SetProgressDelegate(double d); /// /// if present will be used to notify of progress /// used to provide "finishing download" progrses /// 17587 Add Finishing download feedback /// public SetProgressDelegate SetProgress { get; set; } /// /// Perform disk serialization now. /// /// /// /// The path of the directory to contain the written test. /// /// /// /// The to be written out. /// /// public void Write(string directory, string id, Test test, bool bFiltering, bool includeGroupNameInISOExport, double minStartTime, int dataCollectionLength) { try { Write(directory, id, null, test, bFiltering, includeGroupNameInISOExport, null, null, 0, null, null, null, null, null, null, minStartTime, dataCollectionLength); } catch (System.Exception ex) { throw new Exception("encountered problem doing non-event reporting write", ex); } } private void ChannelException(string problem, string channel, System.Exception ex) { APILogger.Log("Exception writing channel: ", channel, " field: ", problem, " exception: ", ex); } /// /// Perform disk serialization now. /// /// /// /// The path of the directory to contin the written test. /// /// /// /// The to be written out. /// /// /// /// The to be notified whenever /// the writer does something noteworthy. /// /// public void Write(string directory, string id, string dataFolder, Test test, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler beginEventHandler, CancelEventHandler cancelEventHandler, EndEventHandler endEventHandler, TickEventHandler tickEventHandler, ErrorEventHandler errorEventHandler, CancelRequested cancelRequested, double minStartTime, int dataCollectionLength) { System.Exception exception = null; //int line = 0; try { if (null == test) { throw new ArgumentNullException("cannot write null test reference"); } //ConfigurationManager.AppSettings test.Software = System.Reflection.Assembly.GetEntryAssembly().GetName().Name; test.SoftwareVersion = System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString(4); //line = 1; var numberOfFiles = 1; // There will always be the main test file. var numberOfTicksSent = 0; foreach (var module in test.Modules) numberOfFiles += module.Channels.Count; beginEventHandler?.Invoke(this, (uint)numberOfFiles); //line = 2; var encoder = Encoding.Default; try { //force UTF-16 for the dts file, it contains "UTF-16" in the xml by default and isn't consumed by anything that requires //codepage exports (CSV/excel) encoder = Common.Utils.FileUtils.GetEncoding(DefaultEncoding); } catch (System.Exception ex) { APILogger.Log("Problem getting encoder", ex); encoder = Encoding.Default; } //line = 3; using (StringWriter writer = new StringWriterWithEncoding(encoder)) { new XmlSerializer(typeof(Test)).Serialize(writer, test); //FB14854 Add option to move ROI Download folders into the main test folder // Cleaned up folder get/set to accomodate ROI both within the main test folder and without var testIdNode = id;// new DirectoryInfo(Path.GetDirectoryName(subPath)).Name; using (var fileWriter = new StreamWriter((directory.EndsWith("\\") ? directory : directory + "\\") + testIdNode + TestFileExtension, false, encoder)) fileWriter.Write(writer.ToString()); tickEventHandler?.Invoke(this, (uint)(++numberOfTicksSent) / numberOfFiles * 100); } var file = 0; if (true == bFiltering) { //line = 4; foreach (var module in test.Modules) { //line = 5; foreach (var channel in module.Channels) { file++; if (null != cancelRequested && cancelRequested()) { break; } CreatePersistentChannel(channel, module.NumberOfSamples, module.SampleRateHz, tickEventHandler, cancelRequested, numberOfFiles, numberOfTicksSent); SetProgress?.Invoke(100D * file / numberOfFiles); } } } } catch (System.Exception ex) { exception = new Exception("encountered problem doing test file write", ex); } finally { endEventHandler?.Invoke(this); if (null != exception && null != errorEventHandler) { errorEventHandler(this, exception); } else if (null != exception) { throw exception; } } } public void Initialize(string pathname, string id, string dataFolder, Test test, bool bFiltering, bool includeGroupNameInISOExport, FilteredData fd, Test.Module.Channel tmChannel, int channelNumber, BeginEventHandler beginEventHandler, CancelEventHandler cancelEventHandler, EndEventHandler endEventHandler, TickEventHandler tickEventHandler, ErrorEventHandler errorEventHandler, CancelRequested cancelRequested) { } public void CreatePersistentChannel(Test.Module.Channel channel, ulong numberOfSamples, float sampleRateHz, TickEventHandler tickEventHandler, CancelRequested cancelRequested, int numberOfFiles, int numberOfTicksSent) { try { //line = 6; channel.ExpressDataInlineOnXmlSerialization = false; const string DefaultIsoCode = "????????????????"; var fields = Enum.GetValues(typeof(PersistentChannel.Field)).Cast().ToArray(); foreach (var field in fields) { try { //line = 7; if (null != cancelRequested && cancelRequested()) { break; } switch (field) { case PersistentChannel.Field.AreSamplesSigned: channel.PersistentChannelInfo.AreSamplesSigned = 1; break; case PersistentChannel.Field.BeginningOfData: break; case PersistentChannel.Field.BeginningOfFile: break; case PersistentChannel.Field.Crc32: break; case PersistentChannel.Field.DataZeroLevelCounts: try { channel.PersistentChannelInfo.DataZeroLevelCounts = channel.DataZeroLevelAdc; }// xxx This needs to be calculated on the fly during download. catch (System.Exception myException) { ChannelException("DataZeroLevelCounts", channel.ChannelDescriptionString, myException); } break; case PersistentChannel.Field.EngineeringUnit: break; case PersistentChannel.Field.EuFieldLengthWithTerminator: break; case PersistentChannel.Field.Excitation: try { channel.PersistentChannelInfo.Excitation = channel.Excitation; } catch (System.Exception) { } break; case PersistentChannel.Field.HeaderVersionNumber: break; case PersistentChannel.Field.IsoCode: try { channel.PersistentChannelInfo.IsoCode = (channel is Common.DAS.Concepts.DAS.Channel.IIsoCodeAware) ? (channel as Common.DAS.Concepts.DAS.Channel.IIsoCodeAware).IsoCode.PadRight(DefaultIsoCode.Length, '?').ToCharArray(0, DefaultIsoCode.Length) : DefaultIsoCode.ToCharArray(); } catch (System.Exception myException) { ChannelException("IsoCode", channel.ChannelDescriptionString, myException); } break; case PersistentChannel.Field.MagicKey: break; case PersistentChannel.Field.MvPerEu: try { channel.PersistentChannelInfo.MvPerEu = channel.Data.MvPerEu; } catch (System.Exception myException) { ChannelException("MvPerEu", channel.ChannelDescriptionString, myException); } break; case PersistentChannel.Field.NumberOfBitsPerSample: channel.PersistentChannelInfo.NumberOfBitsPerSample = 16; break; case PersistentChannel.Field.NumberOfSamples: try { var numSamples = (0 != numberOfSamples ? numberOfSamples : (ulong)channel.Data.Values.Length); channel.PersistentChannelInfo.NumberOfSamples = numSamples; } catch (System.Exception myException) { ChannelException("NumberOfSamples", channel.ChannelDescriptionString, myException); } break; case PersistentChannel.Field.NumberOfTriggers: break; case PersistentChannel.Field.OffsetOfSampleDataStart: try { channel.PersistentChannelInfo.OffsetOfSampleDataStart = (ulong)(channel.PersistentChannelInfo.GetFileOffsetOf(PersistentChannel.Field.BeginningOfData)); } catch (System.Exception myException) { ChannelException("OffsetOfSampleDataStart", channel.ChannelDescriptionString, myException); } break; case PersistentChannel.Field.OriginalOffsetADC: try { channel.PersistentChannelInfo.OriginalOffsetADC = channel.OriginalOffsetADC; } catch (System.Exception) { } break; case PersistentChannel.Field.PostTestDiagnosticsLevelCounts: try { channel.PersistentChannelInfo.PostTestDiagnosticsLevelCounts = 0; } catch (System.Exception myException) { ChannelException("PostTestDiagnosticsLevelCounts", channel.ChannelDescriptionString, myException); } break; case PersistentChannel.Field.PostTestZeroLevelCounts: try { channel.PersistentChannelInfo.PostTestZeroLevelCounts = channel.PreTestZeroLevelAdc; } catch (System.Exception myException) { ChannelException("PostTestZeroLevelCounts", channel.ChannelDescriptionString, myException); } break; case PersistentChannel.Field.PreTestDiagnosticsLevelCounts: channel.PersistentChannelInfo.PreTestDiagnosticsLevelCounts = 0; break; case PersistentChannel.Field.PreTestNoisePercentageOfFullScale: try { channel.PersistentChannelInfo.PreTestNoisePercentageOfFullScale = channel.NoiseAsPercentageOfFullScale; } catch (System.Exception myException) { ChannelException("PreTestNoisePercentageOfFullScale", channel.ChannelDescriptionString, myException); } break; case PersistentChannel.Field.PreTestZeroLevelCounts: try { channel.PersistentChannelInfo.PreTestZeroLevelCounts = channel.PreTestZeroLevelAdc; } catch (System.Exception myException) { ChannelException("PreTestZeroLevelCounts", channel.ChannelDescriptionString, myException); } break; case PersistentChannel.Field.RemovedADC: try { channel.PersistentChannelInfo.RemovedADC = channel.RemovedADC; } catch (System.Exception) { } break; case PersistentChannel.Field.SampleRate: try { channel.PersistentChannelInfo.SampleRate = sampleRateHz; } catch (System.Exception myException) { ChannelException("SampleRate", channel.ChannelDescriptionString, myException); } break; case PersistentChannel.Field.ScaleFactorMv: try { channel.PersistentChannelInfo.ScaleFactorMv = channel.Data.ScaleFactorMv; } catch (System.Exception myException) { ChannelException("ScaleFactorMv", channel.ChannelDescriptionString, myException); } break; case PersistentChannel.Field.TriggerAdjustmentSamples: try { channel.PersistentChannelInfo.TriggerAdjustmentSamples = channel.TriggerAdjustmentSamples; } catch (System.Exception) { } break; case PersistentChannel.Field.TriggerSampleNumbers: break; case PersistentChannel.Field.ZeroMvInADC: try { channel.PersistentChannelInfo.ZeroMvInADC = channel.ZeroMvInADC; } catch (System.Exception) { } break; case PersistentChannel.Field.WindowAverageADC: try { channel.PersistentChannelInfo.WindowAverageADC = channel.WindowAverageADC; } catch (System.Exception) { } break; } } catch (System.Exception ex) { APILogger.Log("exception writing serializing channel header, field: " + field.ToString()); throw ex; } } channel.PersistentChannelInfo.StampCrc(); // force file handle release try { channel.PersistentChannelInfo.Dispose(); channel.PersistentChannelInfo = null; } catch (System.Exception) { } tickEventHandler?.Invoke(this, (uint)(++numberOfTicksSent) / numberOfFiles * 100); } catch (System.Exception channelException) { APILogger.Log("Exception writing serializing channel header, Channel: ", channel.ChannelDescriptionString, " Exception: ", channelException); } } } } }