Big changes

This commit is contained in:
Duc
2025-03-13 12:04:22 -07:00
parent c689fcb7f9
commit ffa9905494
748 changed files with 199255 additions and 3743 deletions

View File

@@ -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);
}
}
}
}

View 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";
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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
}
}

View 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);
}
}
}