Big changes
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Singleton for holding onto message objects
|
||||
/// </summary>
|
||||
public class AutomationRxMsgBuffer
|
||||
{
|
||||
// class variables
|
||||
private static AutomationRxMsgBuffer _AutomationRxMsgBufferInstance;
|
||||
private static object _syncObj = new object();
|
||||
private Dictionary<uint, List<AutomationMessage>> _msgList;
|
||||
private Dictionary<uint, AutoResetEvent> _receivedMsgEvents;
|
||||
private List<uint> _msgIds;
|
||||
|
||||
/// <summary>
|
||||
/// The way to get access to this singleton
|
||||
/// </summary>
|
||||
/// <returns>the instance to this class</returns>
|
||||
public static AutomationRxMsgBuffer Instance(List<uint> msgIds = null)
|
||||
{
|
||||
if (_AutomationRxMsgBufferInstance == null)
|
||||
{
|
||||
_AutomationRxMsgBufferInstance = new AutomationRxMsgBuffer(msgIds);
|
||||
}
|
||||
|
||||
return _AutomationRxMsgBufferInstance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a message to this buffer
|
||||
/// </summary>
|
||||
/// <param name="msg">The message to add</param>
|
||||
/// <param name="shouldWeDeleteOthers">flag for if the other messages of this type should be deleted from the buffer</param>
|
||||
public void AddMsg(AutomationMessage msg, bool shouldWeDeleteOthers = true)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
uint msgId = msg.GetMessageId();
|
||||
|
||||
if (shouldWeDeleteOthers == true)
|
||||
{
|
||||
ClearList(msgId);
|
||||
}
|
||||
|
||||
if (_msgList.ContainsKey(msgId) == false)
|
||||
{
|
||||
_msgList[msgId] = new List<AutomationMessage>();
|
||||
}
|
||||
|
||||
_msgList[msgId].Add(msg);
|
||||
|
||||
_receivedMsgEvents[msgId].Set();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all messages from the buffer
|
||||
/// </summary>
|
||||
public void ClearAllMsgs()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
foreach (uint id in _msgList.Keys)
|
||||
{
|
||||
ClearList(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all messages of the command type from the buffer
|
||||
/// </summary>
|
||||
/// <param name="id">The message id to remove</param>
|
||||
public void ClearList(uint id)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_msgList.ContainsKey(id) == true)
|
||||
{
|
||||
_msgList[id].Clear();
|
||||
|
||||
_msgList.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the oldest message in the buffer
|
||||
/// </summary>
|
||||
/// <param name="id">The id of the message to get</param>
|
||||
/// <returns>The oldest message in the buffer</returns>
|
||||
public AutomationMessage GetOldestMessage(uint id)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_msgList.ContainsKey(id))
|
||||
{
|
||||
List<AutomationMessage> list = _msgList[id];
|
||||
|
||||
AutomationMessage oldestMsg = list[0];
|
||||
|
||||
list.RemoveAt(0);
|
||||
|
||||
return oldestMsg;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("no message exists with id: " + id.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the most recent message from the buffer
|
||||
/// </summary>
|
||||
/// <param name="id">The id of the message to get</param>
|
||||
/// <param name="shouldWeDeleteOthers">flag controlling if the other messages of this type should be deleted</param>
|
||||
/// <returns>The message</returns>
|
||||
public AutomationMessage GetNewestMessage(uint id, bool shouldWeDeleteOthers = true)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_msgList.ContainsKey(id))
|
||||
{
|
||||
List<AutomationMessage> list = _msgList[id];
|
||||
|
||||
AutomationMessage newestMsg = list[list.Count - 1];
|
||||
|
||||
list.RemoveAt(list.Count - 1);
|
||||
|
||||
if (shouldWeDeleteOthers == true)
|
||||
{
|
||||
ClearList(id);
|
||||
}
|
||||
|
||||
return newestMsg;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("no message exists with id: " + id.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the number of messages of this type in the buffer
|
||||
/// </summary>
|
||||
/// <param name="id">The id of the message to get</param>
|
||||
/// <returns>the number of messages of this type in the buffer</returns>
|
||||
public int GetNumMsgsInQueue(uint id)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
if (_msgList.ContainsKey(id) == true)
|
||||
{
|
||||
return _msgList[id].Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
public void ResetRxEvent(uint id)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_receivedMsgEvents[id].Reset();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wait for a message to get added to the buffer
|
||||
/// </summary>
|
||||
/// <param name="id">The message id to wait for</param>
|
||||
/// <param name="timeoutMs">The amount of time in ms to wait</param>
|
||||
/// <returns>true if the message arrived, false if it did not</returns>
|
||||
public bool WaitForRspMsg(uint id, int timeoutMs)
|
||||
{
|
||||
return _receivedMsgEvents[id].WaitOne(timeoutMs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The constructor
|
||||
/// </summary>
|
||||
private AutomationRxMsgBuffer(List<uint> msgIds)
|
||||
{
|
||||
_msgList = new Dictionary<uint, List<AutomationMessage>>();
|
||||
|
||||
_msgIds = msgIds;
|
||||
|
||||
// create an event for each msg.
|
||||
_receivedMsgEvents = new Dictionary<uint, AutoResetEvent>();
|
||||
|
||||
foreach (uint id in _msgIds)
|
||||
{
|
||||
_receivedMsgEvents[id] = new AutoResetEvent(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Source/TSRealLib/Common/Raytheon.Common/Lib/Constants.cs
Normal file
28
Source/TSRealLib/Common/Raytheon.Common/Lib/Constants.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// A spot to hold application constants
|
||||
/// </summary>
|
||||
public static class Constants
|
||||
{
|
||||
public const string InstrumentConfigFolder = "InstrumentConfig";
|
||||
}
|
||||
}
|
||||
|
||||
324
Source/TSRealLib/Common/Raytheon.Common/Lib/DataBuffer.cs
Normal file
324
Source/TSRealLib/Common/Raytheon.Common/Lib/DataBuffer.cs
Normal file
@@ -0,0 +1,324 @@
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// this class is a container. It acts like an array that allows bytes to be removed from its
|
||||
/// front. When bytes are removed, the beginning of the buffer moves to the byte following
|
||||
/// those which were removed. A typical use of this is to AddData(), then use CheckOutStartOfData()/CheckInStartOfData to get
|
||||
/// a pointer to the data and the amount of bytes that the pointer points to.
|
||||
/// </summary>
|
||||
public class DataBuffer: IDisposable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private unsafe byte[] _buffer;
|
||||
private uint _endOfDataIndex; // index of last used byte
|
||||
private uint _startOfDataIndex = uint.MaxValue; // index of first used byte, MaxValue means that buffer is empty
|
||||
private uint _startOfCheckedOutDataIndex = uint.MaxValue; // index of first used byte, MaxValue means that buffer is empty
|
||||
|
||||
private static object _syncObj = new Object();
|
||||
private IntPtr _pStartOfBuffer;
|
||||
private IntPtr _pStartOfCheckedOutData;
|
||||
private GCHandle _pinnedArray;
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// The constructor which allocates a byte array and pins it so we can return byte*s in StartOfData()
|
||||
/// </summary>
|
||||
/// <param name="bufferSize">The number of bytes in the data buffer</param>
|
||||
public DataBuffer(uint bufferSize)
|
||||
{
|
||||
_buffer = new byte[bufferSize];
|
||||
_pinnedArray = GCHandle.Alloc(_buffer, GCHandleType.Pinned);
|
||||
_pStartOfBuffer = _pinnedArray.AddrOfPinnedObject();
|
||||
_pStartOfCheckedOutData = IntPtr.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The finalizer
|
||||
/// </summary>
|
||||
~DataBuffer()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// adds bytes to the buffer
|
||||
/// throws exception if requesting to add more bytes than entire buffer will hold.
|
||||
/// throws an exception if data is checked out and this call attempts to overwrite the checked out data
|
||||
/// </summary>
|
||||
/// <param name="data">array from which to add bytes to buffer</param>
|
||||
/// <param name="numBytesToAdd"># if bytes from array to add to buffer</param>
|
||||
public void Add(byte[] data, uint numBytesToAdd)
|
||||
{
|
||||
// get exclusive access to array, indexes...
|
||||
lock (_syncObj)
|
||||
{
|
||||
uint numBytesCurrentlyUsed = BytesUsed;
|
||||
|
||||
// not enough room in entire buffer?
|
||||
if (numBytesToAdd > (_buffer.Length - numBytesCurrentlyUsed))
|
||||
{
|
||||
throw new Exception("DataBuffer::Add() - Not enough room in buffer for data - need to increase size of buffer");
|
||||
}
|
||||
|
||||
// empty buffer?
|
||||
if (_startOfDataIndex == UInt32.MaxValue)
|
||||
{
|
||||
Array.Copy(data, _buffer, numBytesToAdd);
|
||||
_startOfDataIndex = 0;
|
||||
_endOfDataIndex = numBytesToAdd - 1;
|
||||
}
|
||||
else // not empty
|
||||
{
|
||||
// not enough room at end?
|
||||
if (numBytesToAdd > (_buffer.Length - _endOfDataIndex - 1))
|
||||
{
|
||||
// make sure not overwritting checked out data
|
||||
ulong afterShiftEndOfDataAddy = (ulong)_pStartOfBuffer + numBytesCurrentlyUsed - 1 + numBytesToAdd;
|
||||
|
||||
if (_pStartOfCheckedOutData != IntPtr.Zero &&
|
||||
afterShiftEndOfDataAddy >= (ulong)_pStartOfCheckedOutData)
|
||||
{
|
||||
throw new Exception("DataBuffer::Add() - attempting to overwrite data that is checked out (when shifting data to beginning)");
|
||||
}
|
||||
|
||||
// shuffle to front of buffer
|
||||
Array.Copy(_buffer, _startOfDataIndex, _buffer, 0, BytesUsed);
|
||||
_endOfDataIndex = BytesUsed - 1;
|
||||
_startOfDataIndex = 0;
|
||||
}
|
||||
else if (_pStartOfCheckedOutData != IntPtr.Zero)
|
||||
{
|
||||
// make sure not trying to overwrite data when it is checked out
|
||||
ulong endOfDataAddress = (ulong)_pStartOfBuffer + _endOfDataIndex;
|
||||
|
||||
if (endOfDataAddress < (ulong)_pStartOfCheckedOutData &&
|
||||
endOfDataAddress + numBytesToAdd >= (ulong)_pStartOfCheckedOutData)
|
||||
{
|
||||
throw new Exception("DataBuffer::Add() - attempting to overwrite data that is checked out");
|
||||
}
|
||||
}
|
||||
|
||||
Array.Copy(data, 0, _buffer, _endOfDataIndex + 1, numBytesToAdd);
|
||||
_endOfDataIndex += numBytesToAdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns # of bytes used in buffer
|
||||
/// </summary>
|
||||
public uint BytesUsed
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
// is buffer empty?
|
||||
if (_startOfDataIndex == uint.MaxValue)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _endOfDataIndex - _startOfDataIndex + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks in the data. This should be used after a call to CheckOutStartOfData()
|
||||
/// </summary>
|
||||
public void CheckInStartOfData()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
_pStartOfCheckedOutData = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This returns a pointer to the start of the new data
|
||||
/// </summary>
|
||||
/// <param name="numBytesInReturnedBuffer">The number of bytes that the returned pointer contains</param>
|
||||
/// <returns>A pointer to the data</returns>
|
||||
public IntPtr CheckOutStartOfData(ref uint numBytesInReturnedBuffer)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
// hold onto the start index of the checked out data
|
||||
_startOfCheckedOutDataIndex = _startOfDataIndex;
|
||||
|
||||
numBytesInReturnedBuffer = 0;
|
||||
|
||||
// if nothing is in the buffer, _startOfCheckedOutDataIndex will be MaxValue
|
||||
if (_startOfCheckedOutDataIndex != uint.MaxValue)
|
||||
{
|
||||
// wrap around condition
|
||||
if (_endOfDataIndex < _startOfCheckedOutDataIndex)
|
||||
{
|
||||
// set the number of bytes from start of data to the end of the buffer
|
||||
numBytesInReturnedBuffer = (uint)_buffer.Length - _startOfCheckedOutDataIndex + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
numBytesInReturnedBuffer = _endOfDataIndex - _startOfCheckedOutDataIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
_pStartOfCheckedOutData = IntPtr.Add(_pStartOfBuffer, (int)_startOfCheckedOutDataIndex);
|
||||
|
||||
return _pStartOfCheckedOutData;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies data into specified array from buffer
|
||||
/// Throws exception if asking to copy more bytes than buffer contains
|
||||
/// </summary>
|
||||
/// <param name="data">array into which to copy data from buffer</param>
|
||||
/// <param name="numBytesToCopy"># bytes to copy from buffer to array</param>
|
||||
public void Copy(ref byte[] data, uint numBytesToCopy)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
// asking to copy more bytes than we have?
|
||||
if (numBytesToCopy > BytesUsed)
|
||||
{
|
||||
throw new Exception("DataBuffer::Copy() - Asking to copy more bytes than exist in buffer");
|
||||
}
|
||||
|
||||
Array.Copy(_buffer, _startOfDataIndex, data, 0, numBytesToCopy);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of resources
|
||||
/// </summary>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly")]
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the buffer
|
||||
/// </summary>
|
||||
/// <returns>returns the number of bytes of the buffer.</returns>
|
||||
public uint GetSize()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
return (uint)(_buffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes data from the buffer
|
||||
/// </summary>
|
||||
/// <param name="numBytesToRemove">The number of bytes to remove</param>
|
||||
public void Remove(uint numBytesToRemove)
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
// asking to remove more bytes than we have?
|
||||
if (numBytesToRemove > BytesUsed)
|
||||
{
|
||||
throw new Exception("DataBuffer::Remove() - Requested to remove more bytes than exist in buffer");
|
||||
}
|
||||
|
||||
// remove all bytes?
|
||||
if (numBytesToRemove == BytesUsed)
|
||||
{
|
||||
_startOfDataIndex = UInt32.MaxValue;
|
||||
|
||||
// all of the data is gone, need to set the _pStartOfCheckedOutData back to zero to prevent a race condition between adding data and the host checking the data back in
|
||||
_pStartOfCheckedOutData = IntPtr.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
_startOfDataIndex += numBytesToRemove;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all data from the buffer
|
||||
/// </summary>
|
||||
public void RemoveAll()
|
||||
{
|
||||
lock (_syncObj)
|
||||
{
|
||||
Remove(BytesUsed);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of resources
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_pinnedArray.Free();
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
123
Source/TSRealLib/Common/Raytheon.Common/Lib/ErrorLogger.cs
Normal file
123
Source/TSRealLib/Common/Raytheon.Common/Lib/ErrorLogger.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Singleton for logging debug information and errors.
|
||||
/// </summary>
|
||||
public class ErrorLogger : IDisposable
|
||||
{
|
||||
#region PublicClassMembers
|
||||
|
||||
/// <summary>
|
||||
/// Enum for tagging the logged data.
|
||||
/// </summary>
|
||||
public enum LogLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// (Ordinal = 0) : Most verbose level. Used for development and seldom enabled in production.
|
||||
/// </summary>
|
||||
TRACE,
|
||||
/// <summary>
|
||||
/// (Ordinal = 1) : Debugging the application behavior from internal events of interest.
|
||||
/// </summary>
|
||||
DEBUG,
|
||||
/// <summary>
|
||||
/// An informational log statement.
|
||||
/// (Ordinal = 2) : Information that highlights progress or application lifetime events.
|
||||
/// </summary>
|
||||
INFO,
|
||||
/// <summary>
|
||||
/// (Ordinal = 3) : Warnings about validation issues or temporary failures that can be recovered.
|
||||
/// </summary>
|
||||
WARN,
|
||||
/// <summary>
|
||||
/// (Ordinal = 4) : Errors where functionality has failed or <see cref="System.Exception"/> have been caught.
|
||||
/// an error log statement.
|
||||
/// </summary>
|
||||
ERROR,
|
||||
/// <summary>
|
||||
/// (Ordinal = 5) : Most critical level. Application is about to abort.
|
||||
/// </summary>
|
||||
FATAL
|
||||
}
|
||||
|
||||
private readonly ILogger _logger;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateClassMembers
|
||||
private static ErrorLogger _errorLoggerInstance;
|
||||
#endregion
|
||||
|
||||
#region PublicClassFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Getter for this singleton.
|
||||
/// </summary>
|
||||
/// <param name="loggername">File location for Log.</param>
|
||||
/// <returns>The instance of this class.</returns>
|
||||
public static ErrorLogger Instance(string loggername = "CTS")
|
||||
{
|
||||
if (_errorLoggerInstance == null)
|
||||
{
|
||||
_errorLoggerInstance = new ErrorLogger(loggername);
|
||||
}
|
||||
|
||||
return _errorLoggerInstance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="logDestination">The logger destination</param>
|
||||
/// <param name="logname">The location of the file to write to.</param>
|
||||
/// <param name="form"></param>
|
||||
private ErrorLogger(string logname)
|
||||
{
|
||||
_logger = LogManager.GetLogger(logname);
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
//TODO: Unhandled exception if no nlog.config
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write data to the log file.
|
||||
/// </summary>
|
||||
/// <param name="message">The data to write.</param>
|
||||
public void Write(string message, LogLevel logLevel = LogLevel.ERROR)
|
||||
{
|
||||
_logger.Log(NLog.LogLevel.FromOrdinal((int)logLevel), message);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
450
Source/TSRealLib/Common/Raytheon.Common/Lib/ExcelReader.cs
Normal file
450
Source/TSRealLib/Common/Raytheon.Common/Lib/ExcelReader.cs
Normal file
@@ -0,0 +1,450 @@
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
using Microsoft.Office.Interop.Excel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface to an excel workbook
|
||||
/// </summary>
|
||||
public class ExcelReader : IDisposable
|
||||
{
|
||||
#region PublicClassMembers
|
||||
public struct CellRowInfo
|
||||
{
|
||||
public int _colNumber;
|
||||
public string _cellValue;
|
||||
|
||||
internal CellRowInfo(int colNumber, string cellValue)
|
||||
{
|
||||
_colNumber = colNumber;
|
||||
_cellValue = cellValue;
|
||||
}
|
||||
};
|
||||
#endregion
|
||||
|
||||
#region PrivateClassMembers
|
||||
private readonly string _fileName;
|
||||
private Application _excelApp;
|
||||
private _Workbook _excelWorkBook;
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// The constructor.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The excel file name (full path)</param>
|
||||
public ExcelReader(string fileName)
|
||||
{
|
||||
_fileName = System.IO.Path.GetFullPath(fileName);
|
||||
|
||||
bool doesFileExist = File.Exists(_fileName);
|
||||
|
||||
if (doesFileExist == false)
|
||||
{
|
||||
throw new Exception("ExcelReader::ExcelReader() - File: " + fileName + " Does not exist");
|
||||
}
|
||||
|
||||
//Start Excel and get Application object.
|
||||
_excelApp = new Application();
|
||||
_excelApp.Visible = false;
|
||||
|
||||
_excelWorkBook = _excelApp.Workbooks.Open(_fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
~ExcelReader()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sheetName"></param>
|
||||
/// <param name="rows"></param>
|
||||
public void AddRows(string sheetName, List<List<ExcelReader.CellRowInfo>> rows)
|
||||
{
|
||||
_Worksheet sheet = null;
|
||||
Range excelRange = null;
|
||||
|
||||
try
|
||||
{
|
||||
sheet = _excelWorkBook.Sheets[sheetName];
|
||||
sheet.Select(Type.Missing);
|
||||
excelRange = sheet.UsedRange;
|
||||
|
||||
int rowCount = excelRange.Rows.Count;
|
||||
int colCount = excelRange.Columns.Count;
|
||||
int newRowNumber = rowCount + 1;
|
||||
|
||||
// insert the new rows
|
||||
string insertCommand = newRowNumber.ToString() + ":" + (newRowNumber + rows.Count).ToString();
|
||||
|
||||
sheet.Range[insertCommand].Insert();
|
||||
|
||||
// fill the cell values
|
||||
foreach (List<ExcelReader.CellRowInfo> cellInfoList in rows)
|
||||
{
|
||||
foreach (CellRowInfo cellInfo in cellInfoList)
|
||||
{
|
||||
Range cell = sheet.Cells[newRowNumber, cellInfo._colNumber];
|
||||
cell.Value = cellInfo._cellValue;
|
||||
}
|
||||
|
||||
newRowNumber++;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.ReleaseComObject(excelRange);
|
||||
Marshal.ReleaseComObject(sheet);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sheetName"></param>
|
||||
/// <param name="rowValues"></param>
|
||||
/*public void AddRow(string sheetName, List<CellRowInfo> rowValues)
|
||||
{
|
||||
_Worksheet sheet = null;
|
||||
Range excelRange = null;
|
||||
|
||||
try
|
||||
{
|
||||
sheet = _excelWorkBook.Sheets[sheetName];
|
||||
sheet.Select(Type.Missing);
|
||||
excelRange = sheet.UsedRange;
|
||||
|
||||
int rowCount = excelRange.Rows.Count;
|
||||
int colCount = excelRange.Columns.Count;
|
||||
int newRowNumber = rowCount + 1;
|
||||
|
||||
// insert the new row
|
||||
sheet.Rows[rowCount].Insert(newRowNumber);
|
||||
|
||||
// set each cell to empty string
|
||||
int col = 1;
|
||||
while (col < colCount)
|
||||
{
|
||||
Range cell = sheet.Cells[newRowNumber, col];
|
||||
cell.Value = "";
|
||||
col++;
|
||||
}
|
||||
|
||||
// fill the cell values
|
||||
foreach (CellRowInfo cellInfo in rowValues)
|
||||
{
|
||||
Range cell = sheet.Cells[newRowNumber, cellInfo.colNumber];
|
||||
cell.Value = cellInfo.cellValue;
|
||||
col++;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.ReleaseComObject(excelRange);
|
||||
Marshal.ReleaseComObject(sheet);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sheetName"></param>
|
||||
/// <param name="rowValues"></param>
|
||||
public void AddRow(string sheetName, List<string> rowValues)
|
||||
{
|
||||
_Worksheet sheet = null;
|
||||
Range excelRange = null;
|
||||
|
||||
try
|
||||
{
|
||||
sheet = _excelWorkBook.Sheets[sheetName];
|
||||
sheet.Select(Type.Missing);
|
||||
excelRange = sheet.UsedRange;
|
||||
|
||||
int rowCount = excelRange.Rows.Count;
|
||||
int colCount = excelRange.Columns.Count;
|
||||
int newRowNumber = rowCount + 1;
|
||||
|
||||
// insert the new row
|
||||
sheet.Rows[rowCount].Insert(newRowNumber);
|
||||
|
||||
// set each cell to empty string
|
||||
int col = 1;
|
||||
while (col < colCount)
|
||||
{
|
||||
Range cell = sheet.Cells[newRowNumber, col];
|
||||
cell.Value = "";
|
||||
col++;
|
||||
}
|
||||
|
||||
// fill the cell values
|
||||
foreach (string cellValue in rowValues)
|
||||
{
|
||||
Range cell = sheet.Cells[newRowNumber, col];
|
||||
cell.Value = cellValue;
|
||||
col++;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.ReleaseComObject(excelRange);
|
||||
Marshal.ReleaseComObject(sheet);
|
||||
}
|
||||
}*/
|
||||
|
||||
public void ColorCell(string sheetName, int row, int col, System.Drawing.Color color)
|
||||
{
|
||||
_Worksheet sheet = null;
|
||||
Range excelRange = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (row < 1 || col < 1)
|
||||
{
|
||||
throw new Exception("ExcelReader::ColorCell() - row and col inputs must be greater than 0");
|
||||
}
|
||||
|
||||
sheet = _excelWorkBook.Sheets[sheetName];
|
||||
sheet.Select(Type.Missing);
|
||||
excelRange = sheet.UsedRange;
|
||||
|
||||
Range cell = sheet.Cells[row, col];
|
||||
|
||||
cell.Interior.Color = color;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.ReleaseComObject(excelRange);
|
||||
Marshal.ReleaseComObject(sheet);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<string> ReadAllSheetNames()
|
||||
{
|
||||
List<string> sheetList = new List<string>();
|
||||
|
||||
foreach (_Worksheet temp in _excelWorkBook.Sheets)
|
||||
{
|
||||
sheetList.Add(temp.Name.ToUpper());
|
||||
}
|
||||
|
||||
return sheetList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sheetName"></param>
|
||||
/// <param name="startingRow"></param>
|
||||
/// <param name="startingCol"></param>
|
||||
/// <returns></returns>
|
||||
public string ReadAllRows(string sheetName, int startingRow, int startingCol)
|
||||
{
|
||||
_Worksheet sheet = null;
|
||||
Range excelRange = null;
|
||||
|
||||
try
|
||||
{
|
||||
ErrorLogger.Instance().Write("ExcelReader::ReadAllRows() - for sheet " + sheetName, ErrorLogger.LogLevel.INFO);
|
||||
|
||||
if (startingRow < 1 || startingCol < 1)
|
||||
{
|
||||
throw new Exception("ExcelReader::ReadAllRows() - startingRow and startingCol inputs must be greater than 0");
|
||||
}
|
||||
|
||||
// check to see if the requested sheet exists.
|
||||
bool doesSheetExist = false;
|
||||
foreach (_Worksheet temp in _excelWorkBook.Sheets)
|
||||
{
|
||||
if (temp.Name.ToUpper() == sheetName.ToUpper())
|
||||
{
|
||||
doesSheetExist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// give a nice error if it doesnt exist
|
||||
if (doesSheetExist == false)
|
||||
{
|
||||
throw new Exception("ExcelReader::ReadAllRows() - sheet: " + sheetName + " does not exist in file: " + _fileName);
|
||||
}
|
||||
|
||||
sheet = _excelWorkBook.Sheets[sheetName];
|
||||
sheet.Select(Type.Missing);
|
||||
excelRange = sheet.UsedRange;
|
||||
|
||||
string allRows = "";
|
||||
|
||||
int rowCount = excelRange.Rows.Count;
|
||||
int colCount = excelRange.Columns.Count;
|
||||
|
||||
for (int currentRowIndex = startingRow; currentRowIndex <= rowCount; currentRowIndex++)
|
||||
{
|
||||
string currentRowData = "";
|
||||
for (int currentColIndex = startingCol; currentColIndex <= colCount; currentColIndex++)
|
||||
{
|
||||
if (excelRange.Cells[currentRowIndex, currentColIndex] != null)
|
||||
{
|
||||
if (excelRange.Cells[currentRowIndex, currentColIndex].Value2 == null)
|
||||
{
|
||||
currentRowData += ",";
|
||||
}
|
||||
else
|
||||
{
|
||||
string cellValue = excelRange.Cells[currentRowIndex, currentColIndex].Value2.ToString();
|
||||
cellValue = cellValue.Replace(',', ' ');
|
||||
currentRowData += cellValue + ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove any newlines
|
||||
currentRowData = currentRowData.Replace('\n', ' ');
|
||||
|
||||
// strip off the last comma and add the newline
|
||||
currentRowData = currentRowData.TrimEnd(',');
|
||||
allRows += currentRowData + "\n";
|
||||
}
|
||||
|
||||
// remove the \n at the end of the string
|
||||
allRows = allRows.TrimEnd('\n');
|
||||
|
||||
return allRows;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (excelRange != null)
|
||||
{
|
||||
Marshal.ReleaseComObject(excelRange);
|
||||
}
|
||||
|
||||
if (sheet != null)
|
||||
{
|
||||
Marshal.ReleaseComObject(sheet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
public void SaveAs(string fileName)
|
||||
{
|
||||
_excelWorkBook.SaveAs(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
//close and release
|
||||
if (_excelWorkBook != null)
|
||||
{
|
||||
_excelWorkBook.Close();
|
||||
Marshal.ReleaseComObject(_excelWorkBook);
|
||||
}
|
||||
|
||||
//quit and release
|
||||
if (_excelApp != null)
|
||||
{
|
||||
_excelApp.Quit();
|
||||
Marshal.ReleaseComObject(_excelApp);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
try
|
||||
{
|
||||
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Do not rethrow. Exception from error logger that has already been garbage collected
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
183
Source/TSRealLib/Common/Raytheon.Common/Lib/IniFile.cs
Normal file
183
Source/TSRealLib/Common/Raytheon.Common/Lib/IniFile.cs
Normal file
@@ -0,0 +1,183 @@
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Read/Write to an ini file.
|
||||
/// </summary>
|
||||
public class IniFile
|
||||
{
|
||||
#region PrivateMemberVariables
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal static class NativeMethods
|
||||
{
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, string lpReturnedstring, int nSize, string lpFileName);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string line, string lpFileName);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern int GetPrivateProfileSectionNames(byte[] sections, int bufferSize, string filename);
|
||||
}
|
||||
|
||||
private readonly string _fileName;
|
||||
|
||||
#endregion
|
||||
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
/// The constructor. It will check to make sure the file exists and throw an exception it if does not
|
||||
/// </summary>
|
||||
/// <param name="fileName">The ini file name (path).</param>
|
||||
public IniFile(string fileName)
|
||||
{
|
||||
_fileName = fileName;
|
||||
|
||||
if (File.Exists(_fileName) == false)
|
||||
{
|
||||
throw new Exception("IniFile::IniFile() - The file does not exist: " + _fileName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads from the ini file.
|
||||
/// </summary>
|
||||
/// <param name="section">The section.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <returns>The value.</returns>
|
||||
public string ReadValue(string section, string key)
|
||||
{
|
||||
// just a swag
|
||||
const int BUFFER_SIZE = 10240;
|
||||
|
||||
string temp = new string('\0', BUFFER_SIZE);
|
||||
|
||||
int numBytes = NativeMethods.GetPrivateProfileString(section, key, "", temp, BUFFER_SIZE, _fileName);
|
||||
|
||||
if (numBytes == 0)
|
||||
{
|
||||
throw new Exception("IniFile::ReadValue() - GetPrivateProfilestring returned 0 bytes for section: " + section + ", key: " + key);
|
||||
}
|
||||
|
||||
temp = temp.TrimEnd('\0');
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads all keys from a section of an ini file.
|
||||
/// </summary>
|
||||
/// <param name="section">The section.</param>
|
||||
/// <returns>A list of all keys.</returns>
|
||||
public List<string> ReadAllKeys(string section)
|
||||
{
|
||||
// just a swag
|
||||
const int BUFFER_SIZE = 102400;
|
||||
|
||||
string temp = new string('\0', BUFFER_SIZE);
|
||||
|
||||
int numBytes = NativeMethods.GetPrivateProfileString(section, null, "", temp, BUFFER_SIZE, _fileName);
|
||||
|
||||
if (numBytes == 0)
|
||||
{
|
||||
List<string> keyList = new List<string>();
|
||||
return keyList;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = temp.TrimEnd('\0');
|
||||
|
||||
List<string> keyList = new List<string>(temp.Split('\0'));
|
||||
|
||||
return keyList;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of all of the sections in the ini file.
|
||||
/// </summary>
|
||||
/// <returns>A list of all sections.</returns>
|
||||
public List<string> ReadAllSections()
|
||||
{
|
||||
// just a swag
|
||||
const int BUFFER_SIZE = 102040;
|
||||
|
||||
// allocate a 10K buffer. Should be enough to handle plenty of power systems
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
|
||||
int numBytesReturned = NativeMethods.GetPrivateProfileSectionNames(buffer, BUFFER_SIZE, _fileName);
|
||||
|
||||
if (numBytesReturned == BUFFER_SIZE)
|
||||
{
|
||||
throw new Exception("IniFile::ReadAllSections() - returned the max buffer size. Probably have more items in config file than we can handle");
|
||||
}
|
||||
else if (numBytesReturned == 0)
|
||||
{
|
||||
throw new Exception("IniFile::ReadAllSections() - GetPrivateProfileSectionNames returned 0 bytes");
|
||||
}
|
||||
|
||||
// convert the buffer to a string
|
||||
string result = System.Text.Encoding.Unicode.GetString(buffer);
|
||||
|
||||
// trim the end of the string
|
||||
result = result.TrimEnd('\0');
|
||||
|
||||
// split the string
|
||||
string[] sectionListTemp = result.Split('\0');
|
||||
|
||||
// ass the sections to a list
|
||||
List<string> sectionList = new List<string>();
|
||||
|
||||
for (int i = 0; i < sectionListTemp.Length; ++i)
|
||||
{
|
||||
sectionList.Add(sectionListTemp[i]);
|
||||
}
|
||||
|
||||
return sectionList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="lineToWrite"></param>
|
||||
public void WriteValue(string section, string key, string lineToWrite)
|
||||
{
|
||||
bool success = NativeMethods.WritePrivateProfileString(section, key, lineToWrite, _fileName);
|
||||
|
||||
if (success == false)
|
||||
{
|
||||
throw new Exception("IniFile::WriteValue() - WritePrivateProfileString returned false for section: " + section + ", key: " + key + " , line: " + lineToWrite);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
316
Source/TSRealLib/Common/Raytheon.Common/Lib/MemoryMap.cs
Normal file
316
Source/TSRealLib/Common/Raytheon.Common/Lib/MemoryMap.cs
Normal file
@@ -0,0 +1,316 @@
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that reads a memory map upon construction and then serves up the fields of an entry upon request
|
||||
/// </summary>
|
||||
public class MemoryMap
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
public struct MemoryMapFields
|
||||
{
|
||||
public readonly uint _page;
|
||||
public readonly uint _address;
|
||||
public readonly int _startBit;
|
||||
public readonly int _numBits;
|
||||
public readonly uint _regDefault;
|
||||
public readonly double _scaleFactor;
|
||||
|
||||
public MemoryMapFields(uint page, uint address, int startBit, int numBits, uint regDefault, double scaleFactor)
|
||||
{
|
||||
_page = page;
|
||||
_address = address;
|
||||
_startBit = startBit;
|
||||
_numBits = numBits;
|
||||
_regDefault = regDefault;
|
||||
_scaleFactor = scaleFactor;
|
||||
}
|
||||
}
|
||||
|
||||
private struct BitInfo
|
||||
{
|
||||
public int _start;
|
||||
public int _numOfBits;
|
||||
}
|
||||
|
||||
private const string _NEWLINE = "\r\n";
|
||||
private Dictionary<string, MemoryMapFields> _mapData;
|
||||
private double _scaleFactor = 1.0;
|
||||
#endregion
|
||||
|
||||
#region PrivateFuctions
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fileLocation"></param>
|
||||
/// <returns></returns>
|
||||
private Dictionary<string, MemoryMapFields> CreateMemoryMapDictionary(string fileLocation)
|
||||
{
|
||||
Dictionary<string, MemoryMapFields> temp = new Dictionary<string, MemoryMapFields>();
|
||||
|
||||
//Open file for processing (read-only)
|
||||
using (FileStream readStream = new FileStream(fileLocation, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
//Process the memmap
|
||||
ProcessFile(readStream, temp);
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the memory map files into a data structure
|
||||
/// </summary>
|
||||
/// <param name="fs"></param>
|
||||
/// <param name="memoryMap"></param>
|
||||
private void ProcessFile(FileStream fs, Dictionary<string, MemoryMapFields> memoryMap)
|
||||
{
|
||||
uint page = 0;
|
||||
uint address = 0;
|
||||
uint regDefault = 0;
|
||||
char[] delimit = { ' ' };
|
||||
|
||||
uint prevPage = 0;
|
||||
uint prevAddress = 0;
|
||||
uint parentRegDefault = 0;
|
||||
|
||||
using (StreamReader reader = new StreamReader(fs))
|
||||
{
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
//Read a line from the file
|
||||
string line = reader.ReadLine();
|
||||
|
||||
//Parse the line by spaces (remove empty entries)
|
||||
string[] fields = line.Split(delimit, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
//If nothing to read, stop processing
|
||||
if (fields.Length == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//Get the key (Register Name)
|
||||
string key = fields[0].ToUpper();
|
||||
|
||||
//Check for duplicates
|
||||
if (memoryMap.ContainsKey(key))
|
||||
{
|
||||
throw new Exception("Duplicate item found in file: " + fs.Name + ", Item key: " + key);
|
||||
}
|
||||
|
||||
//Check if the register is a parent or child
|
||||
//A child will use its parent address and gets it default value from its parent
|
||||
if (line.StartsWith(" "))
|
||||
{
|
||||
regDefault = parentRegDefault;
|
||||
page = prevPage;
|
||||
address = prevAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Get the page number
|
||||
page = ProcessPageNum(fields[1]);
|
||||
|
||||
//Get register address
|
||||
address = ProcessDecimalHex(fields[1]);
|
||||
|
||||
//Get register default values
|
||||
regDefault = ProcessDecimalHex(fields[5]);
|
||||
|
||||
//Get scale factor
|
||||
_scaleFactor = ProcessScaleFactor(line);
|
||||
}
|
||||
|
||||
//Process bits
|
||||
BitInfo bitInfo = ProcessBitInfo(fields[3]);
|
||||
|
||||
double scaleFactor = _scaleFactor;
|
||||
|
||||
// parse out the default value for this child item
|
||||
if (bitInfo._numOfBits < 32)
|
||||
{
|
||||
// clear the upper bits
|
||||
int numBitsToClear = 32 - (bitInfo._start + bitInfo._numOfBits);
|
||||
regDefault = regDefault << numBitsToClear;
|
||||
|
||||
// clear lower bits and place into position
|
||||
int numBitsForPosition = bitInfo._start + numBitsToClear;
|
||||
regDefault = regDefault >> numBitsForPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
parentRegDefault = regDefault;
|
||||
}
|
||||
|
||||
memoryMap.Add(key, new MemoryMapFields(page, address, bitInfo._start, bitInfo._numOfBits, regDefault, scaleFactor));
|
||||
|
||||
// hold onto previous values for child items
|
||||
prevPage = page;
|
||||
prevAddress = address;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="pageNumber"></param>
|
||||
/// <returns></returns>
|
||||
private uint ProcessPageNum(string pageNumber)
|
||||
{
|
||||
//Delimiter used to parse string
|
||||
char[] delimit = { '.' };
|
||||
|
||||
//Array of parsed string
|
||||
string[] strPageValues = pageNumber.Split(delimit);
|
||||
|
||||
//Convert first array element
|
||||
uint value = uint.Parse(strPageValues[0]);
|
||||
|
||||
//Return conversion
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <returns></returns>
|
||||
private uint ProcessDecimalHex(string address)
|
||||
{
|
||||
//Delimiter used to parse string
|
||||
char[] delimit = { '.' };
|
||||
|
||||
//Array of parsed string
|
||||
string[] strValues = address.Split(delimit);
|
||||
|
||||
string strCombined = "";
|
||||
|
||||
//Address = 0.XXXX.XXXX, register values = XXXX.XXXX
|
||||
if (strValues.Length == 3)
|
||||
{
|
||||
strCombined = strValues[1] + strValues[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
strCombined = strValues[0] + strValues[1];
|
||||
}
|
||||
|
||||
//Convert hex number to UInt
|
||||
uint value = uint.Parse(strCombined, System.Globalization.NumberStyles.HexNumber);
|
||||
|
||||
//Return value
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="bits"></param>
|
||||
/// <returns></returns>
|
||||
private BitInfo ProcessBitInfo(string bits)
|
||||
{
|
||||
//Structure for bit information
|
||||
BitInfo temp;
|
||||
|
||||
//Delimiter used to parse string
|
||||
char[] delimit = { ':' };
|
||||
char[] trimChar = { '(', ')' };
|
||||
|
||||
string trimBits = bits.Trim(trimChar);
|
||||
string[] values = trimBits.Split(delimit);
|
||||
|
||||
if (values.Length == 2)
|
||||
{
|
||||
//values represents a range of bits
|
||||
int start = int.Parse(values[1]);
|
||||
int end = int.Parse(values[0]);
|
||||
|
||||
//Add one for zero offset
|
||||
temp._start = start;
|
||||
temp._numOfBits = end - start + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Only a single bit
|
||||
temp._numOfBits = 1;
|
||||
temp._start = int.Parse(values[0]);
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="scaleFactor"></param>
|
||||
/// <returns></returns>
|
||||
private double ProcessScaleFactor(string scaleFactor)
|
||||
{
|
||||
const string PATTERN = @"[+-]?[0-9]{1,}\.[0-9]{1,}[e][+-]?[0-9]{1,}";
|
||||
|
||||
//Find Scale Factor (default = 1)
|
||||
string sf = "1";
|
||||
|
||||
foreach (Match match in Regex.Matches(scaleFactor, PATTERN))
|
||||
{
|
||||
sf = match.Value;
|
||||
}
|
||||
|
||||
double value = double.Parse(sf);
|
||||
|
||||
return value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// The constructor
|
||||
/// </summary>
|
||||
/// <param name="memMapLocation">The memory map file</param>
|
||||
public MemoryMap(string memMapLocation)
|
||||
{
|
||||
_mapData = CreateMemoryMapDictionary(memMapLocation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="registerName">The name of the register</param>
|
||||
/// <returns></returns>
|
||||
public MemoryMapFields GetRegisterInfoByString(string registerName)
|
||||
{
|
||||
if (_mapData.ContainsKey(registerName.ToUpper()) == false)
|
||||
{
|
||||
throw new Exception("The requested register: " + registerName + " is not in the memory map");
|
||||
}
|
||||
|
||||
return _mapData[registerName.ToUpper()];
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
418
Source/TSRealLib/Common/Raytheon.Common/Lib/Util.cs
Normal file
418
Source/TSRealLib/Common/Raytheon.Common/Lib/Util.cs
Normal file
@@ -0,0 +1,418 @@
|
||||
// UNCLASSIFIED
|
||||
/*-------------------------------------------------------------------------
|
||||
RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION
|
||||
PROPRIETARY TO RAYTHEON COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS
|
||||
AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. DISCLOSURE TO
|
||||
UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO
|
||||
RAYTHEON COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS
|
||||
CONTENTS SHALL BE FURNISHED OR DISCLOSED TO OR COPIED OR USED BY PERSONS
|
||||
OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF RAYTHEON
|
||||
COMPANY.
|
||||
|
||||
THIS PROPRIETARY NOTICE IS NOT APPLICABLE IF DELIVERED TO THE U.S.
|
||||
GOVERNMENT.
|
||||
|
||||
UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// A collection of utilities.
|
||||
/// </summary>
|
||||
public static class Util
|
||||
{
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="registerContents"></param>
|
||||
/// <param name="startBit"></param>
|
||||
/// <param name="numOfBitsToMask"></param>
|
||||
/// <param name="inverseFlag"></param>
|
||||
/// <returns></returns>
|
||||
public static uint ApplyBitMask(uint registerContents, int startBit, int numOfBitsToMask, bool inverseFlag = false)
|
||||
{
|
||||
uint mask = 1;
|
||||
for (int i = 0; i < numOfBitsToMask - 1; i++)
|
||||
{
|
||||
mask = mask << 1;
|
||||
mask = mask + 1;
|
||||
}
|
||||
|
||||
//left shift to startbit position
|
||||
mask = mask << startBit;
|
||||
|
||||
//Inverse the mask
|
||||
if (inverseFlag)
|
||||
{
|
||||
mask = ~mask;
|
||||
}
|
||||
|
||||
//Apply Mask and return
|
||||
return (registerContents & mask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="ba"></param>
|
||||
/// <returns></returns>
|
||||
public static string ByteArrayToHexString(byte[] ba)
|
||||
{
|
||||
StringBuilder hex = new StringBuilder(ba.Length * 2);
|
||||
|
||||
foreach (byte b in ba)
|
||||
{
|
||||
hex.AppendFormat("{0:x2}", b);
|
||||
}
|
||||
|
||||
return hex.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="pattern"></param>
|
||||
/// <returns></returns>
|
||||
public static int ByteArraySearch(byte[] src, int srcStartIndex, byte[] pattern)
|
||||
{
|
||||
int maxFirstCharSlot = src.Length - pattern.Length + 1;
|
||||
for (int i = srcStartIndex; i < maxFirstCharSlot; i++)
|
||||
{
|
||||
if (src[i] != pattern[0]) // compare only first byte
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// found a match on first byte, now try to match rest of the pattern
|
||||
for (int j = pattern.Length - 1; j >= 1; j--)
|
||||
{
|
||||
if (src[i + j] != pattern[j]) break;
|
||||
if (j == 1) return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="stringToConvert"></param>
|
||||
/// <returns></returns>
|
||||
public static double ConvertStringToDouble(string stringToConvert)
|
||||
{
|
||||
try
|
||||
{
|
||||
double rsp = Convert.ToDouble(stringToConvert);
|
||||
|
||||
return rsp;
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
throw new Exception("Util::ConvertStringToDouble() - " + err.Message + ". Faulty String: " + stringToConvert);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string to a ushort
|
||||
/// </summary>
|
||||
/// <param name="stringToConvert"></param>
|
||||
/// <returns></returns>
|
||||
public static ushort ConvertStringToUInt16(string stringToConvert)
|
||||
{
|
||||
try
|
||||
{
|
||||
ushort rsp = Convert.ToUInt16(stringToConvert);
|
||||
|
||||
return rsp;
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
throw new Exception("Util::ConvertStringToUInt16() - " + err.Message + ". Faulty String: " + stringToConvert);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="stringToConvert"></param>
|
||||
/// <returns></returns>
|
||||
public static int ConvertStringToInt32(string stringToConvert)
|
||||
{
|
||||
try
|
||||
{
|
||||
int rsp = Convert.ToInt32(stringToConvert);
|
||||
|
||||
return rsp;
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
throw new Exception("Util::ConvertStringToInt32() - " + err.Message + ". Faulty String: " + stringToConvert);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="sourceDirName"></param>
|
||||
/// <param name="destDirName"></param>
|
||||
/// <param name="copySubDirs"></param>
|
||||
public static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
|
||||
{
|
||||
// Get the subdirectories for the specified directory.
|
||||
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
|
||||
|
||||
if (!dir.Exists)
|
||||
{
|
||||
throw new DirectoryNotFoundException(
|
||||
"Source directory does not exist or could not be found: "
|
||||
+ sourceDirName);
|
||||
}
|
||||
|
||||
DirectoryInfo[] dirs = dir.GetDirectories();
|
||||
// If the destination directory doesn't exist, create it.
|
||||
if (!Directory.Exists(destDirName))
|
||||
{
|
||||
Directory.CreateDirectory(destDirName);
|
||||
}
|
||||
|
||||
// Get the files in the directory and copy them to the new location.
|
||||
FileInfo[] files = dir.GetFiles();
|
||||
foreach (FileInfo file in files)
|
||||
{
|
||||
string temppath = Path.Combine(destDirName, file.Name);
|
||||
file.CopyTo(temppath, false);
|
||||
}
|
||||
|
||||
// If copying subdirectories, copy them and their contents to new location.
|
||||
if (copySubDirs)
|
||||
{
|
||||
foreach (DirectoryInfo subdir in dirs)
|
||||
{
|
||||
string temppath = Path.Combine(destDirName, subdir.Name);
|
||||
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the contents of two files
|
||||
/// </summary>
|
||||
/// <param name="fileName1"></param>
|
||||
/// <param name="fileName2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool FileEquals(string fileName1, string fileName2)
|
||||
{
|
||||
using (var file1 = new FileStream(fileName1, FileMode.Open))
|
||||
using (var file2 = new FileStream(fileName2, FileMode.Open))
|
||||
return FileStreamEquals(file1, file2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the contents of two file streams
|
||||
/// </summary>
|
||||
/// <param name="stream1"></param>
|
||||
/// <param name="stream2"></param>
|
||||
/// <returns></returns>
|
||||
public static bool FileStreamEquals(Stream stream1, Stream stream2)
|
||||
{
|
||||
const int BUFFER_SIZE = 2048;
|
||||
byte[] buffer1 = new byte[BUFFER_SIZE]; //buffer size
|
||||
byte[] buffer2 = new byte[BUFFER_SIZE];
|
||||
|
||||
while (true)
|
||||
{
|
||||
int count1 = stream1.Read(buffer1, 0, BUFFER_SIZE);
|
||||
int count2 = stream2.Read(buffer2, 0, BUFFER_SIZE);
|
||||
|
||||
if (count1 != count2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count1 == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// You might replace the following with an efficient "memcmp"
|
||||
if (!buffer1.Take(count1).SequenceEqual(buffer2.Take(count2)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a timestamp in string form.
|
||||
/// </summary>
|
||||
/// <returns>The timestamp string.</returns>
|
||||
public static string GetTimeString()
|
||||
{
|
||||
DateTime nowTime = DateTime.Now;
|
||||
string time = nowTime.Year.ToString("0000") + "_" + nowTime.Month.ToString("00") + "_" + nowTime.Day.ToString("00") + "_" + nowTime.Hour.ToString("00") + "_" + nowTime.Minute.ToString("00") + "_" + nowTime.Second.ToString("00") + "_" + nowTime.Millisecond.ToString("000");
|
||||
return time;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="address"></param>
|
||||
/// <param name="pingTimeOutInMs"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsIpAddressReachable(string address, int pingTimeOutInMs = 1000)
|
||||
{
|
||||
bool isReachable = false;
|
||||
|
||||
System.Net.NetworkInformation.Ping p = new System.Net.NetworkInformation.Ping();
|
||||
|
||||
System.Net.NetworkInformation.PingReply reply = p.Send(address, pingTimeOutInMs);
|
||||
|
||||
if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
|
||||
{
|
||||
isReachable = true;
|
||||
}
|
||||
|
||||
return isReachable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="registerContents"></param>
|
||||
/// <param name="startBit"></param>
|
||||
/// <param name="numOfBitsToMask"></param>
|
||||
/// <returns></returns>
|
||||
public static uint ParseRegisterItem(uint registerContents, int startBit, int numOfBitsToMask)
|
||||
{
|
||||
uint mask = 1;
|
||||
for (int i = 0; i < numOfBitsToMask - 1; i++)
|
||||
{
|
||||
mask = mask << 1;
|
||||
mask = mask + 1;
|
||||
}
|
||||
|
||||
//left shift to startbit position
|
||||
mask = mask << startBit;
|
||||
|
||||
uint dataToReturn = (registerContents & mask);
|
||||
|
||||
dataToReturn = dataToReturn >> startBit;
|
||||
|
||||
//Apply Mask and return
|
||||
return dataToReturn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static ushort ReverseBits16(ushort data)
|
||||
{
|
||||
ushort reversedData = 0;
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
reversedData <<= 1;
|
||||
reversedData |= (ushort)(data & 1);
|
||||
data >>= 1;
|
||||
}
|
||||
|
||||
return reversedData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] Swap(byte[] input)
|
||||
{
|
||||
Array.Reverse(input);
|
||||
return input;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static double Swap(double input)
|
||||
{
|
||||
byte[] byteArray = BitConverter.GetBytes(input);
|
||||
Array.Reverse(byteArray);
|
||||
return BitConverter.ToDouble(byteArray, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static ulong Swap(ulong input)
|
||||
{
|
||||
byte[] byteArray = BitConverter.GetBytes(input);
|
||||
Array.Reverse(byteArray);
|
||||
return BitConverter.ToUInt64(byteArray, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverse the byte order of the input parameter (16bit).
|
||||
/// </summary>
|
||||
/// <param name="input">16bit data.</param>
|
||||
/// <returns>Reversed 16bit data.</returns>
|
||||
public static ushort Swap(ushort input)
|
||||
{
|
||||
byte[] byteArray = BitConverter.GetBytes(input);
|
||||
Array.Reverse(byteArray);
|
||||
return BitConverter.ToUInt16(byteArray, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverse the byte order of the input parameter (32bit).
|
||||
/// </summary>
|
||||
/// <param name="input">32bit data.</param>
|
||||
/// <returns>Reversed 32bit data.</returns>
|
||||
public static uint Swap(uint input)
|
||||
{
|
||||
byte[] byteArray = BitConverter.GetBytes(input);
|
||||
Array.Reverse(byteArray);
|
||||
return BitConverter.ToUInt32(byteArray, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static float Swap(float input)
|
||||
{
|
||||
byte[] byteArray = BitConverter.GetBytes(input);
|
||||
Array.Reverse(byteArray);
|
||||
return BitConverter.ToSingle(byteArray, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dataBeingSwapped"></param>
|
||||
/// <returns></returns>
|
||||
public static uint SwapHighAndLowBytes(uint dataBeingSwapped)
|
||||
{
|
||||
//Using a 16-bit shift to move around four hex values at a time
|
||||
dataBeingSwapped = ((dataBeingSwapped & 0xFFFF) << 16) | ((uint)(dataBeingSwapped & 0xFFFF0000) >> 16);
|
||||
return dataBeingSwapped;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
248
Source/TSRealLib/Common/Raytheon.Common/Lib/WinApi.cs
Normal file
248
Source/TSRealLib/Common/Raytheon.Common/Lib/WinApi.cs
Normal file
@@ -0,0 +1,248 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Win_API
|
||||
{
|
||||
public static class NativeMethods
|
||||
{
|
||||
// The following GitHub link was very helpful in understanding how some of the WinApi calls work together, as well as
|
||||
// for certain const values like DIGCF_PRESENT. https://github.com/mikeobrien/HidLibrary/tree/dc9026067dd0c511574c8ce726682ece4f45939e
|
||||
|
||||
//https://docs.microsoft.com/en-us/windows-hardware/drivers/install/setupapi
|
||||
|
||||
//https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/introduction-to-hid-concepts
|
||||
|
||||
|
||||
public const uint GENERIC_READ = 0x80000000;
|
||||
public const uint GENERIC_WRITE = 0x40000000;
|
||||
public const int FILE_FLAG_OVERLAPPED = 0x40000000;
|
||||
public const int FILE_ATTRIBUTE_NORMAL = 0x128;
|
||||
|
||||
public const short DIGCF_PRESENT = 0x2;
|
||||
public const short DIGCF_DEVICEINTERFACE = 0x10;
|
||||
public const int DIGCF_ALLCLASSES = 0x4;
|
||||
|
||||
public static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
|
||||
|
||||
/// <summary>
|
||||
/// Zero prevents other processes from opening a file or device if they request delete, read, or write access.
|
||||
/// </summary>
|
||||
public enum FileShareMode
|
||||
{
|
||||
Zero = 0x00000000,
|
||||
FILE_SHARE_DELETE = 0x00000004,
|
||||
FILE_SHARE_READ = 0x00000001,
|
||||
FILE_SHARE_WRITE = 0x00000002
|
||||
}
|
||||
|
||||
public struct SECURITY_ATTRIBUTES
|
||||
{
|
||||
public int nLength;
|
||||
public IntPtr lpSecurityDescriptor;
|
||||
public bool bInheritHandle;
|
||||
}
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool CancelIo(IntPtr hFile);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr CreateFileA(
|
||||
string lpFileName,
|
||||
uint dwDesiredAccess,
|
||||
int dwShareMode,
|
||||
ref SECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
int dwCreationDisposition,
|
||||
int dwFlagsAndAttributes,
|
||||
IntPtr hTemplateFile);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool ReadFile(
|
||||
IntPtr hFile,
|
||||
IntPtr lpBuffer,
|
||||
uint nNumberOfBytesToRead,
|
||||
out uint lpNumberOfBytesRead,
|
||||
[In] ref System.Threading.NativeOverlapped lpOverlapped);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool WriteFile(
|
||||
IntPtr hFile,
|
||||
byte[] lpBuffer,
|
||||
uint nNumberOfBytesToWrite,
|
||||
out uint lpNumberOfBytesWritten,
|
||||
[In] ref System.Threading.NativeOverlapped lpOverlapped);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool CloseHandle(IntPtr hHandle);
|
||||
|
||||
/// <summary>
|
||||
/// The caller of this function must delete the returned device information set when it is no longer needed by calling SetupDiDestroyDeviceInfoList.
|
||||
/// </summary>
|
||||
/// <param name="guid"></param>
|
||||
/// <param name="hwndParent"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("Setupapi.dll")]
|
||||
public static extern IntPtr SetupDiCreateDeviceInfoList(Guid Guid, IntPtr HwndParent);
|
||||
|
||||
[DllImport("setupapi.dll")]
|
||||
public static extern bool SetupDiCreateDeviceInfo(IntPtr DeviceInfoSet, string DeviceName, Guid ClassGuid, string DeviceDescription, uint CreationFlags, IntPtr DeviceInfoData);
|
||||
|
||||
[DllImport("setupapi.dll")]
|
||||
public static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, uint MemberIndex, ref SP_DEVINFO_DATA DeviceInfoData);
|
||||
|
||||
[DllImport("setupapi.dll")]
|
||||
public static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, Guid InterfaceClassGuid, uint MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
|
||||
|
||||
[DllImport("setupapi.dll")]
|
||||
public static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, uint DeviceInterfaceDetailDataSize, ref uint RequiredSize, IntPtr DeviceInfoData);
|
||||
|
||||
[DllImport("setupapi.dll")]
|
||||
public static extern bool SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData, uint DeviceInterfaceDetailDataSize, ref uint RequiredSize, IntPtr DeviceInfoData);
|
||||
|
||||
[DllImport("setupapi.dll")]
|
||||
public static extern bool SetupDiGetClassDevs(Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, uint Flags);
|
||||
|
||||
[DllImport("setupapi.dll")]
|
||||
public static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
|
||||
|
||||
/// <summary>
|
||||
/// HidD_GetAttributes returns TRUE if succeeds; otherwise, it returns FALSE.
|
||||
/// </summary>
|
||||
/// <param name="HidDeviceObject"></param>
|
||||
/// <param name="Attributes"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("hid.dll")]
|
||||
public static extern bool HidD_GetAttributes(IntPtr HidDeviceObject, HIDD_ATTRIBUTES Attributes);
|
||||
/// <summary>
|
||||
/// [out] Pointer to a caller-allocated GUID buffer that the routine uses to return the device interface GUID for HIDClass devices.
|
||||
/// </summary>
|
||||
/// <param name="HidGuid"></param>
|
||||
[DllImport("hid.dll")]
|
||||
public static extern void HidD_GetHidGuid(out Guid HidGuid);
|
||||
|
||||
[DllImport("hid.dll")]
|
||||
public static extern bool HidD_GetIndexString(IntPtr HidDeviceObject, ulong StringIndex, out string Buffer, ulong BufferLength);
|
||||
/// <summary>
|
||||
/// The maximum possible number of characters in an embedded string is device specific. For USB devices, the maximum string length is 126 wide characters (not including the terminating NULL character).
|
||||
/// If the supplied buffer is not <= 4093 bytes(2^12 – 3) the call may fail(depending on the underlying protocol, HID/Bluetooth/SPI) with error code ERROR_GEN_FAILURE(0x0000001f).
|
||||
/// </summary>
|
||||
/// <param name="HidDeviceObject"></param>
|
||||
/// <param name="Buffer"></param>
|
||||
/// <param name="BufferLength"></param>
|
||||
/// <returns>bool</returns>
|
||||
[DllImport("hid.dll")]
|
||||
public static extern bool HidD_GetManufacturerString(IntPtr HidDeviceObject, out string Buffer, ulong BufferLength);
|
||||
|
||||
/// <summary>
|
||||
/// HidD_GetPhysicalDescriptor returns TRUE if it succeeds; otherwise, it returns FALSE. Use GetLastError to get extended error information.
|
||||
/// </summary>
|
||||
/// <param name="HidDeviceObject"></param>
|
||||
/// <param name="Buffer"></param>
|
||||
/// <param name="BufferLength"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("hid.dll")]
|
||||
public static extern bool HidD_GetPhysicalDescriptor(IntPtr HidDeviceObject, out string Buffer, [In] ulong BufferLength);
|
||||
|
||||
[DllImport("hid.dll")]
|
||||
public static extern bool HidD_GetPreparsedData(IntPtr HidDeviceObject, out HID_COLLECTION_INFORMATION PreparsedData);
|
||||
|
||||
/// <summary>
|
||||
/// The supplied buffer must be <= 4093 bytes (2^12 – 3).
|
||||
/// </summary>
|
||||
/// <param name="HidDeviceObject"></param>
|
||||
/// <param name="Buffer"></param>
|
||||
/// <param name="BufferLength"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("hid.dll")]
|
||||
public static extern bool HidD_GetProductString(IntPtr HidDeviceObject, out string Buffer, ulong BufferLength);
|
||||
|
||||
[DllImport("hid.dll")]
|
||||
public static extern bool HidD_GetSerialNumberString(IntPtr HidDeviceObject, out string Buffer, ulong BufferLength);
|
||||
|
||||
[DllImport("hid.dll")]
|
||||
public static extern bool HidD_GetNumInputBuffers(IntPtr HidDeviceObject, out ulong NumberBuffers);
|
||||
[DllImport("hid.dll")]
|
||||
public static extern bool HidD_SetNumInputBuffers(IntPtr HidDeviceObject, ulong NumberBuffers);
|
||||
|
||||
/// <summary>
|
||||
/// A caller of HidD_GetAttributes, uses this structure to obtain a device's vendor information.
|
||||
/// Before using a HIDD_ATTRIBUTES structure with HIDClass support routines, the caller must set the Size member.
|
||||
/// </summary>
|
||||
public struct HIDD_ATTRIBUTES
|
||||
{
|
||||
public ulong Size;
|
||||
public ushort VendorID;
|
||||
public ushort ProductID;
|
||||
public ushort VersionNumber;
|
||||
}
|
||||
|
||||
public struct HID_COLLECTION_INFORMATION
|
||||
{
|
||||
public ulong DescriptorSize;
|
||||
public bool Polled;
|
||||
public char[] Reserved1;
|
||||
public ushort VendorID;
|
||||
public ushort ProductID;
|
||||
public ushort VersionNumber;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SP_DEVICE_INTERFACE_DATA
|
||||
{
|
||||
public uint cbSize;
|
||||
public Guid InterfaceClassGuid;
|
||||
public uint Flags;
|
||||
public IntPtr Reserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SP_DEVINFO_DATA
|
||||
{
|
||||
public uint cbSize;
|
||||
public Guid ClassGuid;
|
||||
public uint DevInst;
|
||||
public IntPtr Reserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SP_DEVICE_INTERFACE_DETAIL_DATA
|
||||
{
|
||||
public uint cbSize;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string DevicePath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static SECURITY_ATTRIBUTES InitWithDefaultAttributes()
|
||||
{
|
||||
SECURITY_ATTRIBUTES attributes = new SECURITY_ATTRIBUTES
|
||||
{
|
||||
bInheritHandle = false,
|
||||
lpSecurityDescriptor = IntPtr.Zero
|
||||
};
|
||||
attributes.nLength = Marshal.SizeOf(attributes);
|
||||
return attributes;
|
||||
}
|
||||
public static IntPtr CreateNonManagedBuffer(byte[] buffer)
|
||||
{
|
||||
return Marshal.AllocHGlobal(buffer.Length);
|
||||
}
|
||||
|
||||
public static byte[] CopyUnManagedBufferToManagedBuffer(IntPtr unManagedBuffer, int bytesRead)
|
||||
{
|
||||
var buffer = new byte[] { };
|
||||
Marshal.Copy(unManagedBuffer, buffer, 0, bytesRead);
|
||||
return buffer;
|
||||
}
|
||||
public static void DisposeNonManagedObject(IntPtr nonManagedObj)
|
||||
{
|
||||
Marshal.FreeHGlobal(nonManagedObj);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user