/*
* TDAS.File.PersistentChannel.cs
*
* Copyright © 2009
* Diversified Technical Systems, Inc.
* All Rights Reserved
*/
using System;
using System.IO;
using System.Linq;
using DTS.Common.DAS.Concepts.DAS.Channel;
using DTS.Common.Utilities;
using DTS.Common.Utilities.DotNetProgrammingConstructs;
using DTS.Common.Utilities.IO.MemoryMap;
using DTS.Common.Utilities.Logging;
namespace DTS.Serialization.TDAS
{
public partial class File
{
///
/// Representation of a channel. Changes made to this representation
/// are immediately manifest in the associated channel file.
///
public partial class PersistentChannel
: ExceptionalList,
ILargeDataAware,
IChannelHeader,
IDisposable
{
///
/// The window into this persistent channel's soul.
///
protected FileMapViewArray ViewArray
{
get => _ViewArray.Value;
set => _ViewArray.Value = value;
}
private readonly Property _ViewArray
= new Property(
typeof(PersistentChannel).Namespace + ".File.PersistentChannel.ViewArray",
null,
false
);
///
/// Get value indicating whether or not this class has been
/// preinitialized from an existing serialization.
///
protected bool IsInitializedFromFile
{
get => _IsInitializedFromFile.Value;
private set => _IsInitializedFromFile.Value = value;
}
private readonly Property _IsInitializedFromFile
= new Property(
typeof(PersistentChannel).Namespace + ".File.PersistentChannel.IsInitializedFromFile",
false,
false
);
private readonly Property _minADC
= new Property(
typeof(PersistentChannel).Namespace + ".File.PersistentChannel.MinADC",
short.MinValue,
false);
public short MinADC
{
get
{
if (!_minADC.IsInitialized) { ComputeMinMaxADC(); }
return _minADC.Value;
}
}
private readonly Property _maxADC
= new Property(
typeof(PersistentChannel).Namespace + ".File.PersistentChannel.MaxADC",
short.MaxValue,
false);
private static readonly object MyLock = new object();
public short MaxADC
{
get
{
if (!_maxADC.IsInitialized) { ComputeMinMaxADC(); }
return _maxADC.Value;
}
}
internal void ComputeMinMaxADC()
{
var min = short.MaxValue;
var max = short.MinValue;
for (ulong sample = 0; sample < NumberOfSamples; sample++)
{
min = Math.Min(min, Data[sample]);
max = Math.Max(max, Data[sample]);
}
_minADC.Value = min;
_maxADC.Value = max;
}
///
/// Initialize an instance of this class.
///
///
///
/// The filename of the associated channel data file.
///
///
///
/// The channel header to be written into the associated channel data file.
///
///
public PersistentChannel(string filename, TDASBinaryChannelHeader channelHeader, bool overwriteIfExists)
{
try
{
IsInitializedFromFile = System.IO.File.Exists(Filename = filename);
IsMemoryMapped = false;
if (!IsInitializedFromFile || overwriteIfExists)
{
if (null == channelHeader)
throw new ArgumentNullException("channel header is required to generate new file but none was provided");
//else
// this.NumberOfTriggerSamples = channelHeader.NumberOfTriggers;
//APILogger.Log("writing 2 ", this.Filename);
//using (var mutex = new System.Threading.Mutex(false, Filename.Replace(Path.DirectorySeparatorChar, '_')))
lock (MyLock)
{
//while (!mutex.WaitOne(50, false)) { System.Threading.Thread.Sleep(5); }
//try
{
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.OpenOrCreate)))
{
var fields = Enum.GetValues(typeof(Field)).Cast().ToArray();
// convert to byte[]
//var euBA = Encoding.UTF8.GetBytes(channelHeader.EngineeringUnit);
//if (euBA.Length % 2 != 0)
//{
// var xStr = new string(channelHeader.EngineeringUnit) + ' ';
// euBA = Encoding.UTF8.GetBytes(xStr);
//}
foreach (var field in fields)
{
switch (field)
{
case Field.AcquisitionRate:
fileWriter.Write(this.channelHeader.AcquisitionRate = channelHeader.AcquisitionRate); _AcquisitionRateInitialized = true;
break;
case Field.NumberOfPostT0DataPoints:
fileWriter.Write(this.channelHeader.NumberOfPostT0DataPoints = channelHeader.NumberOfPostT0DataPoints); _NumberOfPostT0DataPointsInitialized = true;
break;
case Field.NumberOfPreT0DataPoints:
fileWriter.Write(this.channelHeader.NumberOfPreT0DataPoints = channelHeader.NumberOfPreT0DataPoints); _NumberOfPreT0DataPointsInitialized = true;
break;
case Field.PreZeroLevelInCnts:
fileWriter.Write(this.channelHeader.PreZeroLevelInCnts = channelHeader.PreZeroLevelInCnts); _PreZeroLevelInCntsInitialized = true;
break;
case Field.PreCalLevelInCnts:
fileWriter.Write(this.channelHeader.PreCalLevelInCnts = channelHeader.PreCalLevelInCnts); _PreCalLevelInCntsInitialized = true;
break;
case Field.SignalToNoiseRatioInDb:
fileWriter.Write(this.channelHeader.SignalToNoiseRatioInDb = channelHeader.SignalToNoiseRatioInDb); _SignalToNoiseRatioInDbInitialized = true;
break;
case Field.PostZeroLevelInCnts:
fileWriter.Write(this.channelHeader.PostZeroLevelInCnts = channelHeader.PostZeroLevelInCnts); _PostZeroLevelInCntsInitialized = true;
break;
case Field.PostCalLevelInCnts:
fileWriter.Write(this.channelHeader.PostCalLevelInCnts = channelHeader.PostCalLevelInCnts); _PostCalLevelInCntsInitialized = true;
break;
case Field.DataZeroLevelInCnts:
fileWriter.Write(this.channelHeader.DataZeroLevelInCnts = channelHeader.DataZeroLevelInCnts); _DataZeroLevelInCntsInitialized = true;
break;
case Field.ScaleFactorMVPerCnt:
fileWriter.Write(this.channelHeader.ScaleFactorMVPerCnt = channelHeader.ScaleFactorMVPerCnt); _ScaleFactorMVPerCntInitialized = true;
break;
case Field.ScaleFactorEUPerCnt:
fileWriter.Write(this.channelHeader.ScaleFactorEUPerCnt = channelHeader.ScaleFactorEUPerCnt); _ScaleFactorEUPerCntInitialized = true;
break;
}
}
}
}
//finally { mutex.ReleaseMutex(); }
}
}
}
catch (System.Exception ex)
{
throw new Exception("encountered problem constructing " + GetType().FullName, ex);
}
}
// xxx Make this a recursive function, with the terminating condition being a call with the first case, which
// returns the offset of "start of file".
//
public enum Field
{
AcquisitionRate, //public Double
NumberOfPreT0DataPoints, //public Int32
NumberOfPostT0DataPoints, //public Int32
PreZeroLevelInCnts, //public Int32
PreCalLevelInCnts, //public Int32
SignalToNoiseRatioInDb, //public Double
PostZeroLevelInCnts, //public Int32
PostCalLevelInCnts, //public Int32
DataZeroLevelInCnts, //public Int32
ScaleFactorMVPerCnt, //public Double
ScaleFactorEUPerCnt //public Double
}
//this is wasteful, we should improve it to use cached results when we've already computed the offset of previous fields rather than
//recursively calculating everytime ... however we don't do it much so it's probably low priority
private int GetSizeOf(Field field)
{
switch (field)
{
case Field.AcquisitionRate:
return sizeof(double);
case Field.NumberOfPostT0DataPoints:
return sizeof(int);
case Field.NumberOfPreT0DataPoints:
return sizeof(int);
case Field.PreZeroLevelInCnts:
return sizeof(int);
case Field.PreCalLevelInCnts:
return sizeof(int);
case Field.SignalToNoiseRatioInDb:
return sizeof(double);
case Field.PostZeroLevelInCnts:
return sizeof(int);
case Field.PostCalLevelInCnts:
return sizeof(int);
case Field.DataZeroLevelInCnts:
return sizeof(int);
case Field.ScaleFactorMVPerCnt:
return sizeof(double);
case Field.ScaleFactorEUPerCnt:
return sizeof(double);
}
return 0;
}
///
///
///
public int GetFileOffsetOf(Field field)
{
try
{
var offset = 0;
if (field == Field.AcquisitionRate)
{
offset = 0;
}
else
{
var previousField = (Field)(((int)field) - 1);
offset = GetFileOffsetOf(previousField) + GetSizeOf(previousField);
}
return offset;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting file offset for property", ex);
}
}
///
/// Get value indicating whether or not all necessary properties of this
/// class have been initialized to make this object useable.
///
public bool IsInitialized
{
get
{
try
{
return _AcquisitionRateInitialized
&& _NumberOfPreT0DataPointsInitialized
&& _NumberOfPostT0DataPointsInitialized
&& _PreZeroLevelInCntsInitialized
&& _PreCalLevelInCntsInitialized
&& _SignalToNoiseRatioInDbInitialized
&& _PostZeroLevelInCntsInitialized
&& _PostCalLevelInCntsInitialized
&& _DataZeroLevelInCntsInitialized
&& _ScaleFactorMVPerCntInitialized
&& _ScaleFactorEUPerCntInitialized
;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem determining initialization status", ex);
}
}
}
public bool IsDataArraySized => NumberOfSamples < int.MaxValue;
///
/// Get/set the number of trigger samples.
///
protected int NumberOfTriggerSamples
{
get;
set;
}
///
/// size of view into memory-mapped file.
///
protected int ViewSize
{
get;
set;
}
private bool _IsViewSizeInitialized = false;
///
/// to indicate whether or not a memory mapping has already been
/// established for this object.
///
protected bool IsMemoryMapped
{
get;
set;
}
///
/// Get the length of this persistent channel's data.
///
public long Length
{
get
{
try
{
if (NumberOfSamples > long.MaxValue)
throw new ApplicationException("ulong overflowed while being cast to long");
return (long)NumberOfSamples;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem determining total amount of channel data", ex);
}
}
}
///
/// Get the data count of this persistent channel's data.
///
public new int Count
{
get
{
try
{
if (Length > int.MaxValue)
throw new ApplicationException("long overflowed while being cast to int");
return (int)Length;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting channel data count", ex);
}
}
}
///
/// Override long-indexing here. Return a sample of the underlying array.
///
///
///
/// The index of the sample being affected.
///
///
///
/// The sample at the specified index.
///
///
public short this[long i]
{
get
{
try { return this[(ulong)i]; }
catch (System.Exception ex)
{
throw new Exception("encountered problem getting long-indexable value at index " + i.ToString(), ex);
}
}
set
{
try { this[(ulong)i] = value; }
catch (System.Exception ex)
{
throw new Exception("encountered problem setting long-indexable value at index " + i.ToString(), ex);
}
}
}
public void UnSet()
{
lock (MyLock)
{
_Data.Value = new short[0];
_Data.UnInitialize();
}
}
// Override indexing operator here, return a sample of the underlying array.
public short this[ulong i]
{
get
{
//using (var mutex = new System.Threading.Mutex(false, Filename.Replace(Path.DirectorySeparatorChar, '_')))
lock (MyLock)
{
//while (!mutex.WaitOne(50, false)) { System.Threading.Thread.Sleep(5); }
try
{
ulong offsetSampleDataStart = 8 + 4 + 4 + 4 + 4 + 8 + 4 + 4 + 4 + 8 + 8; // OffsetOfSampleDataStart;
if (!_IsViewSizeInitialized)
{
//
// Memory map array object map view paging math seems to be a bit
// screwed. If you don't make the page exactly the same size as the
// system memory allocation granularity, it will start returning trash
// data after the first page fault.
//
const int StandardPageSize = 65536;
if (NumberOfSamples + offsetSampleDataStart > StandardPageSize)
{
ViewSize = StandardPageSize;
}
else
{ //
// If the map size exceeds the file size, we'll get strange COM error
// codes.
//
var numberOfDataBytes = NumberOfSamples * 2;
if (numberOfDataBytes + offsetSampleDataStart > int.MaxValue)
throw new Exception("overflowed view size variable (max value: " + int.MaxValue.ToString() + ") when downcasting number of bytes in test data (" + numberOfDataBytes.ToString() + ")");
ViewSize = (int)(numberOfDataBytes + offsetSampleDataStart);
}
_IsViewSizeInitialized = true;
}
// MMBAD: Possible inefficiency. Perhaps either for "debug" build, or find some other way
// to verify this outside of the array access.
//
//if ( !IsInitialized && !IsInitializedFromFile )
// throw new NotInitializedException( "object initialization has not completed" );
//else if ( !IsMemoryMapped )
if (!IsMemoryMapped)
{
var fileInfo = new FileInfo(Filename);
// Make a new mapViewArray for the file with proper offset and
// readonly privilages to protect sample integrity.
ViewArray = new FileMapViewArray(Path.GetFullPath(Filename),
MapAccess.FileMapRead,
MapProtection.PageReadOnly,
offsetSampleDataStart,
(fileInfo.Length),
ViewSize);
IsMemoryMapped = true;
}
// MMBAD: possible inefficiency: these values are supposed to be cached, but they may be accessing
// disk each time. Can't copy at this level because all channels come through here, but it is
// supposed to be getting cached at least.
//short a = (short)((ViewArray[(long)(this.OffsetOfSampleDataStart + (2 * i))] & 0xFFFF));
//short b = (short)((ViewArray[(long)(this.OffsetOfSampleDataStart + (2 * i) + 1)] & 0xFFFF) << 8);
//rv = a;
//rv += b;
//if (rv > 20000)
//{
// int j = rv;
//}
var rv = (short)((ViewArray[(long)(offsetSampleDataStart + (2 * i))] & 0xFFFF));
rv += (short)((ViewArray[(long)(offsetSampleDataStart + (2 * i) + 1)] & 0xFFFF) << 8);
return rv;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting short value at index " + i.ToString(), ex);
}
//finally { mutex.ReleaseMutex(); }
}
}
set
{
try
{
throw new NotSupportedException("SliceRaw::File::PersistentChannel::[] Sample Data is READ_ONLY.");
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting short value at index " + i.ToString(), ex);
}
}
}
///
/// Get/set the filename of the associated channel data file.
///
public string Filename
{
get => _Filename.Value;
private set => _Filename.Value = value;
}
private readonly Property _Filename
= new Property(
typeof(PersistentChannel).Namespace + ".File.PreAllocatedChannel.Filename",
null,
false
);
///
/// Get/set data array value.
///
public short[] Data
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!IsDataArraySized)
throw new DataTooBigForArrayException("Data size (" + Count.ToString() + ") is too large to be safely handled within the application");
if (!_Data.IsInitialized)
{ //
// If we haven't handed out one of these yet, make one up and then hang onto it
// to use for subsequent requests to we don't have clones all over the place.
//
var dataArray = new short[Count];
for (var i = 0; i < dataArray.Length; i++)
dataArray[i] = this[i];
_Data.Value = dataArray;
}
return _Data.Value;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".Data property value", ex);
}
}
set
{
try
{
_Data.Value = value;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + ".Data property value", ex);
}
}
}
private readonly Property _Data
= new Property(
typeof(PersistentChannel).Namespace + ".File.PreAllocatedChannel.Data",
null,
false
);
///
/// Get/set binary writer to be used by data append session.
///
private BinaryWriter AppendSessionWriter
{
get;
set;
}
///
/// Prepare this object for repeated calls to AppendSessionData.
///
public void BeginAppendSession()
{
try
{
APILogger.Log("beginning append writes ", Filename);
AppendSessionWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open));
}
catch (System.Exception ex)
{
throw new Exception("encountered problem beginning data append session", ex);
}
}
///
/// Secure object from repeated calls to AppendSessionData.
///
public void EndAppendSession()
{
try
{
APILogger.Log("ending append writes ", Filename);
AppendSessionWriter.Close();
AppendSessionWriter.Dispose();
AppendSessionWriter = null;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem ending data append session", ex);
}
}
///
/// Object to cache header property accesses.
///
public TDASBinaryChannelHeader channelHeader = new TDASBinaryChannelHeader();
///
/// Get/set number of samples.
///
public ulong NumberOfSamples
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_NumberOfSamplesInitialized)
{
//APILogger.Log("reading 37 ", Filename);
//using (var mutex = new System.Threading.Mutex(false, Filename.Replace(Path.DirectorySeparatorChar, '_')))
lock (MyLock)
{
//while (!mutex.WaitOne(50, false)) { System.Threading.Thread.Sleep(5); }
//try
{
//long valueOffset = GetFileOffsetOf(PersistentChannel.Field.NumberOfSamples);
long valueOffset = GetFileOffsetOf(Field.NumberOfPostT0DataPoints);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open, FileAccess.Read)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
//channelHeader.NumberOfSamples = fileReader.ReadUInt64();
channelHeader.NumberOfPostT0DataPoints = (int)fileReader.ReadUInt32();
valueOffset = GetFileOffsetOf(Field.NumberOfPreT0DataPoints);
fileReader.BaseStream.Position = valueOffset;
channelHeader.NumberOfPreT0DataPoints = (int)fileReader.ReadUInt32();
fileReader.BaseStream.Position = prevPosition;
_NumberOfSamplesInitialized = true;
}
}
//finally { mutex.ReleaseMutex(); }
}
}
//return channelHeader.NumberOfSamples;
return (ulong)(channelHeader.NumberOfPostT0DataPoints + channelHeader.NumberOfPreT0DataPoints);
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".NumberOfSamples property value", ex);
}
}
}
private bool _NumberOfSamplesInitialized = false;
///
/// Get/set acquisition rate.
///
public double AcquisitionRate
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_AcquisitionRateInitialized)
{
lock (MyLock)
{
{
long valueOffset = GetFileOffsetOf(Field.AcquisitionRate);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
channelHeader.AcquisitionRate = fileReader.ReadDouble();
fileReader.BaseStream.Position = prevPosition;
_AcquisitionRateInitialized = true;
}
}
}
}
return channelHeader.AcquisitionRate;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".AcquisitionRate property value", ex);
}
}
set
{
try
{
lock (MyLock)
{
{
var offset = GetFileOffsetOf(Field.AcquisitionRate);
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open)))
{
fileWriter.Seek(offset, SeekOrigin.Begin);
fileWriter.Write(channelHeader.AcquisitionRate = value);
}
}
}
_AcquisitionRateInitialized = true;
//// If at this point the persistent channel object has been initialized, go ahead and
//// keep the CRC current.
//if (this.IsInitialized)
// this.Crc32 = channelHeader.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + ".AcquisitionRate property value", ex);
}
}
}
private bool _AcquisitionRateInitialized = false;
public int NumberOfPreT0DataPoints
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_NumberOfPreT0DataPointsInitialized)
{
lock (MyLock)
{
{
long valueOffset = GetFileOffsetOf(Field.NumberOfPreT0DataPoints);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
channelHeader.NumberOfPreT0DataPoints = fileReader.ReadInt32();
fileReader.BaseStream.Position = prevPosition;
_NumberOfPreT0DataPointsInitialized = true;
}
}
}
}
return channelHeader.NumberOfPreT0DataPoints;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".NumberOfPreT0DataPoints property value", ex);
}
}
set
{
try
{
lock (MyLock)
{
{
var offset = GetFileOffsetOf(Field.NumberOfPreT0DataPoints);
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open)))
{
fileWriter.Seek(offset, SeekOrigin.Begin);
fileWriter.Write(channelHeader.NumberOfPreT0DataPoints = value);
}
}
}
_NumberOfPreT0DataPointsInitialized = true;
//// If at this point the persistent channel object has been initialized, go ahead and
//// keep the CRC current.
//if (this.IsInitialized)
// this.Crc32 = channelHeader.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + ".NumberOfPreT0DataPoints property value", ex);
}
}
}
private bool _NumberOfPreT0DataPointsInitialized = false;
public int NumberOfPostT0DataPoints
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_NumberOfPostT0DataPointsInitialized)
{
lock (MyLock)
{
{
long valueOffset = GetFileOffsetOf(Field.NumberOfPostT0DataPoints);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
channelHeader.NumberOfPostT0DataPoints = fileReader.ReadInt32();
fileReader.BaseStream.Position = prevPosition;
_NumberOfPostT0DataPointsInitialized = true;
}
}
}
}
return channelHeader.NumberOfPostT0DataPoints;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".NumberOfPostT0DataPoints property value", ex);
}
}
set
{
try
{
lock (MyLock)
{
{
var offset = GetFileOffsetOf(Field.NumberOfPostT0DataPoints);
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open)))
{
fileWriter.Seek(offset, SeekOrigin.Begin);
fileWriter.Write(channelHeader.NumberOfPostT0DataPoints = value);
}
}
}
_NumberOfPostT0DataPointsInitialized = true;
//// If at this point the persistent channel object has been initialized, go ahead and
//// keep the CRC current.
//if (this.IsInitialized)
// this.Crc32 = channelHeader.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + ".NumberOfPostT0DataPoints property value", ex);
}
}
}
private bool _NumberOfPostT0DataPointsInitialized = false;
public int PreZeroLevelInCnts
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_PreZeroLevelInCntsInitialized)
{
lock (MyLock)
{
{
long valueOffset = GetFileOffsetOf(Field.PreZeroLevelInCnts);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
channelHeader.PreZeroLevelInCnts = fileReader.ReadInt32();
fileReader.BaseStream.Position = prevPosition;
_PreZeroLevelInCntsInitialized = true;
}
}
}
}
return channelHeader.PreZeroLevelInCnts;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".PreZeroLevelInCnts property value", ex);
}
}
set
{
try
{
lock (MyLock)
{
{
var offset = GetFileOffsetOf(Field.PreZeroLevelInCnts);
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open)))
{
fileWriter.Seek(offset, SeekOrigin.Begin);
fileWriter.Write(channelHeader.PreZeroLevelInCnts = value);
}
}
}
_PreZeroLevelInCntsInitialized = true;
//// If at this point the persistent channel object has been initialized, go ahead and
//// keep the CRC current.
//if (this.IsInitialized)
// this.Crc32 = channelHeader.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + ".PreZeroLevelInCnts property value", ex);
}
}
}
private bool _PreZeroLevelInCntsInitialized = false;
public int PreCalLevelInCnts
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_PreCalLevelInCntsInitialized)
{
lock (MyLock)
{
{
long valueOffset = GetFileOffsetOf(Field.PreCalLevelInCnts);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
channelHeader.PreCalLevelInCnts = fileReader.ReadInt32();
fileReader.BaseStream.Position = prevPosition;
_PreCalLevelInCntsInitialized = true;
}
}
}
}
return channelHeader.PreCalLevelInCnts;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".PreCalLevelInCnts property value", ex);
}
}
set
{
try
{
lock (MyLock)
{
{
var offset = GetFileOffsetOf(Field.PreCalLevelInCnts);
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open)))
{
fileWriter.Seek(offset, SeekOrigin.Begin);
fileWriter.Write(channelHeader.PreCalLevelInCnts = value);
}
}
}
_PreCalLevelInCntsInitialized = true;
//// If at this point the persistent channel object has been initialized, go ahead and
//// keep the CRC current.
//if (this.IsInitialized)
// this.Crc32 = channelHeader.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + "._PreCalLevelInCnts property value", ex);
}
}
}
private bool _PreCalLevelInCntsInitialized = false;
public double SignalToNoiseRatioInDb
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_SignalToNoiseRatioInDbInitialized)
{
lock (MyLock)
{
{
long valueOffset = GetFileOffsetOf(Field.SignalToNoiseRatioInDb);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
channelHeader.SignalToNoiseRatioInDb = fileReader.ReadDouble();
fileReader.BaseStream.Position = prevPosition;
_SignalToNoiseRatioInDbInitialized = true;
}
}
}
}
return channelHeader.SignalToNoiseRatioInDb;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".SignalToNoiseRatioInDb property value", ex);
}
}
set
{
try
{
lock (MyLock)
{
{
var offset = GetFileOffsetOf(Field.SignalToNoiseRatioInDb);
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open)))
{
fileWriter.Seek(offset, SeekOrigin.Begin);
fileWriter.Write(channelHeader.SignalToNoiseRatioInDb = value);
}
}
}
_SignalToNoiseRatioInDbInitialized = true;
//// If at this point the persistent channel object has been initialized, go ahead and
//// keep the CRC current.
//if (this.IsInitialized)
// this.Crc32 = channelHeader.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + ".SignalToNoiseRatioInDb property value", ex);
}
}
}
private bool _SignalToNoiseRatioInDbInitialized = false;
public int PostZeroLevelInCnts
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_PostZeroLevelInCntsInitialized)
{
lock (MyLock)
{
{
long valueOffset = GetFileOffsetOf(Field.PostZeroLevelInCnts);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
channelHeader.PostZeroLevelInCnts = fileReader.ReadInt32();
fileReader.BaseStream.Position = prevPosition;
_PostZeroLevelInCntsInitialized = true;
}
}
}
}
return channelHeader.PostZeroLevelInCnts;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".PostZeroLevelInCnts property value", ex);
}
}
set
{
try
{
lock (MyLock)
{
{
var offset = GetFileOffsetOf(Field.PostZeroLevelInCnts);
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open)))
{
fileWriter.Seek(offset, SeekOrigin.Begin);
fileWriter.Write(channelHeader.PostZeroLevelInCnts = value);
}
}
}
_PostZeroLevelInCntsInitialized = true;
//// If at this point the persistent channel object has been initialized, go ahead and
//// keep the CRC current.
//if (this.IsInitialized)
// this.Crc32 = channelHeader.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + ".PostZeroLevelInCnts property value", ex);
}
}
}
private bool _PostZeroLevelInCntsInitialized = false;
public int PostCalLevelInCnts
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_PostCalLevelInCntsInitialized)
{
lock (MyLock)
{
{
long valueOffset = GetFileOffsetOf(Field.PostCalLevelInCnts);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
channelHeader.PostCalLevelInCnts = fileReader.ReadInt32();
fileReader.BaseStream.Position = prevPosition;
_PostCalLevelInCntsInitialized = true;
}
}
}
}
return channelHeader.PostCalLevelInCnts;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".PostCalLevelInCnts property value", ex);
}
}
set
{
try
{
lock (MyLock)
{
{
var offset = GetFileOffsetOf(Field.PostCalLevelInCnts);
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open)))
{
fileWriter.Seek(offset, SeekOrigin.Begin);
fileWriter.Write(channelHeader.PostCalLevelInCnts = value);
}
}
}
_PostCalLevelInCntsInitialized = true;
//// If at this point the persistent channel object has been initialized, go ahead and
//// keep the CRC current.
//if (this.IsInitialized)
// this.Crc32 = channelHeader.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + ".PostCalLevelInCnts property value", ex);
}
}
}
private bool _PostCalLevelInCntsInitialized = false;
public int DataZeroLevelInCnts
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_DataZeroLevelInCntsInitialized)
{
lock (MyLock)
{
{
long valueOffset = GetFileOffsetOf(Field.DataZeroLevelInCnts);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open, FileAccess.Read)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
channelHeader.DataZeroLevelInCnts = fileReader.ReadInt32();
fileReader.BaseStream.Position = prevPosition;
_DataZeroLevelInCntsInitialized = true;
}
}
}
}
return channelHeader.DataZeroLevelInCnts;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".DataZeroLevelInCnts property value", ex);
}
}
set
{
try
{
lock (MyLock)
{
{
var offset = GetFileOffsetOf(Field.DataZeroLevelInCnts);
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open)))
{
fileWriter.Seek(offset, SeekOrigin.Begin);
fileWriter.Write(channelHeader.DataZeroLevelInCnts = value);
}
}
}
_DataZeroLevelInCntsInitialized = true;
//// If at this point the persistent channel object has been initialized, go ahead and
//// keep the CRC current.
//if (this.IsInitialized)
// this.Crc32 = channelHeader.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + ".DataZeroLevelInCnts property value", ex);
}
}
}
private bool _DataZeroLevelInCntsInitialized = false;
public double ScaleFactorMVPerCnt
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_ScaleFactorMVPerCntInitialized)
{
lock (MyLock)
{
{
long valueOffset = GetFileOffsetOf(Field.ScaleFactorMVPerCnt);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
channelHeader.ScaleFactorMVPerCnt = fileReader.ReadDouble();
fileReader.BaseStream.Position = prevPosition;
_ScaleFactorMVPerCntInitialized = true;
}
}
}
}
return channelHeader.ScaleFactorMVPerCnt;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".ScaleFactorMVPerCnt property value", ex);
}
}
set
{
try
{
lock (MyLock)
{
{
var offset = GetFileOffsetOf(Field.ScaleFactorMVPerCnt);
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open)))
{
fileWriter.Seek(offset, SeekOrigin.Begin);
fileWriter.Write(channelHeader.ScaleFactorMVPerCnt = value);
}
}
}
_ScaleFactorMVPerCntInitialized = true;
//// If at this point the persistent channel object has been initialized, go ahead and
//// keep the CRC current.
//if (this.IsInitialized)
// this.Crc32 = channelHeader.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + ".ScaleFactorMVPerCnt property value", ex);
}
}
}
private bool _ScaleFactorMVPerCntInitialized = false;
public double ScaleFactorEUPerCnt
{
get
{
try
{
if (!IsInitialized && !IsInitializedFromFile)
throw new NotInitializedException("object initialization has not completed");
if (!_ScaleFactorEUPerCntInitialized)
{
//APILogger.Log("reading 38 ", Filename);
//using (var mutex = new System.Threading.Mutex(false, Filename.Replace(Path.DirectorySeparatorChar, '_')))
lock (MyLock)
{
//while (!mutex.WaitOne(50, false)) { System.Threading.Thread.Sleep(5); }
//try
{
long valueOffset = GetFileOffsetOf(Field.ScaleFactorEUPerCnt);
using (var fileReader = new BinaryReader(new FileStream(Filename, FileMode.Open)))
{
var prevPosition = fileReader.BaseStream.Position;
fileReader.BaseStream.Position = valueOffset;
channelHeader.ScaleFactorEUPerCnt = fileReader.ReadDouble();
fileReader.BaseStream.Position = prevPosition;
_ScaleFactorEUPerCntInitialized = true;
}
}
//finally { mutex.ReleaseMutex(); }
}
}
return channelHeader.ScaleFactorEUPerCnt;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem getting " + GetType().FullName + ".ScaleFactorEUPerCnt property value", ex);
}
}
set
{
try
{
lock (MyLock)
{
{
var offset = GetFileOffsetOf(Field.ScaleFactorEUPerCnt);
using (var fileWriter = new BinaryWriter(new FileStream(Filename, FileMode.Open)))
{
fileWriter.Seek(offset, SeekOrigin.Begin);
fileWriter.Write(channelHeader.ScaleFactorEUPerCnt = value);
}
}
}
_ScaleFactorEUPerCntInitialized = true;
//// If at this point the persistent channel object has been initialized, go ahead and
//// keep the CRC current.
//if (this.IsInitialized)
// this.Crc32 = channelHeader.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem setting " + GetType().FullName + ".ScaleFactorEUPerCnt property value", ex);
}
}
}
private bool _ScaleFactorEUPerCntInitialized = false;
///
/// Get the CRC for the current state of the header.
///
//public UInt32 Crc32
//{
// get
// {
// try
// {
// if (!IsInitialized)
// throw new NotInitializedException( "object initialization has not completed" );
// else return channelHeader.Crc32;
// }
// catch ( System.Exception ex )
// {
// throw new PersistentChannel.Exception( "encountered problem getting " + this.GetType( ).FullName + ".Crc32 property value", ex );
// }
// }
// private set
// {
// try
// {
// //APILogger.Log("writing 34 ", Filename);
// //using (var mutex = new System.Threading.Mutex(false, Filename.Replace(Path.DirectorySeparatorChar, '_')))
// lock(MyLock)
// {
// //while (!mutex.WaitOne(50, false)) { System.Threading.Thread.Sleep(5); }
// //try
// {
// int offset = GetFileOffsetOf(PersistentChannel.Field.Crc32);
// using (BinaryWriter fileWriter = new BinaryWriter(new FileStream(this.Filename, FileMode.Open)))
// {
// fileWriter.Seek(offset, SeekOrigin.Begin);
// fileWriter.Write(value);
// }
// }
// //finally { mutex.ReleaseMutex(); }
// }
// }
// catch ( System.Exception ex )
// {
// throw new PersistentChannel.Exception( "encountered problem setting " + this.GetType( ).FullName + ".Crc32 property", ex );
// }
// }
//}
///
/// Populate the persistent CRC property with the CRC of the current state of the channel header.
///
public void StampCrc()
{
try
{ //
// Calling the "get" accessor for all properties will ensure that they
// are populated, which is important if the CRC is going to be running
// over them.
//
var header = new TDASBinaryChannelHeader();
header.AcquisitionRate = AcquisitionRate;
header.NumberOfPostT0DataPoints = NumberOfPostT0DataPoints;
header.NumberOfPreT0DataPoints = NumberOfPreT0DataPoints;
header.PreZeroLevelInCnts = PreZeroLevelInCnts;
header.PreCalLevelInCnts = PreCalLevelInCnts;
header.SignalToNoiseRatioInDb = SignalToNoiseRatioInDb;
header.PostZeroLevelInCnts = PostZeroLevelInCnts;
header.PostCalLevelInCnts = PostCalLevelInCnts;
header.DataZeroLevelInCnts = DataZeroLevelInCnts;
header.ScaleFactorMVPerCnt = ScaleFactorMVPerCnt;
header.ScaleFactorEUPerCnt = ScaleFactorEUPerCnt;
//this.Crc32 = channelHeader.Crc32;
//this.Crc32 = header.Crc32;
}
catch (System.Exception ex)
{
throw new Exception("encountered problem stamping persistent channel CRC", ex);
}
}
///
/// Dispose of this object's Disposables.
///
public void Dispose()
{
//using (var mutex = new System.Threading.Mutex(false, Filename.Replace(Path.DirectorySeparatorChar, '_')))
lock (MyLock)
{
//while (!mutex.WaitOne(50, false)) { System.Threading.Thread.Sleep(5); }
try
{
if (_ViewArray.IsInitialized)
{
IsMemoryMapped = false; //Is this right?
}
try
{
ViewArray.Dispose();
}
catch (System.Exception) { }
}
catch (System.Exception ex)
{
// If the ViewArray was not yet initialized, that's OK. Eat the exception
if (null == ex.InnerException || ex.InnerException.GetType() != typeof(Property.NotInitializedException))
{
throw new Exception("encountered problem disposing of " + GetType().FullName, ex);
}
}
//finally { mutex.ReleaseMutex(); }
}
}
}
}
}