Big changes
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
// **********************************************************************************************************
|
||||
// AutomationMessage.cs
|
||||
// 1/8/2024
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract base class for AutomationMessages that go between the client and server
|
||||
/// </summary>
|
||||
public abstract class AutomationMessage : ICloneable
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private string _description;
|
||||
protected AutomationMessageHeader _header;
|
||||
#endregion
|
||||
|
||||
#region PrivateClassFunctions
|
||||
|
||||
/// <summary>
|
||||
/// The constructor
|
||||
/// </summary>
|
||||
/// <param name="AutomationMessageId">The AutomationMessage id</param>
|
||||
/// <param name="description">The AutomationMessage description</param>
|
||||
/// <param name="messageId">The number of bytes in the payload of the AutomationMessage. (The number of bytes in the child class)</param>
|
||||
protected AutomationMessage(uint messageId, string description, uint messageLength)
|
||||
{
|
||||
_description = description;
|
||||
_header = new AutomationMessageHeader(messageId, messageLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy Constructor
|
||||
/// </summary>
|
||||
/// <param name="message">The AutomationMessage to copy from</param>
|
||||
protected AutomationMessage(AutomationMessage message)
|
||||
{
|
||||
_header = new AutomationMessageHeader(message._header);
|
||||
_description = message._description;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the number of bytes in the entire AutomationMessage, including header.
|
||||
/// Some times when receiving a AutomationMessage, you must instantiate the object before you know how many bytes the AutomationMessage is
|
||||
/// </summary>
|
||||
/// <param name="messageLength">The number of bytes in the entire AutomationMessage</param>
|
||||
protected void SetMessageLen(uint messageLength)
|
||||
{
|
||||
_header.SetMessageLen(messageLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// abstract function for children to implement a clone of their object
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected abstract object CloneSelf();
|
||||
|
||||
/// <summary>
|
||||
/// abstract function for children to implement the function that they serve
|
||||
/// </summary>
|
||||
public abstract void ExecuteMsg();
|
||||
|
||||
/// <summary>
|
||||
/// abstract function for children to implement the formatting of their parameters
|
||||
/// </summary>
|
||||
/// <param name="pData"></param>
|
||||
protected abstract void FormatData(IntPtr pData);
|
||||
|
||||
/// <summary>
|
||||
/// abstract function for children to implement the parsing of their parameters
|
||||
/// </summary>
|
||||
/// <param name="pData"></param>
|
||||
protected abstract void ParseData(IntPtr pData);
|
||||
#endregion
|
||||
|
||||
#region PublicClassFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Get a copy of the AutomationMessage object
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public object Clone()
|
||||
{
|
||||
// tell the child to clone itself
|
||||
return this.CloneSelf();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the AutomationMessage into a byte array for sending
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the AutomationMessage items</param>
|
||||
public void Format(IntPtr pData)
|
||||
{
|
||||
_header.Format(pData);
|
||||
|
||||
IntPtr pPayload = IntPtr.Add(pData, (int)GetHeaderLength());
|
||||
|
||||
// ask child class to format its data
|
||||
FormatData(pPayload);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Getter
|
||||
/// </summary>
|
||||
/// <returns>The description</returns>
|
||||
public string GetDescription()
|
||||
{
|
||||
return _description;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Getter
|
||||
/// </summary>
|
||||
/// <returns>The number of bytes in the AutomationMessage, including header</returns>
|
||||
public uint GetEntireMsgLength()
|
||||
{
|
||||
return _header.GetEntireMsgLength();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter
|
||||
/// </summary>
|
||||
/// <returns>The id</returns>
|
||||
public uint GetMessageId()
|
||||
{
|
||||
return _header.GetMessageId();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter
|
||||
/// </summary>
|
||||
/// <returns>The number of bytes in the head</returns>
|
||||
public uint GetHeaderLength()
|
||||
{
|
||||
return _header.GetHeaderLength();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the AutomationMessage object
|
||||
/// </summary>
|
||||
/// <param name="pData">The AutomationMessage in byte form</param>
|
||||
public void Parse(IntPtr pData)
|
||||
{
|
||||
_header.Parse(pData);
|
||||
|
||||
IntPtr pPayLoad = IntPtr.Add(pData, (int)GetHeaderLength());
|
||||
|
||||
ParseData(pPayLoad);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this AutomationMessage into string form
|
||||
/// </summary>
|
||||
/// <returns>The AutomationMessage in string form</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return "Description: " + GetDescription() + "\n" + _header.ToString();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
// **********************************************************************************************************
|
||||
// AutomationMessageHeader.cs
|
||||
// 1/8/2024
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// The header for all messages
|
||||
/// </summary>
|
||||
public class AutomationMessageHeader
|
||||
{
|
||||
#region PublicClassMembers
|
||||
public const int HEADER_EXPECTED_SIZE = 8;
|
||||
#endregion
|
||||
|
||||
#region PrivateClassMembers
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
private struct HeaderStruct
|
||||
{
|
||||
public uint messageId;
|
||||
public uint messageLength;// total msg size in bytes..Including the header.
|
||||
};
|
||||
|
||||
private HeaderStruct _headerStruct;
|
||||
#endregion
|
||||
|
||||
#region PublicClassFunctions
|
||||
|
||||
/// <summary>
|
||||
/// Copy constructor
|
||||
/// </summary>
|
||||
/// <param name="header">The header to copy</param>
|
||||
public AutomationMessageHeader(AutomationMessageHeader header)
|
||||
{
|
||||
_headerStruct = new HeaderStruct();
|
||||
_headerStruct = header._headerStruct;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for when receiving data.
|
||||
/// Use this constructor and then parse to populate it
|
||||
/// </summary>
|
||||
public AutomationMessageHeader()
|
||||
{
|
||||
_headerStruct = new HeaderStruct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for sending
|
||||
/// </summary>
|
||||
/// <param name="msgId">the message id</param>
|
||||
/// <param name="messageLength">The number of bytes in the message, not including the header</param>
|
||||
public AutomationMessageHeader(uint msgId, uint messageLength)
|
||||
{
|
||||
_headerStruct = new HeaderStruct
|
||||
{
|
||||
messageId = msgId,
|
||||
messageLength = messageLength + GetHeaderLength()
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Encode the header into a byte array for sending
|
||||
/// </summary>
|
||||
/// <param name="pData">The buffer to put the message items</param>
|
||||
public void Format(IntPtr pData)
|
||||
{
|
||||
Marshal.StructureToPtr(_headerStruct, pData, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Getter
|
||||
/// </summary>
|
||||
/// <returns>The number of bytes in the message, including header</returns>
|
||||
public uint GetEntireMsgLength()
|
||||
{
|
||||
return _headerStruct.messageLength;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter
|
||||
/// </summary>
|
||||
/// <returns>The id</returns>
|
||||
public uint GetMessageId()
|
||||
{
|
||||
return _headerStruct.messageId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// getter
|
||||
/// </summary>
|
||||
/// <returns>The header length in bytes</returns>
|
||||
public uint GetHeaderLength()
|
||||
{
|
||||
return (uint)Marshal.SizeOf(_headerStruct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes an array of bytes and populates the header object
|
||||
/// </summary>
|
||||
/// <param name="pData">The header in byte form</param>
|
||||
public void Parse(IntPtr pData)
|
||||
{
|
||||
_headerStruct = (HeaderStruct)Marshal.PtrToStructure(pData, typeof(HeaderStruct));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="messageLength"></param>
|
||||
public void SetMessageLen(uint messageLength)
|
||||
{
|
||||
_headerStruct.messageLength = messageLength + GetHeaderLength();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a string version of the header members
|
||||
/// </summary>
|
||||
/// <returns>A string containing the header data</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string msg = "Header Data:\r\n";
|
||||
msg += "msg id: " + Convert.ToString(_headerStruct.messageId) + "\r\n";
|
||||
msg += "msg len: " + Convert.ToString(_headerStruct.messageLength) + "\r\n";
|
||||
return msg;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of the IConfigurationFile interface for Json file format
|
||||
/// </summary>
|
||||
public class JsonConfigurationFile : ConfigurationFileBase
|
||||
{
|
||||
|
||||
private Dictionary<string, Dictionary<string, string>> _data;
|
||||
|
||||
/// <summary>
|
||||
/// constructor
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public JsonConfigurationFile(string fileName)
|
||||
: base(fileName)
|
||||
{
|
||||
if (_configurationType != ConfigurationFileType.JSON)
|
||||
{
|
||||
throw new ArgumentException("Expecting JSON file configuration type");
|
||||
}
|
||||
|
||||
if (!_fileInfo.Exists)
|
||||
{
|
||||
using (File.Create(_fileInfo.FullName)) { }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads all available keys from given section from current configuration file
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <returns></returns>
|
||||
public override List<string> ReadAllKeys(string section)
|
||||
{
|
||||
string json = File.ReadAllText(_fileName);
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
{
|
||||
_data = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(json);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data = new Dictionary<string, Dictionary<string, string>>();
|
||||
}
|
||||
return _data.ContainsKey(section) ? _data[section].Keys.ToList() : new List<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads all available sections from current configuration file
|
||||
/// </summary>
|
||||
/// <returns>list of sections</returns>
|
||||
public override List<string> ReadAllSections()
|
||||
{
|
||||
string json = File.ReadAllText(_fileName);
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
{
|
||||
_data = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(json);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data = new Dictionary<string, Dictionary<string, string>>();
|
||||
}
|
||||
return _data.Keys.ToList();
|
||||
}
|
||||
|
||||
public override List<T> ReadList<T>(string section, string key, IList<T> defList = null)
|
||||
{
|
||||
return ReadValue(section, key, defList).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a single value in json format
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defValue"></param>
|
||||
/// <returns>configuration value</returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public override T ReadValue<T>(string section, string key, T defValue = default)
|
||||
{
|
||||
string json = File.ReadAllText(_fileName);
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
{
|
||||
_data = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(json);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data = new Dictionary<string, Dictionary<string, string>>();
|
||||
}
|
||||
|
||||
if (_data.ContainsKey(section) && _data[section].ContainsKey(key))
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(_data[section][key]);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteValue(section, key, defValue);
|
||||
return defValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a single value in json format
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns>configuration value</returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public override string ReadValue(string section, string key)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a list of values of any generic type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="listToWrite"></param>
|
||||
public override void WriteList<T>(string section, string key, IList<T> listToWrite)
|
||||
{
|
||||
WriteValue(section, key, listToWrite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a single value
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="lineToWrite"></param>
|
||||
public override void WriteValue<T>(string section, string key, T lineToWrite)
|
||||
{
|
||||
string json = File.ReadAllText(_fileName);
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
{
|
||||
_data = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(json);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data = new Dictionary<string, Dictionary<string, string>>();
|
||||
}
|
||||
|
||||
if (!_data.ContainsKey(section))
|
||||
{
|
||||
_data[section] = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
_data[section][key] = JsonConvert.SerializeObject(lineToWrite);
|
||||
|
||||
using (StreamWriter writer = new StreamWriter(_fileName, false))
|
||||
{
|
||||
writer.WriteLine(JsonConvert.SerializeObject(_data));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
// Ignore Spelling: Yaml
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
public class YamlConfigurationFile : ConfigurationFileBase
|
||||
{
|
||||
|
||||
//private Dictionary<string, Dictionary<string, string>> _data;
|
||||
|
||||
/// <summary>
|
||||
/// constructor
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public YamlConfigurationFile(string fileName)
|
||||
: base(fileName)
|
||||
{
|
||||
if (_configurationType != ConfigurationFileType.OTHER)
|
||||
{
|
||||
throw new ArgumentException("Expecting YAML file configuration type");
|
||||
}
|
||||
|
||||
if (!_fileInfo.Exists)
|
||||
{
|
||||
using (File.Create(_fileInfo.FullName)) { }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads all available keys from given section from current configuration file
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <returns></returns>
|
||||
public override List<string> ReadAllKeys(string section)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads all available sections from current configuration file
|
||||
/// </summary>
|
||||
/// <returns>list of sections</returns>
|
||||
public override List<string> ReadAllSections()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override List<T> ReadList<T>(string section, string key, IList<T> defList = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a single value in yaml format
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defValue"></param>
|
||||
/// <returns>configuration value</returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public override T ReadValue<T>(string section, string key, T defValue = default)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a single value in json format
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns>configuration value</returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public override string ReadValue(string section, string key)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a list of values of any generic type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="listToWrite"></param>
|
||||
public override void WriteList<T>(string section, string key, IList<T> listToWrite)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a single value
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="lineToWrite"></param>
|
||||
public override void WriteValue<T>(string section, string key, T lineToWrite)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
public class YamlConfigurationFileFactory : ConfigurationFileFactoryBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
public override IConfigurationFile CreateConfigurationFile(string fileName)
|
||||
{
|
||||
return new YamlConfigurationFile(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// main class to be instantiated when working with configuration files
|
||||
/// </summary>
|
||||
public class ConfigurationFile : ConfigurationFileBase
|
||||
{
|
||||
/// <summary>
|
||||
/// concrete implementation reference
|
||||
/// </summary>
|
||||
protected IConfigurationFile _configurationFile;
|
||||
|
||||
/// <summary>
|
||||
/// Raytheon.Configuration will support INI and XML file formats.
|
||||
/// For other formats have to use designated constructor
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public ConfigurationFile(string fileName)
|
||||
: base(fileName)
|
||||
{
|
||||
if (!_fileInfo.Exists)
|
||||
{
|
||||
throw new Exception($"Can't find file: {fileName}");
|
||||
}
|
||||
var factory = GetFactory();
|
||||
_configurationFile = factory.GetConfigurationFile(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// extension constructor, for other types based on the provided factory
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="factory"></param>
|
||||
public ConfigurationFile(string fileName, ConfigurationFileFactoryBase factory)
|
||||
: base(fileName)
|
||||
{
|
||||
if (!_fileInfo.Exists)
|
||||
{
|
||||
throw new Exception($"Can't find file: {fileName}");
|
||||
}
|
||||
_configurationFile = factory.GetConfigurationFile(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// extension constructor, for other types based on provided type
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="type"></param>
|
||||
public ConfigurationFile(string fileName, string type)
|
||||
: base(fileName)
|
||||
{
|
||||
if (!_fileInfo.Exists)
|
||||
{
|
||||
throw new Exception($"Can't find file: {fileName}");
|
||||
}
|
||||
ConfigurationFileFactory factory = new(type);
|
||||
_configurationFile = factory.GetConfigurationFile(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns a factory based on file extension
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
private static ConfigurationFileFactoryBase GetFactory()
|
||||
{
|
||||
ConfigurationFileType configurationType = ConfigurationTypeFromFileExtension(_fileInfo.Extension);
|
||||
|
||||
ConfigurationFileFactoryBase factory = configurationType switch
|
||||
{
|
||||
ConfigurationFileType.INI => new IniConfigurationFileFactory(),
|
||||
ConfigurationFileType.XML => new XmlConfigurationFileFactory(),
|
||||
ConfigurationFileType.JSON => new JsonConfigurationFileFactory(),
|
||||
ConfigurationFileType.TOML => new TomlConfigurationFileFactory(),
|
||||
_ => throw new ArgumentException($"Configuration Type ({configurationType}) not supported by Configuration Manager"),
|
||||
};
|
||||
return factory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads all keys from a section of an ini file.
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <returns></returns>
|
||||
public override List<string> ReadAllKeys(string section)
|
||||
{
|
||||
return _configurationFile.ReadAllKeys(section);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of all of the sections in the ini file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override List<string> ReadAllSections()
|
||||
{
|
||||
return _configurationFile.ReadAllSections();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a list of values from configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defList"></param>
|
||||
/// <returns></returns>
|
||||
public override List<T> ReadList<T>(string section, string key, IList<T> defList = null)
|
||||
{
|
||||
return _configurationFile.ReadList<T>(section, key, defList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a value from configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defValue"></param>
|
||||
/// <returns></returns>
|
||||
public override T ReadValue<T>(string section, string key, T defValue = default)
|
||||
{
|
||||
return _configurationFile.ReadValue<T>(section, key, defValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a single value in json format
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns>configuration value</returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public override string ReadValue(string section, string key)
|
||||
{
|
||||
return _configurationFile.ReadValue(section, key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a list of values to configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="listToWrite"></param>
|
||||
public override void WriteList<T>(string section, string key, IList<T> listToWrite)
|
||||
{
|
||||
_configurationFile.WriteList<T>(section, key, listToWrite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string value
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="lineToWrite"></param>
|
||||
public override void WriteValue<T>(string section, string key, T lineToWrite)
|
||||
{
|
||||
_configurationFile.WriteValue(section, key, lineToWrite);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class ConfigurationFileBase : IConfigurationFile
|
||||
{
|
||||
/// <summary>
|
||||
/// configuration file info
|
||||
/// </summary>
|
||||
protected static FileInfo _fileInfo;
|
||||
|
||||
/// <summary>
|
||||
/// configuration file name
|
||||
/// </summary>
|
||||
protected string _fileName;
|
||||
|
||||
/// <summary>
|
||||
/// returns file name
|
||||
/// </summary>
|
||||
public string FileName => _fileName;
|
||||
|
||||
/// <summary>
|
||||
/// configuration type derived based on file extension
|
||||
/// or by the type of the IConfigurationFile implementation
|
||||
/// </summary>
|
||||
protected ConfigurationFileType _configurationType;
|
||||
|
||||
/// <summary>
|
||||
/// returns configuration type
|
||||
/// </summary>
|
||||
public ConfigurationFileType ConfigurationFileType => _configurationType;
|
||||
|
||||
/// <summary>
|
||||
/// constructor that takes file name
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public ConfigurationFileBase(string fileName)
|
||||
{
|
||||
_fileInfo = new FileInfo(fileName);
|
||||
_fileName = _fileInfo.FullName;
|
||||
_configurationType = ConfigurationTypeFromFileExtension(_fileInfo.Extension);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns supported configuration type enum based on the file type
|
||||
/// </summary>
|
||||
/// <param name="fileExtension"></param>
|
||||
/// <returns></returns>
|
||||
protected static ConfigurationFileType ConfigurationTypeFromFileExtension(string fileExtension)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fileExtension))
|
||||
{
|
||||
return ConfigurationFileType.OTHER;
|
||||
}
|
||||
return fileExtension.ToLower() switch
|
||||
{
|
||||
".ini" => ConfigurationFileType.INI,
|
||||
".xml" => ConfigurationFileType.XML,
|
||||
".json" => ConfigurationFileType.JSON,
|
||||
".toml" => ConfigurationFileType.TOML,
|
||||
".yaml" => ConfigurationFileType.YAML,
|
||||
_ => ConfigurationFileType.OTHER,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads all keys from a section of configuration file.
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <returns></returns>
|
||||
public abstract List<string> ReadAllKeys(string section);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of all of the sections in the configuration file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract List<string> ReadAllSections();
|
||||
|
||||
/// <summary>
|
||||
/// reads a list of values from configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defList"></param>
|
||||
/// <returns></returns>
|
||||
public abstract List<T> ReadList<T>(string section, string key, IList<T> defList = null);
|
||||
|
||||
/// <summary>
|
||||
/// reads a single value from configuration file by section and key
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defValue"></param>
|
||||
/// <returns></returns>
|
||||
public abstract T ReadValue<T>(string section, string key, T defValue = default);
|
||||
|
||||
/// <summary>
|
||||
/// reads a single value from configuration file by section and key
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public abstract string ReadValue(string section, string key);
|
||||
|
||||
/// <summary>
|
||||
/// writes a list of values to configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="listToWrite"></param>
|
||||
public abstract void WriteList<T>(string section, string key, IList<T> listToWrite);
|
||||
|
||||
/// <summary>
|
||||
/// Write a single value to a given section by key
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="lineToWrite"></param>
|
||||
public abstract void WriteValue<T>(string section, string key, T lineToWrite);
|
||||
|
||||
/// <summary>
|
||||
/// checks if the value exists in configuration file
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
virtual public bool ValueExists(string section, string key)
|
||||
{
|
||||
return ReadAllKeys(section).Contains(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
// Ignore Spelling: Deserialize
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using System.Xml.XPath;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// for serializing and deserializing class types
|
||||
/// </summary>
|
||||
internal static class XmlSerializerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// deserializes XML type into an object
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static T Deserialize<T>(this string value)
|
||||
{
|
||||
XmlSerializer serializer = new XmlSerializer(typeof(T));
|
||||
using(StringReader reader = new StringReader(value))
|
||||
{
|
||||
return (T)serializer.Deserialize(reader);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// extension method to serialize XML type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static string Serialize<T>(this T value)
|
||||
{
|
||||
if(value == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
XmlSerializer xmlSerializer = new(typeof(T));
|
||||
|
||||
using(StringWriter stringWriter = new())
|
||||
{
|
||||
using(XmlWriter xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true }))
|
||||
{
|
||||
xmlSerializer.Serialize(xmlWriter, value);
|
||||
return stringWriter.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// extension method to serialize XML type without a namespace
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static string SerializeNoNamespace<T>(this T value)
|
||||
{
|
||||
if(value == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
XmlSerializerNamespaces emptyNamespaces = new(new[] { XmlQualifiedName.Empty });
|
||||
XmlSerializer serializer = new(value.GetType());
|
||||
XmlWriterSettings settings = new()
|
||||
{
|
||||
Indent = true,
|
||||
OmitXmlDeclaration = true
|
||||
};
|
||||
|
||||
using(StringWriter stream = new())
|
||||
{
|
||||
using(XmlWriter writer = XmlWriter.Create(stream, settings))
|
||||
{
|
||||
serializer.Serialize(writer, value, emptyNamespaces);
|
||||
return stream.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// type conversion utility with a special case for enums
|
||||
/// </summary>
|
||||
public static class TypeConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// special rule for enumeration when converting a type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static T ChangeType<T>(object value)
|
||||
{
|
||||
return typeof(T).IsEnum ? (T)Enum.Parse(typeof(T), value.ToString()) : (T)ChangeType(typeof(T), value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// convert type with TypeDescriptor
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static object ChangeType(Type t, object value)
|
||||
{
|
||||
System.ComponentModel.TypeConverter tc = TypeDescriptor.GetConverter(t);
|
||||
return tc.ConvertFrom(value);
|
||||
}
|
||||
/// <summary>
|
||||
/// register type with the type descriptor for later conversion
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TC"></typeparam>
|
||||
public static void RegisterTypeConverter<T, TC>() where TC : System.ComponentModel.TypeConverter
|
||||
{
|
||||
TypeDescriptor.AddAttributes(typeof(T), new TypeConverterAttribute(typeof(TC)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper class contains extension functions for reading types other than strings from configuration,
|
||||
/// as well as reading lists of values
|
||||
/// </summary>
|
||||
public static class ConfigurationHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// template function for reading different types from configuration
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="configuration"></param>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
public static T GetConfigurationValue<T>(this IConfiguration configuration, string section, string key, T defaultValue)
|
||||
{
|
||||
Type defaultType = typeof(T);
|
||||
if(!defaultType.IsValueType && defaultType != typeof(string))
|
||||
{
|
||||
string tmpResult = configuration.GetConfigurationValue(section, key, string.Empty);
|
||||
|
||||
if(!string.IsNullOrEmpty(tmpResult))
|
||||
{
|
||||
return tmpResult.Deserialize<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
configuration.SetConfigurationValue(section, key, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string tmpResult = configuration.GetConfigurationValue(section, key, defaultValue.ToString());
|
||||
return !string.IsNullOrEmpty(tmpResult) ? TypeConverter.ChangeType<T>(tmpResult) : default;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets configuration value.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="configuration"></param>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="valueToWrite"></param>
|
||||
public static void SetConfigurationValue<T>(this IConfiguration configuration, string section, string key, T valueToWrite)
|
||||
{
|
||||
Type defaultType = typeof(T);
|
||||
if(!defaultType.IsValueType && defaultType != typeof(string))
|
||||
{
|
||||
configuration.SetConfigurationValue(section, key, valueToWrite.SerializeNoNamespace());
|
||||
}
|
||||
else
|
||||
{
|
||||
configuration.SetConfigurationValue(section, key, valueToWrite.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns multi-value result (list of T) from configuration
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="configuration"></param>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
public static List<T> GetConfigurationListValue<T>(this IConfiguration configuration, string section, string key, IList<T> defaultValue)
|
||||
{
|
||||
string tmpResult = configuration.GetXmlConfiguration(section);
|
||||
if(string.IsNullOrEmpty(tmpResult) || !ContainsSection(tmpResult, key))
|
||||
{
|
||||
SetConfigurationListValue(configuration, section, key, defaultValue);
|
||||
return new List<T>(defaultValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
var stringRes = BuildElementListFromXml(tmpResult, key);
|
||||
|
||||
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
|
||||
|
||||
List<T> result = new List<T>();
|
||||
|
||||
foreach(string item in stringRes)
|
||||
{
|
||||
if(string.IsNullOrEmpty(item))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(item.TrimStart().StartsWith("<"))
|
||||
{
|
||||
result.Add(item.Deserialize<T>());
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Add(TypeConverter.ChangeType<T>(item));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes configuration list of values.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="configuration"></param>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="listToWrite"></param>
|
||||
public static void SetConfigurationListValue<T>(this IConfiguration configuration, string section, string key, IList<T> listToWrite)
|
||||
{
|
||||
StringBuilder xmlStr = new();
|
||||
string data = configuration.GetXmlConfiguration(section);
|
||||
if(ContainsSection(data, $"{key}s"))
|
||||
{
|
||||
xmlStr.Append($"<{key}s>");
|
||||
foreach(var item in listToWrite)
|
||||
{
|
||||
xmlStr.Append($"<{key}>");
|
||||
xmlStr.Append(item.ToString());
|
||||
xmlStr.Append($"</{key}>");
|
||||
}
|
||||
xmlStr.Append($"</{key}s>");
|
||||
configuration.SetXmlConfiguration(section, xmlStr.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlStr.Append($"<{key}>");
|
||||
foreach(var item in listToWrite)
|
||||
{
|
||||
xmlStr.Append(item.SerializeNoNamespace());
|
||||
}
|
||||
xmlStr.Append($"</{key}>");
|
||||
|
||||
XElement xElement = new XElement(key, XElement.Parse(xmlStr.ToString()));
|
||||
|
||||
if(string.IsNullOrEmpty(data))
|
||||
{
|
||||
data = $"<XmlConfiguration name=\"{section}\"></XmlConfiguration>";
|
||||
}
|
||||
|
||||
XDocument doc = XDocument.Parse(data);
|
||||
XElement existing = doc.Descendants(key).FirstOrDefault();
|
||||
|
||||
if(existing != null)
|
||||
{
|
||||
existing.ReplaceWith(xElement);
|
||||
|
||||
var reader = doc.CreateReader();
|
||||
reader.MoveToContent();
|
||||
string innerXml = reader.ReadInnerXml();
|
||||
|
||||
configuration.SetXmlConfiguration(section, innerXml);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
doc.Root.Add(xElement.FirstNode);
|
||||
var reader = doc.CreateReader();
|
||||
reader.MoveToContent();
|
||||
string outerXml = reader.ReadOuterXml();
|
||||
|
||||
configuration.SetXmlConfiguration(section, outerXml);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns values from XML section converted to string list
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
private static List<string> BuildElementListFromXml(string data, string key)
|
||||
{
|
||||
XElement doc = XElement.Parse(data);
|
||||
IEnumerable<XElement> xmlMessages;
|
||||
|
||||
if(ContainsSection(data, $"{key}s"))
|
||||
{
|
||||
xmlMessages = from m in doc.Elements($"{key}s").Elements(key)
|
||||
select m;
|
||||
|
||||
var messages = xmlMessages.Select(x => x.Value);
|
||||
return messages?.ToList();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlMessages = from m in doc.Elements($"{key}").Elements()
|
||||
select m;
|
||||
|
||||
List<string> result = new();
|
||||
|
||||
foreach(var item in xmlMessages)
|
||||
{
|
||||
var reader = item.CreateReader();
|
||||
reader.MoveToContent();
|
||||
result.Add(reader.ReadOuterXml());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ContainsSection(string xmlString, string sectionName)
|
||||
{
|
||||
if(string.IsNullOrEmpty(xmlString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
XDocument doc = XDocument.Parse(xmlString);
|
||||
return doc.Descendants(sectionName).Any();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// From XML configuration file reads all sections under IniConfiguration root
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<string> GetAvailableConfigSections(string fileName)
|
||||
{
|
||||
List<string> sections = new();
|
||||
|
||||
FileInfo fileInfo = new(fileName);
|
||||
if(!fileInfo.Exists)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
XDocument xdocument = XDocument.Load(fileInfo.FullName);
|
||||
if(xdocument != null)
|
||||
{
|
||||
var configurationSection = xdocument.Root.Element("IniConfiguration");
|
||||
if(configurationSection != null && configurationSection.HasElements)
|
||||
{
|
||||
var sectionElements = configurationSection.Elements();
|
||||
sections.AddRange(from item in sectionElements
|
||||
let name = item?.FirstAttribute?.Value
|
||||
where !string.IsNullOrEmpty(name)
|
||||
select name);
|
||||
}
|
||||
|
||||
configurationSection = xdocument.Root.Element("XmlConfigurations");
|
||||
if(configurationSection != null && configurationSection.HasElements)
|
||||
{
|
||||
var sectionElements = configurationSection.Elements();
|
||||
sections.AddRange(from item in sectionElements
|
||||
let name = item?.FirstAttribute?.Value
|
||||
where !string.IsNullOrEmpty(name)
|
||||
select name);
|
||||
}
|
||||
}
|
||||
|
||||
return sections;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// From XML configuration file reads all keys from config sections under IniConfiguration root
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<string> GetAvailableConfigSectionKeys(string fileName, string sectionName)
|
||||
{
|
||||
List<string> sections = new();
|
||||
|
||||
FileInfo fileInfo = new(fileName);
|
||||
if(!fileInfo.Exists)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
XDocument xdocument = XDocument.Load(fileInfo.FullName);
|
||||
if(xdocument != null)
|
||||
{
|
||||
var configurationSection = xdocument.XPathSelectElement($"//IniConfiguration//section[@name='{sectionName}']");
|
||||
if(configurationSection != null && configurationSection.HasElements)
|
||||
{
|
||||
var sectionElements = configurationSection.Elements();
|
||||
sections.AddRange(from item in sectionElements
|
||||
let name = item?.FirstAttribute?.Value
|
||||
where !string.IsNullOrEmpty(name)
|
||||
select name);
|
||||
}
|
||||
|
||||
configurationSection = xdocument.XPathSelectElement($"//XmlConfigurations//XmlConfiguration[@name='{sectionName}']");
|
||||
if(configurationSection != null && configurationSection.HasElements)
|
||||
{
|
||||
var sectionElements = configurationSection.Elements();
|
||||
sections.AddRange(from item in sectionElements
|
||||
let name = item?.Name
|
||||
where name != null
|
||||
select name.ToString());
|
||||
}
|
||||
}
|
||||
return sections;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Generic configuration factory based on the type
|
||||
/// </summary>
|
||||
public class ConfigurationFileFactory : ConfigurationFileFactoryBase
|
||||
{
|
||||
private readonly string _type;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
public ConfigurationFileFactory(string type)
|
||||
{
|
||||
_type = type;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public override IConfigurationFile CreateConfigurationFile(string fileName)
|
||||
{
|
||||
Type type = Type.GetType(_type);
|
||||
if (type == null)
|
||||
{
|
||||
throw new InvalidOperationException($"File format not supported with {_type} package.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return (IConfigurationFile)Activator.CreateInstance(type, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration file factory base class for the Factory Method pattern
|
||||
/// </summary>
|
||||
public abstract class ConfigurationFileFactoryBase
|
||||
{
|
||||
/// <summary>
|
||||
/// template method for creating configuration file
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
public abstract IConfigurationFile CreateConfigurationFile(string fileName);
|
||||
|
||||
/// <summary>
|
||||
/// creates configuration file based on the overwrite of the
|
||||
/// concrete implementation of the CreateConfigurationFile method
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
public IConfigurationFile GetConfigurationFile(string fileName)
|
||||
{
|
||||
IConfigurationFile configurationFile = CreateConfigurationFile(fileName);
|
||||
return configurationFile;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// IniConfigurationFile factory class
|
||||
/// </summary>
|
||||
public class IniConfigurationFileFactory : ConfigurationFileFactoryBase
|
||||
{
|
||||
/// <summary>
|
||||
/// IniConfigurationFile factory method
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
public override IConfigurationFile CreateConfigurationFile(string fileName)
|
||||
{
|
||||
return new IniConfigurationFile(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// JsonConfigurationFile factory class
|
||||
/// </summary>
|
||||
public class JsonConfigurationFileFactory : ConfigurationFileFactoryBase
|
||||
{
|
||||
/// <summary>
|
||||
/// JsonConfigurationFile factory method
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public override IConfigurationFile CreateConfigurationFile(string fileName)
|
||||
{
|
||||
Type jsonType = Type.GetType("Raytheon.Common.JsonConfigurationFile, Raytheon.Configuration.Json");
|
||||
if (jsonType == null)
|
||||
{
|
||||
throw new InvalidOperationException($"JSON file format supported with Raytheon.Configuration.Json package.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return (IConfigurationFile)Activator.CreateInstance(jsonType, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// TomlConfigurationFile factory class
|
||||
/// </summary>
|
||||
public class TomlConfigurationFileFactory : ConfigurationFileFactoryBase
|
||||
{
|
||||
/// <summary>
|
||||
/// TomlConfigurationFile factory method
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public override IConfigurationFile CreateConfigurationFile(string fileName)
|
||||
{
|
||||
Type tomlType = Type.GetType("Raytheon.Common.TomlConfigurationFile, Raytheon.Configuration.Toml");
|
||||
if (tomlType == null)
|
||||
{
|
||||
throw new InvalidOperationException($"TOML file format supported with Raytheon.Configuration.Toml package.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return (IConfigurationFile)Activator.CreateInstance(tomlType, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// XmlConfigurationFile factory class
|
||||
/// </summary>
|
||||
public class XmlConfigurationFileFactory : ConfigurationFileFactoryBase
|
||||
{
|
||||
/// <summary>
|
||||
/// XmlConfigurationFile factory method
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
public override IConfigurationFile CreateConfigurationFile(string fileName)
|
||||
{
|
||||
return new XmlConfigurationFile(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Read/Write to an ini file.
|
||||
/// </summary>
|
||||
public class IniConfigurationFile : ConfigurationFileBase
|
||||
{
|
||||
#region PrivateMemberVariables
|
||||
|
||||
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)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool WritePrivateProfileSection(string lpAppName, string line, string lpFileName);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern int GetPrivateProfileSectionNames(byte[] sections, int bufferSize, string filename);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <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 IniConfigurationFile(string fileName)
|
||||
: base(fileName)
|
||||
{
|
||||
if (ConfigurationFileType != ConfigurationFileType.INI)
|
||||
{
|
||||
throw new ArgumentException("Expecting INI file configuration type");
|
||||
}
|
||||
|
||||
if (!_fileInfo.Exists)
|
||||
{
|
||||
throw new Exception($"Can't find file: {fileName}");
|
||||
}
|
||||
}
|
||||
|
||||
#region PublicFunctions
|
||||
|
||||
/// <summary>
|
||||
/// reads a value from configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
public override T ReadValue<T>(string section, string key, T defaultValue = default)
|
||||
{
|
||||
const int BUFFER_SIZE = 1024;
|
||||
string temp = new string('\0', BUFFER_SIZE);
|
||||
int numBytes = NativeMethods.GetPrivateProfileString(section, key, "", temp, BUFFER_SIZE, _fileName);
|
||||
if (numBytes == 0)
|
||||
{
|
||||
WriteValue<T>(section, key, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = temp.TrimEnd('\0');
|
||||
return TypeConverter.ChangeType<T>(temp);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a value from configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
public override string ReadValue(string section, string key)
|
||||
{
|
||||
const int BUFFER_SIZE = 1024;
|
||||
string temp = new string('\0', BUFFER_SIZE);
|
||||
|
||||
if (!ReadAllSections().Contains(section))
|
||||
throw new Exception($"Section '{section}' doesn't exist in {_fileName}");
|
||||
|
||||
if (!ReadAllKeys(section).Contains(key))
|
||||
throw new Exception($"Key '{key}' doesn't exist under section '{section}' in {_fileName}");
|
||||
|
||||
int numBytes = NativeMethods.GetPrivateProfileString(section, key, "", temp, BUFFER_SIZE, _fileName);
|
||||
if (numBytes > 0)
|
||||
{
|
||||
return temp.TrimEnd('\0');
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"The value associated with key '{key}' under section '{section}' is empty in {_fileName}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string value
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="lineToWrite"></param>
|
||||
public override void WriteValue<T>(string section, string key, T lineToWrite)
|
||||
{
|
||||
if (!NativeMethods.WritePrivateProfileString(section, key, $"{lineToWrite}", _fileName))
|
||||
{
|
||||
throw new Exception($"IniFile::WriteValue() - WritePrivateProfileString returned false for section: {section}, key {key}, line {lineToWrite}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a list of values from INI configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultList"></param>
|
||||
/// <returns></returns>
|
||||
public override List<T> ReadList<T>(string section, string key, IList<T> defaultList = null)
|
||||
{
|
||||
List<T> resultList = new();
|
||||
|
||||
string stringResult = ReadValue(section, key, string.Empty);
|
||||
|
||||
if (string.IsNullOrEmpty(stringResult))
|
||||
{
|
||||
WriteList(section, key, defaultList);
|
||||
return new List<T>(defaultList);
|
||||
}
|
||||
|
||||
foreach (string item in stringResult.Split('|'))
|
||||
{
|
||||
resultList.Add(TypeConverter.ChangeType<T>(item));
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a list of values to INI configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="listToWrite"></param>
|
||||
public override void WriteList<T>(string section, string key, IList<T> listToWrite)
|
||||
{
|
||||
List<string> stringListToWrite = new(listToWrite.Select(a => a.ToString()));
|
||||
WriteValue(section, key, string.Join("|", stringListToWrite));
|
||||
}
|
||||
|
||||
/// <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 override List<string> ReadAllKeys(string section)
|
||||
{
|
||||
const int BUFFER_SIZE = 2500;
|
||||
string temp = new('\0', BUFFER_SIZE);
|
||||
int numBytes = NativeMethods.GetPrivateProfileString(section, null, "", temp, BUFFER_SIZE, _fileName);
|
||||
|
||||
List<string> keyList = new List<string>();
|
||||
|
||||
if (numBytes == 0)
|
||||
{
|
||||
return keyList;
|
||||
}
|
||||
|
||||
temp = temp.TrimEnd('\0');
|
||||
keyList.AddRange(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 override List<string> ReadAllSections()
|
||||
{
|
||||
List<string> sectionList = new();
|
||||
|
||||
// allocate a 10K buffer.
|
||||
const int BUFFER_SIZE = 10240;
|
||||
// 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)
|
||||
{
|
||||
return sectionList;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
for (int i = 0; i < sectionListTemp.Length; ++i)
|
||||
{
|
||||
sectionList.Add(sectionListTemp[i]);
|
||||
}
|
||||
|
||||
return sectionList;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of the IConfiguration interface
|
||||
/// </summary>
|
||||
public class RaytheonConfiguration : IConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// returns configuration file path
|
||||
/// </summary>
|
||||
private string configFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(OutputPath, string.Concat(Name, ".xml"));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// configuration file name
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// configuration file location
|
||||
/// </summary>
|
||||
public string OutputPath
|
||||
{
|
||||
get;
|
||||
internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// default constructor
|
||||
/// </summary>
|
||||
public RaytheonConfiguration()
|
||||
{
|
||||
OutputPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Raytheon", "Configuration");
|
||||
IsValidPath(OutputPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// constructor that takes configuration file name
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public RaytheonConfiguration(string name) : this()
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// constructor that takes file name and location
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="outputPath"></param>
|
||||
public RaytheonConfiguration(string name, string outputPath) : this(name)
|
||||
{
|
||||
if (IsValidPath(outputPath))
|
||||
{
|
||||
OutputPath = outputPath;
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateConfigurationFile(FileInfo file)
|
||||
{
|
||||
XDocument xDocument = new XDocument();
|
||||
xDocument.Add(new XElement("Configurations"));
|
||||
xDocument.Root.Add(new XElement("IniConfiguration"));
|
||||
xDocument.Root.Add(new XElement("XmlConfigurations"));
|
||||
xDocument.Save(file.FullName);
|
||||
}
|
||||
|
||||
private FileInfo CreateFileIfMissing()
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(configFilePath);
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
throw new Exception($"Can't find file: {configFilePath}");
|
||||
}
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
private static XElement GetConfigSection(string section, XElement iniConfiguration, string configFilePath)
|
||||
{
|
||||
XElement xElement = (
|
||||
from s in iniConfiguration.Descendants("section")
|
||||
where (string)s.Attribute("name") == section
|
||||
select s).FirstOrDefault();
|
||||
if (xElement == null)
|
||||
{
|
||||
throw new Exception($"There is no <section> tag with 'name={section}' in {configFilePath}");
|
||||
}
|
||||
return xElement;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads single string value from XML configuration file by section name and a key
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
public string GetConfigurationValue(string section, string key, string defaultValue)
|
||||
{
|
||||
FileInfo fileInfo = CreateFileIfMissing();
|
||||
XDocument xDocument = XDocument.Load(fileInfo.FullName);
|
||||
XElement xElement = xDocument.Root.Element("IniConfiguration");
|
||||
XElement configSection = GetConfigSection(section, xElement, configFilePath);
|
||||
XElement xElement1 = (
|
||||
from k in configSection.Descendants("key")
|
||||
where (string)k.Attribute("name") == key
|
||||
select k).FirstOrDefault();
|
||||
if (xElement1 == null)
|
||||
{
|
||||
XName xName = "key";
|
||||
object[] xAttribute = new object[] { new XAttribute("name", key), new XAttribute("value", defaultValue) };
|
||||
xElement1 = new XElement(xName, xAttribute);
|
||||
configSection.Add(xElement1);
|
||||
xDocument.Save(fileInfo.FullName);
|
||||
}
|
||||
XAttribute xAttribute1 = xElement1.Attribute("value");
|
||||
if (xAttribute1 == null)
|
||||
{
|
||||
xAttribute1 = new XAttribute("value", defaultValue);
|
||||
xElement1.Add(xAttribute1);
|
||||
xDocument.Save(fileInfo.FullName);
|
||||
}
|
||||
if (xAttribute1 == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return xAttribute1.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads single string value from XML configuration file by section name and a key
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
public string GetConfigurationValue(string section, string key)
|
||||
{
|
||||
FileInfo fileInfo = CreateFileIfMissing();
|
||||
XDocument xDocument = XDocument.Load(fileInfo.FullName);
|
||||
XElement xElement = xDocument.Root.Element("IniConfiguration");
|
||||
XElement configSection = GetConfigSection(section, xElement, configFilePath);
|
||||
XElement xElement1 = (
|
||||
from k in configSection.Descendants("key")
|
||||
where (string)k.Attribute("name") == key
|
||||
select k).FirstOrDefault();
|
||||
if (xElement1 == null)
|
||||
{
|
||||
throw new Exception($"There is no <key> tag with 'name={key}' under section {section} in {configFilePath}");
|
||||
}
|
||||
XAttribute xAttribute1 = xElement1.Attribute("value");
|
||||
if (xAttribute1 == null)
|
||||
{
|
||||
throw new Exception($"Attribute 'value' is missing for <key> tag with 'name={key}' under section {section} in {configFilePath}");
|
||||
}
|
||||
return xAttribute1.Value;
|
||||
}
|
||||
|
||||
private static XElement GetConfigXml(string name, XElement xmlConfigurations)
|
||||
{
|
||||
XElement xElement = (
|
||||
from s in xmlConfigurations.Descendants("XmlConfiguration")
|
||||
where (string)s.Attribute("name") == name
|
||||
select s).FirstOrDefault();
|
||||
return xElement;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads XML configuration from a file
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public string GetXmlConfiguration(string name)
|
||||
{
|
||||
XDocument xDocument = XDocument.Load(CreateFileIfMissing().FullName);
|
||||
XElement xElement = xDocument.Root.Element("XmlConfigurations");
|
||||
XElement configXml = GetConfigXml(name, xElement);
|
||||
if (configXml == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
return configXml.ToString();
|
||||
}
|
||||
|
||||
internal void Initialize()
|
||||
{
|
||||
Directory.CreateDirectory(OutputPath);
|
||||
CreateFileIfMissing();
|
||||
}
|
||||
|
||||
private static bool IsValidPath(string outputPath)
|
||||
{
|
||||
bool flag;
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(outputPath);
|
||||
flag = true;
|
||||
}
|
||||
catch (PathTooLongException)
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
private static void SetConfigKey(string key, string value, XElement configSection)
|
||||
{
|
||||
XElement xElement = (
|
||||
from k in configSection.Descendants("key")
|
||||
where (string)k.Attribute("name") == key
|
||||
select k).FirstOrDefault();
|
||||
if (xElement != null)
|
||||
{
|
||||
xElement.SetAttributeValue("value", value);
|
||||
return;
|
||||
}
|
||||
XName xName = "key";
|
||||
object[] xAttribute = new object[] { new XAttribute("name", key), null };
|
||||
xAttribute[1] = new XAttribute("value", value ?? string.Empty);
|
||||
xElement = new XElement(xName, xAttribute);
|
||||
configSection.Add(xElement);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes configuration value by section name and by key
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
public void SetConfigurationValue(string section, string key, string value)
|
||||
{
|
||||
FileInfo fileInfo = CreateFileIfMissing();
|
||||
XDocument xDocument = XDocument.Load(fileInfo.FullName);
|
||||
XElement xElement = xDocument.Root.Element("IniConfiguration");
|
||||
SetConfigKey(key, value, GetConfigSection(section, xElement, configFilePath));
|
||||
xDocument.Save(fileInfo.FullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// saves XML string into XML file
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="xml"></param>
|
||||
public void SetXmlConfiguration(string name, string xml)
|
||||
{
|
||||
FileInfo fileInfo = CreateFileIfMissing();
|
||||
XElement xElement = XElement.Parse(xml);
|
||||
int elementCount = xElement.Elements().Count();
|
||||
|
||||
XDocument xDocument = XDocument.Load(fileInfo.FullName);
|
||||
XElement xmlConfigurations = xDocument.Root.Element("XmlConfigurations");
|
||||
XElement sectionXml = GetConfigXml(name, xmlConfigurations);
|
||||
|
||||
XName xName = "XmlConfiguration";
|
||||
object[] xAttribute = new object[1 + elementCount];
|
||||
xAttribute[0] = new XAttribute("name", name);
|
||||
if (elementCount == 1)
|
||||
{
|
||||
xAttribute[1] = xElement.FirstNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i = 1;
|
||||
foreach (var item in xElement.Elements())
|
||||
{
|
||||
xAttribute[i++] = item;
|
||||
}
|
||||
}
|
||||
|
||||
if (sectionXml == null)
|
||||
{
|
||||
xmlConfigurations.Add(new XElement(xName, xAttribute));
|
||||
}
|
||||
else
|
||||
{
|
||||
sectionXml.ReplaceWith(new XElement(xName, xAttribute));
|
||||
}
|
||||
|
||||
xDocument.Save(fileInfo.FullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// tries reading enumeration value by section and key name
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public bool TryGetEnumValue<T>(string section, string key, out T value)
|
||||
where T : struct
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(section))
|
||||
{
|
||||
throw new ArgumentException("'section' cannot be Null or Whitespace", "section");
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
{
|
||||
throw new ArgumentException("'key' cannot be Null or Whitespace", "key");
|
||||
}
|
||||
if (!typeof(T).IsEnum)
|
||||
{
|
||||
throw new ArgumentException("T must be an enumerated type");
|
||||
}
|
||||
bool flag = Enum.TryParse<T>(GetConfigurationValue(section, key, string.Concat("NOT_A_VALID_", key.ToUpper())), out value);
|
||||
if (!flag)
|
||||
{
|
||||
int num = 0;
|
||||
string[] names = Enum.GetNames(typeof(T));
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
string str = names[i];
|
||||
int num1 = num + 1;
|
||||
num = num1;
|
||||
int num2 = num1;
|
||||
SetConfigurationValue(string.Concat("Valid_", key), num2.ToString(), str);
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// implementation of the Raytheon Configuration Manager
|
||||
/// </summary>
|
||||
[Export(typeof(IConfigurationManager))]
|
||||
public class RaytheonConfigurationManager : IConfigurationManager
|
||||
{
|
||||
private object _configLock = new();
|
||||
|
||||
private Dictionary<string, RaytheonConfiguration> _configurations = new();
|
||||
|
||||
private static readonly string DefaultStoragePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Raytheon", "InstrumentManagerService");
|
||||
|
||||
private string _storagePath;
|
||||
|
||||
/// <summary>
|
||||
/// gets or sets configuration storage path
|
||||
/// when setting the path and it does not exist will use the default value instead
|
||||
/// </summary>
|
||||
public string ConfigurationStoragePath
|
||||
{
|
||||
get
|
||||
{
|
||||
return _storagePath;
|
||||
}
|
||||
set
|
||||
{
|
||||
string item = value;
|
||||
|
||||
if(string.IsNullOrWhiteSpace(item))
|
||||
{
|
||||
item = ConfigurationManager.AppSettings["ConfigurationPath"];
|
||||
}
|
||||
|
||||
if(!IsValidPath(item, true))
|
||||
{
|
||||
Trace.WriteLine(string.Format("The Application Setting [ConfigurationPath] '{0}' is invalid.", item));
|
||||
_storagePath = DefaultStoragePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
_storagePath = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// if path not provided will be using either app settings value or default
|
||||
/// </summary>
|
||||
public RaytheonConfigurationManager()
|
||||
{
|
||||
ConfigurationStoragePath = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// constructor that takes configuration file path
|
||||
/// </summary>
|
||||
/// <param name="defaultPath"></param>
|
||||
public RaytheonConfigurationManager(string defaultPath) => ConfigurationStoragePath = defaultPath;
|
||||
|
||||
/// <summary>
|
||||
/// returns RaytheonConfiguration instance
|
||||
/// </summary>
|
||||
/// <param name="configurationName"></param>
|
||||
/// <returns></returns>
|
||||
public IConfiguration GetConfiguration(string configurationName)
|
||||
{
|
||||
RaytheonConfiguration item = null;
|
||||
lock(_configLock)
|
||||
{
|
||||
if(_configurations.ContainsKey(configurationName))
|
||||
{
|
||||
item = _configurations[configurationName];
|
||||
}
|
||||
else
|
||||
{
|
||||
item = new RaytheonConfiguration(configurationName, ConfigurationStoragePath);
|
||||
item.Initialize();
|
||||
_configurations.Add(configurationName, item);
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// checks if the configuration storage path for config file is valid
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="allowRelativePaths"></param>
|
||||
/// <returns></returns>
|
||||
private bool IsValidPath(string path, bool allowRelativePaths = false)
|
||||
{
|
||||
if(string.IsNullOrEmpty(path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isValid;
|
||||
try
|
||||
{
|
||||
string fullPath = Path.GetFullPath(path);
|
||||
|
||||
if(allowRelativePaths)
|
||||
{
|
||||
isValid = Path.IsPathRooted(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
string root = Path.GetPathRoot(path);
|
||||
isValid = string.IsNullOrEmpty(root.Trim(new char[] { '\\', '/' })) == false;
|
||||
}
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Read/Write to an XML file.
|
||||
/// </summary>
|
||||
public class XmlConfigurationFile : ConfigurationFileBase
|
||||
{
|
||||
#region PrivateMemberVariables
|
||||
|
||||
/// <summary>
|
||||
/// Raytheon configuration
|
||||
/// </summary>
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#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 XmlConfigurationFile(string fileName)
|
||||
: base(fileName)
|
||||
{
|
||||
if (ConfigurationFileType != ConfigurationFileType.XML)
|
||||
{
|
||||
throw new ArgumentException("Expecting XML file configuration type");
|
||||
}
|
||||
|
||||
_configurationManager = new RaytheonConfigurationManager(_fileInfo.DirectoryName);
|
||||
_configuration = _configurationManager.GetConfiguration(NameWithoutExtension(_fileInfo));
|
||||
}
|
||||
private static string NameWithoutExtension(FileInfo fileInfo)
|
||||
{
|
||||
return fileInfo.Name.Remove(fileInfo.Name.LastIndexOf("."));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a value from configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
public override T ReadValue<T>(string section, string key, T defaultValue = default)
|
||||
{
|
||||
return _configuration.GetConfigurationValue<T>(section, key, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a value from configuration file
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public override string ReadValue(string section, string key)
|
||||
{
|
||||
return _configuration.GetConfigurationValue(section, key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string value
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="lineToWrite"></param>
|
||||
public override void WriteValue<T>(string section, string key, T lineToWrite)
|
||||
{
|
||||
_configuration.SetConfigurationValue<T>(section, key, lineToWrite);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reads a list of values from configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultList"></param>
|
||||
/// <returns></returns>
|
||||
public override List<T> ReadList<T>(string section, string key, IList<T> defaultList = null)
|
||||
{
|
||||
return _configuration.GetConfigurationListValue<T>(section, key, defaultList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// writes a list of values to configuration file
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="listToWrite"></param>
|
||||
public override void WriteList<T>(string section, string key, IList<T> listToWrite)
|
||||
{
|
||||
_configuration.SetConfigurationListValue(section, key, listToWrite);
|
||||
}
|
||||
|
||||
/// <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 override List<string> ReadAllKeys(string section)
|
||||
{
|
||||
return ConfigurationHelper.GetAvailableConfigSectionKeys(_fileName, section);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of all of the sections in the ini file.
|
||||
/// </summary>
|
||||
/// <returns>A list of all sections.</returns>
|
||||
public override List<string> ReadAllSections()
|
||||
{
|
||||
return ConfigurationHelper.GetAvailableConfigSections(_fileName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
[DataContract]
|
||||
public class ConfigurationException : Exception
|
||||
{
|
||||
public ConfigurationException()
|
||||
:base()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ConfigurationException(string message)
|
||||
:base(message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ConfigurationException(string message, Exception innerException)
|
||||
:base(message, innerException)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ConfigurationException(SerializationInfo info, StreamingContext context)
|
||||
:base(info, context)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// interface for flaging the moment when configurable object is done with configuration
|
||||
/// restored from the previous version of Raytheon.Configuration package
|
||||
/// </summary>
|
||||
public interface IConfigurable
|
||||
{
|
||||
void OnConfigured();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration interface
|
||||
/// restored from the previous version of Raytheon.Configuration package
|
||||
/// </summary>
|
||||
public interface IConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the configuration value.
|
||||
/// </summary>
|
||||
/// <param name="section">The section.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
void SetConfigurationValue(string section, string key, string value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the configuration value.
|
||||
/// </summary>
|
||||
/// <param name="section">The section.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="defaultValue">The default value.</param>
|
||||
/// <returns></returns>
|
||||
string GetConfigurationValue(string section, string key, string defaultValue);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the configuration value.
|
||||
/// </summary>
|
||||
/// <param name="section">The section.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <returns></returns>
|
||||
string GetConfigurationValue(string section, string key);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the XML configuration.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="xml">The XML.</param>
|
||||
void SetXmlConfiguration(string name, string xml);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the XML configuration.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns></returns>
|
||||
string GetXmlConfiguration(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the enumerated configuration value.
|
||||
/// If it does not exist or cannot be parsed to a valid value,
|
||||
/// it will create a new section called Valid_{key} and list the valid enumeration values.
|
||||
/// </summary>
|
||||
/// <param name="section">The section.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="defaultValue">The default value.</param>
|
||||
/// <returns></returns>
|
||||
bool TryGetEnumValue<T>(string section, string key, out T value) where T : struct;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// supported file types
|
||||
/// </summary>
|
||||
public enum ConfigurationFileType
|
||||
{
|
||||
INI,
|
||||
XML,
|
||||
TOML,
|
||||
JSON,
|
||||
YAML,
|
||||
OTHER
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// updated version of IConfiguration interface
|
||||
/// allows reading and writing generic types as well as lists
|
||||
/// </summary>
|
||||
public interface IConfigurationFile
|
||||
{
|
||||
/// <summary>
|
||||
/// reads a single generic type value from the file section
|
||||
/// if value or section does not exist, will create one and will add the default value
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defValue"></param>
|
||||
/// <returns></returns>
|
||||
T ReadValue<T>(string section, string key, T defValue = default);
|
||||
|
||||
/// <summary>
|
||||
/// reads a single generic type value from the file section
|
||||
/// if value doesn't exist, throw exception
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
string ReadValue(string section, string key);
|
||||
|
||||
/// <summary>
|
||||
/// reads a list of generic type values from the file section
|
||||
/// if list or section does not exist, will create one and will populate with the default list
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defList"></param>
|
||||
/// <returns></returns>
|
||||
List<T> ReadList<T>(string section, string key, IList<T> defList = null);
|
||||
|
||||
/// <summary>
|
||||
/// reads all available keys from the given section of configuration file
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <returns></returns>
|
||||
List<string> ReadAllKeys(string section);
|
||||
|
||||
/// <summary>
|
||||
/// reads all available sections from configuration file
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<string> ReadAllSections();
|
||||
|
||||
/// <summary>
|
||||
/// writes a single value of a generic type
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="lineToWrite"></param>
|
||||
void WriteValue<T>(string section, string key, T lineToWrite);
|
||||
|
||||
/// <summary>
|
||||
/// writes a list of generic values
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="listToWrite"></param>
|
||||
void WriteList<T>(string section, string key, IList<T> listToWrite);
|
||||
|
||||
/// <summary>
|
||||
/// checks if the value exists in the given section and given key
|
||||
/// </summary>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
bool ValueExists(string section, string key);
|
||||
|
||||
/// <summary>
|
||||
/// configuration file name
|
||||
/// </summary>
|
||||
string FileName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// configuration file type
|
||||
/// </summary>
|
||||
ConfigurationFileType ConfigurationFileType { get; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// ******************************************************************************//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
// ****************************************************************************//
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Configuration Manager interface
|
||||
/// </summary>
|
||||
public interface IConfigurationManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the configuration by name.
|
||||
/// </summary>
|
||||
/// <param name="configurationName">Name of the configuration.</param>
|
||||
/// <returns></returns>
|
||||
IConfiguration GetConfiguration(string configurationName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the configuration storage path or the location of the configuration files
|
||||
/// </summary>
|
||||
string ConfigurationStoragePath { get; set; }
|
||||
}
|
||||
}
|
||||
54
Source/TSRealLib/Common/Raytheon.Common/FPGA/HssUtilSs.cs
Normal file
54
Source/TSRealLib/Common/Raytheon.Common/FPGA/HssUtilSs.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
// 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.Text;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// A collection of utilities.
|
||||
/// </summary>
|
||||
public static class HssUtilSs
|
||||
{
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="chassisHandle"></param>
|
||||
/// <param name="errorCode"></param>
|
||||
/// <param name="moduleName"></param>
|
||||
/// <returns></returns>
|
||||
public static string BuildErrorString(uint chassisHandle, int errorCode, string moduleName)
|
||||
{
|
||||
StringBuilder errorStrTemp = new StringBuilder(512);
|
||||
|
||||
int ret = HssubNativeMethods.terHsi_error_message(chassisHandle, errorCode, errorStrTemp);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
throw new Exception("HssUtilSs::BuildErrorString() - terHsi_error_message returned an error(" + ret + ")");
|
||||
}
|
||||
|
||||
string errorMsg = errorStrTemp.ToString();
|
||||
|
||||
return errorMsg += "(" + moduleName + ")";
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
119
Source/TSRealLib/Common/Raytheon.Common/FPGA/HssUtilTs.cs
Normal file
119
Source/TSRealLib/Common/Raytheon.Common/FPGA/HssUtilTs.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
// 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.Text;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
/// A collection of utilities.
|
||||
/// </summary>
|
||||
public static class HssUtilTs
|
||||
{
|
||||
|
||||
public struct LocalBusParams
|
||||
{
|
||||
public int cardHandle;
|
||||
public int address;
|
||||
public int data;
|
||||
}
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="chassisHandle"></param>
|
||||
/// <param name="errorCode"></param>
|
||||
/// <param name="moduleName"></param>
|
||||
/// <returns></returns>
|
||||
public static string BuildErrorString(uint chassisHandle, int errorCode, string moduleName)
|
||||
{
|
||||
StringBuilder errorStrTemp = new StringBuilder(512);
|
||||
|
||||
int ret = HssubNativeMethods.terHss_error_message(chassisHandle, errorCode, errorStrTemp);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
throw new Exception("HssUtilTs::BuildErrorString() - terHss_error_message returned an error(" + ret + ")");
|
||||
}
|
||||
|
||||
string errorMsg = errorStrTemp.ToString();
|
||||
|
||||
return errorMsg += "(" + moduleName + ")";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static LocalBusParams ByteArrayToLocalBusParms(byte[] data)
|
||||
{
|
||||
GCHandle rxPinnedArray = GCHandle.Alloc(data, GCHandleType.Pinned);
|
||||
IntPtr pBytePtr = rxPinnedArray.AddrOfPinnedObject();
|
||||
LocalBusParams lbParams = (LocalBusParams)(Marshal.PtrToStructure(pBytePtr, typeof(LocalBusParams)));
|
||||
rxPinnedArray.Free();
|
||||
|
||||
return lbParams;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="lbParams"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] LocalBusParmsToByteArray(LocalBusParams lbParams)
|
||||
{
|
||||
// get the size of the structure
|
||||
int structureSize = Marshal.SizeOf(lbParams);
|
||||
|
||||
// allocate a byte array
|
||||
byte[] dataToSend = new byte[structureSize];
|
||||
|
||||
// convert structure to byte array
|
||||
IntPtr pBytePtr = Marshal.AllocHGlobal(structureSize);
|
||||
Marshal.StructureToPtr(lbParams, pBytePtr, true);
|
||||
Marshal.Copy(pBytePtr, dataToSend, 0, structureSize);
|
||||
Marshal.FreeHGlobal(pBytePtr);
|
||||
|
||||
return dataToSend;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="chassisHandle"></param>
|
||||
/// <param name="hssubSubSystemAppSync"></param>
|
||||
/// <param name="name"></param>
|
||||
public static void WaitForSync(uint chassisHandle, int hssubSubSystemAppSync, string name)
|
||||
{
|
||||
//0 is VI_FALSE, 1 is VI_TRUE
|
||||
int hssubSyncData = 0;
|
||||
int ret = HssubNativeMethods.terHss_Application_WaitForSyncObject(chassisHandle, hssubSubSystemAppSync, HssubNativeMethods.TERHSS_TIMEOUT_10SEC, 1, ref hssubSyncData);
|
||||
if (ret != 0)
|
||||
{
|
||||
string errorStr = HssUtilTs.BuildErrorString(chassisHandle, ret, name);
|
||||
|
||||
throw new Exception("HssUtilTs::WaitForSync() - terHss_Application_WaitForSyncObject() returned an error(" + ret + ")" + ": " + errorStr);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace FpgaMeasurementInstrumentsLib
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public unsafe static class HssubNativeMethods
|
||||
{
|
||||
public const int TERHSI_FPGA_TEST_DEFINED = 1;
|
||||
|
||||
// timeouts
|
||||
public const int TERHSS_TIMEOUT_INDEFINITE = 0;
|
||||
public const int TERHSS_TIMEOUT_60SEC = 60;
|
||||
public const int TERHSS_TIMEOUT_10SEC = 10;
|
||||
|
||||
//
|
||||
public const int TERHSS_OPTION_ALLOW_OVERWRITE = 1;
|
||||
public const int TERHSS_OPTION_NONE = 0;
|
||||
|
||||
// callback codes
|
||||
public const int MESSAGE_CONTEXT_INIT_INSTRUMENT = 0;
|
||||
public const int MESSAGE_CONTEXT_LOAD_INSTRUMENT = 1;
|
||||
public const int MESSAGE_CONTEXT_LB_WRITE32 = 2;
|
||||
public const int MESSAGE_CONTEXT_LB_READ32 = 3;
|
||||
public const int MESSAGE_CONTEXT_PAM_BLOCK_CREATE = 4;
|
||||
public const int MESSAGE_CONTEXT_PAM_BLOCK_READ = 5;
|
||||
public const int MESSAGE_CONTEXT_NBLOCK_WRITE = 6;
|
||||
public const int MESSAGE_CONTEXT_NBLOCK_READ = 7;
|
||||
public const int MESSAGE_CONTEXT_RUN_EXE = 8;
|
||||
public const int MESSAGE_CONTEXT_RUN_JTAG = 9;
|
||||
public const int MESSAGE_CONTEXT_DMA_CREATE_PAM_BLOCK = 10;
|
||||
public const int MESSAGE_CONTEXT_DMA_READ_PAM_BLOCK = 11;
|
||||
public const int MESSAGE_CONTEXT_DMA_WRITE_PAM_BLOCK = 12;
|
||||
public const int MESSAGE_CONTEXT_DMA_MEMORY_MOVE = 13;
|
||||
public const int MESSAGE_CONTEXT_DMA_PAM_CLEAR = 14;
|
||||
public const int MESSAGE_CONTEXT_UCLK_SET = 20;
|
||||
|
||||
// HSS imports (running on the remote test station)
|
||||
public delegate void MessageCallbackDelagate(uint chassisHandle, int applicationHandle, int messageContext, uint messageSize, byte* message);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_error_message(uint chassisHandle, int errorCode, StringBuilder errorMessage);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_init(string resourceName, ushort idQuery, ushort reset, ref uint pdwVi);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_Application_CreateSyncObject(uint chassisHandle, string syncName, ref int syncObjectHandle);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_Application_RegisterMessageCallback(uint chassisHandle, MessageCallbackDelagate callback);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_Subsystem_SendFile(uint chassisHandle, string sourceFile, string destinationFile, int options);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_Application_Load(uint chassisHandle, string applicationName, string remotePath, ref int applicationHandle);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_Application_Start(uint chassisHandle, int applicationHandle, string cmdLineArgs, double timeout);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_Application_WaitForSyncObject(uint chassisHandle, int syncHandle, double timeout, ushort autoReset, ref int contextValue);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_Application_SendMessage(uint chassisHandle, int applicationHandle, int messageContext, int messageArraySize, byte[] message, double timeout);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_Subsystem_DeleteFile(uint chassisHandle, string file, int options);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_close(uint chassisHandle);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHss.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHss_self_test(uint chassisHandle, ref short result, StringBuilder message);
|
||||
|
||||
|
||||
// HSI imports (running on the local sub system)
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHsi_32.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHsi_error_message(uint chassisHandle, int errorCode, StringBuilder errorMessage);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHsi_32.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHsi_init(string resourceName, ushort idQuery, ushort reset, ref uint pdwVi);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHsi_32.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHsi_Firmware_Load(uint chassisHandle, int fpga, string fwFileName, ref ushort customerId, ref ushort applicationID, ref uint revisionID);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHsi_32.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHsi_LB_Read32(uint chassisHandle, uint offset, ref uint data);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHsi_32.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHsi_LB_ReadBlock32(uint chassisHandle, uint offset, uint numberWordsToRead, uint* data);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHsi_32.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHsi_LB_Write32(uint chassisHandle, uint offset, uint data);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHsi_32.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHsi_LB_WriteBlock32(uint chassisHandle, uint offset, uint numberWordsToWrite, uint[] data);
|
||||
//public static extern int terHsi_LB_WriteBlock32(uint chassisHandle, uint offset, uint numberWordsToWrite, uint* data);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHsi_32.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHsi_close(uint chassisHandle);
|
||||
|
||||
[DllImport("C:\\Program Files (x86)\\IVI Foundation\\IVI\\Bin\\terHsi_32.dll", CallingConvention = CallingConvention.StdCall)]
|
||||
public static extern int terHsi_reset(uint chassisHandle);
|
||||
}
|
||||
}
|
||||
123
Source/TSRealLib/Common/Raytheon.Common/Interfaces/IDisplay.cs
Normal file
123
Source/TSRealLib/Common/Raytheon.Common/Interfaces/IDisplay.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
// **********************************************************************************************************
|
||||
// IDisplay.cs
|
||||
// 2/17/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <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,
|
||||
/// <summary>
|
||||
/// Off log level (Ordinal = 6)
|
||||
/// </summary>
|
||||
OFF
|
||||
}
|
||||
|
||||
public interface IDisplay
|
||||
{
|
||||
/// <summary>
|
||||
/// user interface capability with error logger
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="logLevel"></param>
|
||||
void ShowMessage(string message, LogLevel logLevel = LogLevel.INFO);
|
||||
}
|
||||
|
||||
public interface IChillerDisplay
|
||||
{
|
||||
void ChillerMonitorUiUpdate(ActiveHealthMonitorData data, int errorCode);
|
||||
}
|
||||
|
||||
public interface IDioDisplay
|
||||
{
|
||||
void DioControlUiUpdate(List<string> inputNames, List<string> outputNames);
|
||||
}
|
||||
|
||||
public interface IFpgaDisplay
|
||||
{
|
||||
void FpgaControlUiUpdate(List<string> fpgaNames);
|
||||
}
|
||||
|
||||
public interface IPowerControlDisplay
|
||||
{
|
||||
void PowerControlUiUpdate(List<string> powerFormNames);
|
||||
}
|
||||
|
||||
public interface IPowerMonitorDisplay
|
||||
{
|
||||
void PowerMonitorUiUpdate(List<PowerMonitorCallbackData> callBackDataList, int errorCode);
|
||||
}
|
||||
|
||||
public interface IHealthMonitorDisplay
|
||||
{
|
||||
void HealthMonitorControlUiUpdate(List<ActiveHealthMonitorData> callBackDataList);
|
||||
}
|
||||
|
||||
public interface INGIDisplay : IDisplay, IChillerDisplay, IDioDisplay, IFpgaDisplay, IPowerControlDisplay, IPowerMonitorDisplay, IHealthMonitorDisplay
|
||||
{
|
||||
}
|
||||
|
||||
public interface IHandleCriticalError
|
||||
{
|
||||
void HandleCriticalError(string message, bool shallWeStopThreads = true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// 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;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines an interface for specific message parsing routines
|
||||
/// used in conjunction with MsgDevice
|
||||
/// </summary>
|
||||
public interface IMsgParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Will parse data looking for a complete message
|
||||
/// </summary>
|
||||
/// <param name="pData">The data to parse</param>
|
||||
/// <param name="numBytesInPdata">The number of bytes in pData</param>
|
||||
/// <param name="bytesToRemove">The data to remove once the parse job is complete</param>
|
||||
/// <param name="messageId">The ID of the message that was parsed</param>
|
||||
/// <param name="errorCode">optional error codes for a child parser to user</param>
|
||||
/// <returns>true if a complete message was found, false otherwise</returns>
|
||||
bool Run(IntPtr pData, uint numBytesInPdata, ref uint bytesToRemove, ref uint messageId, ref uint errorCode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// 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;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface to a serial port device
|
||||
/// </summary>
|
||||
public interface ISerialPort : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Close the communication interface
|
||||
/// </summary>
|
||||
void Close();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void Open();
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dataRead"></param>
|
||||
/// <returns></returns>
|
||||
UInt32 Read(ref byte[] dataRead);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dataToWrite"></param>
|
||||
void Write(byte[] dataToWrite);
|
||||
|
||||
void Write(String dataToWrite);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// **********************************************************************************************************
|
||||
// IWorkerInterface.cs
|
||||
// 2/17/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface that defines required functions for a worker.
|
||||
/// Typically a worker is invoked as a thread.
|
||||
/// </summary>
|
||||
public interface IWorkerInterface : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The function that is passed into the thread.
|
||||
/// </summary>
|
||||
void DoWork();
|
||||
|
||||
/// <summary>
|
||||
/// Commands the worker to quit.
|
||||
/// </summary>
|
||||
void QuitWork();
|
||||
}
|
||||
}
|
||||
215
Source/TSRealLib/Common/Raytheon.Common/Interfaces/MsgDevice.cs
Normal file
215
Source/TSRealLib/Common/Raytheon.Common/Interfaces/MsgDevice.cs
Normal file
@@ -0,0 +1,215 @@
|
||||
// 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;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for handling incoming messages
|
||||
/// </summary>
|
||||
public abstract class MsgDevice : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// A callback def for a completed message
|
||||
/// </summary>
|
||||
/// <param name="msgId"></param>
|
||||
/// <param name="pData"></param>
|
||||
/// <param name="numBytes"></param>
|
||||
/// <param name="errorCode"></param>
|
||||
unsafe public delegate void CompleteMessageCallback(uint msgId, IntPtr pData, uint numBytes, uint errorCode);
|
||||
|
||||
private DataBuffer _dataBuffer;
|
||||
private AutoResetEvent _dataInBufferEvent;
|
||||
private IWorkerInterface _msgProcessorWorker;
|
||||
private bool _isProcessorThreadRunning;
|
||||
private Thread _msgProcessorThread;
|
||||
|
||||
/// <summary>
|
||||
/// The constructor
|
||||
/// </summary>
|
||||
/// <param name="msgParser"></param>
|
||||
/// <param name="bufferSize"></param>
|
||||
public MsgDevice(IMsgParser msgParser, uint bufferSize)
|
||||
{
|
||||
try
|
||||
{
|
||||
_isProcessorThreadRunning = false;
|
||||
_dataBuffer = new DataBuffer(bufferSize);
|
||||
_dataInBufferEvent = new AutoResetEvent(false);
|
||||
_msgProcessorWorker = new MsgProcessorWorker(msgParser, ref _dataBuffer, ref _dataInBufferEvent);
|
||||
_msgProcessorThread = new Thread(_msgProcessorWorker.DoWork);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The finalizer
|
||||
/// </summary>
|
||||
~MsgDevice()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The public dispose function. Necessary for commanding threads to quit
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add data to the buffer
|
||||
/// </summary>
|
||||
/// <param name="data">The data to add</param>
|
||||
/// <param name="numBytes">the number of bytes to add</param>
|
||||
protected void AddToBuffer(byte[] data, uint numBytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
_dataBuffer.Add(data, numBytes);
|
||||
|
||||
_dataInBufferEvent.Set();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear all data from the buffer
|
||||
/// </summary>
|
||||
protected void ClearBuffer()
|
||||
{
|
||||
try
|
||||
{
|
||||
_dataBuffer.RemoveAll();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The local dispose function. Necessary for commanding threads to quit
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
_msgProcessorWorker.QuitWork();
|
||||
|
||||
Thread.Sleep(500);
|
||||
|
||||
_msgProcessorThread.Abort();
|
||||
|
||||
if (_msgProcessorThread.IsAlive)
|
||||
{
|
||||
_msgProcessorThread.Join();
|
||||
}
|
||||
|
||||
_dataInBufferEvent.Dispose();
|
||||
|
||||
_msgProcessorWorker.Dispose();
|
||||
|
||||
_dataBuffer.Dispose();
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run the message processor thread
|
||||
/// </summary>
|
||||
protected void RunThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
_msgProcessorThread.Start();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the callback that will be invoked when a complete message is parsed out
|
||||
/// </summary>
|
||||
/// <param name="callback">The callback function</param>
|
||||
protected void SetCompleteMessageCallback(CompleteMessageCallback callback)
|
||||
{
|
||||
try
|
||||
{
|
||||
((MsgProcessorWorker)_msgProcessorWorker).SetCallback(callback);
|
||||
|
||||
// now that the callback is set, we can run the thread
|
||||
if (_isProcessorThreadRunning == false)
|
||||
{
|
||||
_msgProcessorThread.Start();
|
||||
_isProcessorThreadRunning = true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop the message processor thread
|
||||
/// </summary>
|
||||
protected void QuitThread()
|
||||
{
|
||||
try
|
||||
{
|
||||
_msgProcessorWorker.QuitWork();
|
||||
|
||||
if (_msgProcessorThread.IsAlive)
|
||||
{
|
||||
_msgProcessorThread.Join();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// abstract function for the children to implement
|
||||
/// </summary>
|
||||
/// <param name="data">The data to add</param>
|
||||
/// <param name="numBytes">The number of bytes to add</param>
|
||||
public abstract void AddData(byte[] data, uint numBytes);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// **********************************************************************************************************
|
||||
// ActiveHealthMonitorData.cs
|
||||
// 2/17/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
public enum MonitorStatus
|
||||
{
|
||||
NOMINAL,
|
||||
WARNING,
|
||||
ABORT
|
||||
}
|
||||
|
||||
public struct ActiveHealthMonitorData
|
||||
{
|
||||
public string itemName;
|
||||
public double dataValue;
|
||||
public MonitorStatus status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// **********************************************************************************************************
|
||||
// PowerMonitorCallbackData.cs
|
||||
// 2/17/2023
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
public struct PowerMonitorCallbackData
|
||||
{
|
||||
public string powerModule;
|
||||
|
||||
public double overVoltageProtectionValue;
|
||||
|
||||
public double overCurrentProtectionValue;
|
||||
|
||||
public double voltage;
|
||||
|
||||
public double voltageSetpoint;
|
||||
|
||||
public double current;
|
||||
|
||||
public bool outputStatus;
|
||||
|
||||
public int ovpocpStatus;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
<OutputType>Library</OutputType>
|
||||
<AssemblyName>Raytheon.Common</AssemblyName>
|
||||
<Product>Raytheon Common Library</Product>
|
||||
<Description>Raytheon Common Library</Description>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<NoWarn>CS0649</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<COMReference Include="Microsoft.Office.Core">
|
||||
<Guid>{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}</Guid>
|
||||
<VersionMajor>2</VersionMajor>
|
||||
<VersionMinor>8</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="Microsoft.Office.Interop.Excel">
|
||||
<Guid>{00020813-0000-0000-C000-000000000046}</Guid>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>9</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="VBIDE">
|
||||
<Guid>{0002E157-0000-0000-C000-000000000046}</Guid>
|
||||
<VersionMajor>5</VersionMajor>
|
||||
<VersionMinor>3</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,247 @@
|
||||
// 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;
|
||||
|
||||
namespace Raytheon.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Processes messages from a buffer
|
||||
/// </summary>
|
||||
public class MsgProcessorWorker : IWorkerInterface
|
||||
{
|
||||
#region PrivateClassMembers
|
||||
private IMsgParser _msgParser;
|
||||
private DataBuffer _dataBuffer;
|
||||
private AutoResetEvent _dataInBufferEvent;
|
||||
private AutoResetEvent _quitEvent;
|
||||
private bool _threadQuitControl;
|
||||
private MsgDevice.CompleteMessageCallback _completeMsgCallback;
|
||||
#endregion
|
||||
|
||||
#region PrivateFunctions
|
||||
/// <summary>
|
||||
/// Dispose of this objects resources
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_quitEvent.Dispose();
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
#region PublicFuctions
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="msgParser">Parses out the messages</param>
|
||||
/// <param name="dataBuffer">The buffer to parse from</param>
|
||||
/// <param name="dataInBufferEvent">A singal to let us know that data has arrived</param>
|
||||
public MsgProcessorWorker(IMsgParser msgParser, ref DataBuffer dataBuffer, ref AutoResetEvent dataInBufferEvent)
|
||||
{
|
||||
_msgParser = msgParser;
|
||||
_dataBuffer = dataBuffer;
|
||||
_dataInBufferEvent = dataInBufferEvent;
|
||||
_threadQuitControl = false;
|
||||
_quitEvent = new AutoResetEvent(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The finalizer for cleaing up resources
|
||||
/// </summary>
|
||||
~MsgProcessorWorker()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose of this objects resources
|
||||
/// </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>
|
||||
/// Parses out messages from the data buffer and then issues callback to the handler with the completed message
|
||||
/// </summary>
|
||||
unsafe public void DoWork()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_completeMsgCallback == null)
|
||||
{
|
||||
throw new Exception("MsgProcessorWorker::DoWork() - Callback not set");
|
||||
}
|
||||
|
||||
WaitHandle[] waithandles = new WaitHandle[2];
|
||||
waithandles[0] = _dataInBufferEvent;
|
||||
waithandles[1] = _quitEvent;
|
||||
|
||||
bool isTheWorkDone = false;
|
||||
|
||||
uint numBytesProcessedInLastIteration = 0;
|
||||
|
||||
while (isTheWorkDone == false)
|
||||
{
|
||||
int eventIndex = 0;
|
||||
|
||||
eventIndex = WaitHandle.WaitAny(waithandles, 100);
|
||||
_dataInBufferEvent.Reset();
|
||||
|
||||
uint dataBufferBytesUsed = _dataBuffer.BytesUsed;
|
||||
if (eventIndex == 0 || dataBufferBytesUsed > 0) // _dataInBufferEvent
|
||||
{
|
||||
uint numBytesToProcess = 0;
|
||||
|
||||
IntPtr pStartOfData = _dataBuffer.CheckOutStartOfData(ref numBytesToProcess);
|
||||
|
||||
bool isThisRoundOfProcessingDone = false;
|
||||
|
||||
uint ourCopyOfDataIndex = 0;
|
||||
|
||||
numBytesProcessedInLastIteration = 0;
|
||||
|
||||
while (isThisRoundOfProcessingDone == false)
|
||||
{
|
||||
uint numBytesLeftInTempBuffer = numBytesToProcess - ourCopyOfDataIndex;
|
||||
|
||||
if (numBytesLeftInTempBuffer == 0)
|
||||
{
|
||||
isThisRoundOfProcessingDone = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint numBytesToRemove = 0;
|
||||
uint msgId = 0;
|
||||
uint errorCode = 0;
|
||||
|
||||
IntPtr payLoadPtr = IntPtr.Add(pStartOfData, (int)ourCopyOfDataIndex);
|
||||
|
||||
if (_msgParser.Run(payLoadPtr, numBytesLeftInTempBuffer, ref numBytesToRemove, ref msgId, ref errorCode) == true)
|
||||
{
|
||||
string msg = "MsgProcessorWorker::DoWork() - removing " + numBytesToRemove.ToString() + " bytes, for msg id: " + msgId.ToString("X8");
|
||||
|
||||
ErrorLogger.Instance().Write(msg, ErrorLogger.LogLevel.INFO);
|
||||
|
||||
// we have a complete message, invoke the call back
|
||||
_completeMsgCallback(msgId, payLoadPtr, numBytesToRemove, errorCode);
|
||||
}
|
||||
|
||||
if (numBytesToRemove == 0)
|
||||
{
|
||||
isThisRoundOfProcessingDone = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ourCopyOfDataIndex += numBytesToRemove;
|
||||
_dataBuffer.Remove(numBytesToRemove);
|
||||
numBytesProcessedInLastIteration += ourCopyOfDataIndex;
|
||||
}
|
||||
|
||||
// were we signaled to quit?
|
||||
if (_threadQuitControl == true)
|
||||
{
|
||||
ErrorLogger.Instance().Write("MsgProcessorWorker::DoWork() - in the midst of procesing data, the quit event was detected, exiting", ErrorLogger.LogLevel.INFO);
|
||||
isTheWorkDone = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Check start of data back in since we are done with it
|
||||
_dataBuffer.CheckInStartOfData();
|
||||
}
|
||||
else if (eventIndex == 1) // _quitEvent
|
||||
{
|
||||
ErrorLogger.Instance().Write("MsgProcessorWorker::DoWork() - quit event was detected, exiting", ErrorLogger.LogLevel.INFO);
|
||||
isTheWorkDone = true;
|
||||
}
|
||||
else if (eventIndex == WaitHandle.WaitTimeout)
|
||||
{
|
||||
// expected, continue
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorLogger.Instance().Write("MsgProcessorWorker::DoWork() - Unhandled return from WaitHandle.WaitAny(): " + eventIndex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
ErrorLogger.Instance().Write("MsgProcessorWorker::DoWork() - exiting", ErrorLogger.LogLevel.INFO);
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the call back function
|
||||
/// </summary>
|
||||
/// <param name="callback">The call back function</param>
|
||||
public void SetCallback(MsgDevice.CompleteMessageCallback callback)
|
||||
{
|
||||
_completeMsgCallback = callback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Command the worker to stop
|
||||
/// </summary>
|
||||
public void QuitWork()
|
||||
{
|
||||
_threadQuitControl = true;
|
||||
_quitEvent.Set();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
382
Source/TSRealLib/Common/Raytheon.Common/Units/Acceleration.cs
Normal file
382
Source/TSRealLib/Common/Raytheon.Common/Units/Acceleration.cs
Normal file
@@ -0,0 +1,382 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents an acceleration.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g.
|
||||
/// FromMetersPerSecSqrd).
|
||||
///
|
||||
/// Properties (e.g. FeetPerSecSqrd) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
///
|
||||
/// Methods (operator overloads) are provided to perform calculations with related types (e.g.
|
||||
/// Velocity, Length).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Acceleration
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
FeetPerSecSqrd,
|
||||
MetersPerSecSqrd,
|
||||
Gs
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.FeetPerSecSqrd, new List<string>(){ "ft/sec^2" } },
|
||||
{Unit.MetersPerSecSqrd, new List<string>(){ "m/sec^2" } },
|
||||
{Unit.Gs, new List<string>(){ "g" } }
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.MetersPerSecSqrd;
|
||||
private const double FeetPerMeter = 3.280839895013123;
|
||||
private const double Gravity = 9.80665; // m/sec^2
|
||||
|
||||
[DataMember(Name = "Acceleration", IsRequired = true)]
|
||||
private double _acceleration; // meters/seconds^2
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<Acceleration>> _unitInfo = new Dictionary<Unit, UnitInfo<Acceleration>>()
|
||||
{
|
||||
{ Unit.FeetPerSecSqrd, new UnitInfo<Acceleration>(UnitAbbreviations[Unit.FeetPerSecSqrd], FromFeetPerSecSqrd, typeof(Acceleration).GetProperty("FeetPerSecSqrd").GetGetMethod()) },
|
||||
{ Unit.MetersPerSecSqrd, new UnitInfo<Acceleration>(UnitAbbreviations[Unit.MetersPerSecSqrd], FromMetersPerSecSqrd, typeof(Acceleration).GetProperty("MetersPerSecSqrd").GetGetMethod()) },
|
||||
{ Unit.Gs, new UnitInfo<Acceleration>(UnitAbbreviations[Unit.Gs], FromGs, typeof(Acceleration).GetProperty("Gs").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="Acceleration"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private Acceleration()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="acceleration">The acceleration - m/sec^2.</param>
|
||||
private Acceleration(double acceleration)
|
||||
{
|
||||
_acceleration = acceleration;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
/// <summary>
|
||||
/// Returns feet/sec^2 as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// feet/sec^2
|
||||
/// </value>
|
||||
public double FeetPerSecSqrd
|
||||
{
|
||||
get { return _acceleration * FeetPerMeter; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns Gs as type double
|
||||
/// </summary>
|
||||
public double Gs
|
||||
{
|
||||
get { return _acceleration / Gravity; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns m/sec^2 as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// m/sec^2
|
||||
/// </value>
|
||||
public double MetersPerSecSqrd
|
||||
{
|
||||
get { return _acceleration; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns Acceleration object interpreting passed value as ft/sec^2
|
||||
/// </summary>
|
||||
/// <param name="feetPerSecSqrd">ft/sec^2</param>
|
||||
/// <returns></returns>
|
||||
public static Acceleration FromFeetPerSecSqrd(double feetPerSecSqrd)
|
||||
{
|
||||
return new Acceleration(feetPerSecSqrd / FeetPerMeter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Acceleration object interpreting passed value as m/sec^2
|
||||
/// </summary>
|
||||
/// <param name="metersPerSecSqrd">m/sec^2</param>
|
||||
/// <returns></returns>
|
||||
public static Acceleration FromMetersPerSecSqrd(double metersPerSecSqrd)
|
||||
{
|
||||
return new Acceleration(metersPerSecSqrd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Acceleration object interpreting passed value as m/sec^2
|
||||
/// </summary>
|
||||
/// <param name="metersPerSecSqrd">m/sec^2</param>
|
||||
/// <returns></returns>
|
||||
public static Acceleration FromGs(double g)
|
||||
{
|
||||
return FromMetersPerSecSqrd(g * Gravity);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Acceleration Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Acceleration value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Acceleration.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Acceleration c = obj as Acceleration;
|
||||
|
||||
return (c == null) ? false : (this._acceleration == c._acceleration);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _acceleration.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static Acceleration operator +(Acceleration left, Acceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Acceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Acceleration");
|
||||
|
||||
return new Acceleration(left._acceleration + right._acceleration);
|
||||
}
|
||||
|
||||
|
||||
public static Acceleration operator -(Acceleration left, Acceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null Acceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null Acceleration");
|
||||
|
||||
return new Acceleration(left._acceleration - right._acceleration);
|
||||
}
|
||||
|
||||
|
||||
public static Acceleration operator *(Acceleration acceleration, double scalar)
|
||||
{
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot multiply a null Acceleration");
|
||||
|
||||
return new Acceleration(acceleration._acceleration * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static Acceleration operator *(double scalar, Acceleration acceleration)
|
||||
{
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot multiply a null Acceleration");
|
||||
|
||||
return new Acceleration(scalar * acceleration._acceleration);
|
||||
}
|
||||
|
||||
|
||||
public static Acceleration operator /(Acceleration acceleration, double scalar)
|
||||
{
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot divide a null Acceleration");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Acceleration by 0");
|
||||
|
||||
return new Acceleration(acceleration._acceleration / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(Acceleration left, Acceleration right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._acceleration == right._acceleration;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Acceleration left, Acceleration right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(Acceleration left, Acceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Acceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Acceleration");
|
||||
|
||||
return left._acceleration < right._acceleration;
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(Acceleration left, Acceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Acceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Acceleration");
|
||||
|
||||
return left._acceleration > right._acceleration;
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(Acceleration left, Acceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Acceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Acceleration");
|
||||
|
||||
return left._acceleration <= right._acceleration;
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(Acceleration left, Acceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Acceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Acceleration");
|
||||
|
||||
return left._acceleration >= right._acceleration;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with other classes
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for Velocity = Acceleration * Time
|
||||
/// </summary>
|
||||
/// <param name="acceleration">The acceleration.</param>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <returns>
|
||||
/// Velocity
|
||||
/// </returns>
|
||||
|
||||
public static Velocity operator *(Acceleration acceleration, PrecisionTimeSpan time)
|
||||
{
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot multiply with null Acceleration");
|
||||
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot multiply with null PrecisionTimeSpan");
|
||||
|
||||
return Velocity.FromMetersPerSec(acceleration.MetersPerSecSqrd * time.Seconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for Velocity = Time * Acceleration
|
||||
/// </summary>
|
||||
/// <param name="acceleration">The acceleration.</param>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <returns>
|
||||
/// Velocity
|
||||
/// </returns>
|
||||
|
||||
public static Velocity operator *(PrecisionTimeSpan time, Acceleration acceleration)
|
||||
{
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot multiply with null Acceleration");
|
||||
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot multiply with null PrecisionTimeSpan");
|
||||
|
||||
return Velocity.FromMetersPerSec(acceleration.MetersPerSecSqrd * time.Seconds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
392
Source/TSRealLib/Common/Raytheon.Common/Units/Angle.cs
Normal file
392
Source/TSRealLib/Common/Raytheon.Common/Units/Angle.cs
Normal file
@@ -0,0 +1,392 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents an angle.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g.
|
||||
/// FromDegrees).
|
||||
///
|
||||
/// Properties (e.g. Radians) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Angle
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
Degrees,
|
||||
Radians,
|
||||
Milliradians
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.Degrees, new List<string>(){ "deg" } },
|
||||
{Unit.Radians, new List<string>(){ "rad" } },
|
||||
{Unit.Milliradians, new List<string>(){ "mrad" } }
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.Degrees;
|
||||
private const double DegreesPerRadian = 180 / Math.PI;
|
||||
private const int MilliradiansPerRadian = 1000;
|
||||
|
||||
[DataMember(Name = "Angle", IsRequired = true)]
|
||||
private double _angle; // radians
|
||||
|
||||
private static IDictionary<Unit, UnitInfo<Angle>> _unitInfo = new Dictionary<Unit, UnitInfo<Angle>>()
|
||||
{
|
||||
{ Unit.Degrees, new UnitInfo<Angle>(UnitAbbreviations[Unit.Degrees], FromDegrees, typeof(Angle).GetProperty("Degrees").GetGetMethod()) },
|
||||
{ Unit.Radians, new UnitInfo<Angle>(UnitAbbreviations[Unit.Radians], FromRadians, typeof(Angle).GetProperty("Radians").GetGetMethod()) },
|
||||
{ Unit.Milliradians, new UnitInfo<Angle>(UnitAbbreviations[Unit.Milliradians], FromMilliradians, typeof(Angle).GetProperty("Milliradians").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="Angle"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private Angle()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="angle">The angle - radians.</param>
|
||||
private Angle(double angle)
|
||||
{
|
||||
_angle = angle;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
/// <summary>
|
||||
/// Returns degrees as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// degrees
|
||||
/// </value>
|
||||
public double Degrees
|
||||
{
|
||||
get
|
||||
{
|
||||
return _angle * DegreesPerRadian;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns milliradians as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// milliradians
|
||||
/// </value>
|
||||
public double Milliradians
|
||||
{
|
||||
get
|
||||
{
|
||||
return _angle * MilliradiansPerRadian;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns radians as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// radians
|
||||
/// </value>
|
||||
public double Radians
|
||||
{
|
||||
get
|
||||
{
|
||||
return _angle;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns Angle object interpreting passed value as degrees
|
||||
/// </summary>
|
||||
/// <param name="degrees">degrees</param>
|
||||
/// <returns></returns>
|
||||
public static Angle FromDegrees(double degrees)
|
||||
{
|
||||
return new Angle(degrees / DegreesPerRadian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Angle object interpreting passed value as milliradians
|
||||
/// </summary>
|
||||
/// <param name="milliradians">milliradians</param>
|
||||
/// <returns></returns>
|
||||
public static Angle FromMilliradians(double milliradians)
|
||||
{
|
||||
return new Angle(milliradians / MilliradiansPerRadian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Angle object interpreting passed value as radians
|
||||
/// </summary>
|
||||
/// <param name="radians">radians</param>
|
||||
/// <returns></returns>
|
||||
public static Angle FromRadians(double radians)
|
||||
{
|
||||
return new Angle(radians);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Angle a = obj as Angle;
|
||||
|
||||
return (a == null) ? false : (this._angle == a._angle);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _angle.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static Angle operator +(Angle left, Angle right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Angle");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Angle");
|
||||
|
||||
return new Angle(left._angle + right._angle);
|
||||
}
|
||||
|
||||
|
||||
public static Angle operator -(Angle left, Angle right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null Angle");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null Angle");
|
||||
|
||||
return new Angle(left._angle - right._angle);
|
||||
}
|
||||
|
||||
|
||||
public static Angle operator *(Angle angle, double scalar)
|
||||
{
|
||||
if (null == angle)
|
||||
throw new ArgumentNullException("angle", "Cannot multiply a null Angle");
|
||||
|
||||
return new Angle(angle._angle * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static Angle operator *(double scalar, Angle angle)
|
||||
{
|
||||
if (null == angle)
|
||||
throw new ArgumentNullException("angle", "Cannot multiply a null Angle");
|
||||
|
||||
return new Angle(scalar * angle._angle);
|
||||
}
|
||||
|
||||
|
||||
public static Angle operator /(Angle angle, double scalar)
|
||||
{
|
||||
if (null == angle)
|
||||
throw new ArgumentNullException("angle", "Cannot divide a null Angle");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Angle by 0");
|
||||
|
||||
return new Angle(angle._angle / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(Angle left, Angle right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._angle == right._angle;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Angle left, Angle right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
public static bool operator <(Angle left, Angle right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Angle");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Angle");
|
||||
|
||||
return (left._angle < right._angle);
|
||||
}
|
||||
|
||||
public static bool operator >(Angle left, Angle right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Angle");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Angle");
|
||||
|
||||
return (left._angle > right._angle);
|
||||
}
|
||||
|
||||
public static bool operator <=(Angle left, Angle right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Angle");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Angle");
|
||||
|
||||
return (left._angle <= right._angle);
|
||||
}
|
||||
|
||||
public static bool operator >=(Angle left, Angle right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Angle");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Angle");
|
||||
|
||||
return (left._angle >= right._angle);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with other classes
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator / for AngularVelocity = Angle / PrecisionTimeSpan
|
||||
/// </summary>
|
||||
/// <param name="velocity">The angle.</param>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <returns>
|
||||
/// AngularVelocity
|
||||
/// </returns>
|
||||
|
||||
public static AngularVelocity operator /(Angle angle, PrecisionTimeSpan time)
|
||||
{
|
||||
if (null == angle)
|
||||
throw new ArgumentNullException("angle", "Cannot divide with null Angle");
|
||||
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot divide with null PrecisionTimeSpan");
|
||||
|
||||
if (0.0 == time.Milliseconds)
|
||||
throw new DivideByZeroException("Cannot divide angle by 0 time");
|
||||
|
||||
return AngularVelocity.FromRadiansPerSec(angle.Radians / time.Seconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator / for PrecisionTimeSpan = Angle / AngularVelocity
|
||||
/// </summary>
|
||||
/// <param name="velocity">The angle.</param>
|
||||
/// <param name="time">The velocity.</param>
|
||||
/// <returns>
|
||||
/// PrecisionTimeSpan
|
||||
/// </returns>
|
||||
|
||||
public static PrecisionTimeSpan operator /(Angle angle, AngularVelocity velocity)
|
||||
{
|
||||
if (null == angle)
|
||||
throw new ArgumentNullException("angle", "Cannot divide with null Angle");
|
||||
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot divide with null AngularVelocity");
|
||||
|
||||
if (0.0 == velocity.RadiansPerSec)
|
||||
throw new DivideByZeroException("Cannot divide angle by 0 angular velocity");
|
||||
|
||||
return PrecisionTimeSpan.FromSeconds(angle.Radians / velocity.RadiansPerSec);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Angle Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Angle value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Angle.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a velocity.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. FromRadiansPerSecSqrd).
|
||||
///
|
||||
/// Properties (e.g. RadiansPerSecSqrd) are provided to convert the value to other units and
|
||||
/// return as type double.
|
||||
///
|
||||
/// Methods (operator overloads) are provided to perform calculations with related types (e.g.
|
||||
/// Angle, AngularVelocity).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class AngularAcceleration
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
DegreesPerSecSqrd,
|
||||
RadiansPerSecSqrd,
|
||||
MilliradiansPerSecSqrd
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.DegreesPerSecSqrd, new List<string>(){ "deg/sec^2" } },
|
||||
{Unit.MilliradiansPerSecSqrd, new List<string>(){ "mrad/sec^2" } },
|
||||
{Unit.RadiansPerSecSqrd, new List<string>(){ "rad/sec^2" } }
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.RadiansPerSecSqrd;
|
||||
private const double DegreesPerRadian = 180 / Math.PI;
|
||||
|
||||
[DataMember(Name = "AngularAcceleration", IsRequired = true)]
|
||||
private double _acceleration; // radians/seconds^2
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<AngularAcceleration>> _unitInfo = new Dictionary<Unit, UnitInfo<AngularAcceleration>>()
|
||||
{
|
||||
{ Unit.DegreesPerSecSqrd, new UnitInfo<AngularAcceleration>(UnitAbbreviations[Unit.DegreesPerSecSqrd], FromDegreesPerSecSqrd, typeof(AngularAcceleration).GetProperty("DegreesPerSecSqrd").GetGetMethod()) },
|
||||
{ Unit.MilliradiansPerSecSqrd, new UnitInfo<AngularAcceleration>(UnitAbbreviations[Unit.MilliradiansPerSecSqrd], FromMilliradiansPerSecSqrd, typeof(AngularAcceleration).GetProperty("MilliradiansPerSecSqrd").GetGetMethod()) },
|
||||
{ Unit.RadiansPerSecSqrd, new UnitInfo<AngularAcceleration>(UnitAbbreviations[Unit.RadiansPerSecSqrd], FromRadiansPerSecSqrd, typeof(AngularAcceleration).GetProperty("RadiansPerSecSqrd").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="AngularAcceleration"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private AngularAcceleration()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="acceleration">The acceleration - radians/sec^2.</param>
|
||||
private AngularAcceleration(double acceleration)
|
||||
{
|
||||
_acceleration = acceleration;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
/// <summary>
|
||||
/// Returns degrees/sec^2 as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// degrees/sec^2
|
||||
/// </value>
|
||||
public double DegreesPerSecSqrd
|
||||
{
|
||||
get { return _acceleration * DegreesPerRadian; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns milliradians/sec^2 as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// milliradians/sec^2
|
||||
/// </value>
|
||||
public double MilliradiansPerSecSqrd
|
||||
{
|
||||
get { return _acceleration * 1000; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns radians/sec^2 as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// radians/sec^2
|
||||
/// </value>
|
||||
public double RadiansPerSecSqrd
|
||||
{
|
||||
get { return _acceleration; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns AngularAcceleration object interpreting passed value as degrees/sec
|
||||
/// </summary>
|
||||
/// <param name="degreesPerSecSqrd">degrees/sec</param>
|
||||
/// <returns></returns>
|
||||
public static AngularAcceleration FromDegreesPerSecSqrd(double degreesPerSecSqrd)
|
||||
{
|
||||
return new AngularAcceleration(degreesPerSecSqrd / DegreesPerRadian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns AngularAcceleration object interpreting passed value as radians/sec^2
|
||||
/// </summary>
|
||||
/// <param name="milliradiansPerSecSqrd">radians/sec^2</param>
|
||||
/// <returns></returns>
|
||||
public static AngularAcceleration FromMilliradiansPerSecSqrd(double milliradiansPerSecSqrd)
|
||||
{
|
||||
return new AngularAcceleration(milliradiansPerSecSqrd / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns AngularAcceleration object interpreting passed value as radians/sec^2
|
||||
/// </summary>
|
||||
/// <param name="radiansPerSecSqrd">radians/sec^2</param>
|
||||
/// <returns></returns>
|
||||
public static AngularAcceleration FromRadiansPerSecSqrd(double radiansPerSecSqrd)
|
||||
{
|
||||
return new AngularAcceleration(radiansPerSecSqrd);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
AngularAcceleration a = obj as AngularAcceleration;
|
||||
|
||||
return (a == null) ? false : (this._acceleration == a._acceleration);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _acceleration.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static AngularAcceleration operator +(AngularAcceleration left, AngularAcceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null AngularAcceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null AngularAcceleration");
|
||||
|
||||
return new AngularAcceleration(left._acceleration + right._acceleration);
|
||||
}
|
||||
|
||||
|
||||
public static AngularAcceleration operator -(AngularAcceleration left, AngularAcceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null AngularAcceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract null AngularAcceleration");
|
||||
|
||||
return new AngularAcceleration(left._acceleration - right._acceleration);
|
||||
}
|
||||
|
||||
|
||||
public static AngularAcceleration operator *(AngularAcceleration acceleration, double scalar)
|
||||
{
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot multiply a null AngularAcceleration");
|
||||
|
||||
return new AngularAcceleration(acceleration._acceleration * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static AngularAcceleration operator *(double scalar, AngularAcceleration acceleration)
|
||||
{
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot multiply a null AngularAcceleration");
|
||||
|
||||
return new AngularAcceleration(scalar * acceleration._acceleration);
|
||||
}
|
||||
|
||||
|
||||
public static AngularAcceleration operator /(AngularAcceleration acceleration, double scalar)
|
||||
{
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot divide a null AngularAcceleration");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Angular Acceleration by 0");
|
||||
|
||||
return new AngularAcceleration(acceleration._acceleration / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(AngularAcceleration left, AngularAcceleration right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._acceleration == right._acceleration;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(AngularAcceleration left, AngularAcceleration right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(AngularAcceleration left, AngularAcceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null AngularAcceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null AngularAcceleration");
|
||||
|
||||
return left._acceleration < right._acceleration;
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(AngularAcceleration left, AngularAcceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null AngularAcceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null AngularAcceleration");
|
||||
|
||||
return left._acceleration > right._acceleration;
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(AngularAcceleration left, AngularAcceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null AngularAcceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null AngularAcceleration");
|
||||
|
||||
return left._acceleration <= right._acceleration;
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(AngularAcceleration left, AngularAcceleration right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null AngularAcceleration");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null AngularAcceleration");
|
||||
|
||||
return left._acceleration >= right._acceleration;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with other classes
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for AngularVelocity = AngularAcceleration * PrecisionTimeSpan
|
||||
/// </summary>
|
||||
/// <param name="acceleration">The velocity.</param>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <returns>
|
||||
/// Angle
|
||||
/// </returns>
|
||||
|
||||
public static AngularVelocity operator *(AngularAcceleration acceleration, PrecisionTimeSpan time)
|
||||
{
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot multiply with null AngularAcceleration");
|
||||
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot multiply with null PrecisionTimeSpan");
|
||||
|
||||
return AngularVelocity.FromRadiansPerSec(acceleration.RadiansPerSecSqrd * time.Seconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for AngularVelocity = PrecisionTimeSpan * AngularAcceleration
|
||||
/// </summary>
|
||||
/// <param name="acceleration">The acceleration.</param>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <returns>
|
||||
/// AngularVelocity
|
||||
/// </returns>
|
||||
|
||||
public static AngularVelocity operator *(PrecisionTimeSpan time, AngularAcceleration acceleration)
|
||||
{
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot multiply with null AngularAcceleration");
|
||||
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot multiply with null PrecisionTimeSpan");
|
||||
|
||||
return AngularVelocity.FromRadiansPerSec(time.Seconds * acceleration.RadiansPerSecSqrd);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static AngularAcceleration Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out AngularAcceleration value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = AngularAcceleration.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 deg/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 deg/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
430
Source/TSRealLib/Common/Raytheon.Common/Units/AngularVelocity.cs
Normal file
430
Source/TSRealLib/Common/Raytheon.Common/Units/AngularVelocity.cs
Normal file
@@ -0,0 +1,430 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a velocity.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. FromRadiansPerSec).
|
||||
///
|
||||
/// Properties (e.g. RadiansPerSec) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
///
|
||||
/// Methods (operator overloads) are provided to perform calculations with related types (e.g.
|
||||
/// Angle, AngularAcceleration).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class AngularVelocity
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
DegreesPerSec,
|
||||
RadiansPerSec,
|
||||
MilliradiansPerSec
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.DegreesPerSec, new List<string>(){ "deg/sec" } },
|
||||
{Unit.RadiansPerSec, new List<string>(){ "rad/sec" } },
|
||||
{Unit.MilliradiansPerSec, new List<string>(){ "mrad/sec" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.RadiansPerSec;
|
||||
private const double DegreesPerRadian = 180 / Math.PI;
|
||||
|
||||
[DataMember(Name = "AngularVelocity", IsRequired = true)]
|
||||
private double _velocity; // radians/second
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<AngularVelocity>> _unitInfo = new Dictionary<Unit, UnitInfo<AngularVelocity>>()
|
||||
{
|
||||
{ Unit.DegreesPerSec, new UnitInfo<AngularVelocity>(UnitAbbreviations[Unit.DegreesPerSec], FromDegreesPerSec, typeof(AngularVelocity).GetProperty("DegreesPerSec").GetGetMethod()) },
|
||||
{ Unit.MilliradiansPerSec, new UnitInfo<AngularVelocity>(UnitAbbreviations[Unit.MilliradiansPerSec], FromMilliradiansPerSec, typeof(AngularVelocity).GetProperty("MilliradiansPerSec").GetGetMethod()) },
|
||||
{ Unit.RadiansPerSec, new UnitInfo<AngularVelocity>(UnitAbbreviations[Unit.RadiansPerSec], FromRadiansPerSec, typeof(AngularVelocity).GetProperty("RadiansPerSec").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="AngularVelocity"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private AngularVelocity()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="velocity">The velocity - radians/sec.</param>
|
||||
private AngularVelocity(double velocity)
|
||||
{
|
||||
_velocity = velocity;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
/// <summary>
|
||||
/// Returns degrees/sec as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// degrees/sec
|
||||
/// </value>
|
||||
public double DegreesPerSec
|
||||
{
|
||||
get { return _velocity * DegreesPerRadian; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns degrees/sec as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// degrees/sec
|
||||
/// </value>
|
||||
public double MilliradiansPerSec
|
||||
{
|
||||
get { return _velocity * 1000; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns radians/sec as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// radians/sec
|
||||
/// </value>
|
||||
public double RadiansPerSec
|
||||
{
|
||||
get { return _velocity; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns AngularVelocity object interpreting passed value as degrees/sec
|
||||
/// </summary>
|
||||
/// <param name="degreesPerSec">degrees/sec</param>
|
||||
/// <returns></returns>
|
||||
public static AngularVelocity FromDegreesPerSec(double degreesPerSec)
|
||||
{
|
||||
return new AngularVelocity(degreesPerSec / DegreesPerRadian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns AngularVelocity object interpreting passed value as milliradians/sec
|
||||
/// </summary>
|
||||
/// <param name="milliradiansPerSec">milliradians/sec</param>
|
||||
/// <returns></returns>
|
||||
public static AngularVelocity FromMilliradiansPerSec(double milliradiansPerSec)
|
||||
{
|
||||
return new AngularVelocity(milliradiansPerSec / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns AngularVelocity object interpreting passed value as radians/sec
|
||||
/// </summary>
|
||||
/// <param name="radiansPerSec">radians/sec</param>
|
||||
/// <returns></returns>
|
||||
public static AngularVelocity FromRadiansPerSec(double radiansPerSec)
|
||||
{
|
||||
return new AngularVelocity(radiansPerSec);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
AngularVelocity v = obj as AngularVelocity;
|
||||
|
||||
return (v == null) ? false : (this._velocity == v._velocity);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _velocity.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static AngularVelocity operator +(AngularVelocity left, AngularVelocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null AngularVelocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null AngularVelocity");
|
||||
|
||||
return new AngularVelocity(left._velocity + right._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static AngularVelocity operator -(AngularVelocity left, AngularVelocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null AngularVelocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null AngularVelocity");
|
||||
|
||||
return new AngularVelocity(left._velocity - right._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static AngularVelocity operator *(AngularVelocity velocity, double scalar)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot multiply a null AngularVelocity");
|
||||
|
||||
return new AngularVelocity(velocity._velocity * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static AngularVelocity operator *(double scalar, AngularVelocity velocity)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot multiply a null AngularVelocity");
|
||||
|
||||
return new AngularVelocity(scalar * velocity._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static AngularVelocity operator /(AngularVelocity velocity, double scalar)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot divide a null AngularVelocity");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Angular Velocity by 0");
|
||||
|
||||
return new AngularVelocity(velocity._velocity / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(AngularVelocity left, AngularVelocity right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._velocity == right._velocity;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(AngularVelocity left, AngularVelocity right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(AngularVelocity left, AngularVelocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null AngularVelocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null AngularVelocity");
|
||||
|
||||
return (left._velocity < right._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(AngularVelocity left, AngularVelocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null AngularVelocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null AngularVelocity");
|
||||
|
||||
return (left._velocity > right._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(AngularVelocity left, AngularVelocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null AngularVelocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null AngularVelocity");
|
||||
|
||||
return (left._velocity <= right._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(AngularVelocity left, AngularVelocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null AngularVelocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null AngularVelocity");
|
||||
|
||||
return (left._velocity >= right._velocity);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with other classes
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for Angle = AngularVelocity * PrecisionTimeSpan
|
||||
/// </summary>
|
||||
/// <param name="velocity">The velocity.</param>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <returns>
|
||||
/// Angle
|
||||
/// </returns>
|
||||
|
||||
public static Angle operator *(AngularVelocity velocity, PrecisionTimeSpan time)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot multiply with null AngularVelocity");
|
||||
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot multiply with null PrecisionTimeSpan");
|
||||
|
||||
return Angle.FromRadians(velocity.RadiansPerSec * time.Seconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for Angle = PrecisionTimeSpan * AngularVelocity
|
||||
/// </summary>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <param name="velocity">The velocity.</param>
|
||||
/// <returns>
|
||||
/// Angle
|
||||
/// </returns>
|
||||
|
||||
public static Angle operator *(PrecisionTimeSpan time, AngularVelocity velocity)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot multiply with null AngularVelocity");
|
||||
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot multiply with null PrecisionTimeSpan");
|
||||
|
||||
return Angle.FromRadians(time.Seconds * velocity.RadiansPerSec);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator / for AngularAcceleration = AngularVelocity / PrecisionTimeSpan
|
||||
/// </summary>
|
||||
/// <param name="velocity">The velocity.</param>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <returns>
|
||||
/// AngularAcceleration
|
||||
/// </returns>
|
||||
|
||||
public static AngularAcceleration operator /(AngularVelocity velocity, PrecisionTimeSpan time)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot divide with null AngularVelocity");
|
||||
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot divide with null PrecisionTimeSpan");
|
||||
|
||||
if (0.0 == time.Milliseconds)
|
||||
throw new DivideByZeroException("Cannot divide Angular Velocity by 0 time");
|
||||
|
||||
return AngularAcceleration.FromRadiansPerSecSqrd(velocity.RadiansPerSec / time.Seconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator / for PrecisionTimeSpan = AngularVelocity / AngularAcceleration
|
||||
/// </summary>
|
||||
/// <param name="velocity">The velocity.</param>
|
||||
/// <param name="acceleration">The acceleration.</param>
|
||||
/// <returns>
|
||||
/// Angle
|
||||
/// </returns>
|
||||
|
||||
public static PrecisionTimeSpan operator /(AngularVelocity velocity, AngularAcceleration acceleration)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot divide with null AngularVelocity");
|
||||
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot divide with null AngularAcceleration");
|
||||
|
||||
if (0.0 == acceleration.RadiansPerSecSqrd)
|
||||
throw new DivideByZeroException("Cannot divide Angular Velocity by 0 Angular Acceleration");
|
||||
|
||||
return PrecisionTimeSpan.FromSeconds(velocity.RadiansPerSec / acceleration.RadiansPerSecSqrd);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static AngularVelocity Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out AngularVelocity value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = AngularVelocity.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
83
Source/TSRealLib/Common/Raytheon.Common/Units/Common.cs
Normal file
83
Source/TSRealLib/Common/Raytheon.Common/Units/Common.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains info related to a unit: to parse, print, and convert values
|
||||
/// </summary>
|
||||
internal class UnitInfo<T>
|
||||
{
|
||||
public UnitInfo( List<string> abbreviation,
|
||||
Func<double, T> conversionMethod,
|
||||
MethodInfo propertyGetter )
|
||||
{
|
||||
Abbreviation = abbreviation;
|
||||
ConversionMethod = conversionMethod;
|
||||
PropertyGetter = propertyGetter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// standard text abbreviation for this unit
|
||||
/// </summary>
|
||||
public List<string> Abbreviation { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// method for converting string to this unit
|
||||
/// </summary>
|
||||
public Func<double, T> ConversionMethod { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// get method for the property associated with this unit
|
||||
/// </summary>
|
||||
public MethodInfo PropertyGetter { get; set; }
|
||||
}
|
||||
|
||||
internal class Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a string that represents a number with a unit to the actual
|
||||
/// unit type.
|
||||
/// </summary>
|
||||
/// <typeparam name="E">Enumeration of the Unit abbreviation</typeparam>
|
||||
/// <typeparam name="T">The actual unit type, i.e Current</typeparam>
|
||||
/// <param name="s">String that represents a unit value, i.e 1.23 Amps</param>
|
||||
/// <param name="unitInfo">Look up table for how to convert the units</param>
|
||||
/// <returns>
|
||||
/// The converted number to the correct unit type. If unable to parse, will return the first
|
||||
/// <see cref="UnitInfo{T}.ConversionMethod"/> with a value of <see cref="double.NaN"/>
|
||||
/// </returns>
|
||||
public static T Parse<E, T>( string s, IDictionary<E, UnitInfo<T>> unitInfo )
|
||||
{
|
||||
const string FloatingPointPattern = @"([-+]?[0-9]+(\.[0-9]+)?([Ee][+-][0-9]+)?)";
|
||||
const string AbbreviationPattern = @"([\w/\^]*)";
|
||||
string pattern = FloatingPointPattern + @"\s*" + AbbreviationPattern;
|
||||
|
||||
Regex regEx = new Regex( pattern );
|
||||
Match match = regEx.Match( s );
|
||||
|
||||
if(!match.Success || match.Groups.Count == 0 )
|
||||
{
|
||||
throw new FormatException( $"UUnknown value : {s}" );
|
||||
}
|
||||
|
||||
string abbreviation = match.Groups[match.Groups.Count - 1].Value;
|
||||
|
||||
IEnumerable<UnitInfo<T>> x = unitInfo.Where( kvp => kvp.Value.Abbreviation.Contains( abbreviation, StringComparer.CurrentCultureIgnoreCase ) )
|
||||
.Select( kvp => kvp.Value );
|
||||
|
||||
// abbreviation not found?
|
||||
if ( x.Count( ) == 0 )
|
||||
{
|
||||
throw new FormatException( $"Unknown units: '{abbreviation}'" );
|
||||
}
|
||||
|
||||
double value = double.Parse( match.Groups[1].Value );
|
||||
|
||||
return x.First( ).ConversionMethod( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Source/TSRealLib/Common/Raytheon.Common/Units/Constants.cs
Normal file
14
Source/TSRealLib/Common/Raytheon.Common/Units/Constants.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
public class Constants
|
||||
{
|
||||
// SI Prefixes decimal value
|
||||
public const double GIGA = 1e9;
|
||||
public const double MEGA = 1e6;
|
||||
public const double KILO = 1e3;
|
||||
public const double CENTI = 1e-2;
|
||||
public const double MILLI = 1e-3;
|
||||
public const double MICRO = 1e-6;
|
||||
public const double NANO = 1e-9;
|
||||
}
|
||||
}
|
||||
342
Source/TSRealLib/Common/Raytheon.Common/Units/Current.cs
Normal file
342
Source/TSRealLib/Common/Raytheon.Common/Units/Current.cs
Normal file
@@ -0,0 +1,342 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents an electrical current.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g.
|
||||
/// FromAmps).
|
||||
///
|
||||
/// Properties (e.g. Amps) are provided to convert the value to other units and return as type
|
||||
/// double.
|
||||
///
|
||||
/// Methods (operator overloads) are provided to perform calculations with related types (e.g.
|
||||
/// Voltage, Resistance).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Current
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
Amps,
|
||||
Milliamps
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.Amps, new List<string>(){ "A" } },
|
||||
{Unit.Milliamps, new List<string>(){ "mA" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.Amps;
|
||||
private const int MilliampsPerAmp = 1000;
|
||||
|
||||
[DataMember(Name = "Current", IsRequired = true)]
|
||||
private double _current; // amps
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<Current>> _unitInfo = new Dictionary<Unit, UnitInfo<Current>>()
|
||||
{
|
||||
{ Unit.Amps, new UnitInfo<Current>(UnitAbbreviations[Unit.Amps], FromAmps, typeof(Current).GetProperty("Amps").GetGetMethod()) },
|
||||
{ Unit.Milliamps, new UnitInfo<Current>(UnitAbbreviations[Unit.Milliamps], FromMilliamps, typeof(Current).GetProperty("Milliamps").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="Current"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private Current()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="current">The current - amps.</param>
|
||||
private Current(double current)
|
||||
{
|
||||
_current = current;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
/// <summary>
|
||||
/// Returns amps as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// amps
|
||||
/// </value>
|
||||
public double Amps
|
||||
{
|
||||
get { return _current; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns milliamps as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// milliamps
|
||||
/// </value>
|
||||
public double Milliamps
|
||||
{
|
||||
get { return _current * MilliampsPerAmp; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns Current object interpreting passed value as amps
|
||||
/// </summary>
|
||||
/// <param name="amps">amps</param>
|
||||
/// <returns></returns>
|
||||
public static Current FromAmps(double amps)
|
||||
{
|
||||
return new Current(amps);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Current object interpreting passed value as milliamps
|
||||
/// </summary>
|
||||
/// <param name="milliamps">milliamps</param>
|
||||
/// <returns></returns>
|
||||
public static Current FromMilliamps(double milliamps)
|
||||
{
|
||||
return new Current(milliamps / MilliampsPerAmp);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Current c = obj as Current;
|
||||
|
||||
return (c == null) ? false : (this._current == c._current);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _current.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static Current operator +(Current left, Current right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Current");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Current");
|
||||
|
||||
return new Current(left._current + right._current);
|
||||
}
|
||||
|
||||
|
||||
public static Current operator -(Current left, Current right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null Current");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null Current");
|
||||
|
||||
return new Current(left._current - right._current);
|
||||
}
|
||||
|
||||
|
||||
public static Current operator *(Current current, double scalar)
|
||||
{
|
||||
if (null == current)
|
||||
throw new ArgumentNullException("current", "Cannot multiply a null Current");
|
||||
|
||||
return new Current(current._current * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static Current operator *(double scalar, Current current)
|
||||
{
|
||||
if (null == current)
|
||||
throw new ArgumentNullException("current", "Cannot multiply a null Current");
|
||||
|
||||
return new Current(scalar * current._current);
|
||||
}
|
||||
|
||||
|
||||
public static Current operator /(Current current, double scalar)
|
||||
{
|
||||
if (null == current)
|
||||
throw new ArgumentNullException("current", "Cannot divide a null Current");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Current by 0");
|
||||
|
||||
return new Current(current._current / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(Current left, Current right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._current == right._current;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Current left, Current right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(Current left, Current right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Current");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Current");
|
||||
|
||||
return (left._current < right._current);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(Current left, Current right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Current");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Current");
|
||||
|
||||
return (left._current > right._current);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(Current left, Current right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Current");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Current");
|
||||
|
||||
return (left._current <= right._current);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(Current left, Current right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Current");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Current");
|
||||
|
||||
return (left._current >= right._current);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with other classes
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for Voltage = Current * Resistance
|
||||
/// </summary>
|
||||
/// <param name="current">The current.</param>
|
||||
/// <param name="resistance">The resistance.</param>
|
||||
/// <returns>
|
||||
/// Voltage
|
||||
/// </returns>
|
||||
|
||||
public static Voltage operator *(Current current, Resistance resistance)
|
||||
{
|
||||
if (null == current)
|
||||
throw new ArgumentNullException("current", "Cannot multiply a null Current");
|
||||
|
||||
if (null == resistance)
|
||||
throw new ArgumentNullException("resistance", "Cannot multiply null Resistance");
|
||||
|
||||
return Voltage.FromVolts(current.Amps * resistance.Ohms);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Current Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Current value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Current.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
322
Source/TSRealLib/Common/Raytheon.Common/Units/Energy.cs
Normal file
322
Source/TSRealLib/Common/Raytheon.Common/Units/Energy.cs
Normal file
@@ -0,0 +1,322 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents energy.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. FromJoulesPerCmSqrd).
|
||||
///
|
||||
/// Properties (e.g. JoulesPerCmSqrd) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Energy
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
JoulesPerCmSqrd,
|
||||
MillijoulesPerCmSqrd
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.JoulesPerCmSqrd, new List<string>(){ "J/cm^2" } },
|
||||
{Unit.MillijoulesPerCmSqrd, new List<string>(){ "mJ/cm^2" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.JoulesPerCmSqrd;
|
||||
|
||||
[DataMember(Name = "Energy", IsRequired = true)]
|
||||
private double _energy; // joules/centimeter^2
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<Energy>> _unitInfo = new Dictionary<Unit, UnitInfo<Energy>>()
|
||||
{
|
||||
{ Unit.JoulesPerCmSqrd, new UnitInfo<Energy>(UnitAbbreviations[Unit.JoulesPerCmSqrd], FromJoulesPerCmSqrd, typeof(Energy).GetProperty("JoulesPerCmSqrd").GetGetMethod()) },
|
||||
{ Unit.MillijoulesPerCmSqrd, new UnitInfo<Energy>(UnitAbbreviations[Unit.MillijoulesPerCmSqrd], FromMillijoulesPerCmSqrd, typeof(Energy).GetProperty("MillijoulesPerCmSqrd").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="Energy"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private Energy()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="energy">The energy - joules/cm^2.</param>
|
||||
private Energy(double energy)
|
||||
{
|
||||
_energy = energy;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
/// <summary>
|
||||
/// Returns joules/cm^2 as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// joules/cm^2
|
||||
/// </value>
|
||||
|
||||
public double JoulesPerCmSqrd
|
||||
{
|
||||
get { return _energy; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns joules/cm^2 as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// joules/cm^2
|
||||
/// </value>
|
||||
|
||||
public double MillijoulesPerCmSqrd
|
||||
{
|
||||
get { return _energy * 1000; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns Energy object interpreting passed value as joules/cm^2
|
||||
/// </summary>
|
||||
/// <param name="joulesPerCmSqrd">joules/cm^2</param>
|
||||
/// <returns></returns>
|
||||
|
||||
public static Energy FromJoulesPerCmSqrd(double joulesPerCmSqrd)
|
||||
{
|
||||
return new Energy(joulesPerCmSqrd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Energy object interpreting passed value as joules/cm^2
|
||||
/// </summary>
|
||||
/// <param name="joulesPerCmSqrd">joules/cm^2</param>
|
||||
/// <returns></returns>
|
||||
|
||||
public static Energy FromMillijoulesPerCmSqrd(double joulesPerCmSqrd)
|
||||
{
|
||||
return new Energy(joulesPerCmSqrd / 1000);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Energy e = obj as Energy;
|
||||
|
||||
return (e == null) ? false : (this._energy == e._energy);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _energy.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static Energy operator +(Energy left, Energy right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Energy");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Energy");
|
||||
|
||||
return new Energy(left._energy + right._energy);
|
||||
}
|
||||
|
||||
|
||||
public static Energy operator -(Energy left, Energy right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null Energy");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null Energy");
|
||||
|
||||
return new Energy(left._energy - right._energy);
|
||||
}
|
||||
|
||||
|
||||
public static Energy operator *(Energy energy, double scalar)
|
||||
{
|
||||
if (null == energy)
|
||||
throw new ArgumentNullException("energy", "Cannot multiply a null Energy");
|
||||
|
||||
return new Energy(energy._energy * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static Energy operator *(double scalar, Energy energy)
|
||||
{
|
||||
if (null == energy)
|
||||
throw new ArgumentNullException("energy", "Cannot multiply a null Energy");
|
||||
|
||||
return new Energy(scalar * energy._energy);
|
||||
}
|
||||
|
||||
|
||||
public static Energy operator /(Energy energy, double scalar)
|
||||
{
|
||||
if (null == energy)
|
||||
throw new ArgumentNullException("energy", "Cannot divide a null Energy");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Energy by 0");
|
||||
|
||||
return new Energy(energy._energy / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(Energy left, Energy right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._energy == right._energy;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Energy left, Energy right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(Energy left, Energy right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Energy");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Energy");
|
||||
|
||||
return (left._energy < right._energy);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(Energy left, Energy right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Energy");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Energy");
|
||||
|
||||
return (left._energy > right._energy);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(Energy left, Energy right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Energy");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Energy");
|
||||
|
||||
return (left._energy <= right._energy);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(Energy left, Energy right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Energy");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Energy");
|
||||
|
||||
return (left._energy >= right._energy);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with other classes
|
||||
|
||||
// no operators right now
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Energy Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Energy value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Energy.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
356
Source/TSRealLib/Common/Raytheon.Common/Units/FlowRate.cs
Normal file
356
Source/TSRealLib/Common/Raytheon.Common/Units/FlowRate.cs
Normal file
@@ -0,0 +1,356 @@
|
||||
//############################################################################//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
//############################################################################//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a Flow Rate.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. FromCubicMetersPerSecond).
|
||||
///
|
||||
/// Properties (e.g. CubicMetersPerSecond) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class FlowRate
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
CubicMetersPerSecond,
|
||||
CubicMetersPerMinute,
|
||||
CubicMetersPerHour,
|
||||
GallonsPerMinute
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.CubicMetersPerSecond, new List<string>(){ "m^3/s" } },
|
||||
{Unit.CubicMetersPerMinute, new List<string>(){ "m^3/min" } },
|
||||
{Unit.CubicMetersPerHour, new List<string>(){ "m^3/h" } },
|
||||
{Unit.GallonsPerMinute, new List<string>(){ "gal/min" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.CubicMetersPerSecond;
|
||||
private const double CubicMetersToGalPerSecMultipler = 15850;
|
||||
private const int SecondsPerMinute = 60;
|
||||
private const int SecondsPerHour = 3600;
|
||||
|
||||
[DataMember(Name = "CubicMetersPerSecond", IsRequired = true)]
|
||||
private readonly double _flowRate;
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static readonly IDictionary<Unit, UnitInfo<FlowRate>> _unitInfo = new Dictionary<Unit, UnitInfo<FlowRate>>()
|
||||
{
|
||||
{ Unit.CubicMetersPerSecond, new UnitInfo<FlowRate>(UnitAbbreviations[Unit.CubicMetersPerSecond], FromCubicMetersPerSecond, typeof(FlowRate).GetProperty("CubicMetersPerSecond").GetGetMethod()) },
|
||||
{ Unit.CubicMetersPerMinute, new UnitInfo<FlowRate>(UnitAbbreviations[Unit.CubicMetersPerMinute], FromCubicMetersPerMinute, typeof(FlowRate).GetProperty("CubicMetersPerMinute").GetGetMethod()) },
|
||||
{ Unit.CubicMetersPerHour, new UnitInfo<FlowRate>(UnitAbbreviations[Unit.CubicMetersPerHour], FromCubicMetersPerHour, typeof(FlowRate).GetProperty("CubicMetersPerHour").GetGetMethod()) },
|
||||
{ Unit.GallonsPerMinute, new UnitInfo<FlowRate>(UnitAbbreviations[Unit.GallonsPerMinute], FromGallonsPerMinute, typeof(FlowRate).GetProperty("GallonsPerMinute").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="FlowRate"/> class from being created
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
private FlowRate()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor used by this class to create objects in FromXXX methods.
|
||||
/// </summary>
|
||||
/// <param name="flowRate">The flow rate - Cubic Meters per second</param>
|
||||
private FlowRate(double cubicMetersPerSecond)
|
||||
{
|
||||
_flowRate = cubicMetersPerSecond;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
/// <summary>
|
||||
/// Returns Cubic Meters Per Second as type double
|
||||
/// </summary>
|
||||
public double CubicMetersPerSecond { get { return _flowRate; } }
|
||||
|
||||
/// <summary>
|
||||
/// Returns Cubic Meters Per Minutes as type double
|
||||
/// </summary>
|
||||
public double CubicMetersPerMinute { get { return _flowRate * SecondsPerMinute; } }
|
||||
|
||||
/// <summary>
|
||||
/// Returns Cubic Meters Per Hour as type double
|
||||
/// </summary>
|
||||
public double CubicMetersPerHour { get { return _flowRate * SecondsPerHour; } }
|
||||
|
||||
/// <summary>
|
||||
/// Returns Gallons Per Minute
|
||||
/// </summary>
|
||||
public double GallonsPerMinute { get { return _flowRate * CubicMetersToGalPerSecMultipler; } }
|
||||
#endregion
|
||||
|
||||
#region Creation Methods
|
||||
/// <summary>
|
||||
/// Returns FlowRate object interpreting passed value as Cubic Meters Per Second
|
||||
/// </summary>
|
||||
/// <param name="flowRate">Cubic Meters Per Second</param>
|
||||
/// <returns></returns>
|
||||
public static FlowRate FromCubicMetersPerSecond(double m3PerSec)
|
||||
{
|
||||
return new FlowRate(m3PerSec);
|
||||
}
|
||||
|
||||
public static FlowRate FromCubicMetersPerMinute(double m3PerMin)
|
||||
{
|
||||
return new FlowRate(m3PerMin / SecondsPerMinute);
|
||||
}
|
||||
|
||||
public static FlowRate FromCubicMetersPerHour(double m3PerHr)
|
||||
{
|
||||
return new FlowRate(m3PerHr / SecondsPerHour);
|
||||
}
|
||||
|
||||
public static FlowRate FromGallonsPerMinute(double gallonPerMin)
|
||||
{
|
||||
return new FlowRate(gallonPerMin / CubicMetersToGalPerSecMultipler);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
FlowRate flowRate = obj as FlowRate;
|
||||
|
||||
return (flowRate == null) ? false : (this._flowRate == flowRate._flowRate);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _flowRate.GetHashCode();
|
||||
}
|
||||
|
||||
#region Binary Operators
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
public static FlowRate operator +(FlowRate left, FlowRate right)
|
||||
{
|
||||
if (null == left)
|
||||
{
|
||||
throw new ArgumentNullException("left", "Cannot add a null Flow Rate");
|
||||
}
|
||||
|
||||
if (null == right)
|
||||
{
|
||||
throw new ArgumentNullException("right", "Cannot add null Flow Rate");
|
||||
}
|
||||
|
||||
return new FlowRate(left._flowRate + right._flowRate);
|
||||
}
|
||||
|
||||
public static FlowRate operator *(FlowRate flowRate, double scalar)
|
||||
{
|
||||
if (null == flowRate)
|
||||
{
|
||||
throw new ArgumentNullException("flowRate", "Cannot multiply a null Flow Rate");
|
||||
}
|
||||
|
||||
return new FlowRate(flowRate._flowRate * scalar);
|
||||
}
|
||||
|
||||
public static FlowRate operator *(double scalar, FlowRate flowRate)
|
||||
{
|
||||
if (null == flowRate)
|
||||
{
|
||||
throw new ArgumentNullException("flowRate", "Cannot multiply a null Flow Rate");
|
||||
}
|
||||
|
||||
return new FlowRate(scalar * flowRate._flowRate);
|
||||
}
|
||||
|
||||
public static FlowRate operator /(FlowRate flowRate, double scalar)
|
||||
{
|
||||
if (null == flowRate)
|
||||
{
|
||||
throw new ArgumentNullException("flowRate", "Cannot divide a null Flow Rate");
|
||||
}
|
||||
|
||||
if (0.0 == scalar)
|
||||
{
|
||||
throw new DivideByZeroException("Cannot divide Flow Rate by 0");
|
||||
}
|
||||
|
||||
return new FlowRate(flowRate._flowRate / scalar);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
public static bool operator ==(FlowRate left, FlowRate right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._flowRate == right._flowRate;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(FlowRate left, FlowRate right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
public static bool operator <(FlowRate left, FlowRate right)
|
||||
{
|
||||
if (null == left)
|
||||
{
|
||||
throw new ArgumentNullException("left", "Cannot compare null Flow Rate");
|
||||
}
|
||||
|
||||
if (null == right)
|
||||
{
|
||||
throw new ArgumentNullException("right", "Cannot compare null Flow Rate");
|
||||
}
|
||||
|
||||
return (left._flowRate < right._flowRate);
|
||||
}
|
||||
|
||||
public static bool operator >(FlowRate left, FlowRate right)
|
||||
{
|
||||
if (null == left)
|
||||
{
|
||||
throw new ArgumentNullException("left", "Cannot compare null Flow Rate");
|
||||
}
|
||||
|
||||
if (null == right)
|
||||
{
|
||||
throw new ArgumentNullException("right", "Cannot compare null Flow Rate");
|
||||
}
|
||||
|
||||
return (left._flowRate > right._flowRate);
|
||||
}
|
||||
|
||||
public static bool operator <=(FlowRate left, FlowRate right)
|
||||
{
|
||||
if (null == left)
|
||||
{
|
||||
throw new ArgumentNullException("left", "Cannot compare null Flow Rate");
|
||||
}
|
||||
|
||||
if (null == right)
|
||||
{
|
||||
throw new ArgumentNullException("right", "Cannot compare null Flow Rate");
|
||||
}
|
||||
|
||||
return (left._flowRate <= right._flowRate);
|
||||
}
|
||||
|
||||
public static bool operator >=(FlowRate left, FlowRate right)
|
||||
{
|
||||
if (null == left)
|
||||
{
|
||||
throw new ArgumentNullException("left", "Cannot compare null Flow Rate");
|
||||
}
|
||||
|
||||
if (null == right)
|
||||
{
|
||||
throw new ArgumentNullException("right", "Cannot compare null Flow Rate");
|
||||
}
|
||||
|
||||
return (left._flowRate >= right._flowRate);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static FlowRate Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out FlowRate value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = FlowRate.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string" /> appended with units symbol (e.g. "1.23 M^3/s").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string" /> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
340
Source/TSRealLib/Common/Raytheon.Common/Units/Frequency.cs
Normal file
340
Source/TSRealLib/Common/Raytheon.Common/Units/Frequency.cs
Normal file
@@ -0,0 +1,340 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents energy.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. FromHertz).
|
||||
///
|
||||
/// Properties (e.g. Hertz) are provided to convert the value to other units and return as type
|
||||
/// double.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Frequency
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
Hertz,
|
||||
KiloHertz,
|
||||
MegaHertz,
|
||||
GigaHertz
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.Hertz, new List<string>(){ "Hz" } },
|
||||
{Unit.KiloHertz, new List<string>(){ "kHz" } },
|
||||
{Unit.MegaHertz, new List<string>(){ "MHz" } },
|
||||
{Unit.GigaHertz, new List<string>(){ "GHz" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.Hertz;
|
||||
|
||||
[DataMember(Name = "Frequency", IsRequired = true)]
|
||||
private double _frequency; // Hertz
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<Frequency>> _unitInfo = new Dictionary<Unit, UnitInfo<Frequency>>()
|
||||
{
|
||||
{ Unit.Hertz, new UnitInfo<Frequency>(UnitAbbreviations[Unit.Hertz], FromHertz, typeof(Frequency).GetProperty("Hertz").GetGetMethod()) },
|
||||
{ Unit.KiloHertz, new UnitInfo<Frequency>(UnitAbbreviations[Unit.KiloHertz], FromKiloHertz, typeof(Frequency).GetProperty("KiloHertz").GetGetMethod()) },
|
||||
{ Unit.MegaHertz, new UnitInfo<Frequency>(UnitAbbreviations[Unit.MegaHertz], FromMegaHertz, typeof(Frequency).GetProperty("MegaHertz").GetGetMethod()) },
|
||||
{ Unit.GigaHertz, new UnitInfo<Frequency>(UnitAbbreviations[Unit.GigaHertz], FromGigaHertz, typeof(Frequency).GetProperty("GigaHertz").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="Frequency"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private Frequency()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="frequency">The frequency - Hertz.</param>
|
||||
private Frequency(double frequency)
|
||||
{
|
||||
_frequency = frequency;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
public double GigaHertz
|
||||
{
|
||||
get { return _frequency / Constants.GIGA; }
|
||||
}
|
||||
|
||||
public double Hertz
|
||||
{
|
||||
get { return _frequency; }
|
||||
}
|
||||
|
||||
public double KiloHertz
|
||||
{
|
||||
get { return _frequency / Constants.KILO; }
|
||||
}
|
||||
|
||||
public double MegaHertz
|
||||
{
|
||||
get { return _frequency / Constants.MEGA; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns Frequency object interpreting passed value as Hertz
|
||||
/// </summary>
|
||||
/// <param name="frequency">Hertz</param>
|
||||
/// <returns></returns>
|
||||
public static Frequency FromGigaHertz(double frequency)
|
||||
{
|
||||
return new Frequency(frequency * Constants.GIGA);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Frequency object interpreting passed value as Hertz
|
||||
/// </summary>
|
||||
/// <param name="frequency">Hertz</param>
|
||||
/// <returns></returns>
|
||||
public static Frequency FromHertz(double frequency)
|
||||
{
|
||||
return new Frequency(frequency);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Frequency object interpreting passed value as Hertz
|
||||
/// </summary>
|
||||
/// <param name="frequency">Hertz</param>
|
||||
/// <returns></returns>
|
||||
public static Frequency FromKiloHertz(double frequency)
|
||||
{
|
||||
return new Frequency(frequency * Constants.KILO);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Frequency object interpreting passed value as Hertz
|
||||
/// </summary>
|
||||
/// <param name="frequency">Hertz</param>
|
||||
/// <returns></returns>
|
||||
public static Frequency FromMegaHertz(double frequency)
|
||||
{
|
||||
return new Frequency(frequency * Constants.MEGA);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Frequency e = obj as Frequency;
|
||||
|
||||
return (e == null) ? false : (this._frequency == e._frequency);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _frequency.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static Frequency operator +(Frequency left, Frequency right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Frequency");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Frequency");
|
||||
|
||||
return new Frequency(left._frequency + right._frequency);
|
||||
}
|
||||
|
||||
|
||||
public static Frequency operator -(Frequency left, Frequency right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null Frequency");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null Frequency");
|
||||
|
||||
return new Frequency(left._frequency - right._frequency);
|
||||
}
|
||||
|
||||
|
||||
public static Frequency operator *(Frequency frequency, double scalar)
|
||||
{
|
||||
if (null == frequency)
|
||||
throw new ArgumentNullException("frequency", "Cannot multiply a null Frequency");
|
||||
|
||||
return new Frequency(frequency._frequency * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static Frequency operator *(double scalar, Frequency frequency)
|
||||
{
|
||||
if (null == frequency)
|
||||
throw new ArgumentNullException("frequency", "Cannot multiply a null Frequency");
|
||||
|
||||
return new Frequency(scalar * frequency._frequency);
|
||||
}
|
||||
|
||||
|
||||
public static Frequency operator /(Frequency frequency, double scalar)
|
||||
{
|
||||
if (null == frequency)
|
||||
throw new ArgumentNullException("frequency", "Cannot divide a null Frequency");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Frequency by 0");
|
||||
|
||||
return new Frequency(frequency._frequency / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(Frequency left, Frequency right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._frequency == right._frequency;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Frequency left, Frequency right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(Frequency left, Frequency right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Frequency");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Frequency");
|
||||
|
||||
return (left._frequency < right._frequency);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(Frequency left, Frequency right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Frequency");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Frequency");
|
||||
|
||||
return (left._frequency > right._frequency);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(Frequency left, Frequency right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Frequency");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Frequency");
|
||||
|
||||
return (left._frequency <= right._frequency);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(Frequency left, Frequency right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Frequency");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Frequency");
|
||||
|
||||
return (left._frequency >= right._frequency);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with other classes
|
||||
|
||||
// no operators right now
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Frequency Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Frequency value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Frequency.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
412
Source/TSRealLib/Common/Raytheon.Common/Units/Length.cs
Normal file
412
Source/TSRealLib/Common/Raytheon.Common/Units/Length.cs
Normal file
@@ -0,0 +1,412 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a length.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. FromMeters).
|
||||
///
|
||||
/// Properties (e.g. Meters) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
///
|
||||
/// Methods (operator overloads) are provided to perform calculations with related types (e.g.
|
||||
/// Velocity).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Length
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
Meters,
|
||||
Centimeters,
|
||||
Millimeters,
|
||||
Micrometers,
|
||||
Nanometers,
|
||||
Inches,
|
||||
Feet
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.Meters, new List<string>(){ "m" } },
|
||||
{Unit.Centimeters, new List<string>(){ "cm" } },
|
||||
{Unit.Millimeters, new List<string>(){ "mm" } },
|
||||
{Unit.Micrometers, new List<string>(){ "um" } },
|
||||
{Unit.Nanometers, new List<string>(){ "nm" } },
|
||||
{Unit.Inches, new List<string>(){ "in" } },
|
||||
{Unit.Feet, new List<string>(){ "ft" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.Meters;
|
||||
private const double FeetPerMeter = 3.280839895013123;
|
||||
private const double InchesPerMeter = 12 * FeetPerMeter;
|
||||
private const double MilesPerMeter = FeetPerMeter / 5280;
|
||||
|
||||
[DataMember(Name = "Length", IsRequired = true)]
|
||||
private double _length; // meters
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<Length>> _unitInfo = new Dictionary<Unit, UnitInfo<Length>>()
|
||||
{
|
||||
{ Unit.Meters, new UnitInfo<Length>(UnitAbbreviations[Unit.Meters], FromMeters, typeof(Length).GetProperty("Meters").GetGetMethod()) },
|
||||
{ Unit.Centimeters, new UnitInfo<Length>(UnitAbbreviations[Unit.Centimeters], FromCentimeters, typeof(Length).GetProperty("Centimeters").GetGetMethod()) },
|
||||
{ Unit.Millimeters, new UnitInfo<Length>(UnitAbbreviations[Unit.Millimeters], FromMillimeters, typeof(Length).GetProperty("Millimeters").GetGetMethod()) },
|
||||
{ Unit.Micrometers, new UnitInfo<Length>(UnitAbbreviations[Unit.Micrometers], FromMicrometers, typeof(Length).GetProperty("Micrometers").GetGetMethod()) },
|
||||
{ Unit.Nanometers, new UnitInfo<Length>(UnitAbbreviations[Unit.Nanometers], FromNanometers, typeof(Length).GetProperty("Nanometers").GetGetMethod()) },
|
||||
{ Unit.Feet, new UnitInfo<Length>(UnitAbbreviations[Unit.Feet], FromFeet, typeof(Length).GetProperty("Feet").GetGetMethod()) },
|
||||
{ Unit.Inches, new UnitInfo<Length>(UnitAbbreviations[Unit.Inches], FromInches, typeof(Length).GetProperty("Inches").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="Length"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private Length()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="length">The length - meters</param>
|
||||
private Length(double length)
|
||||
{
|
||||
_length = length;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
public double Centimeters
|
||||
{
|
||||
get { return _length * 100; }
|
||||
}
|
||||
|
||||
public double Feet
|
||||
{
|
||||
get { return _length * FeetPerMeter; }
|
||||
}
|
||||
|
||||
public double Inches
|
||||
{
|
||||
get { return _length * InchesPerMeter; }
|
||||
}
|
||||
|
||||
public double Meters
|
||||
{
|
||||
get { return _length; }
|
||||
}
|
||||
|
||||
public double Micrometers
|
||||
{
|
||||
get { return _length * 1000000; }
|
||||
}
|
||||
|
||||
public double Millimeters
|
||||
{
|
||||
get { return _length * 1000; }
|
||||
}
|
||||
|
||||
public double Nanometers
|
||||
{
|
||||
get { return _length * 1000000000; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
public static Length FromCentimeters(double centimeters)
|
||||
{
|
||||
return new Length(centimeters / 100);
|
||||
}
|
||||
|
||||
public static Length FromFeet(double feet)
|
||||
{
|
||||
return new Length(feet / FeetPerMeter);
|
||||
}
|
||||
|
||||
public static Length FromInches(double inches)
|
||||
{
|
||||
return new Length(inches / InchesPerMeter);
|
||||
}
|
||||
|
||||
public static Length FromMeters(double meters)
|
||||
{
|
||||
return new Length(meters);
|
||||
}
|
||||
|
||||
public static Length FromMicrometers(double micrometers)
|
||||
{
|
||||
return new Length(micrometers / 1000000);
|
||||
}
|
||||
|
||||
public static Length FromMillimeters(double millimeters)
|
||||
{
|
||||
return new Length(millimeters / 1000);
|
||||
}
|
||||
|
||||
public static Length FromNanometers(double nanometers)
|
||||
{
|
||||
return new Length(nanometers / 1000000000);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Length l = obj as Length;
|
||||
|
||||
return (l == null) ? false : (this._length == l._length);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _length.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static Length operator +(Length left, Length right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Length");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Length");
|
||||
|
||||
return new Length(left._length + right._length);
|
||||
}
|
||||
|
||||
|
||||
public static Length operator -(Length left, Length right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null Length");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null Length");
|
||||
|
||||
return new Length(left._length - right._length);
|
||||
}
|
||||
|
||||
|
||||
public static Length operator *(Length length, double scalar)
|
||||
{
|
||||
if (null == length)
|
||||
throw new ArgumentNullException("length", "Cannot multiply a null Length");
|
||||
|
||||
return new Length(length._length * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static Length operator *(double scalar, Length length)
|
||||
{
|
||||
if (null == length)
|
||||
throw new ArgumentNullException("length", "Cannot multiply a null Length");
|
||||
|
||||
return new Length(scalar * length._length);
|
||||
}
|
||||
|
||||
|
||||
public static Length operator /(Length length, double scalar)
|
||||
{
|
||||
if (null == length)
|
||||
throw new ArgumentNullException("length", "Cannot divide a null Length");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Length by 0");
|
||||
|
||||
return new Length(length._length / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(Length left, Length right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._length == right._length;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Length left, Length right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(Length left, Length right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Length");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Length");
|
||||
|
||||
return (left._length < right._length);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(Length left, Length right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Length");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Length");
|
||||
|
||||
return (left._length > right._length);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(Length left, Length right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Length");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Length");
|
||||
|
||||
return (left._length <= right._length);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(Length left, Length right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Length");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Length");
|
||||
|
||||
return (left._length >= right._length);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with non-length classes
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator / for Velocity = Length / PrecisionTimeSpan
|
||||
/// </summary>
|
||||
/// <param name="length">The length.</param>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <returns>
|
||||
/// Velocity
|
||||
/// </returns>
|
||||
|
||||
public static Velocity operator /(Length length, PrecisionTimeSpan time)
|
||||
//public static Velocity operator /(Length length, TimeSpan time)
|
||||
{
|
||||
if (null == length)
|
||||
throw new ArgumentNullException("length", "Cannot divide a null Length");
|
||||
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot divide by a null PrecisionTimeSpan");
|
||||
|
||||
if (0.0 == time.Milliseconds)
|
||||
throw new DivideByZeroException("Cannot divide Length by 0 time");
|
||||
|
||||
return Velocity.FromMetersPerSec(length.Meters / time.Seconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator / for PrecisionTimeSpan = Length / Velocity
|
||||
/// </summary>
|
||||
/// <param name="length">The length.</param>
|
||||
/// <param name="time">The velocity.</param>
|
||||
/// <returns>
|
||||
/// PrecisionTimeSpan
|
||||
/// </returns>
|
||||
|
||||
public static PrecisionTimeSpan operator /(Length length, Velocity velocity)
|
||||
{
|
||||
if (null == length)
|
||||
throw new ArgumentNullException("length", "Cannot divide a null Length");
|
||||
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot divide by a null Velocity");
|
||||
|
||||
if (0.0 == velocity.MetersPerSec)
|
||||
throw new DivideByZeroException("Cannot divide Length by 0 velocity");
|
||||
|
||||
return PrecisionTimeSpan.FromSeconds(length.Meters / velocity.MetersPerSec);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Length Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Length value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Length.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
333
Source/TSRealLib/Common/Raytheon.Common/Units/Power.cs
Normal file
333
Source/TSRealLib/Common/Raytheon.Common/Units/Power.cs
Normal file
@@ -0,0 +1,333 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents energy.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. FromWatts).
|
||||
///
|
||||
/// Properties (e.g. Watts) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Power
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
Watts,
|
||||
Milliwatts,
|
||||
DecibelMilliWatt
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.Watts, new List<string>(){ "W", "Watts", "Watt" } },
|
||||
{Unit.Milliwatts, new List<string>(){ "mW", "MilliWatt", "MilliWatts" } },
|
||||
{Unit.DecibelMilliWatt, new List<string>(){ "dBm", "DecibelMilliWatt", "DecibelMilliWatts" } }
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.Watts;
|
||||
|
||||
[DataMember(Name = "Power", IsRequired = true)]
|
||||
private readonly double _power; // watts
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static readonly IDictionary<Unit, UnitInfo<Power>> _unitInfo = new Dictionary<Unit, UnitInfo<Power>>()
|
||||
{
|
||||
{ Unit.Watts, new UnitInfo<Power>(UnitAbbreviations[Unit.Watts], FromWatts, typeof(Power).GetProperty("Watts").GetGetMethod()) },
|
||||
{ Unit.Milliwatts, new UnitInfo<Power>(UnitAbbreviations[Unit.Milliwatts], FromMilliwatts, typeof(Power).GetProperty("Milliwatts").GetGetMethod()) },
|
||||
{ Unit.DecibelMilliWatt, new UnitInfo<Power>(UnitAbbreviations[Unit.DecibelMilliWatt], FromDBM, typeof(Power).GetProperty("DBM").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="Power"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private Power()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="energy">The energy - watts/cm^2.</param>
|
||||
private Power(double energy)
|
||||
{
|
||||
_power = energy;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
public double Milliwatts
|
||||
{
|
||||
get { return _power * 1000; }
|
||||
}
|
||||
|
||||
public double Watts
|
||||
{
|
||||
get { return _power; }
|
||||
}
|
||||
|
||||
public double DBM
|
||||
{
|
||||
get { return (10 * Math.Log10(Math.Abs(_power))) + 30; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns watts/cm^2 as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// watts/cm^2
|
||||
/// </value>
|
||||
|
||||
[Obsolete("WattsPerCmSqrd is deprecated, please use Watts instead. This will be removed in a future version.", false)]
|
||||
public double WattsPerCmSqrd
|
||||
{
|
||||
get
|
||||
{
|
||||
return Double.NaN;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// </summary>
|
||||
/// <param name="wattsPerCmSqrd">watts/cm^2</param>
|
||||
/// <returns></returns>
|
||||
|
||||
[Obsolete("FromWattsPerCmSqrd is deprecated, please use FromWatts instead. This will be removed in a future version.", false)]
|
||||
public static Power FromWattsPerCmSqrd(double wattsPerCmSqrd)
|
||||
{
|
||||
return new Power(Double.NaN);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Power object interpreting passed value as milliwatts
|
||||
/// </summary>
|
||||
/// <param name="milliwatts">milliwatts</param>
|
||||
/// <returns></returns>
|
||||
public static Power FromMilliwatts(double milliwatts)
|
||||
{
|
||||
return new Power(milliwatts / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Power object interpreting passed value as watts
|
||||
/// </summary>
|
||||
/// <param name="watts">watts</param>
|
||||
/// <returns></returns>
|
||||
public static Power FromWatts(double watts)
|
||||
{
|
||||
return new Power(watts);
|
||||
}
|
||||
|
||||
public static Power FromDBM(double dbm)
|
||||
{
|
||||
return new Power(Math.Pow(10, (dbm - 30) / 10));
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Power e = obj as Power;
|
||||
|
||||
return (e == null) ? false : (this._power == e._power);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _power.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
public static Power operator +(Power left, Power right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Power");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Power");
|
||||
|
||||
return new Power(left._power + right._power);
|
||||
}
|
||||
|
||||
public static Power operator -(Power left, Power right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null Power");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null Power");
|
||||
|
||||
return new Power(left._power - right._power);
|
||||
}
|
||||
|
||||
public static Power operator *(Power power, double scalar)
|
||||
{
|
||||
if (null == power)
|
||||
throw new ArgumentNullException("power", "Cannot multiply a null Power");
|
||||
|
||||
return new Power(power._power * scalar);
|
||||
}
|
||||
|
||||
public static Power operator *(double scalar, Power power)
|
||||
{
|
||||
if (null == power)
|
||||
throw new ArgumentNullException("power", "Cannot multiply a null Power");
|
||||
|
||||
return new Power(scalar * power._power);
|
||||
}
|
||||
|
||||
public static Power operator /(Power power, double scalar)
|
||||
{
|
||||
if (null == power)
|
||||
throw new ArgumentNullException("power", "Cannot divide a null Power");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Power by 0");
|
||||
|
||||
return new Power(power._power / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(Power left, Power right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._power == right._power;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Power left, Power right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
public static bool operator <(Power left, Power right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Power");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Power");
|
||||
|
||||
return (left._power < right._power);
|
||||
}
|
||||
|
||||
public static bool operator >(Power left, Power right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Power");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Power");
|
||||
|
||||
return (left._power > right._power);
|
||||
}
|
||||
|
||||
public static bool operator <=(Power left, Power right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Power");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Power");
|
||||
|
||||
return (left._power <= right._power);
|
||||
}
|
||||
|
||||
public static bool operator >=(Power left, Power right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Power");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Power");
|
||||
|
||||
return (left._power >= right._power);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with other classes
|
||||
|
||||
// no operators right now
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Power Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Power value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Power.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents precision time spans where the .NET TimeSpan class just does
|
||||
/// not cut the mustard
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. FromSeconds).
|
||||
///
|
||||
/// Properties (e.g. Seconds) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
///
|
||||
/// Methods (operator overloads) are provided to perform calculations with related types
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class PrecisionTimeSpan
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
Seconds,
|
||||
Milliseconds,
|
||||
Microseconds,
|
||||
Nanoseconds
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.Seconds, new List<string>(){ "sec" } },
|
||||
{Unit.Milliseconds, new List<string>(){ "msec" } },
|
||||
{Unit.Microseconds, new List<string>(){ "usec" } },
|
||||
{Unit.Nanoseconds, new List<string>(){ "nsec" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.Seconds;
|
||||
|
||||
[DataMember(Name = "BaseTimeSpan", IsRequired = true)]
|
||||
private Decimal _totalns; //base will be nano seconds... max will be double.MaxValue
|
||||
//min will be 0
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<PrecisionTimeSpan>> _unitInfo = new Dictionary<Unit, UnitInfo<PrecisionTimeSpan>>()
|
||||
{
|
||||
{ Unit.Seconds, new UnitInfo<PrecisionTimeSpan>(UnitAbbreviations[Unit.Seconds], FromSeconds, typeof(PrecisionTimeSpan).GetProperty("Seconds").GetGetMethod()) },
|
||||
{ Unit.Milliseconds, new UnitInfo<PrecisionTimeSpan>(UnitAbbreviations[Unit.Milliseconds], FromMilliseconds, typeof(PrecisionTimeSpan).GetProperty("Milliseconds").GetGetMethod()) },
|
||||
{ Unit.Microseconds, new UnitInfo<PrecisionTimeSpan>(UnitAbbreviations[Unit.Microseconds], FromMicroseconds, typeof(PrecisionTimeSpan).GetProperty("Microseconds").GetGetMethod()) },
|
||||
{ Unit.Nanoseconds, new UnitInfo<PrecisionTimeSpan>(UnitAbbreviations[Unit.Nanoseconds], FromNanoseconds, typeof(PrecisionTimeSpan).GetProperty("Nanoseconds").GetGetMethod()) }
|
||||
};
|
||||
|
||||
internal const Decimal _nanoPerMicro = 1e3M;
|
||||
internal const Decimal _nanoPerMilli = 1e6M;
|
||||
internal const Decimal _nanoPerSec = 1e9M;
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="PrecisionTimeSpan"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private PrecisionTimeSpan()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="totalns">total number of nanoseconds.</param>
|
||||
private PrecisionTimeSpan(Decimal totalns)
|
||||
{
|
||||
if (totalns < 0.0M)
|
||||
throw new ArgumentOutOfRangeException("totalns", "Cannot create a negative timespan");
|
||||
|
||||
_totalns = totalns;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
public double Nanoseconds
|
||||
{
|
||||
get { return (double)_totalns; }
|
||||
}
|
||||
|
||||
public double Microseconds
|
||||
{
|
||||
get { return (double)(_totalns / _nanoPerMicro); }
|
||||
}
|
||||
|
||||
public double Milliseconds
|
||||
{
|
||||
get { return (double)(_totalns / _nanoPerMilli); }
|
||||
}
|
||||
|
||||
public double Seconds
|
||||
{
|
||||
get { return (double)(_totalns / _nanoPerSec); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns PrecisionTimeSpan object interpreting passed value as nanoseconds
|
||||
/// </summary>
|
||||
/// <param name="nanoseconds">total nanoseconds in the desired timespan</param>
|
||||
/// <returns>the precision time span object</returns>
|
||||
public static PrecisionTimeSpan FromNanoseconds(double nanoseconds)
|
||||
{
|
||||
return new PrecisionTimeSpan((Decimal)nanoseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns PrecisionTimeSpan object interpreting passed value as microseconds
|
||||
/// </summary>
|
||||
/// <param name="nanoseconds">total microseconds in the desired timespan</param>
|
||||
/// <returns>the precision time span object</returns>
|
||||
public static PrecisionTimeSpan FromMicroseconds(double microseconds)
|
||||
{
|
||||
return new PrecisionTimeSpan((Decimal)microseconds * _nanoPerMicro);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns PrecisionTimeSpan object interpreting passed value as milliseconds
|
||||
/// </summary>
|
||||
/// <param name="nanoseconds">total milliseconds in the desired timespan</param>
|
||||
/// <returns>the precision time span object</returns>
|
||||
public static PrecisionTimeSpan FromMilliseconds(double milliseconds)
|
||||
{
|
||||
return new PrecisionTimeSpan((Decimal)milliseconds * _nanoPerMilli);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns PrecisionTimeSpan object interpreting passed value as seconds
|
||||
/// </summary>
|
||||
/// <param name="nanoseconds">total seconds in the desired timespan</param>
|
||||
/// <returns>the precision time span object</returns>
|
||||
public static PrecisionTimeSpan FromSeconds(double seconds)
|
||||
{
|
||||
return new PrecisionTimeSpan((Decimal)seconds * _nanoPerSec);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
PrecisionTimeSpan ts = obj as PrecisionTimeSpan;
|
||||
|
||||
return (ts == null) ? false : (this._totalns == ts._totalns);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _totalns.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static PrecisionTimeSpan operator +(PrecisionTimeSpan left, PrecisionTimeSpan right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null PrecisionTimeSpan");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null PrecisionTimeSpan");
|
||||
|
||||
return new PrecisionTimeSpan(left._totalns + right._totalns);
|
||||
}
|
||||
|
||||
|
||||
public static PrecisionTimeSpan operator -(PrecisionTimeSpan left, PrecisionTimeSpan right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null PrecisionTimeSpan");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null PrecisionTimeSpan");
|
||||
|
||||
if (right > left)
|
||||
throw new ArgumentOutOfRangeException("right", "Cannot subtract a larger span from a smaller one");
|
||||
|
||||
return new PrecisionTimeSpan(left._totalns - right._totalns);
|
||||
}
|
||||
|
||||
|
||||
public static PrecisionTimeSpan operator *(PrecisionTimeSpan precisionTimeSpan, double scalar)
|
||||
{
|
||||
if (null == precisionTimeSpan)
|
||||
throw new ArgumentNullException("precisionTimeSpan", "Cannot multiply a null PrecisionTimeSpan");
|
||||
|
||||
return new PrecisionTimeSpan(precisionTimeSpan._totalns * (Decimal)scalar);
|
||||
}
|
||||
|
||||
|
||||
public static PrecisionTimeSpan operator *(double scalar, PrecisionTimeSpan precisionTimeSpan)
|
||||
{
|
||||
if (null == precisionTimeSpan)
|
||||
throw new ArgumentNullException("precisionTimeSpan", "Cannot multiply a null PrecisionTimeSpan");
|
||||
|
||||
return new PrecisionTimeSpan((Decimal)scalar * precisionTimeSpan._totalns);
|
||||
}
|
||||
|
||||
|
||||
public static PrecisionTimeSpan operator /(PrecisionTimeSpan precisionTimeSpan, double scalar)
|
||||
{
|
||||
if (null == precisionTimeSpan)
|
||||
throw new ArgumentNullException("precisionTimeSpan", "Cannot divide a null PrecisionTimeSpan");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Precision Time Span by 0");
|
||||
|
||||
return new PrecisionTimeSpan(precisionTimeSpan._totalns / (Decimal)scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(PrecisionTimeSpan left, PrecisionTimeSpan right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._totalns == right._totalns;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(PrecisionTimeSpan left, PrecisionTimeSpan right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(PrecisionTimeSpan left, PrecisionTimeSpan right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null PrecisionTimeSpan");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null PrecisionTimeSpan");
|
||||
|
||||
return (left._totalns < right._totalns);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(PrecisionTimeSpan left, PrecisionTimeSpan right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null PrecisionTimeSpan");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null PrecisionTimeSpan");
|
||||
|
||||
return (left._totalns > right._totalns);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(PrecisionTimeSpan left, PrecisionTimeSpan right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null PrecisionTimeSpan");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null PrecisionTimeSpan");
|
||||
|
||||
return (left._totalns <= right._totalns);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(PrecisionTimeSpan left, PrecisionTimeSpan right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null PrecisionTimeSpan");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null PrecisionTimeSpan");
|
||||
|
||||
return (left._totalns >= right._totalns);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with other classes
|
||||
|
||||
// no operators right now
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static PrecisionTimeSpan Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out PrecisionTimeSpan value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = PrecisionTimeSpan.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
367
Source/TSRealLib/Common/Raytheon.Common/Units/Pressure.cs
Normal file
367
Source/TSRealLib/Common/Raytheon.Common/Units/Pressure.cs
Normal file
@@ -0,0 +1,367 @@
|
||||
//############################################################################//
|
||||
// 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.
|
||||
//
|
||||
// WARNING: THIS DOCUMENT CONTAINS TECHNICAL DATA AND / OR TECHNOLOGY WHOSE
|
||||
// EXPORT OR DISCLOSURE TO NON-U.S. PERSONS, WHEREVER LOCATED, IS RESTRICTED
|
||||
// BY THE INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) (22 C.F.R. SECTION
|
||||
// 120-130) OR THE EXPORT ADMINISTRATION REGULATIONS (EAR) (15 C.F.R. SECTION
|
||||
// 730-774). THIS DOCUMENT CANNOT BE EXPORTED (E.G., PROVIDED TO A SUPPLIER
|
||||
// OUTSIDE OF THE UNITED STATES) OR DISCLOSED TO A NON-U.S. PERSON, WHEREVER
|
||||
// LOCATED, UNTIL A FINAL JURISDICTION AND CLASSIFICATION DETERMINATION HAS
|
||||
// BEEN COMPLETED AND APPROVED BY RAYTHEON, AND ANY REQUIRED U.S. GOVERNMENT
|
||||
// APPROVALS HAVE BEEN OBTAINED. VIOLATIONS ARE SUBJECT TO SEVERE CRIMINAL
|
||||
// PENALTIES.
|
||||
//
|
||||
// DOD 5220.22-M, INDUSTRIAL SECURITY MANUAL, CHAPTER 5, SECTION 1 THROUGH 9 :
|
||||
// FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN OR DOD 5200.1-R,
|
||||
// INFORMATION SECURITY PROGRAM, CHAPTER 6. FOR UNCLASSIFIED, LIMITED DOCUMENTS
|
||||
// DESTROY BY ANY METHOD THAT WILL PREVENT DISCLOSURE OF CONTENTS OR
|
||||
// RECONSTRUCTION OF THE DOCUMENT.
|
||||
//############################################################################//
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a Pressure
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. Pascal).
|
||||
///
|
||||
/// Properties (e.g. Pascal) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Pressure
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
Bar,
|
||||
Millibar,
|
||||
Pascal,
|
||||
PSI
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.Bar, new List<string>(){ "bar" } },
|
||||
{Unit.Millibar, new List<string>(){ "mbar" } },
|
||||
{Unit.Pascal, new List<string>(){ "Pa" } },
|
||||
{Unit.PSI, new List<string>(){ "PSI" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.PSI;
|
||||
private const int PascalPerBar = 100000;
|
||||
private const double PascalPerPSI = 6894.75729;
|
||||
|
||||
[DataMember(Name = "Pascal", IsRequired = true)]
|
||||
private double _pressure; // Pascal
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<Pressure>> _unitInfo = new Dictionary<Unit, UnitInfo<Pressure>>()
|
||||
{
|
||||
{ Unit.Bar, new UnitInfo<Pressure>(UnitAbbreviations[Unit.Bar], FromBar, typeof(Pressure).GetProperty("Bar").GetGetMethod()) },
|
||||
{ Unit.Millibar, new UnitInfo<Pressure>(UnitAbbreviations[Unit.Millibar], FromMillibar, typeof(Pressure).GetProperty("Millibar").GetGetMethod()) },
|
||||
{ Unit.Pascal, new UnitInfo<Pressure>(UnitAbbreviations[Unit.Pascal], FromPascal, typeof(Pressure).GetProperty("Pascal").GetGetMethod()) },
|
||||
{ Unit.PSI, new UnitInfo<Pressure>(UnitAbbreviations[Unit.PSI], FromPSI, typeof(Pressure).GetProperty("PSI").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="Pressure"/> class from being created
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
private Pressure()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods.
|
||||
/// </summary>
|
||||
/// <param name="pressure">The pressure - pascal</param>
|
||||
private Pressure(double pressure)
|
||||
{
|
||||
this._pressure = pressure;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
public double Bar { get { return _pressure / PascalPerBar; } }
|
||||
|
||||
public double Millibar { get { return _pressure / PascalPerBar * 1000; } }
|
||||
|
||||
public double Pascal { get { return _pressure; } }
|
||||
|
||||
public double PSI { get { return _pressure / PascalPerPSI; } }
|
||||
#endregion
|
||||
|
||||
#region Creation Methods
|
||||
public static Pressure FromBar(double bars)
|
||||
{
|
||||
return new Pressure(bars * PascalPerBar);
|
||||
}
|
||||
|
||||
public static Pressure FromMillibar(double millibars)
|
||||
{
|
||||
return new Pressure(millibars * PascalPerBar / 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Pressure object interpreting passed value as Pascal
|
||||
/// </summary>
|
||||
/// <param name="Pressure">Pascal</param>
|
||||
/// <returns></returns>
|
||||
public static Pressure FromPascal(double pascal)
|
||||
{
|
||||
return new Pressure(pascal);
|
||||
}
|
||||
|
||||
public static Pressure FromPSI(double psi)
|
||||
{
|
||||
return new Pressure(psi * PascalPerPSI);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Pressure pressure = obj as Pressure;
|
||||
|
||||
return (pressure == null) ? false : (this._pressure == pressure._pressure);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _pressure.GetHashCode();
|
||||
}
|
||||
|
||||
#region Binary Operators
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static Pressure operator +(Pressure left, Pressure right)
|
||||
{
|
||||
if (null == left)
|
||||
{
|
||||
throw new ArgumentNullException("left", "Cannot add a null Pressure");
|
||||
}
|
||||
|
||||
if (null == right)
|
||||
{
|
||||
throw new ArgumentNullException("right", "Cannot add null Pressure");
|
||||
}
|
||||
|
||||
return new Pressure(left._pressure + right._pressure);
|
||||
}
|
||||
|
||||
|
||||
public static Pressure operator -(Pressure left, Pressure right)
|
||||
{
|
||||
if (null == left)
|
||||
{
|
||||
throw new ArgumentNullException("left", "Cannot add a null Pressure");
|
||||
}
|
||||
|
||||
if (null == right)
|
||||
{
|
||||
throw new ArgumentNullException("right", "Cannot add null Pressure");
|
||||
}
|
||||
|
||||
return new Pressure(left._pressure - right._pressure);
|
||||
}
|
||||
|
||||
|
||||
public static Pressure operator *(Pressure pressure, double scalar)
|
||||
{
|
||||
if (null == pressure)
|
||||
{
|
||||
throw new ArgumentNullException("pressure", "Cannot multiply a null Pressure");
|
||||
}
|
||||
|
||||
return new Pressure(pressure._pressure * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static Pressure operator *(double scalar, Pressure pressure)
|
||||
{
|
||||
if (null == pressure)
|
||||
{
|
||||
throw new ArgumentNullException("pressure", "Cannot multiply a null Pressure");
|
||||
}
|
||||
|
||||
return new Pressure(scalar * pressure._pressure);
|
||||
}
|
||||
|
||||
|
||||
public static Pressure operator /(Pressure pressure, double scalar)
|
||||
{
|
||||
if (null == pressure)
|
||||
{
|
||||
throw new ArgumentNullException("pressure", "Cannot divide a null Pressure");
|
||||
}
|
||||
|
||||
if (0.0 == scalar)
|
||||
{
|
||||
throw new DivideByZeroException("Cannot divide Pressure by 0");
|
||||
}
|
||||
|
||||
return new Pressure(pressure._pressure / scalar);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
public static bool operator ==(Pressure left, Pressure right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._pressure == right._pressure;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Pressure left, Pressure right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(Pressure left, Pressure right)
|
||||
{
|
||||
if (null == left)
|
||||
{
|
||||
throw new ArgumentNullException("left", "Cannot compare null Pressure");
|
||||
}
|
||||
|
||||
if (null == right)
|
||||
{
|
||||
throw new ArgumentNullException("right", "Cannot compare null Pressure");
|
||||
}
|
||||
|
||||
return (left._pressure < right._pressure);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(Pressure left, Pressure right)
|
||||
{
|
||||
if (null == left)
|
||||
{
|
||||
throw new ArgumentNullException("left", "Cannot compare null Pressure");
|
||||
}
|
||||
|
||||
if (null == right)
|
||||
{
|
||||
throw new ArgumentNullException("right", "Cannot compare null Pressure");
|
||||
}
|
||||
|
||||
return (left._pressure > right._pressure);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(Pressure left, Pressure right)
|
||||
{
|
||||
if (null == left)
|
||||
{
|
||||
throw new ArgumentNullException("left", "Cannot compare null Pressure");
|
||||
}
|
||||
|
||||
if (null == right)
|
||||
{
|
||||
throw new ArgumentNullException("right", "Cannot compare null Pressure");
|
||||
}
|
||||
|
||||
return (left._pressure <= right._pressure);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(Pressure left, Pressure right)
|
||||
{
|
||||
if (null == left)
|
||||
{
|
||||
throw new ArgumentNullException("left", "Cannot compare null Pressure");
|
||||
}
|
||||
|
||||
if (null == right)
|
||||
{
|
||||
throw new ArgumentNullException("right", "Cannot compare null Pressure");
|
||||
}
|
||||
|
||||
return (left._pressure >= right._pressure);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Pressure Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Pressure value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Pressure.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
369
Source/TSRealLib/Common/Raytheon.Common/Units/Resistance.cs
Normal file
369
Source/TSRealLib/Common/Raytheon.Common/Units/Resistance.cs
Normal file
@@ -0,0 +1,369 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents electrical resistance.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. FromOhms).
|
||||
///
|
||||
/// Properties (e.g. KiloOhms) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
///
|
||||
/// Methods (operator overloads) are provided to perform calculations with related types (e.g.
|
||||
/// Current, Voltage).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Resistance
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
Ohms,
|
||||
KiloOhms,
|
||||
MegaOhms
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.Ohms, new List<string>(){ "Ohm" } },
|
||||
{Unit.KiloOhms, new List<string>(){ "kOhm" } },
|
||||
{Unit.MegaOhms, new List<string>(){ "MOhm" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.Ohms;
|
||||
private const int KiloOhmsPerOhm = 1000;
|
||||
private const int MegaOhmsPerOhm = 1000000;
|
||||
|
||||
[DataMember(Name = "Resistance", IsRequired = true)]
|
||||
private double _resistance; // ohms
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<Resistance>> _unitInfo = new Dictionary<Unit, UnitInfo<Resistance>>()
|
||||
{
|
||||
{ Unit.Ohms, new UnitInfo<Resistance>(UnitAbbreviations[Unit.Ohms], FromOhms, typeof(Resistance).GetProperty("Ohms").GetGetMethod()) },
|
||||
{ Unit.KiloOhms, new UnitInfo<Resistance>(UnitAbbreviations[Unit.KiloOhms], FromKiloOhms, typeof(Resistance).GetProperty("KiloOhms").GetGetMethod()) },
|
||||
{ Unit.MegaOhms, new UnitInfo<Resistance>(UnitAbbreviations[Unit.MegaOhms], FromMegaOhms, typeof(Resistance).GetProperty("MegaOhms").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="Resistance"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private Resistance()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="resistance">The resistance - ohms</param>
|
||||
private Resistance(double resistance)
|
||||
{
|
||||
_resistance = resistance;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
/// <summary>
|
||||
/// Returns ohms as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// ohms
|
||||
/// </value>
|
||||
public double Ohms
|
||||
{
|
||||
get { return _resistance; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns kiloohms as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// kiloohms
|
||||
/// </value>
|
||||
public double KiloOhms
|
||||
{
|
||||
get { return _resistance / KiloOhmsPerOhm; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns megaohms as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// megaohms
|
||||
/// </value>
|
||||
public double MegaOhms
|
||||
{
|
||||
get { return _resistance / MegaOhmsPerOhm; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns Resistance object interpreting passed value as kiloohms
|
||||
/// </summary>
|
||||
/// <param name="kiloohms">kiloohms</param>
|
||||
/// <returns></returns>
|
||||
public static Resistance FromKiloOhms(double kiloOhms)
|
||||
{
|
||||
return new Resistance(kiloOhms * KiloOhmsPerOhm);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Resistance object interpreting passed value as megaohms
|
||||
/// </summary>
|
||||
/// <param name="megaohms">megaohms</param>
|
||||
/// <returns></returns>
|
||||
public static Resistance FromMegaOhms(double megaOhms)
|
||||
{
|
||||
return new Resistance(megaOhms * MegaOhmsPerOhm);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Resistance object interpreting passed value as ohms
|
||||
/// </summary>
|
||||
/// <param name="ohms">ohms</param>
|
||||
/// <returns></returns>
|
||||
public static Resistance FromOhms(double ohms)
|
||||
{
|
||||
return new Resistance(ohms);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Resistance r = obj as Resistance;
|
||||
|
||||
return (r == null) ? false : (this._resistance == r._resistance);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _resistance.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static Resistance operator +(Resistance left, Resistance right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Resistance");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Resistance");
|
||||
|
||||
return new Resistance(left._resistance + right._resistance);
|
||||
}
|
||||
|
||||
|
||||
public static Resistance operator -(Resistance left, Resistance right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null Resistance");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null Resistance");
|
||||
|
||||
return new Resistance(left._resistance - right._resistance);
|
||||
}
|
||||
|
||||
|
||||
public static Resistance operator *(Resistance resistance, double scalar)
|
||||
{
|
||||
if (null == resistance)
|
||||
throw new ArgumentNullException("resistance", "Cannot multiply a null Resistance");
|
||||
|
||||
return new Resistance(resistance._resistance * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static Resistance operator *(double scalar, Resistance resistance)
|
||||
{
|
||||
if (null == resistance)
|
||||
throw new ArgumentNullException("resistance", "Cannot multiply a null Resistance");
|
||||
|
||||
return new Resistance(scalar * resistance._resistance);
|
||||
}
|
||||
|
||||
|
||||
public static Resistance operator /(Resistance resistance, double scalar)
|
||||
{
|
||||
if (null == resistance)
|
||||
throw new ArgumentNullException("resistance", "Cannot divide a null Resistance");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Resistance by 0");
|
||||
|
||||
return new Resistance(resistance._resistance / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(Resistance left, Resistance right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._resistance == right._resistance;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Resistance left, Resistance right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(Resistance left, Resistance right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Resistance");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Resistance");
|
||||
|
||||
return (left._resistance < right._resistance);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(Resistance left, Resistance right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Resistance");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Resistance");
|
||||
|
||||
return (left._resistance > right._resistance);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(Resistance left, Resistance right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Resistance");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Resistance");
|
||||
|
||||
return (left._resistance <= right._resistance);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(Resistance left, Resistance right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Resistance");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Resistance");
|
||||
|
||||
return (left._resistance >= right._resistance);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with non-resistance classes
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for Voltage = Resistance / Current
|
||||
/// </summary>
|
||||
/// <param name="resistance">The resistance.</param>
|
||||
/// <param name="current">The current.</param>
|
||||
/// <returns>
|
||||
/// Voltage
|
||||
/// </returns>
|
||||
|
||||
public static Voltage operator *(Resistance resistance, Current current)
|
||||
{
|
||||
if (null == resistance)
|
||||
throw new ArgumentNullException("resistance", "Cannot divide a null Resistance");
|
||||
|
||||
if (null == current)
|
||||
throw new ArgumentNullException("current", "Cannot divide by a null Current");
|
||||
|
||||
if (0.0 == current.Amps)
|
||||
throw new DivideByZeroException("Cannot divide Resistance by 0 Current");
|
||||
|
||||
return Voltage.FromVolts(resistance.Ohms * current.Amps);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Resistance Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Resistance value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Resistance.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
325
Source/TSRealLib/Common/Raytheon.Common/Units/Temperature.cs
Normal file
325
Source/TSRealLib/Common/Raytheon.Common/Units/Temperature.cs
Normal file
@@ -0,0 +1,325 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Temperature
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
DegreesC,
|
||||
DegreesF,
|
||||
DegreesK
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.DegreesC, new List<string>(){ "C" } },
|
||||
{Unit.DegreesF, new List<string>(){ "F" } },
|
||||
{Unit.DegreesK, new List<string>(){ "K" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.DegreesC;
|
||||
private const double CdegreesPerFdegree = 5.0 / 9.0;
|
||||
private const double CtoF_Offset = 32.0;
|
||||
private const double KtoC_Offset = 273.15;
|
||||
|
||||
[DataMember(Name = "Temperature", IsRequired = true)]
|
||||
private double _temperature; // degrees C
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<Temperature>> _unitInfo = new Dictionary<Unit, UnitInfo<Temperature>>()
|
||||
{
|
||||
{ Unit.DegreesC, new UnitInfo<Temperature>(UnitAbbreviations[Unit.DegreesC], FromDegreesC, typeof(Temperature).GetProperty("DegreesC").GetGetMethod()) },
|
||||
{ Unit.DegreesF, new UnitInfo<Temperature>(UnitAbbreviations[Unit.DegreesF], FromDegreesF, typeof(Temperature).GetProperty("DegreesF").GetGetMethod()) },
|
||||
{ Unit.DegreesK, new UnitInfo<Temperature>(UnitAbbreviations[Unit.DegreesK], FromDegreesK, typeof(Temperature).GetProperty("DegreesK").GetGetMethod()) }
|
||||
};
|
||||
|
||||
private Temperature()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
private Temperature(double temperature)
|
||||
{
|
||||
_temperature = temperature;
|
||||
}
|
||||
|
||||
#region output properties
|
||||
|
||||
public double DegreesC
|
||||
{
|
||||
get
|
||||
{
|
||||
return _temperature;
|
||||
}
|
||||
}
|
||||
|
||||
public double DegreesF
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_temperature / CdegreesPerFdegree) + CtoF_Offset;
|
||||
}
|
||||
}
|
||||
|
||||
public double DegreesK
|
||||
{
|
||||
get
|
||||
{
|
||||
return DegreesC + KtoC_Offset;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
public static Temperature FromDegreesC(double temperature)
|
||||
{
|
||||
return new Temperature(temperature);
|
||||
}
|
||||
|
||||
public static Temperature FromDegreesF(double temperature)
|
||||
{
|
||||
return new Temperature((temperature - CtoF_Offset) * CdegreesPerFdegree);
|
||||
}
|
||||
|
||||
public static Temperature FromDegreesK(double temperature)
|
||||
{
|
||||
return FromDegreesC(temperature - KtoC_Offset);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region add delta methods
|
||||
|
||||
public void Add(TemperatureDelta delta)
|
||||
{
|
||||
if (delta == null)
|
||||
{
|
||||
throw new ArgumentNullException("delta");
|
||||
}
|
||||
|
||||
_temperature += delta.DegreesC;
|
||||
}
|
||||
|
||||
public void AddDegreesC(double delta)
|
||||
{
|
||||
_temperature += TemperatureDelta.FromDegreesC(delta).DegreesC;
|
||||
}
|
||||
|
||||
public void AddDegreesF(double delta)
|
||||
{
|
||||
_temperature += TemperatureDelta.FromDegreesF(delta).DegreesC;
|
||||
}
|
||||
|
||||
public void AddDegreesK(double delta)
|
||||
{
|
||||
_temperature += TemperatureDelta.FromDegreesK(delta).DegreesC;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region binary operators
|
||||
|
||||
|
||||
public static Temperature operator +(Temperature left, TemperatureDelta right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Temperature");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null TemperatureDelta");
|
||||
|
||||
return new Temperature(left.DegreesC + right.DegreesC);
|
||||
}
|
||||
|
||||
|
||||
public static Temperature operator +(TemperatureDelta left, Temperature right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null TemperatureDelta");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Temperature");
|
||||
|
||||
return new Temperature(left.DegreesC + right.DegreesC);
|
||||
}
|
||||
|
||||
|
||||
public static TemperatureDelta operator -(Temperature left, Temperature right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Temperature");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Temperature");
|
||||
|
||||
return TemperatureDelta.FromDegreesC(left.DegreesC - right.DegreesC);
|
||||
}
|
||||
|
||||
|
||||
public static Temperature operator -(Temperature left, TemperatureDelta right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Temperature");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null TemperatureDelta");
|
||||
|
||||
return Temperature.FromDegreesC(left.DegreesC - right.DegreesC);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(Temperature left, Temperature right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._temperature == right._temperature;
|
||||
}
|
||||
}
|
||||
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Temperature left, Temperature right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(Temperature left, Temperature right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Temperature");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Temperature");
|
||||
|
||||
return (left._temperature < right._temperature);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(Temperature left, Temperature right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Temperature");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Temperature");
|
||||
|
||||
return (left._temperature > right._temperature);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(Temperature left, Temperature right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Temperature");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Temperature");
|
||||
|
||||
return (left._temperature <= right._temperature);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(Temperature left, Temperature right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Temperature");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Temperature");
|
||||
|
||||
return (left._temperature >= right._temperature);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Temperature Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Temperature value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Temperature.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Object overrides
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Temperature t = obj as Temperature;
|
||||
|
||||
return (t == null) ? false : (this._temperature == t._temperature);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _temperature.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class TemperatureDelta
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
DegreesC,
|
||||
DegreesF,
|
||||
DegreesK
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.DegreesC, new List<string>(){ "C" } },
|
||||
{Unit.DegreesF, new List<string>(){ "F" } },
|
||||
{Unit.DegreesK, new List<string>(){ "K" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.DegreesC;
|
||||
private const double CdegreesPerFdegree = 5.0 / 9.0;
|
||||
|
||||
[DataMember(Name = "Delta", IsRequired = true)]
|
||||
private double _delta; // degrees C or K
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<TemperatureDelta>> _unitInfo = new Dictionary<Unit, UnitInfo<TemperatureDelta>>()
|
||||
{
|
||||
{ Unit.DegreesC, new UnitInfo<TemperatureDelta>(UnitAbbreviations[Unit.DegreesC], FromDegreesC, typeof(TemperatureDelta).GetProperty("DegreesC").GetGetMethod()) },
|
||||
{ Unit.DegreesF, new UnitInfo<TemperatureDelta>(UnitAbbreviations[Unit.DegreesF], FromDegreesF, typeof(TemperatureDelta).GetProperty("DegreesF").GetGetMethod()) },
|
||||
{ Unit.DegreesK, new UnitInfo<TemperatureDelta>(UnitAbbreviations[Unit.DegreesK], FromDegreesK, typeof(TemperatureDelta).GetProperty("DegreesK").GetGetMethod()) }
|
||||
};
|
||||
|
||||
private TemperatureDelta()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
private TemperatureDelta(double delta)
|
||||
{
|
||||
_delta = delta;
|
||||
}
|
||||
|
||||
#region output properties
|
||||
|
||||
public double DegreesC
|
||||
{
|
||||
get
|
||||
{
|
||||
return _delta;
|
||||
}
|
||||
}
|
||||
|
||||
public double DegreesF
|
||||
{
|
||||
get
|
||||
{
|
||||
return _delta / CdegreesPerFdegree;
|
||||
}
|
||||
}
|
||||
|
||||
public double DegreesK
|
||||
{
|
||||
get
|
||||
{
|
||||
return _delta;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
public static TemperatureDelta FromDegreesC(double temperature)
|
||||
{
|
||||
return new TemperatureDelta(temperature);
|
||||
}
|
||||
|
||||
public static TemperatureDelta FromDegreesF(double temperature)
|
||||
{
|
||||
return new TemperatureDelta(temperature * CdegreesPerFdegree);
|
||||
}
|
||||
|
||||
public static TemperatureDelta FromDegreesK(double temperature)
|
||||
{
|
||||
return new TemperatureDelta(temperature);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// binary operators are in Temperature class
|
||||
|
||||
#region comparison operators
|
||||
|
||||
|
||||
public static bool operator <(TemperatureDelta left, TemperatureDelta right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null TemperatureDelta");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null TemperatureDelta");
|
||||
|
||||
return (left._delta < right._delta);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(TemperatureDelta left, TemperatureDelta right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null TemperatureDelta");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null TemperatureDelta");
|
||||
|
||||
return (left._delta > right._delta);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(TemperatureDelta left, TemperatureDelta right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null TemperatureDelta");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null TemperatureDelta");
|
||||
|
||||
return (left._delta <= right._delta);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(TemperatureDelta left, TemperatureDelta right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null TemperatureDelta");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null TemperatureDelta");
|
||||
|
||||
return (left._delta >= right._delta);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static TemperatureDelta Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out TemperatureDelta value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = TemperatureDelta.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Object overrides
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
TemperatureDelta d = obj as TemperatureDelta;
|
||||
|
||||
return (d == null) ? false : (this._delta == d._delta);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _delta.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
409
Source/TSRealLib/Common/Raytheon.Common/Units/Velocity.cs
Normal file
409
Source/TSRealLib/Common/Raytheon.Common/Units/Velocity.cs
Normal file
@@ -0,0 +1,409 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a velocity.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. FromMetersPerSec).
|
||||
///
|
||||
/// Properties (e.g. FeetPerSec) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
///
|
||||
/// Methods (operator overloads) are provided to perform calculations with related types (e.g.
|
||||
/// Acceleration, Length).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Velocity
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
FeetPerSecond,
|
||||
MetersPerSecond,
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.FeetPerSecond, new List<string>(){ "ft/sec" } },
|
||||
{Unit.MetersPerSecond, new List<string>(){ "m/sec" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.MetersPerSecond;
|
||||
private const double FeetPerMeter = 3.280839895013123;
|
||||
|
||||
[DataMember(Name = "Velocity", IsRequired = true)]
|
||||
private double _velocity; // meters/second
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<Velocity>> _unitInfo = new Dictionary<Unit, UnitInfo<Velocity>>()
|
||||
{
|
||||
{ Unit.FeetPerSecond, new UnitInfo<Velocity>(UnitAbbreviations[Unit.FeetPerSecond], FromFeetPerSec, typeof(Velocity).GetProperty("FeetPerSec").GetGetMethod()) },
|
||||
{ Unit.MetersPerSecond, new UnitInfo<Velocity>(UnitAbbreviations[Unit.MetersPerSecond], FromMetersPerSec, typeof(Velocity).GetProperty("MetersPerSec").GetGetMethod()) },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="Velocity"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private Velocity()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="velocity">The velocity - m/sec.</param>
|
||||
private Velocity(double velocity)
|
||||
{
|
||||
_velocity = velocity;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
/// <summary>
|
||||
/// Returns feet/sec as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// feet/sec
|
||||
/// </value>
|
||||
public double FeetPerSec
|
||||
{
|
||||
get { return _velocity * FeetPerMeter; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns meters/sec as type double
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// meters/sec
|
||||
/// </value>
|
||||
public double MetersPerSec
|
||||
{
|
||||
get { return _velocity; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns Velocity object interpreting passed value as ft/sec
|
||||
/// </summary>
|
||||
/// <param name="feetPerSec">ft/sec</param>
|
||||
/// <returns></returns>
|
||||
public static Velocity FromFeetPerSec(double feetPerSec)
|
||||
{
|
||||
return new Velocity(feetPerSec / FeetPerMeter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Velocity object interpreting passed value as meters/sec
|
||||
/// </summary>
|
||||
/// <param name="metersPerSec">meters/sec</param>
|
||||
/// <returns></returns>
|
||||
public static Velocity FromMetersPerSec(double metersPerSec)
|
||||
{
|
||||
return new Velocity(metersPerSec);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Velocity v = obj as Velocity;
|
||||
|
||||
return (v == null) ? false : (this._velocity == v._velocity);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _velocity.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static Velocity operator +(Velocity left, Velocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Velocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Velocity");
|
||||
|
||||
return new Velocity(left._velocity + right._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static Velocity operator -(Velocity left, Velocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null Velocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null Velocity");
|
||||
|
||||
return new Velocity(left._velocity - right._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static Velocity operator *(Velocity velocity, double scalar)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot multiply a null Velocity");
|
||||
|
||||
return new Velocity(velocity._velocity * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static Velocity operator *(double scalar, Velocity velocity)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot multiply a null Velocity");
|
||||
|
||||
return new Velocity(scalar * velocity._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static Velocity operator /(Velocity velocity, double scalar)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot divide a null Velocity");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Velocity by 0");
|
||||
|
||||
return new Velocity(velocity._velocity / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(Velocity left, Velocity right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._velocity == right._velocity;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Velocity left, Velocity right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(Velocity left, Velocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Velocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Velocity");
|
||||
|
||||
return (left._velocity < right._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(Velocity left, Velocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Velocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Velocity");
|
||||
|
||||
return (left._velocity > right._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(Velocity left, Velocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Velocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Velocity");
|
||||
|
||||
return (left._velocity <= right._velocity);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(Velocity left, Velocity right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Velocity");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Velocity");
|
||||
|
||||
return (left._velocity >= right._velocity);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with other classes
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for Length = Velocity * PrecisionTimeSpan
|
||||
/// </summary>
|
||||
/// <param name="velocity">The velocity.</param>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <returns>
|
||||
/// Length
|
||||
/// </returns>
|
||||
|
||||
public static Length operator *(Velocity velocity, PrecisionTimeSpan time)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot multiply a null Velocity");
|
||||
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot multiply a null PrecisionTimeSpan");
|
||||
|
||||
return Length.FromMeters(velocity.MetersPerSec * time.Seconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for Length = PrecisionTimeSpan * Velocity
|
||||
/// </summary>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <param name="velocity">The velocity.</param>
|
||||
/// <returns>
|
||||
/// Length
|
||||
/// </returns>
|
||||
|
||||
public static Length operator *(PrecisionTimeSpan time, Velocity velocity)
|
||||
{
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot divide a null PrecisionTimeSpan");
|
||||
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot divide by a null Velocity");
|
||||
|
||||
if (0.0 == velocity.MetersPerSec)
|
||||
throw new DivideByZeroException("Cannot divide Time Span by 0 Velocity");
|
||||
|
||||
return Length.FromMeters(time.Seconds * velocity.MetersPerSec);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for Acceleration = Velocity / PrecisionTimeSpan
|
||||
/// </summary>
|
||||
/// <param name="velocity">The velocity.</param>
|
||||
/// <param name="time">The time.</param>
|
||||
/// <returns>
|
||||
/// Acceleration
|
||||
/// </returns>
|
||||
|
||||
public static Acceleration operator /(Velocity velocity, PrecisionTimeSpan time)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot divide a null Velocity");
|
||||
|
||||
if (null == time)
|
||||
throw new ArgumentNullException("time", "Cannot divide by a null PrecisionTimeSpan");
|
||||
|
||||
if (0.0 == time.Milliseconds)
|
||||
throw new DivideByZeroException("Cannot divide Velocity by 0 Time Span");
|
||||
|
||||
return Acceleration.FromMetersPerSecSqrd(velocity.MetersPerSec / time.Seconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for PrecisionTimeSpan = Velocity / Acceleration
|
||||
/// </summary>
|
||||
/// <param name="velocity">The velocity.</param>
|
||||
/// <param name="time">The acceleration.</param>
|
||||
/// <returns>
|
||||
/// PrecisionTimeSpan
|
||||
/// </returns>
|
||||
|
||||
public static PrecisionTimeSpan operator /(Velocity velocity, Acceleration acceleration)
|
||||
{
|
||||
if (null == velocity)
|
||||
throw new ArgumentNullException("velocity", "Cannot divide a null Velocity");
|
||||
|
||||
if (null == acceleration)
|
||||
throw new ArgumentNullException("acceleration", "Cannot divide by a null Acceleration");
|
||||
|
||||
if (0.0 == acceleration.MetersPerSecSqrd)
|
||||
throw new DivideByZeroException("Cannot divide Velocity by 0 Acceleration");
|
||||
|
||||
return PrecisionTimeSpan.FromSeconds(velocity.MetersPerSec / acceleration.MetersPerSecSqrd);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Velocity Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Velocity value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Velocity.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
356
Source/TSRealLib/Common/Raytheon.Common/Units/Voltage.cs
Normal file
356
Source/TSRealLib/Common/Raytheon.Common/Units/Voltage.cs
Normal file
@@ -0,0 +1,356 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Raytheon.Units
|
||||
{
|
||||
/// <summary>
|
||||
/// This class represents a voltage.
|
||||
///
|
||||
/// It has no constructors. Instead, it provides multiple methods for creating objects of this
|
||||
/// type. Those methods are of the form FromXXX, where XXX is a unit (e.g. FromVolts).
|
||||
///
|
||||
/// Properties (e.g. Volts) are provided to convert the value to other units and return
|
||||
/// as type double.
|
||||
///
|
||||
/// Methods (operator overloads) are provided to perform calculations with related types (e.g.
|
||||
/// Current, Resistance).
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract]
|
||||
public class Voltage
|
||||
{
|
||||
public enum Unit
|
||||
{
|
||||
Volts,
|
||||
Millivolts
|
||||
}
|
||||
|
||||
public static IDictionary<Unit, List<string>> UnitAbbreviations = new Dictionary<Unit, List<string>>()
|
||||
{
|
||||
{Unit.Volts, new List<string>(){ "V" } },
|
||||
{Unit.Millivolts, new List<string>(){ "mV" } },
|
||||
};
|
||||
|
||||
private const Unit DefaultUnits = Unit.Volts;
|
||||
|
||||
[DataMember(Name = "Voltage", IsRequired = true)]
|
||||
private double _voltage; // volts
|
||||
|
||||
// map: unit => abbreviation, conversion method and property
|
||||
private static IDictionary<Unit, UnitInfo<Voltage>> _unitInfo = new Dictionary<Unit, UnitInfo<Voltage>>()
|
||||
{
|
||||
{ Unit.Volts, new UnitInfo<Voltage>(UnitAbbreviations[Unit.Volts], FromVolts, typeof(Voltage).GetProperty("Volts").GetGetMethod()) },
|
||||
{ Unit.Millivolts, new UnitInfo<Voltage>(UnitAbbreviations[Unit.Millivolts], FromMillivolts, typeof(Voltage).GetProperty("Millivolts").GetGetMethod()) }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Prevents a default instance of the <see cref="Voltage"/> class from being created.
|
||||
/// Use FromXXX methods to create objects of this type.
|
||||
/// </summary>
|
||||
/// <exception cref="System.Exception">No one should be calling this, it is only here to prevent users from creating default object</exception>
|
||||
private Voltage()
|
||||
{
|
||||
throw new InvalidOperationException("No one should be calling this, it is only here to prevent users from creating default object");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ctor used by this class to create objects in FromXXX methods
|
||||
/// </summary>
|
||||
/// <param name="voltage">The voltage - volts.</param>
|
||||
private Voltage(double voltage)
|
||||
{
|
||||
_voltage = voltage;
|
||||
}
|
||||
|
||||
#region conversion properties
|
||||
|
||||
public double Volts
|
||||
{
|
||||
get { return _voltage; }
|
||||
}
|
||||
|
||||
|
||||
public double Millivolts
|
||||
{
|
||||
get { return _voltage * 1000; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns Voltage object interpreting passed value as volts
|
||||
/// </summary>
|
||||
/// <param name="volts">volts</param>
|
||||
/// <returns></returns>
|
||||
public static Voltage FromVolts(double volts)
|
||||
{
|
||||
return new Voltage(volts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Voltage object interpreting passed value as millivolts
|
||||
/// </summary>
|
||||
/// <param name="millivolts">millivolts</param>
|
||||
/// <returns></returns>
|
||||
|
||||
|
||||
public static Voltage FromMillivolts(double millivolts)
|
||||
{
|
||||
return new Voltage(millivolts / 1000);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Voltage v = obj as Voltage;
|
||||
|
||||
return (v == null) ? false : (this._voltage == v._voltage);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _voltage.GetHashCode();
|
||||
}
|
||||
|
||||
#region binary operators
|
||||
|
||||
// not implementing %, &, |, ^, <<, >>
|
||||
|
||||
|
||||
public static Voltage operator +(Voltage left, Voltage right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot add a null Voltage");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot add null Voltage");
|
||||
|
||||
return new Voltage(left._voltage + right._voltage);
|
||||
}
|
||||
|
||||
|
||||
public static Voltage operator -(Voltage left, Voltage right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot subtract a null Voltage");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot subtract a null Voltage");
|
||||
|
||||
return new Voltage(left._voltage - right._voltage);
|
||||
}
|
||||
|
||||
|
||||
public static Voltage operator *(Voltage voltage, double scalar)
|
||||
{
|
||||
if (null == voltage)
|
||||
throw new ArgumentNullException("voltage", "Cannot multiply a null Voltage");
|
||||
|
||||
return new Voltage(voltage._voltage * scalar);
|
||||
}
|
||||
|
||||
|
||||
public static Voltage operator *(double scalar, Voltage voltage)
|
||||
{
|
||||
if (null == voltage)
|
||||
throw new ArgumentNullException("voltage", "Cannot multiply a null Voltage");
|
||||
|
||||
return new Voltage(scalar * voltage._voltage);
|
||||
}
|
||||
|
||||
|
||||
public static Voltage operator /(Voltage voltage, double scalar)
|
||||
{
|
||||
if (null == voltage)
|
||||
throw new ArgumentNullException("voltage", "Cannot divide a null Voltage");
|
||||
|
||||
if (0.0 == scalar)
|
||||
throw new DivideByZeroException("Cannot divide Voltage by 0");
|
||||
|
||||
return new Voltage(voltage._voltage / scalar);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region comparison operators
|
||||
|
||||
public static bool operator ==(Voltage left, Voltage right)
|
||||
{
|
||||
bool bReturn = false;
|
||||
if (object.ReferenceEquals(left, null))
|
||||
{
|
||||
if (object.ReferenceEquals(right, null))
|
||||
{
|
||||
//both are null, so we are ==
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!object.ReferenceEquals(left, null) &&
|
||||
!object.ReferenceEquals(right, null))
|
||||
{
|
||||
bReturn = left._voltage == right._voltage;
|
||||
}
|
||||
}
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
public static bool operator !=(Voltage left, Voltage right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <(Voltage left, Voltage right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Voltage");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Voltage");
|
||||
|
||||
return (left._voltage < right._voltage);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >(Voltage left, Voltage right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Voltage");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Voltage");
|
||||
|
||||
return (left._voltage > right._voltage);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator <=(Voltage left, Voltage right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Voltage");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Voltage");
|
||||
|
||||
return (left._voltage <= right._voltage);
|
||||
}
|
||||
|
||||
|
||||
public static bool operator >=(Voltage left, Voltage right)
|
||||
{
|
||||
if (null == left)
|
||||
throw new ArgumentNullException("left", "Cannot compare null Voltage");
|
||||
|
||||
if (null == right)
|
||||
throw new ArgumentNullException("right", "Cannot compare null Voltage");
|
||||
|
||||
return (left._voltage >= right._voltage);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region operators with non-Voltage classes
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for Current = Voltage / Resistance
|
||||
/// </summary>
|
||||
/// <param name="voltage">The voltage.</param>
|
||||
/// <param name="time">The resistance.</param>
|
||||
/// <returns>
|
||||
/// Current
|
||||
/// </returns>
|
||||
|
||||
public static Current operator /(Voltage voltage, Resistance resistance)
|
||||
{
|
||||
if (null == voltage)
|
||||
throw new ArgumentNullException("voltage", "Cannot divide a null Voltage");
|
||||
|
||||
if (null == resistance)
|
||||
throw new ArgumentNullException("resistance", "Cannot divide by a null Resistance");
|
||||
|
||||
if (0.0 == resistance.Ohms)
|
||||
throw new DivideByZeroException("Cannot divide Voltage by 0 Resistance");
|
||||
|
||||
return Current.FromAmps(voltage.Volts / resistance.Ohms);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator * for Resistance = Voltage / Current
|
||||
/// </summary>
|
||||
/// <param name="voltage">The voltage.</param>
|
||||
/// <param name="time">The current.</param>
|
||||
/// <returns>
|
||||
/// Resistance
|
||||
/// </returns>
|
||||
|
||||
public static Resistance operator /(Voltage voltage, Current current)
|
||||
{
|
||||
if (null == voltage)
|
||||
throw new ArgumentNullException("voltage", "Cannot divide a null Voltage");
|
||||
|
||||
if (null == current)
|
||||
throw new ArgumentNullException("current", "Cannot divide by a null Current");
|
||||
|
||||
if (0.0 == current.Amps)
|
||||
throw new DivideByZeroException("Cannot divide Voltage by 0 Current");
|
||||
|
||||
return Resistance.FromOhms(voltage.Volts / current.Amps);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region parsing
|
||||
|
||||
public static Voltage Parse(string s)
|
||||
{
|
||||
return Common.Parse(s, _unitInfo);
|
||||
}
|
||||
|
||||
public static bool TryParse(string s, out Voltage value)
|
||||
{
|
||||
try
|
||||
{
|
||||
value = Voltage.Parse(s);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string appended with default units (e.g. "1.23 m/sec^2").
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents this instance
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultUnits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// overload that returns a string appended with specified units (e.g. "1.23 ft/sec^2").
|
||||
/// </summary>
|
||||
/// <param name="units"></param>
|
||||
/// <returns></returns>
|
||||
public string ToString(Unit units)
|
||||
{
|
||||
double value = (double)_unitInfo[units].PropertyGetter.Invoke(this, null);
|
||||
|
||||
return $"{value} {_unitInfo[units].Abbreviation[0]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<AssemblyName>Raytheon.Instruments.Implementation</AssemblyName>
|
||||
<Product>Implementation Master</Product>
|
||||
<Description>Packages all instrument implementation assemlbies into one package</Description>
|
||||
|
||||
<!-- Dynamic Versioning (Suitable for Release) -->
|
||||
<!-- <Version>$(Version)$(Suffix)</Version> -->
|
||||
|
||||
<!-- Static Versioning (Suitable for Development) -->
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<NoWarn>NU1603</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Add extra dependencies to the nuget package -->
|
||||
<Target Name="AddDependenciesToPackage" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<Content Include="$(HalTempFolder)\*">
|
||||
<Pack>true</Pack>
|
||||
<PackagePath>lib\$(TargetFramework)</PackagePath>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="DeleteHalTempFolder" AfterTargets="Pack">
|
||||
<RemoveDir Directories="$(HalTempFolder)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,6 @@
|
||||
This implementation master project will create a nuget package that includes all the assemblies of all the instrument implementations.
|
||||
So by including this package, one has access to all assemblies of all instrument implementations. No need to include individual package of each instrument implementation.
|
||||
|
||||
When creating a new implementation for an instrument, make sure that this project depends on that new project so that it builds before this project builds by going to the project dependencies and select all the Implementations that this project depends on.
|
||||
|
||||
No need to depend on Sim instrument. Since each instrument implementation must reference the appropriate Sim instrument.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,143 @@
|
||||
// **********************************************************************************************************
|
||||
// BITCOEDeviceInstrumentFactory.cs
|
||||
// 6/21/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using NLog;
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
[ExportInstrumentFactory(ModelNumber = "BITCOEDeviceInstrumentFactory")]
|
||||
public class BITCOEDeviceInstrumentFactory : IInstrumentFactory
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private ILogger _logger;
|
||||
/// <summary>
|
||||
/// The supported interfaces
|
||||
/// </summary>
|
||||
private readonly List<Type> _supportedInterfaces = new List<Type>();
|
||||
private readonly IConfigurationManager _configurationManager;
|
||||
private const string DefaultConfigPath = @"C:\ProgramData\Raytheon\InstrumentManagerService";
|
||||
private static string DefaultPath;
|
||||
private readonly DriverType _driverType;
|
||||
|
||||
public BITCOEDeviceInstrumentFactory(string defaultConfigPath = DefaultConfigPath)
|
||||
: this(null, defaultConfigPath)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// COECommDeviceInstrumentFactory injection constructor
|
||||
/// </summary>
|
||||
/// <param name="configManager"></param>
|
||||
/// <param name="simEngine"></param>
|
||||
/// <param name="logger"></param>
|
||||
[ImportingConstructor]
|
||||
public BITCOEDeviceInstrumentFactory([Import(AllowDefault = false)] IConfigurationManager configManager,
|
||||
[Import(AllowDefault = true)] string defaultConfigPath = null,
|
||||
[Import(AllowDefault = true)] DriverType driverType = DriverType.TCP)
|
||||
{
|
||||
DefaultPath = defaultConfigPath;
|
||||
|
||||
if (LogManager.Configuration == null)
|
||||
{
|
||||
var assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(assemblyFolder + "\\nlog.config");
|
||||
}
|
||||
|
||||
_configurationManager = configManager ?? GetConfigurationManager();
|
||||
_driverType = driverType;
|
||||
_supportedInterfaces.Add(typeof(IBit));
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public IInstrument GetInstrument(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
return new BITCOEDeviceInstrument(name, _configurationManager, _driverType, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instrument
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public object GetInstrument(string name, bool simulateHw)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger = LogManager.GetLogger(name);
|
||||
|
||||
return new BITCOEDeviceInstrument(name, _configurationManager, _driverType, _logger);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICollection<Type> GetSupportedInterfaces()
|
||||
{
|
||||
return _supportedInterfaces.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static IConfigurationManager GetConfigurationManager()
|
||||
{
|
||||
return string.IsNullOrEmpty(DefaultPath) ? new RaytheonConfigurationManager() : new RaytheonConfigurationManager(DefaultPath);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.BITCOEDeviceNode</AssemblyName>
|
||||
<Description>Specialized instrument implementation of IBit interface for running real time Build In Tests via COE</Description>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Deploy|AnyCPU'">
|
||||
<Optimize>False</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
<PackageReference Include="Raytheon.Common" Version="1.0.0" />
|
||||
<PackageReference Include="Raytheon.Instruments.BIT.Contracts" Version="1.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\COEComm\COEComm.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,135 @@
|
||||
// **********************************************************************************************************
|
||||
// ConfigurationHelper.cs
|
||||
// 7/5/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
|
||||
using Raytheon.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Raytheon.Instruments
|
||||
{
|
||||
/// <summary>
|
||||
/// type conversion utility with a special case for enums
|
||||
/// </summary>
|
||||
public static class TypeConverter
|
||||
{
|
||||
public static T ChangeType<T>(object value)
|
||||
{
|
||||
return typeof(T).IsEnum ? (T)Enum.Parse(typeof(T), value.ToString()) : (T)ChangeType(typeof(T), value);
|
||||
}
|
||||
|
||||
public static object ChangeType(Type t, object value)
|
||||
{
|
||||
System.ComponentModel.TypeConverter tc = TypeDescriptor.GetConverter(t);
|
||||
return tc.ConvertFrom(value);
|
||||
}
|
||||
|
||||
public static void RegisterTypeConverter<T, TC>() where TC : System.ComponentModel.TypeConverter
|
||||
{
|
||||
TypeDescriptor.AddAttributes(typeof(T), new TypeConverterAttribute(typeof(TC)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper class contains extention fuctions for reading types other than strings from configuration,
|
||||
/// as well as reading lists of values
|
||||
/// </summary>
|
||||
public static class ConfigurationHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// template function for reading different types from configuration
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
public static T GetConfigurationValue<T>(this IConfiguration configuration, string section, string key, string defaultValue)
|
||||
{
|
||||
var tmpResult = configuration.GetConfigurationValue(section, key, defaultValue);
|
||||
return !string.IsNullOrEmpty(tmpResult) ? TypeConverter.ChangeType<T>(tmpResult) : default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns multivalue result (list of T) from configuration
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="defaultValue"></param>
|
||||
/// <returns></returns>
|
||||
public static List<T> GetConfigurationListValue<T>(this IConfiguration configuration, string section, string key, List<T> defaultValue)
|
||||
{
|
||||
var tmpResult = configuration.GetXmlConfiguration(section);
|
||||
if (string.IsNullOrEmpty(tmpResult))
|
||||
{
|
||||
var xmlStr = new StringBuilder();
|
||||
xmlStr.Append($"<{key}s>");
|
||||
foreach (var item in defaultValue)
|
||||
{
|
||||
xmlStr.Append($"<{key}>");
|
||||
xmlStr.Append(item.ToString());
|
||||
xmlStr.Append($"</{key}>");
|
||||
}
|
||||
xmlStr.Append($"</{key}s>");
|
||||
|
||||
configuration.SetXmlConfiguration(section, xmlStr.ToString());
|
||||
return defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var stringRes = BuildElementListFromXml(tmpResult, key);
|
||||
return new List<T>(stringRes.Select(x => TypeConverter.ChangeType<T>(x)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns values from XML section converted to string list
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
private static List<string> BuildElementListFromXml(string data, string key)
|
||||
{
|
||||
XElement doc = XElement.Parse(data);
|
||||
IEnumerable<XElement> xmlMessages = from m
|
||||
in doc.Elements($"{key}s").Elements(key)
|
||||
select m;
|
||||
var messages = xmlMessages.Select(x => x.Value);
|
||||
return messages?.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="$(SolutionDir)Solution.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<AssemblyName>Raytheon.Instruments.COEComm</AssemblyName>
|
||||
<Description>C# wrapper for the COE Windows, integrated real-time software operating environment designed for use in embedded systems</Description>
|
||||
|
||||
<!-- Static versioning (Suitable for Development) -->
|
||||
<!-- Disable the line below for dynamic versioning -->
|
||||
<Version>1.0.0</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<NoWarn>1701;1702;NU1803</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NLog" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<PrepareForRunDependsOn>$(PrepareForRunDependsOn);CopyFilesTargetName</PrepareForRunDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<coeDLLs>build\R04.$(Configuration)\x86\coeWindows-shared.dll</coeDLLs>
|
||||
<coeDLLs Condition="'$(Configuration)'=='Debug' OR '$(Configuration)'=='Release' OR '$(Configuration)'=='Deploy'">build\R04.06.05.02\x86\coeWindows-shared.dll;build\R04.06.05.02\x86\coeWindows-sharedd.dll</coeDLLs>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="$(coeDLLs)">
|
||||
<PackagePath>lib\$(TargetFramework)</PackagePath>
|
||||
<TargetPath></TargetPath>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
<Pack>True</Pack>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CopyFilesTargetName" BeforeTargets="Build">
|
||||
<Copy SourceFiles="$(coeDLLs)" DestinationFolder="$(OutDir)" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy all *.dlls and *.pdb in the output folder to a temp folder -->
|
||||
<Target Name="CopyFiles" AfterTargets="AfterBuild">
|
||||
<ItemGroup>
|
||||
<FILES_1 Include="$(OutDir)*.dll" />
|
||||
<FILES_2 Include="$(OutDir)*.pdb" />
|
||||
</ItemGroup>
|
||||
<Copy SourceFiles="@(FILES_1)" DestinationFolder="$(HalTempFolder)" />
|
||||
<Copy SourceFiles="@(FILES_2)" DestinationFolder="$(HalTempFolder)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,218 @@
|
||||
// **********************************************************************************************************
|
||||
// BitFieldGeneric.cs
|
||||
// 5/18/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Instruments.MessagingUtilities
|
||||
{
|
||||
// This is a generic class used to apply a bitfield to
|
||||
// a value to get the desired value
|
||||
class BitFieldGeneric<T> where T : IConvertible
|
||||
{
|
||||
protected long m_Value; // This is the value being operated on
|
||||
protected ulong m_Mask;
|
||||
|
||||
public char ToChar()
|
||||
{
|
||||
return (char)m_Value;
|
||||
}
|
||||
|
||||
public sbyte ToSByte()
|
||||
{
|
||||
return (sbyte)m_Value;
|
||||
}
|
||||
|
||||
public short ToShort()
|
||||
{
|
||||
return (short)m_Value;
|
||||
}
|
||||
|
||||
public int ToInt()
|
||||
{
|
||||
return (int)m_Value;
|
||||
}
|
||||
|
||||
public long ToLong()
|
||||
{
|
||||
return (long)m_Value;
|
||||
}
|
||||
|
||||
public ushort ToUShort()
|
||||
{
|
||||
return (ushort)m_Value;
|
||||
}
|
||||
|
||||
public uint ToUInt()
|
||||
{
|
||||
return (uint)m_Value;
|
||||
}
|
||||
|
||||
public ulong ToULong()
|
||||
{
|
||||
return (ulong)m_Value;
|
||||
}
|
||||
|
||||
public BitFieldGeneric(T value, ulong bitMask)
|
||||
{
|
||||
m_Mask = bitMask;
|
||||
try
|
||||
{
|
||||
m_Value = ApplyBitMask((ulong)value.ToInt64(null), bitMask);
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_Value = ApplyBitMask(value.ToUInt64(null), bitMask);
|
||||
}
|
||||
}
|
||||
|
||||
public BitFieldGeneric(string value, ulong bitMask)
|
||||
{
|
||||
m_Mask = bitMask;
|
||||
|
||||
if(string.IsNullOrEmpty(value))
|
||||
{
|
||||
value = "0";
|
||||
}
|
||||
|
||||
if (Parse.Try(value, out m_Value) == true)
|
||||
{
|
||||
m_Value = PrepareWithBitMask(m_Value, bitMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unable to parse value = " + value);
|
||||
}
|
||||
}
|
||||
|
||||
// count the number of 1 bits in a ulong
|
||||
int BitCount(ulong x)
|
||||
{
|
||||
int n = 0;
|
||||
if (x > 0) do ++n; while ((x &= x - 1) > 1);
|
||||
return n;
|
||||
}
|
||||
|
||||
// Check to see if the MSB is set after accounting for
|
||||
// the mask. If it is, then the number should be converted
|
||||
// to display a negative number
|
||||
public void ToSigned()
|
||||
{
|
||||
if (m_Mask > 0)
|
||||
{
|
||||
// See if the sign bit is set
|
||||
int numbits = BitCount(m_Mask);
|
||||
if (m_Value > (Math.Pow(2, numbits - 1)))
|
||||
{
|
||||
// If it is, take the two's complement
|
||||
m_Value = (~m_Value) + 1;
|
||||
|
||||
// Mask off the leading F's from the conversion
|
||||
ulong mask = 1;
|
||||
for (int i = 0; i < numbits - 1; i++)
|
||||
{
|
||||
mask = (mask << 1) + 1;
|
||||
}
|
||||
|
||||
m_Value = (long)(((ulong)m_Value) & mask);
|
||||
|
||||
// Add the negative sign
|
||||
m_Value = -m_Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return m_Value.ToString();
|
||||
}
|
||||
|
||||
public void BitOR(T value)
|
||||
{
|
||||
long orValue = value.ToInt64(null);
|
||||
m_Value |= orValue;
|
||||
}
|
||||
|
||||
private long PrepareWithBitMask(long val, ulong bitMask)
|
||||
{
|
||||
ulong value = (ulong)val;
|
||||
ulong mask = bitMask;
|
||||
|
||||
if (bitMask != 0)
|
||||
{
|
||||
if ((mask & 1) != 1)
|
||||
{
|
||||
while (((mask >> 1) & 1) != 1) //shift mask to LSB
|
||||
{
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
mask >>= 1; // one last shift not done by loop
|
||||
}
|
||||
|
||||
value &= mask; // ensure value is contained in the same # of bits as the mask
|
||||
|
||||
// Shift the value back to its proper spot in the memory
|
||||
while (mask != bitMask)
|
||||
{
|
||||
value <<= 1;
|
||||
mask <<= 1;
|
||||
}
|
||||
}
|
||||
return (long)value;
|
||||
}
|
||||
|
||||
private long ApplyBitMask(ulong val, ulong bitMask)
|
||||
{
|
||||
ulong value = val;
|
||||
|
||||
if (bitMask != 0) // Apply the bit field
|
||||
{
|
||||
value &= bitMask;
|
||||
|
||||
// Shift until the bitmask resides in the LSB
|
||||
if ((bitMask & 1) != 1)
|
||||
{
|
||||
while (((bitMask >> 1) & 1) != 1)
|
||||
{
|
||||
value >>= 1;
|
||||
bitMask >>= 1;
|
||||
}
|
||||
|
||||
// We need one more shift after leaving the while loop
|
||||
value >>= 1;
|
||||
}
|
||||
}
|
||||
return (long)value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,502 @@
|
||||
// **********************************************************************************************************
|
||||
// BytePackingXml.cs
|
||||
// 5/18/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using System.Xml.XPath;
|
||||
|
||||
namespace Raytheon.Instruments.MessagingUtilities
|
||||
{
|
||||
// Takes an XML ICD and adds in nodes to represent the byte packing
|
||||
// The padding added will be displayed in the tool as arrays of characters
|
||||
internal class BytePackingXml : XmlDocument
|
||||
{
|
||||
private readonly int m_Packing = 8;
|
||||
private readonly Dictionary<string, double> m_ConstMap;
|
||||
private readonly Dictionary<string, int> m_SizeMap;
|
||||
private readonly Dictionary<string, int> m_PadMap;
|
||||
|
||||
public BytePackingXml(string icdStr) : base()
|
||||
{
|
||||
// Create the dictionaries
|
||||
m_ConstMap = new Dictionary<string, double>();
|
||||
m_PadMap = new Dictionary<string, int>();
|
||||
m_SizeMap = new Dictionary<string, int>();
|
||||
|
||||
// Create an XML document from the string
|
||||
LoadXml(icdStr);
|
||||
|
||||
XPathNavigator node = CreateNavigator();
|
||||
//Get the type of packing
|
||||
XPathNodeIterator nodeset = node.Select("/interface/packing");
|
||||
if (nodeset.MoveNext() == true)
|
||||
{
|
||||
if (!Parse.Try(nodeset.Current.Value.Trim(), out m_Packing))
|
||||
{
|
||||
switch (nodeset.Current.Value.Trim())
|
||||
{
|
||||
case "char":
|
||||
case "1":
|
||||
m_Packing = 1;
|
||||
break;
|
||||
case "short":
|
||||
case "2":
|
||||
m_Packing = 2;
|
||||
break;
|
||||
case "long":
|
||||
case "4":
|
||||
m_Packing = 4;
|
||||
break;
|
||||
case "double":
|
||||
case "8":
|
||||
default:
|
||||
m_Packing = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle all of the constants
|
||||
nodeset = node.Select("/interface/constant");
|
||||
while (nodeset.MoveNext())
|
||||
{
|
||||
ProcessConstantNode(nodeset.Current);
|
||||
}
|
||||
|
||||
nodeset = node.Select("/interface/typedef");
|
||||
while (nodeset.MoveNext())
|
||||
{
|
||||
ProcessTypedefNode(nodeset.Current);
|
||||
}
|
||||
|
||||
nodeset = node.Select("/interface/enum");
|
||||
while (nodeset.MoveNext())
|
||||
{
|
||||
ProcessEnumerationNode(nodeset.Current);
|
||||
}
|
||||
|
||||
nodeset = node.Select("/interface/structure|/interface/message");
|
||||
while (nodeset.MoveNext())
|
||||
{
|
||||
ProcessStructureNode(nodeset.Current);
|
||||
}
|
||||
|
||||
NormalizeIcdLabels();
|
||||
}
|
||||
|
||||
// This function takes all of the messages in the ICD
|
||||
// and converts the labels into decimal, so when we do
|
||||
// a string lookup, they will all be in the same known format
|
||||
private void NormalizeIcdLabels()
|
||||
{
|
||||
XPathNavigator navigator = CreateNavigator();
|
||||
XPathNodeIterator nodeset;
|
||||
|
||||
nodeset = navigator.Select("/interface/message/label");
|
||||
while (nodeset.MoveNext())
|
||||
{
|
||||
try
|
||||
{
|
||||
double dLabel = GetConstFromString(nodeset.Current.Value);
|
||||
nodeset.Current.SetValue(((int)dLabel).ToString());
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new Exception("Message Label, " + nodeset.Current.Value + ", can not be converted to an integer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessConstantNode(XPathNavigator node)
|
||||
{
|
||||
string name = "";
|
||||
string constStr = "";
|
||||
double constNum = 0;
|
||||
|
||||
if (node.MoveToChild("name", ""))
|
||||
{
|
||||
name = node.Value.Trim();
|
||||
node.MoveToParent();
|
||||
}
|
||||
if (node.MoveToChild("value", ""))
|
||||
{
|
||||
constStr = node.Value.Trim();
|
||||
if ((constStr.Length != 0) && (constStr[0] != '\"'))
|
||||
{
|
||||
constNum = GetConstFromString(constStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
constNum = 0;
|
||||
}
|
||||
node.MoveToParent();
|
||||
}
|
||||
|
||||
// Verify the correctnes of the <constant> tag
|
||||
if ((name != "") && (constStr != ""))
|
||||
{
|
||||
AddItemToMap(m_ConstMap, name, constNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(
|
||||
"ERROR: Constant Definition Incorrect - <name>:" + name +
|
||||
" <value>:" + constStr);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessTypedefNode(XPathNavigator node)
|
||||
{
|
||||
string name = "";
|
||||
string type = "";
|
||||
int typeSize = 0; // Size of the item
|
||||
int typePad = 0; //Size of the largest item to pad to
|
||||
|
||||
if (node.MoveToChild("name", ""))
|
||||
{
|
||||
name = node.Value.Trim();
|
||||
node.MoveToParent();
|
||||
}
|
||||
if (node.MoveToChild("value", ""))
|
||||
{
|
||||
type = node.Value.Trim();
|
||||
GetSizeFromType(type, out typeSize, out typePad);
|
||||
node.MoveToParent();
|
||||
}
|
||||
|
||||
// Verify the correctnes of the <typedef> tag
|
||||
if ((name != "") && (type != ""))
|
||||
{
|
||||
AddItemToMap(m_PadMap, name, typePad);
|
||||
AddItemToMap(m_SizeMap, name, typeSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception(
|
||||
"ERROR: Typedef Definition Incorrect - <name>:" + name +
|
||||
" <value>:" + type);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessEnumerationNode(XPathNavigator node)
|
||||
{
|
||||
string name;
|
||||
double constNum = 0;
|
||||
var constStr = string.Empty;
|
||||
|
||||
if (node.MoveToChild("name", ""))
|
||||
{
|
||||
name = node.Value.Trim();
|
||||
AddItemToMap(m_PadMap, name, 4);
|
||||
AddItemToMap(m_SizeMap, name, 4);
|
||||
node.MoveToParent();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("ERROR: Enumeration Definition Incorrect. No <name> tag present.");
|
||||
}
|
||||
|
||||
XPathNodeIterator nodeSet = node.Select("item|enum_item");
|
||||
while (nodeSet.MoveNext())
|
||||
{
|
||||
name = string.Empty;
|
||||
|
||||
if ((nodeSet.Current.MoveToChild("name", "")) ||
|
||||
(nodeSet.Current.MoveToChild("item_name", "")))
|
||||
{
|
||||
name = nodeSet.Current.Value.Trim();
|
||||
nodeSet.Current.MoveToParent();
|
||||
}
|
||||
if (nodeSet.Current.MoveToChild("value", ""))
|
||||
{
|
||||
constStr = nodeSet.Current.Value.Trim();
|
||||
constNum = GetConstFromString(constStr);
|
||||
nodeSet.Current.MoveToParent();
|
||||
}
|
||||
|
||||
// Verify the correctnes of the <enum><item> tag
|
||||
if ((name != "") && (constStr != ""))
|
||||
{
|
||||
AddItemToMap(m_ConstMap, name, constNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"ERROR: Enumeration Item Definition Incorrect - <name>: {name} <value>: {constStr}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessStructureNode(XPathNavigator node)
|
||||
{
|
||||
string name;
|
||||
|
||||
if (node.MoveToChild("name", ""))
|
||||
{
|
||||
name = node.Value.Trim();
|
||||
node.MoveToParent();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("ERROR: Stucture/Message Definition Incorrect. No <name> tag present.");
|
||||
}
|
||||
|
||||
int maxSize = 0;
|
||||
int padCount = 0;
|
||||
uint bitCount = 0; // Used to see how many bits have been processed.
|
||||
int lastItemSize = 0;
|
||||
|
||||
var nodeSet = node.Select("item|struct_item|msg_item");
|
||||
while (nodeSet.MoveNext())
|
||||
{
|
||||
GetItemSize(nodeSet.Current, out int padSize, out int itemSize, out int reps, out uint bits);
|
||||
if ((lastItemSize != itemSize) || ((bitCount + bits) > (uint)(itemSize * 8)))
|
||||
{
|
||||
bitCount = 0; // Size changed or bit rollover
|
||||
}
|
||||
|
||||
if (bitCount == 0)
|
||||
{
|
||||
padCount += AddPadding(node, nodeSet.Current, padSize, padCount);
|
||||
|
||||
// Set maxSize
|
||||
if (padSize > maxSize)
|
||||
{
|
||||
maxSize = padSize;
|
||||
}
|
||||
|
||||
// Keep up with the pad count
|
||||
padCount += (itemSize * reps);
|
||||
}
|
||||
|
||||
lastItemSize = itemSize;
|
||||
bitCount += bits;
|
||||
}
|
||||
|
||||
if (maxSize != 0)
|
||||
{
|
||||
// Add final padding
|
||||
padCount += AddPadding(node, null, maxSize, padCount);
|
||||
}
|
||||
|
||||
AddItemToMap(m_PadMap, name, maxSize);
|
||||
AddItemToMap(m_SizeMap, name, padCount);
|
||||
}
|
||||
|
||||
private void GetItemSize(XPathNavigator node, out int padSize, out int itemSize, out int reps, out uint bits)
|
||||
{
|
||||
string name = "";
|
||||
|
||||
if ((node.MoveToChild("name", "")) ||
|
||||
(node.MoveToChild("item_name", "")))
|
||||
{
|
||||
name = node.Value.Trim();
|
||||
node.MoveToParent();
|
||||
}
|
||||
|
||||
itemSize = -1;
|
||||
padSize = -1;
|
||||
reps = 1;
|
||||
bits = 0;
|
||||
|
||||
var nodeSet = node.Select("type");
|
||||
while (nodeSet.MoveNext())
|
||||
{
|
||||
GetSizeFromType(nodeSet.Current.Value.Trim(), out padSize, out itemSize);
|
||||
}
|
||||
|
||||
nodeSet = node.Select("bits");
|
||||
if (nodeSet.MoveNext())
|
||||
{
|
||||
bits = (uint)GetConstFromString(nodeSet.Current.Value.Trim());
|
||||
}
|
||||
|
||||
nodeSet = node.Select("arrayLength|imageWidth|imageHeight");
|
||||
while (nodeSet.MoveNext())
|
||||
{
|
||||
try
|
||||
{
|
||||
reps *= (int)GetConstFromString(nodeSet.Current.Value.Trim());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new Exception
|
||||
(e.Message + " item name = \"" + name + "\", tag = <" +
|
||||
nodeSet.Current.Name + ">.");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((itemSize == -1) || (padSize == -1))
|
||||
{
|
||||
throw new Exception
|
||||
("ERROR: Item named " + name + "does not contain a <type> tag.");
|
||||
}
|
||||
|
||||
if (bits == 0)
|
||||
bits = (uint)padSize * 8;
|
||||
}
|
||||
|
||||
private double GetConstFromString(string constStr)
|
||||
{
|
||||
if ((constStr.Length > 0) && (constStr[0] == '\''))
|
||||
{
|
||||
byte charData = (byte)constStr[1];
|
||||
constStr = charData.ToString();
|
||||
}
|
||||
|
||||
if (Parse.Try(constStr, out double data) == false)
|
||||
{
|
||||
if (Parse.Try(constStr, out int iData) == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
data = m_ConstMap[constStr];
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new Exception("ERROR: ConstantValue - \"" + constStr + "\" does not resolve to a number.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data = (double)iData;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private void AddItemToMap(Dictionary<string, int> map, string name, int value)
|
||||
{
|
||||
if (map.ContainsKey(name))
|
||||
{
|
||||
throw new Exception("ERROR: Element " + name + " is defined multiple times.");
|
||||
}
|
||||
else
|
||||
{
|
||||
map.Add(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddItemToMap(Dictionary<string, double> map, string name, double value)
|
||||
{
|
||||
if (map.ContainsKey(name))
|
||||
{
|
||||
throw new Exception("ERROR: Element " + name + " is defined multiple times.");
|
||||
}
|
||||
else
|
||||
{
|
||||
map.Add(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetSizeFromType(string type, out int typePad, out int typeSize)
|
||||
{
|
||||
// Remove all whitespace
|
||||
type = type.Replace(" ", "");
|
||||
|
||||
if ((type == "char") || (type == "unsignedchar"))
|
||||
{
|
||||
typePad = 1;
|
||||
typeSize = 1;
|
||||
}
|
||||
else if ((type == "short") || (type == "unsignedshort"))
|
||||
{
|
||||
typePad = 2;
|
||||
typeSize = 2;
|
||||
}
|
||||
else if ((type == "unsigned") || (type == "unsignedint") ||
|
||||
(type == "int") || (type == "float") ||
|
||||
(type == "boolean") || (type == "address"))
|
||||
{
|
||||
typePad = 4;
|
||||
typeSize = 4;
|
||||
}
|
||||
else if ((type == "double") || (type == "longlong") ||
|
||||
(type == "unsignedlonglong"))
|
||||
{
|
||||
typePad = 8;
|
||||
typeSize = 8;
|
||||
}
|
||||
else // The type is complex and has already been defined
|
||||
{
|
||||
try
|
||||
{
|
||||
typePad = m_PadMap[type];
|
||||
typeSize = m_SizeMap[type];
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new Exception("ERROR: <type> - " + type + " used without being defined.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int AddPadding(XPathNavigator ParentElement, XPathNavigator CurrentElement, int padSize, int padCount)
|
||||
{
|
||||
int padAdd = 0;
|
||||
int padTo = padSize;
|
||||
|
||||
if (m_Packing < padSize)
|
||||
{
|
||||
padTo = m_Packing;
|
||||
}
|
||||
|
||||
if ((padTo != 0) && (padCount % padTo != 0))
|
||||
{
|
||||
padAdd = padTo - (padCount % padTo);
|
||||
InsertPaddingNode(ParentElement, CurrentElement, padAdd);
|
||||
}
|
||||
|
||||
return padAdd;
|
||||
}
|
||||
|
||||
private void InsertPaddingNode(XPathNavigator ParentElement, XPathNavigator CurrentElement, int padAdd)
|
||||
{
|
||||
string pad = "<item>" +
|
||||
"<name>" + Message.PADDING_ITEM_NAME + "</name>" +
|
||||
"<type>char</type>" +
|
||||
"<arrayLength>" + padAdd + "</arrayLength>" +
|
||||
"<instruType>S</instruType>" +
|
||||
"</item>";
|
||||
if (CurrentElement != null)
|
||||
{
|
||||
CurrentElement.InsertBefore(pad);
|
||||
}
|
||||
else // End padding
|
||||
{
|
||||
ParentElement.AppendChild(pad);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,600 @@
|
||||
// **********************************************************************************************************
|
||||
// MessageData.cs
|
||||
// 5/18/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using Raytheon.Instruments.coeCSharp;
|
||||
|
||||
namespace Raytheon.Instruments.MessagingUtilities
|
||||
{
|
||||
public class MessageData : ICloneable
|
||||
{
|
||||
public string FieldName;
|
||||
public string FieldType;
|
||||
public string FieldValue;
|
||||
public string FieldArrayValue;
|
||||
public string FieldDefaultValue;
|
||||
public string FieldMaxValue;
|
||||
public string FieldMinValue;
|
||||
public string FieldBitValue;
|
||||
public string FieldInstruType;
|
||||
public string Variable;
|
||||
public string MaxOffset;
|
||||
public string MinOffset;
|
||||
public string VerifyType;
|
||||
public bool isSelected;
|
||||
public bool isArray;
|
||||
public bool isStructure;
|
||||
public bool isArrayOfStructures;
|
||||
public bool isEnum;
|
||||
public bool usesRegister;
|
||||
public bool isValid;
|
||||
public bool useRange;
|
||||
public int arrayLength;
|
||||
public uint imageWidth;
|
||||
public uint imageHeight;
|
||||
public uint imagePixelSize;
|
||||
public ulong bitMask;
|
||||
public bool expanded;
|
||||
public int depth;
|
||||
public byte[] imageBuffer;
|
||||
public uint imageBufferSize;
|
||||
public MessageData[] MessageArray;
|
||||
|
||||
public delegate coe.Status ReadImageDelegate
|
||||
(
|
||||
string filename,
|
||||
uint columns,
|
||||
uint rows,
|
||||
uint pixel_size,
|
||||
byte[] buffer
|
||||
);
|
||||
|
||||
private MessageXmlDocument m_Icd;
|
||||
|
||||
internal int m_BitCounter = 0; // used to calculate the bit mask
|
||||
|
||||
internal static Dictionary<string, ReadImageDelegate> m_ReadFunctions = null;
|
||||
private MessageData() { }
|
||||
private MessageData(MessageXmlDocument Icd)
|
||||
{
|
||||
FieldName = null;
|
||||
FieldType = null;
|
||||
FieldValue = null;
|
||||
FieldArrayValue = null;
|
||||
FieldDefaultValue = null;
|
||||
FieldMaxValue = null;
|
||||
FieldMinValue = null;
|
||||
FieldBitValue = null;
|
||||
Variable = null;
|
||||
MaxOffset = null;
|
||||
MinOffset = null;
|
||||
VerifyType = null;
|
||||
isSelected = false;
|
||||
isArray = false;
|
||||
isStructure = false;
|
||||
isArrayOfStructures = false;
|
||||
usesRegister = false;
|
||||
useRange = false;
|
||||
arrayLength = 0;
|
||||
imageWidth = 0;
|
||||
imageHeight = 0;
|
||||
imagePixelSize = 0;
|
||||
bitMask = 0;
|
||||
expanded = false;
|
||||
depth = 0;
|
||||
imageBufferSize = 0;
|
||||
imageBuffer = null;
|
||||
|
||||
m_Icd = Icd;
|
||||
}
|
||||
|
||||
public MessageData(string fieldname,
|
||||
string fieldtype,
|
||||
string fieldvalue,
|
||||
string fielddefaultvalue,
|
||||
MessageXmlDocument Icd) :
|
||||
this(Icd)
|
||||
{
|
||||
FieldName = fieldname;
|
||||
FieldType = fieldtype;
|
||||
FieldValue = fieldvalue;
|
||||
|
||||
SetInstruType(null);
|
||||
SetDefaultValue(fielddefaultvalue);
|
||||
|
||||
}
|
||||
|
||||
public MessageData(string fieldname,
|
||||
string fieldtype,
|
||||
string fieldvalue,
|
||||
string fielddefaultvalue,
|
||||
string fieldmaxvalue,
|
||||
string fieldminvalue,
|
||||
MessageXmlDocument Icd) :
|
||||
this(fieldname, fieldtype, fieldvalue, fielddefaultvalue, Icd)
|
||||
{
|
||||
SetMaxValue(fieldmaxvalue);
|
||||
SetMinValue(fieldminvalue);
|
||||
}
|
||||
|
||||
public string FormattedValue
|
||||
{
|
||||
get { return FormatValue(FieldValue); }
|
||||
}
|
||||
public string FormattedMinValue
|
||||
{
|
||||
get { return FormatValue(FieldMinValue); }
|
||||
}
|
||||
public string FormattedMaxValue
|
||||
{
|
||||
get { return FormatValue(FieldMaxValue); }
|
||||
}
|
||||
|
||||
public static string ImageFileReadTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
string fileTypes = "";
|
||||
if (m_ReadFunctions == null) return null;
|
||||
foreach (string type in m_ReadFunctions.Keys)
|
||||
{
|
||||
if (fileTypes != "")
|
||||
fileTypes += "|";
|
||||
|
||||
fileTypes += type.ToUpper() + " files (*." + type.ToLower() + ")|*." + type.ToLower();
|
||||
}
|
||||
|
||||
return fileTypes;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddReadExtension(string extension, ReadImageDelegate readFunc)
|
||||
{
|
||||
if (m_ReadFunctions == null)
|
||||
m_ReadFunctions = new Dictionary<string, ReadImageDelegate>();
|
||||
|
||||
if (m_ReadFunctions.ContainsKey(extension))
|
||||
m_ReadFunctions[extension] = readFunc;
|
||||
else
|
||||
m_ReadFunctions.Add(extension, readFunc);
|
||||
}
|
||||
|
||||
public void UpdateImage()
|
||||
{
|
||||
if (FieldInstruType == "P")
|
||||
{
|
||||
if (File.Exists(FieldValue))
|
||||
{
|
||||
string extension = FieldValue.Substring(FieldValue.LastIndexOf(".") + 1);
|
||||
m_ReadFunctions[extension](FieldValue,
|
||||
imageWidth,
|
||||
imageHeight,
|
||||
imagePixelSize,
|
||||
imageBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO add error message
|
||||
//MessageBox.Show("Unable to open file " + FieldValue +
|
||||
// " to populate " + FieldName,
|
||||
// "File Read Error",
|
||||
// MessageBoxButtons.OK,
|
||||
// MessageBoxIcon.Error);
|
||||
FieldValue = "";
|
||||
for (int i = 0; i < imageBuffer.Length; i++)
|
||||
{
|
||||
imageBuffer[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetDefaultValue(string fieldDefaultValue)
|
||||
{
|
||||
// Initialize uninitialized value
|
||||
if (fieldDefaultValue == null)
|
||||
{
|
||||
fieldDefaultValue = "";
|
||||
}
|
||||
|
||||
if ((FieldType == "char") && (fieldDefaultValue.Contains("\"")))
|
||||
{
|
||||
FieldInstruType = "S";
|
||||
}
|
||||
|
||||
FieldDefaultValue = RemoveCharFromString(fieldDefaultValue, '\"');
|
||||
}
|
||||
|
||||
public void SetMaxValue(string fieldmaxvalue)
|
||||
{
|
||||
if (fieldmaxvalue == null) return; /* Bad argument */
|
||||
|
||||
if ((FieldType == "char") && (fieldmaxvalue.Contains("\"")))
|
||||
{
|
||||
FieldInstruType = "S";
|
||||
}
|
||||
|
||||
FieldMaxValue = RemoveCharFromString(fieldmaxvalue, '\"');
|
||||
}
|
||||
|
||||
public void SetMinValue(string fieldminvalue)
|
||||
{
|
||||
if (fieldminvalue == null) return; /* Bad argument */
|
||||
|
||||
if ((FieldType == "char") && (fieldminvalue.Contains("\"")))
|
||||
{
|
||||
FieldInstruType = "S";
|
||||
}
|
||||
|
||||
FieldMinValue = RemoveCharFromString(fieldminvalue, '\"');
|
||||
}
|
||||
|
||||
public void SetBitValue(int bits)
|
||||
{
|
||||
int size = (int)Message.GetTypeSize(FieldType, isEnum);
|
||||
|
||||
// Determine the bitMask
|
||||
if (bits == 0)
|
||||
{
|
||||
m_BitCounter = 0;
|
||||
FieldBitValue = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
FieldBitValue = bits.ToString();
|
||||
|
||||
// If bits overflow across the type boundary, then
|
||||
// they start at the next boundary.
|
||||
//
|
||||
// MSDN :
|
||||
// "Note that nYear is 8 bits long and would overflow
|
||||
// the word boundary of the declared type, unsigned short.
|
||||
// Therefore, it is begun at the beginning of a
|
||||
// new unsigned short."
|
||||
if (m_BitCounter + bits > size * 8)
|
||||
{
|
||||
m_BitCounter = 0;
|
||||
}
|
||||
|
||||
// 2^bits-1 will give a bit mask with bit# of 1's
|
||||
// ex: bits = 5, bitMask = 11111
|
||||
bitMask = (ulong)Math.Pow(2, (double)bits) - 1;
|
||||
|
||||
// We must slide the bitMask left to put it in place
|
||||
bitMask <<= m_BitCounter;
|
||||
m_BitCounter += bits;
|
||||
|
||||
// If we have used all the bits in the type that was defined, then
|
||||
// restart the counter
|
||||
if (m_BitCounter == size * 8)
|
||||
m_BitCounter = 0;
|
||||
}
|
||||
|
||||
if (bitMask == 0xffffff)
|
||||
{
|
||||
bitMask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetArraySize(int size)
|
||||
{
|
||||
char result;
|
||||
|
||||
arrayLength = size; // Save the size
|
||||
|
||||
if (!isArray && !isStructure)
|
||||
{
|
||||
// Don't handle strings as arrays
|
||||
if ((FieldInstruType != "S") && (FieldInstruType != "P"))
|
||||
{
|
||||
isArray = true;
|
||||
|
||||
MessageArray = new MessageData[size];
|
||||
// If the field type is char or unsigned char and the default value
|
||||
// exists and is a string then write one char of the string to
|
||||
// each element of the array
|
||||
if ((FieldType == "char" || FieldType == "unsigned char") &&
|
||||
FieldDefaultValue != null &&
|
||||
!Parse.Try(FieldDefaultValue, out result))
|
||||
{
|
||||
for (uint index = 0; index < size; index++)
|
||||
{
|
||||
//Only the elements that are required to spell out the string should
|
||||
//receive default values.
|
||||
if (index < FieldDefaultValue.Length)
|
||||
{
|
||||
MessageArray[index] = new MessageData(FieldName + "[" + index + "]",
|
||||
FieldType, FieldValue, FieldDefaultValue[(int)index].ToString(),
|
||||
FieldMaxValue, FieldMinValue, m_Icd);
|
||||
MessageArray[index].FieldInstruType = FieldInstruType;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageArray[index] = new MessageData(FieldName + "[" + index + "]",
|
||||
FieldType, FieldValue, "0",
|
||||
FieldMaxValue, FieldMinValue, m_Icd);
|
||||
MessageArray[index].FieldInstruType = FieldInstruType;
|
||||
}
|
||||
MessageArray[index].depth = depth + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint index = 0; index < size; index++)
|
||||
{
|
||||
MessageArray[index] = new MessageData(FieldName + "[" + index + "]",
|
||||
FieldType, FieldValue, FieldDefaultValue, FieldMaxValue,
|
||||
FieldMinValue, m_Icd);
|
||||
MessageArray[index].FieldInstruType = FieldInstruType;
|
||||
MessageArray[index].depth = depth + 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetStructureSize(int size)
|
||||
{
|
||||
if (!isArray && !isStructure)
|
||||
{
|
||||
isStructure = true;
|
||||
MessageArray = new MessageData[size];
|
||||
for (uint index = 0; index < size; index++)
|
||||
{
|
||||
MessageArray[index] = new MessageData(FieldName + ".", null, null, null, m_Icd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetInstruType(string Type)
|
||||
{
|
||||
if (Type != null)
|
||||
{
|
||||
FieldInstruType = Type;
|
||||
|
||||
// Ensure 'S' is used properly
|
||||
if ((Type == "S") && (FieldType != "char"))
|
||||
{
|
||||
return; /* << EXIT >> */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((FieldType != null) &&
|
||||
((FieldType.Trim() == "float") || (FieldType.Trim() == "double")))
|
||||
{
|
||||
FieldInstruType = "F";
|
||||
}
|
||||
else
|
||||
{
|
||||
FieldInstruType = "I";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetPixelSize()
|
||||
{
|
||||
// Only do this if the user did not define a size
|
||||
if (imagePixelSize == 0)
|
||||
{
|
||||
switch (FieldType)
|
||||
{
|
||||
case "char":
|
||||
case "unsigned char":
|
||||
case "unsignedchar":
|
||||
imagePixelSize = 1;
|
||||
break;
|
||||
|
||||
case "short":
|
||||
case "unsigned short":
|
||||
case "unsignedshort":
|
||||
imagePixelSize = 2;
|
||||
break;
|
||||
|
||||
case "int":
|
||||
case "unsigned int":
|
||||
case "unsignedint":
|
||||
case "unsigned":
|
||||
case "boolean":
|
||||
case "address":
|
||||
case "float":
|
||||
imagePixelSize = 4;
|
||||
break;
|
||||
|
||||
case "double":
|
||||
case "long long":
|
||||
case "longlong":
|
||||
case "unsigned long long":
|
||||
case "unsignedlonglong":
|
||||
imagePixelSize = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isEnum)
|
||||
{
|
||||
imagePixelSize = 4;
|
||||
}
|
||||
else // Error case
|
||||
{
|
||||
imagePixelSize = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string FormatValue(string Value)
|
||||
{
|
||||
if ((Value == null) || (Value == ""))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else // Value exists
|
||||
{
|
||||
if (isEnum == false)
|
||||
{
|
||||
if (FieldInstruType == "I")
|
||||
{
|
||||
// This is being represented as a decimal
|
||||
if (Parse.Try(Value, out long dec) == true)
|
||||
{
|
||||
return dec.ToString();
|
||||
}
|
||||
}
|
||||
else if (FieldInstruType == "F")
|
||||
{
|
||||
// This is being represented as floating point
|
||||
if (Parse.Try(Value, out double flt) == true)
|
||||
{
|
||||
return flt.ToString();
|
||||
}
|
||||
}
|
||||
else if ((FieldInstruType == "X") ||
|
||||
(FieldInstruType == "B") ||
|
||||
(FieldInstruType == "T"))
|
||||
{
|
||||
// This is being represented as a hexadecimal value
|
||||
if (Parse.Try(Value, out long hex) == true)
|
||||
{
|
||||
return "0x" + hex.ToString("X");
|
||||
}
|
||||
}
|
||||
else if (FieldInstruType == "N")
|
||||
{
|
||||
// This is being represented as a binary number
|
||||
if (Parse.Try(Value, out long bin) == true)
|
||||
{
|
||||
return Convert.ToString(bin, 2) + "b";
|
||||
}
|
||||
}
|
||||
// else InstruType == 'S' or 'P' or anything else return the value
|
||||
}
|
||||
else // This value is an enumeration
|
||||
{
|
||||
Dictionary<string, string> enums = m_Icd.GetEnumerations(FieldType);
|
||||
if (enums.ContainsValue(Value) == true)
|
||||
{
|
||||
foreach (KeyValuePair<string, string> pair in enums)
|
||||
{
|
||||
if (pair.Value.Trim() == Value.Trim())
|
||||
{
|
||||
return pair.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Value; // If nothing above applies, simply return the value string
|
||||
}
|
||||
|
||||
private String RemoveCharFromString(String str, char c)
|
||||
{
|
||||
if (str == null) return null; // Handle null case
|
||||
|
||||
int index = str.IndexOf(c);
|
||||
while (index != -1)
|
||||
{
|
||||
str = str.Remove(index, 1);
|
||||
index = str.IndexOf(c);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
MessageData clone = new MessageData();
|
||||
|
||||
clone.FieldName = FieldName;
|
||||
clone.FieldType = FieldType;
|
||||
clone.FieldValue = FieldValue;
|
||||
clone.FieldArrayValue = FieldArrayValue;
|
||||
clone.FieldDefaultValue = FieldDefaultValue;
|
||||
clone.FieldMaxValue = FieldMaxValue;
|
||||
clone.FieldMinValue = FieldMinValue;
|
||||
clone.FieldBitValue = FieldBitValue;
|
||||
clone.FieldInstruType = FieldInstruType;
|
||||
clone.Variable = Variable;
|
||||
clone.MaxOffset = MaxOffset;
|
||||
clone.MinOffset = MinOffset;
|
||||
clone.VerifyType = VerifyType;
|
||||
clone.isSelected = isSelected;
|
||||
clone.isArray = isArray;
|
||||
clone.isStructure = isStructure;
|
||||
clone.isArrayOfStructures = isArrayOfStructures;
|
||||
clone.isEnum = isEnum;
|
||||
clone.usesRegister = usesRegister;
|
||||
clone.isValid = isValid;
|
||||
clone.useRange = useRange;
|
||||
clone.arrayLength = arrayLength;
|
||||
clone.bitMask = bitMask;
|
||||
clone.expanded = expanded;
|
||||
clone.depth = depth;
|
||||
clone.m_Icd = m_Icd;
|
||||
clone.imageWidth = imageWidth;
|
||||
clone.imageHeight = imageHeight;
|
||||
clone.imagePixelSize = imagePixelSize;
|
||||
clone.imageBufferSize = imageBufferSize;
|
||||
if (imageBufferSize > 0)
|
||||
{
|
||||
clone.imageBuffer = new byte[imageBufferSize];
|
||||
imageBuffer.CopyTo(clone.imageBuffer, 0);
|
||||
}
|
||||
|
||||
if (MessageArray == null)
|
||||
{
|
||||
clone.MessageArray = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
clone.MessageArray = new MessageData[MessageArray.Length];
|
||||
for (int i = 0; i < MessageArray.Length; i++)
|
||||
{
|
||||
clone.MessageArray[i] = (MessageData)MessageArray[i].Clone();
|
||||
}
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,426 @@
|
||||
// **********************************************************************************************************
|
||||
// MessageXmlDocument.cs
|
||||
// 5/18/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.XPath;
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using NLog;
|
||||
|
||||
namespace Raytheon.Instruments.MessagingUtilities
|
||||
{
|
||||
public class MessageXmlDocument : XmlDocument
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly string _XmlFileName;
|
||||
private string BuiltXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><?xml-stylesheet type=\"text/xsl\" ?><interface>";
|
||||
|
||||
private uint m_MaxMsgSize = 0;
|
||||
private readonly List<string> m_IncludeList;
|
||||
|
||||
private MessageXmlDocument() : base()
|
||||
{
|
||||
}
|
||||
|
||||
public MessageXmlDocument(string Pathname,
|
||||
ILogger logger) :
|
||||
base()
|
||||
{
|
||||
_logger = logger;
|
||||
_XmlFileName = Pathname;
|
||||
|
||||
m_IncludeList = new List<string>();
|
||||
RecurseProcessing(Pathname);
|
||||
|
||||
BuiltXML = string.Concat(BuiltXML, "</interface>");
|
||||
BytePackingXml addPacking = new BytePackingXml(BuiltXML);
|
||||
LoadXml(addPacking.OuterXml);
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetEnumerations(string Type)
|
||||
{
|
||||
Dictionary<string, string> enumList = new Dictionary<string, string>();
|
||||
|
||||
// Get XML nodes to parse the XML ICD document
|
||||
XPathNavigator Node = CreateNavigator();
|
||||
XPathNodeIterator Nodeset = Node.Select("interface/enum/name");
|
||||
|
||||
while (Nodeset.MoveNext())
|
||||
{
|
||||
// Find the enumeration with the name of the type
|
||||
if (Nodeset.Current.Value.Trim().Equals(Type.Trim()))
|
||||
{
|
||||
// Find all the enumeration items
|
||||
XPathNavigator enumNode = Nodeset.Current.Clone();
|
||||
while (enumNode.MoveToNext())
|
||||
{
|
||||
if (enumNode.Name.Trim().Equals("item") ||
|
||||
enumNode.Name.Trim().Equals("enum_item"))
|
||||
{
|
||||
string name = null;
|
||||
string value = null;
|
||||
|
||||
// Find all name nodes
|
||||
XPathNavigator childNode = enumNode.Clone();
|
||||
childNode.MoveToFirstChild();
|
||||
do
|
||||
{
|
||||
if (childNode.Name.Trim().Equals("name"))
|
||||
{
|
||||
name = childNode.Value.Trim();
|
||||
}
|
||||
else if (childNode.Name.Trim().Equals("item_name"))
|
||||
{
|
||||
name = childNode.Value.Trim();
|
||||
}
|
||||
|
||||
if (childNode.Name.Trim().Equals("value"))
|
||||
{
|
||||
value = childNode.Value.Trim();
|
||||
}
|
||||
|
||||
// Once we find the name & value, add it to the list
|
||||
if ((name != null) && (value != null))
|
||||
{
|
||||
enumList.Add(name, value);
|
||||
break;
|
||||
}
|
||||
} while (childNode.MoveToNext());
|
||||
}
|
||||
}
|
||||
|
||||
break; // We found the enumeration we wanted
|
||||
}
|
||||
}
|
||||
|
||||
return enumList;
|
||||
}
|
||||
|
||||
private void RecurseProcessing(string pathName)
|
||||
{
|
||||
string directory;
|
||||
string IncludePathname;
|
||||
XPathNodeIterator nodeset;
|
||||
|
||||
// Only process each file once
|
||||
pathName = pathName.Replace('/', '\\');
|
||||
if (m_IncludeList.Contains(pathName))
|
||||
{
|
||||
return; // This file has already been processed
|
||||
}
|
||||
else
|
||||
{
|
||||
m_IncludeList.Add(pathName);
|
||||
}
|
||||
|
||||
_logger.Log(LogLevel.Info, $"Loading File: {pathName}");
|
||||
XPathDocument document = new XPathDocument(pathName);
|
||||
XPathNavigator navigator = document.CreateNavigator();
|
||||
|
||||
// Verify this is a COE XML ICD
|
||||
nodeset = navigator.Select("/interface");
|
||||
if (nodeset.Count == 0)
|
||||
{
|
||||
// This is not an XML ICD
|
||||
throw new Exception($"Invalid COE XML Format. Unable to process {pathName}" +
|
||||
"\nEnsure this is a properly formatted ICD.");
|
||||
}
|
||||
|
||||
nodeset = navigator.Select("/interface/include/file");
|
||||
while (nodeset.MoveNext())
|
||||
{
|
||||
try
|
||||
{
|
||||
directory = DirectoryOf(pathName);
|
||||
}
|
||||
catch
|
||||
{
|
||||
directory = ".\\";
|
||||
}
|
||||
|
||||
IncludePathname = nodeset.Current.Value.Trim();
|
||||
if ((!IncludePathname.StartsWith("\\")) && (!IncludePathname.Contains(":")))
|
||||
{
|
||||
while (IncludePathname.StartsWith("."))
|
||||
{
|
||||
if ((IncludePathname.StartsWith("..\\")) || (IncludePathname.StartsWith("../")))
|
||||
{
|
||||
directory = DirectoryOf(directory);
|
||||
IncludePathname = IncludePathname.Remove(0, 3);
|
||||
}
|
||||
else if ((IncludePathname.StartsWith(".\\")) || (IncludePathname.StartsWith("./")))
|
||||
{
|
||||
IncludePathname = IncludePathname.Remove(0, 2);
|
||||
}
|
||||
}
|
||||
IncludePathname = string.Concat(directory, "\\", IncludePathname);
|
||||
}
|
||||
RecurseProcessing(IncludePathname);
|
||||
}
|
||||
|
||||
nodeset = navigator.Select("/interface/packing|/interface/typedef|/interface/constant|interface/enum|/interface/structure|/interface/message");
|
||||
while (nodeset.MoveNext())
|
||||
{
|
||||
string item = nodeset.Current.OuterXml;
|
||||
int index;
|
||||
while ((index = item.IndexOf("<description>")) != -1)
|
||||
{
|
||||
item = item.Remove(index, item.IndexOf("</description>") + 14 - index);
|
||||
}
|
||||
while ((index = item.IndexOf("<!--")) != -1)
|
||||
{
|
||||
item = item.Remove(index, item.IndexOf("-->") + 3 - index);
|
||||
}
|
||||
while (item.IndexOf("> ") != -1)
|
||||
{
|
||||
item = item.Replace("> ", ">");
|
||||
}
|
||||
while (item.IndexOf(" <") != -1)
|
||||
{
|
||||
item = item.Replace(" <", "<");
|
||||
}
|
||||
//_logger.Log(LogLevel.Trace, $"Loading Node :\n{item}");
|
||||
Thread.Sleep(1);
|
||||
BuiltXML = string.Concat(BuiltXML, item);
|
||||
}
|
||||
}
|
||||
|
||||
private string DirectoryOf(string Pathname)
|
||||
{
|
||||
return Pathname.Remove(Pathname.LastIndexOf("\\"));
|
||||
}
|
||||
|
||||
//
|
||||
// From the XML document, the definition of a single message can be identified
|
||||
// from the Message Name and returned as an XML string.
|
||||
//
|
||||
public string XmlFileName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _XmlFileName;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetMessage(string messageName)
|
||||
{
|
||||
string message;
|
||||
|
||||
messageName = messageName.Trim();
|
||||
_logger.Log(LogLevel.Info, $"Searching for message : {messageName}");
|
||||
try
|
||||
{
|
||||
message = SelectSingleNode($"/interface/message[name='{messageName}']").OuterXml;
|
||||
message = TranslateValue(message);
|
||||
_logger.Log(LogLevel.Trace, $"Found by name: {message}");
|
||||
}
|
||||
catch
|
||||
{
|
||||
message = null;
|
||||
_logger.Log(LogLevel.Error, "Message not found");
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
//
|
||||
// From the XML document, the definition of a single message can be identified
|
||||
// from the Message Label and returned as an XML string.
|
||||
//
|
||||
public string GetMessageFromLabel(string messageLabel)
|
||||
{
|
||||
string message;
|
||||
string msgLabel = "";
|
||||
|
||||
if (Parse.Try(messageLabel, out int label) == true)
|
||||
{
|
||||
msgLabel = label.ToString();
|
||||
}
|
||||
|
||||
_logger.Log(LogLevel.Info, $"Searching for message: {msgLabel}");
|
||||
try
|
||||
{
|
||||
// Search by message label
|
||||
message = SelectSingleNode($"/interface/message[label='{msgLabel}']").OuterXml;
|
||||
message = TranslateValue(message);
|
||||
_logger.Log(LogLevel.Trace, $"Found by label: {message}");
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
// Search by instruLabel
|
||||
message = SelectSingleNode($"/interface/message[instruLabel='{messageLabel}']").OuterXml;
|
||||
message = TranslateValue(message);
|
||||
_logger.Log(LogLevel.Trace, $"Found by instrument Label: {message}");
|
||||
}
|
||||
catch
|
||||
{
|
||||
message = null;
|
||||
_logger.Log(LogLevel.Error, "Message not found");
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
//
|
||||
// From the XML document, the definition of a single message can be identified
|
||||
// from the Message InstruLabel and returned as an XML string.
|
||||
//
|
||||
public string GetMessageFromInstruLabel(string messageInstruLabel)
|
||||
{
|
||||
string message;
|
||||
|
||||
messageInstruLabel = messageInstruLabel.Trim();
|
||||
_logger.Log(LogLevel.Info, $"Searching for message: {messageInstruLabel}");
|
||||
try
|
||||
{
|
||||
message = SelectSingleNode($"/interface/message[instruLabel='{messageInstruLabel}']").OuterXml;
|
||||
message = TranslateValue(message);
|
||||
_logger.Log(LogLevel.Trace, $"Found by instrument label: {message}");
|
||||
}
|
||||
catch
|
||||
{
|
||||
message = null;
|
||||
_logger.Log(LogLevel.Error, "Message not found");
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
public uint GetLargestMessageSize()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
// return the max message size if we have already calculated it
|
||||
if (m_MaxMsgSize != 0)
|
||||
{
|
||||
return m_MaxMsgSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
DateTime t1 = DateTime.Now;
|
||||
|
||||
XPathNavigator navigator = CreateNavigator();
|
||||
XPathNodeIterator nodeset = navigator.Select("/interface/message/name");
|
||||
|
||||
while (nodeset.MoveNext())
|
||||
{
|
||||
Message msg = new Message(nodeset.Current.Value.Trim(), this);
|
||||
uint msgSize = msg.GetMessageSize();
|
||||
if (msgSize > m_MaxMsgSize)
|
||||
{
|
||||
m_MaxMsgSize = msgSize;
|
||||
}
|
||||
}
|
||||
|
||||
DateTime t2 = DateTime.Now;
|
||||
TimeSpan duration = t2 - t1;
|
||||
Debug.WriteLine("Max Msg Size Algorithm Time = " + duration);
|
||||
}
|
||||
}
|
||||
|
||||
return m_MaxMsgSize;
|
||||
}
|
||||
|
||||
public uint GetMessageSize(string MsgName)
|
||||
{
|
||||
uint msg_size = 0;
|
||||
|
||||
lock (this)
|
||||
{
|
||||
XPathNavigator navigator = CreateNavigator();
|
||||
XPathNodeIterator nodeset = navigator.Select("/interface/message/name");
|
||||
|
||||
while (nodeset.MoveNext())
|
||||
{
|
||||
if (MsgName == nodeset.Current.Value.Trim())
|
||||
{
|
||||
Message msg = new Message(nodeset.Current.Value.Trim(), this);
|
||||
msg_size = msg.GetMessageSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return msg_size;
|
||||
}
|
||||
|
||||
//
|
||||
// Since the XML message definitions contain the definitions of all the enumerations and constants,
|
||||
// this object is the only one containing the knowledge to interpret strings using enumerations and/or
|
||||
// constants. This method will substitute enumerations and constants with their respective base values
|
||||
// in a specified string.
|
||||
//
|
||||
public string TranslateValue(string Value)
|
||||
{
|
||||
XPathNavigator navigator = CreateNavigator();
|
||||
XPathNavigator position;
|
||||
string NewValue = Value;
|
||||
|
||||
//
|
||||
// Substitute enumeration
|
||||
//
|
||||
try
|
||||
{
|
||||
position = navigator.SelectSingleNode("/interface/enum/item[name='" + NewValue + "']");
|
||||
if (position == null)
|
||||
{
|
||||
position = navigator.SelectSingleNode("/interface/enum/item[item_name='" + NewValue + "']");
|
||||
}
|
||||
if (position != null)
|
||||
{
|
||||
position.MoveToChild("value", "");
|
||||
NewValue = position.Value;
|
||||
}
|
||||
|
||||
//
|
||||
// Substitute constants
|
||||
//
|
||||
position = navigator.SelectSingleNode("/interface/constant[name='" + NewValue + "']");
|
||||
if (position != null)
|
||||
{
|
||||
NewValue = position.Value;
|
||||
_logger.Log(LogLevel.Info, "Translating field value : " + Value + " -> " + NewValue);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e.Message);
|
||||
}
|
||||
|
||||
return NewValue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// **********************************************************************************************************
|
||||
// OeMessage.cs
|
||||
// 5/18/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
|
||||
using Raytheon.Instruments.coeCSharp;
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Instruments.MessagingUtilities
|
||||
{
|
||||
public class OeMessage : coeMessage
|
||||
{
|
||||
public Message XmlMessage
|
||||
{
|
||||
get { return m_Msg; }
|
||||
set
|
||||
{
|
||||
m_Msg = value;
|
||||
Label = value.Label;
|
||||
Size = value.GetMessageSize();
|
||||
}
|
||||
}
|
||||
|
||||
public new string Label
|
||||
{
|
||||
get { return base.Label.ToString(); }
|
||||
set
|
||||
{
|
||||
if (Parse.Try(value, out uint label) == true)
|
||||
{
|
||||
base.Label = label;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("OeMessage: Label does not parse to an Unsigned Integer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public new string Domain
|
||||
{
|
||||
get { return base.Domain.ToString(); }
|
||||
set
|
||||
{
|
||||
if (Parse.Try(value, out uint domain) == true)
|
||||
{
|
||||
base.Domain = domain;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("OeMessage: Domain does not parse to an Unsigned Integer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OeMessage() : base(0) { m_Msg = null; }
|
||||
public OeMessage(int size) : base(size) { m_Msg = null; }
|
||||
public OeMessage(Message msg)
|
||||
: base(0)
|
||||
{
|
||||
XmlMessage = msg;
|
||||
}
|
||||
public OeMessage(Message msg, int msgSize) : base(msgSize)
|
||||
{
|
||||
XmlMessage = msg;
|
||||
}
|
||||
|
||||
override public void Serialize()
|
||||
{
|
||||
if (m_Msg != null)
|
||||
{
|
||||
byte[] serializedBuffer = m_Msg.serialize();
|
||||
if (serializedBuffer.Length > BufferSize)
|
||||
{
|
||||
BufferSize = serializedBuffer.Length;
|
||||
}
|
||||
Size = (uint)serializedBuffer.Length;
|
||||
copyToMessageBuffer(serializedBuffer);
|
||||
Domain = m_Msg.Domain;
|
||||
}
|
||||
}
|
||||
|
||||
override public void Deserialize()
|
||||
{
|
||||
if (m_Msg != null)
|
||||
{
|
||||
// Get sending time and pass it to the XmlMessage object;
|
||||
GetSendTime(out ulong sendSec, out uint sendSecFrac);
|
||||
m_Msg.SendSecond = sendSec;
|
||||
m_Msg.SendSecondFraction = sendSecFrac;
|
||||
m_Msg.Domain = Domain;
|
||||
byte[] receiveBuffer = copyFromMessageBuffer();
|
||||
if (receiveBuffer != null)
|
||||
{
|
||||
m_Msg.deserialize(receiveBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Message m_Msg = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
// **********************************************************************************************************
|
||||
// Parse.cs
|
||||
// 5/18/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Instruments.MessagingUtilities
|
||||
{
|
||||
public class Parse
|
||||
{
|
||||
public static bool Try(string value, out byte result)
|
||||
{
|
||||
result = 0;
|
||||
if (value == null)
|
||||
return false; // Handle bad argument
|
||||
|
||||
bool passed = byte.TryParse(value, out result);
|
||||
if (passed == false)
|
||||
{
|
||||
if (value.StartsWith("0x") == true)
|
||||
{
|
||||
value = value.Substring(2, value.Length - 2);
|
||||
passed = byte.TryParse(value, System.Globalization.NumberStyles.HexNumber, null, out result);
|
||||
}
|
||||
else if (value.EndsWith("b") == true)
|
||||
{
|
||||
value = value.TrimEnd("b".ToCharArray());
|
||||
try
|
||||
{
|
||||
result = Convert.ToByte(value, 2);
|
||||
passed = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
passed = true; // Handle Boolean TYPES
|
||||
if (value.Trim().ToUpper().Equals("TRUE"))
|
||||
result = 1;
|
||||
else if (value.Trim().ToUpper().Equals("FALSE"))
|
||||
result = 0;
|
||||
else
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
public static bool Try(string value, out decimal result)
|
||||
{
|
||||
result = 0;
|
||||
if (value == null)
|
||||
return false; // Handle bad argument
|
||||
|
||||
bool passed = decimal.TryParse(value, System.Globalization.NumberStyles.Any, null, out result);
|
||||
if (passed == false)
|
||||
{
|
||||
if (value.StartsWith("0x") == true)
|
||||
{
|
||||
value = value.Substring(2, value.Length - 2);
|
||||
passed = int.TryParse(value, System.Globalization.NumberStyles.HexNumber, null, out int hexResult);
|
||||
if (passed)
|
||||
{
|
||||
result = hexResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
public static bool Try(string value, out short result)
|
||||
{
|
||||
result = 0;
|
||||
if (value == null)
|
||||
return false; // Handle bad argument
|
||||
|
||||
bool passed = short.TryParse(value, out result);
|
||||
if (passed == false)
|
||||
{
|
||||
if (value.StartsWith("0x") == true)
|
||||
{
|
||||
value = value.Substring(2, value.Length - 2);
|
||||
passed = short.TryParse(value, System.Globalization.NumberStyles.HexNumber, null, out result);
|
||||
}
|
||||
else if (value.EndsWith("b") == true)
|
||||
{
|
||||
value = value.TrimEnd("b".ToCharArray());
|
||||
try
|
||||
{
|
||||
result = Convert.ToInt16(value, 2);
|
||||
passed = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
passed = true; // Handle Boolean TYPES
|
||||
if (value.Trim().ToUpper().Equals("TRUE"))
|
||||
result = 1;
|
||||
else if (value.Trim().ToUpper().Equals("FALSE"))
|
||||
result = 0;
|
||||
else
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
public static bool Try(string value, out ushort result)
|
||||
{
|
||||
result = 0;
|
||||
if (value == null)
|
||||
return false; // Handle bad argument
|
||||
|
||||
bool passed = ushort.TryParse(value, out result);
|
||||
if (passed == false)
|
||||
{
|
||||
if (value.StartsWith("0x") == true)
|
||||
{
|
||||
value = value.Substring(2, value.Length - 2);
|
||||
passed = ushort.TryParse(value, System.Globalization.NumberStyles.HexNumber, null, out result);
|
||||
}
|
||||
else if (value.EndsWith("b") == true)
|
||||
{
|
||||
value = value.TrimEnd("b".ToCharArray());
|
||||
try
|
||||
{
|
||||
result = Convert.ToUInt16(value, 2);
|
||||
passed = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
passed = true; // Handle Boolean TYPES
|
||||
if (value.Trim().ToUpper().Equals("TRUE"))
|
||||
result = 1;
|
||||
else if (value.Trim().ToUpper().Equals("FALSE"))
|
||||
result = 0;
|
||||
else
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
public static bool Try(string value, out int result)
|
||||
{
|
||||
result = 0;
|
||||
if (value == null)
|
||||
return false; // Handle bad argument
|
||||
|
||||
bool passed = int.TryParse(value, System.Globalization.NumberStyles.Any, null, out result);
|
||||
if (passed == false)
|
||||
{
|
||||
if (value.StartsWith("0x") == true)
|
||||
{
|
||||
value = value.Substring(2, value.Length - 2);
|
||||
passed = int.TryParse(value, System.Globalization.NumberStyles.HexNumber, null, out result);
|
||||
}
|
||||
else if (value.EndsWith("b") == true)
|
||||
{
|
||||
value = value.TrimEnd("b".ToCharArray());
|
||||
try
|
||||
{
|
||||
result = Convert.ToInt32(value, 2);
|
||||
passed = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
passed = true; // Handle Boolean TYPES
|
||||
if (value.Trim().ToUpper().Equals("TRUE"))
|
||||
result = 1;
|
||||
else if (value.Trim().ToUpper().Equals("FALSE"))
|
||||
result = 0;
|
||||
else
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
public static bool Try(string value, out uint result)
|
||||
{
|
||||
result = 0;
|
||||
if (value == null)
|
||||
return false; // Handle bad argument
|
||||
|
||||
bool passed = uint.TryParse(value, out result);
|
||||
if (passed == false)
|
||||
{
|
||||
if (value.StartsWith("0x") == true)
|
||||
{
|
||||
value = value.Substring(2, value.Length - 2);
|
||||
passed = uint.TryParse(value, System.Globalization.NumberStyles.HexNumber, null, out result);
|
||||
}
|
||||
else if (value.EndsWith("b") == true)
|
||||
{
|
||||
value = value.TrimEnd("b".ToCharArray());
|
||||
try
|
||||
{
|
||||
result = Convert.ToUInt32(value, 2);
|
||||
passed = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
passed = true; // Handle Boolean TYPES
|
||||
if (value.Trim().ToUpper().Equals("TRUE"))
|
||||
result = 1;
|
||||
else if (value.Trim().ToUpper().Equals("FALSE"))
|
||||
result = 0;
|
||||
else
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
public static bool Try(string value, out long result)
|
||||
{
|
||||
result = 0;
|
||||
if (value == null || value == "")
|
||||
return false; // Handle bad argument
|
||||
|
||||
bool passed = long.TryParse(value, out result);
|
||||
if (passed == false)
|
||||
{
|
||||
if (value.StartsWith("0x") == true)
|
||||
{
|
||||
value = value.Substring(2, value.Length - 2);
|
||||
passed = long.TryParse(value, System.Globalization.NumberStyles.HexNumber, null, out result);
|
||||
}
|
||||
else if (value.EndsWith("b") == true)
|
||||
{
|
||||
value = value.TrimEnd("b".ToCharArray());
|
||||
try
|
||||
{
|
||||
result = Convert.ToInt64(value, 2);
|
||||
passed = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
passed = true; // Handle Boolean TYPES
|
||||
if (value.Trim().ToUpper().Equals("TRUE"))
|
||||
result = 1;
|
||||
else if (value.Trim().ToUpper().Equals("FALSE"))
|
||||
result = 0;
|
||||
else
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
public static bool Try(string value, out ulong result)
|
||||
{
|
||||
result = 0;
|
||||
if (value == null)
|
||||
return false; // Handle bad argument
|
||||
|
||||
bool passed = ulong.TryParse(value, out result);
|
||||
if (passed == false)
|
||||
{
|
||||
if (value.StartsWith("0x") == true)
|
||||
{
|
||||
value = value.Substring(2, value.Length - 2);
|
||||
passed = ulong.TryParse(value, System.Globalization.NumberStyles.HexNumber, null, out result);
|
||||
}
|
||||
else if (value.EndsWith("b") == true)
|
||||
{
|
||||
value = value.TrimEnd("b".ToCharArray());
|
||||
try
|
||||
{
|
||||
result = Convert.ToUInt64(value, 2);
|
||||
passed = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
passed = true; // Handle Boolean TYPES
|
||||
if (value.Trim().ToUpper().Equals("TRUE"))
|
||||
result = 1;
|
||||
else if (value.Trim().ToUpper().Equals("FALSE"))
|
||||
result = 0;
|
||||
else
|
||||
passed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
public static bool Try(string value, out char result)
|
||||
{
|
||||
return char.TryParse(value, out result);
|
||||
}
|
||||
|
||||
public static bool Try(string value, out float result)
|
||||
{
|
||||
if (value.EndsWith("f") == true)
|
||||
value = value.TrimEnd("f".ToCharArray());
|
||||
|
||||
return float.TryParse(value, System.Globalization.NumberStyles.Any, null, out result);
|
||||
}
|
||||
|
||||
public static bool Try(string value, out double result)
|
||||
{
|
||||
if (value.EndsWith("f") == true)
|
||||
value = value.TrimEnd("f".ToCharArray());
|
||||
|
||||
return double.TryParse(value, System.Globalization.NumberStyles.Any, null, out result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
// **********************************************************************************************************
|
||||
// XmlMbitParser.cs
|
||||
// 6/6/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.XPath;
|
||||
|
||||
namespace Raytheon.Instruments.XmlUtilities
|
||||
{
|
||||
public class XmlMbitParser
|
||||
{
|
||||
private readonly NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly Dictionary<string, XmlParser.CommonXmlElements> _commonElements = new Dictionary<string, XmlParser.CommonXmlElements>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
// store messages defined in xml files
|
||||
private readonly List<XmlParser.XmlMbitMessage> _mbitMessages = new List<XmlParser.XmlMbitMessage>();
|
||||
|
||||
// store duplicate messages for diagnostic purposes
|
||||
private readonly Dictionary<string, List<string>> _duplicateMbitMessages = new Dictionary<string, List<string>>();
|
||||
|
||||
// store each enumeration type and its associate key/value pairs
|
||||
private readonly Dictionary<string, XmlParser.XmlEnumeration> _xmlEnums = new Dictionary<string, XmlParser.XmlEnumeration>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
// store duplicate enumerations for diagnostic purposes
|
||||
private readonly Dictionary<string, List<string>> _duplicateEnums = new Dictionary<string, List<string>>();
|
||||
|
||||
// store each structure type and its associated data members
|
||||
private readonly Dictionary<string, XmlParser.XmlStructure> _xmlStructures = new Dictionary<string, XmlParser.XmlStructure>(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
// store duplicate structures for diagnostic purposes
|
||||
private readonly Dictionary<string, List<string>> _duplicateStructures = new Dictionary<string, List<string>>();
|
||||
|
||||
// look up table for constants, the key is the constant name. A constant name can be defined in more than one namespace and have different values
|
||||
private ILookup<string, XmlParser.XmlConstant> _xmlConstantsLookUpByConstantName = null;
|
||||
|
||||
// look up table for constants, the key is the namespace in which the constant is defined. A constant name can be defined in more than one namespace and have different values
|
||||
private ILookup<string, XmlParser.XmlConstant> _xmlConstantsLookUpByNameSpace = null;
|
||||
|
||||
// store duplicate constants for diagnostic purposes
|
||||
private readonly Dictionary<string, List<string>> _duplicateConstants = new Dictionary<string, List<string>>();
|
||||
|
||||
// store names of files that contain data types that we need to generate
|
||||
public List<string> m_dataTypeFilesToBeGenerated = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Parse XML files from the path folder
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public bool ParseXmlFiles(string path)
|
||||
{
|
||||
bool isSuccessful = true;
|
||||
string xmlNamespace = string.Empty;
|
||||
List<XmlParser.XmlConstant> constantList = new List<XmlParser.XmlConstant>();
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
_logger.Error($"Path {path} not found");
|
||||
|
||||
isSuccessful = false;
|
||||
return isSuccessful;
|
||||
}
|
||||
|
||||
string[] files = Directory.GetFiles(path, "*.xml", SearchOption.AllDirectories);
|
||||
|
||||
List<string> dataTypeFiles = new List<string>(files.ToList());
|
||||
|
||||
foreach (string xmlFile in dataTypeFiles)
|
||||
{
|
||||
XPathDocument doc = null;
|
||||
|
||||
int prevEnumCount = _xmlEnums.Count;
|
||||
int prevStructureCount = _xmlStructures.Count;
|
||||
int prevMessageCount = _mbitMessages.Count;
|
||||
int prevConstantCount = constantList.Count;
|
||||
|
||||
List<string> comments = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
XmlReaderSettings readerSettings = new XmlReaderSettings()
|
||||
{
|
||||
// tells the xmlreader to ignore comment in XML file
|
||||
IgnoreComments = true
|
||||
};
|
||||
|
||||
using (XmlReader reader = XmlReader.Create(xmlFile, readerSettings))
|
||||
{
|
||||
// load the XML file
|
||||
doc = new XPathDocument(reader);
|
||||
}
|
||||
|
||||
XPathNavigator nav = doc.CreateNavigator();
|
||||
|
||||
xmlNamespace = Path.GetFileNameWithoutExtension(xmlFile);
|
||||
|
||||
_commonElements[xmlNamespace] = new XmlParser.CommonXmlElements();
|
||||
|
||||
nav.MoveToRoot();
|
||||
|
||||
try
|
||||
{
|
||||
_logger.Info($"Parsing {Path.GetFileName(xmlFile)}");
|
||||
|
||||
if (nav.MoveToFirstChild())
|
||||
{
|
||||
do
|
||||
{
|
||||
if (string.Equals(nav.Name, "interface", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (nav.MoveToFirstChild())
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!XmlParser.GetCommonElementsFromXml(nav, _commonElements[xmlNamespace]))
|
||||
{
|
||||
if (string.Equals(nav.Name, "enum", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
XmlParser.GetEnumeration(nav, xmlNamespace, _xmlEnums, _duplicateEnums);
|
||||
}
|
||||
else if (string.Equals(nav.Name, "structure", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
XmlParser.GetStructure(nav, xmlNamespace, _xmlStructures, comments, _duplicateStructures);
|
||||
comments.Clear();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "constant", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
XmlParser.GetConstant(nav, xmlNamespace, constantList, _duplicateConstants);
|
||||
}
|
||||
else if (string.Equals(nav.Name, "message", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
XmlParser.GetMbitMessage(nav, xmlNamespace, _mbitMessages, _duplicateMbitMessages);
|
||||
}
|
||||
else if (string.Equals(nav.Name, "comment", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
comments.Add(nav.Value.Trim());
|
||||
}
|
||||
else if (nav.Name.Length > 0)
|
||||
{
|
||||
throw new XmlParsingException("Unknown element \"" + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + "\" on line " + ((IXmlLineInfo)nav).LineNumber.ToString());
|
||||
}
|
||||
}
|
||||
} while (nav.MoveToNext());
|
||||
}
|
||||
}
|
||||
} while (nav.MoveToNext());
|
||||
}
|
||||
}
|
||||
catch (XmlParsingException ex)
|
||||
{
|
||||
string message = "File : " + xmlFile + "\n" + ex.Message;
|
||||
throw new Exception(message);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e);
|
||||
isSuccessful = false;
|
||||
}
|
||||
|
||||
if (isSuccessful)
|
||||
{
|
||||
_logger.Info(" - SUCCESS");
|
||||
|
||||
_logger.Info("Results:");
|
||||
_logger.Info($"Constants: {constantList.Count - prevConstantCount}");
|
||||
_logger.Info($"Enumerations: {_xmlEnums.Count - prevEnumCount}");
|
||||
_logger.Info($"Structures: {_xmlStructures.Count - prevStructureCount}");
|
||||
_logger.Info($"Messages: {_mbitMessages.Count - prevMessageCount}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Warn(" - FAIL");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (constantList.Count > 0)
|
||||
{
|
||||
// we want to create a look up table from a list of constants
|
||||
// the key for this table will be the constant name
|
||||
_xmlConstantsLookUpByConstantName = constantList.ToLookup(item => item.name);
|
||||
|
||||
// we want to create a look up table from a list of constants
|
||||
// the key for this table will be the namespace
|
||||
_xmlConstantsLookUpByNameSpace = constantList.ToLookup(item => item.nameSpace);
|
||||
}
|
||||
|
||||
if (_duplicateMbitMessages.Count > 0 || _duplicateConstants.Count > 0 || _duplicateEnums.Count > 0 || _duplicateStructures.Count > 0)
|
||||
{
|
||||
StreamWriter writer = null;
|
||||
FileStream fs = null;
|
||||
bool firstLineInFileAllocated = false;
|
||||
string textToBeWrittenToFile = string.Empty;
|
||||
string diagnosticFile = Path.Combine(path, "diagnostics.txt");
|
||||
|
||||
_logger.Info("Generating diagnostic information...");
|
||||
|
||||
foreach (KeyValuePair<string, List<string>> dictItem in _duplicateMbitMessages)
|
||||
{
|
||||
if (!firstLineInFileAllocated)
|
||||
firstLineInFileAllocated = true;
|
||||
else
|
||||
textToBeWrittenToFile += "\r\n\r\n";
|
||||
|
||||
textToBeWrittenToFile += "Duplicate definition for message \"" + dictItem.Key + "\" found in the following files: ";
|
||||
foreach (string listItem in dictItem.Value)
|
||||
{
|
||||
textToBeWrittenToFile += "\r\n" + GetCodeIndentation(1) + listItem;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, List<string>> dictItem in _duplicateStructures)
|
||||
{
|
||||
if (!firstLineInFileAllocated)
|
||||
firstLineInFileAllocated = true;
|
||||
else
|
||||
textToBeWrittenToFile += "\r\n\r\n";
|
||||
|
||||
textToBeWrittenToFile += "Duplicate definition for structure \"" + dictItem.Key + "\" found in the following files: ";
|
||||
foreach (string listItem in dictItem.Value)
|
||||
{
|
||||
textToBeWrittenToFile += "\r\n" + GetCodeIndentation(1) + listItem;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, List<string>> dictItem in _duplicateEnums)
|
||||
{
|
||||
if (!firstLineInFileAllocated)
|
||||
firstLineInFileAllocated = true;
|
||||
else
|
||||
textToBeWrittenToFile += "\r\n\r\n";
|
||||
|
||||
textToBeWrittenToFile += "Duplicate definition for enum \"" + dictItem.Key + "\" found in the following files: ";
|
||||
foreach (string listItem in dictItem.Value)
|
||||
{
|
||||
textToBeWrittenToFile += "\r\n" + GetCodeIndentation(1) + listItem;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, List<string>> dictItem in _duplicateConstants)
|
||||
{
|
||||
if (!firstLineInFileAllocated)
|
||||
firstLineInFileAllocated = true;
|
||||
else
|
||||
textToBeWrittenToFile += "\r\n\r\n";
|
||||
|
||||
textToBeWrittenToFile += "Duplicate definition for constant \"" + dictItem.Key + "\" found in the following files: ";
|
||||
foreach (string listItem in dictItem.Value)
|
||||
{
|
||||
textToBeWrittenToFile += "\r\n" + GetCodeIndentation(1) + listItem;
|
||||
}
|
||||
}
|
||||
|
||||
if (textToBeWrittenToFile.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
fs = new FileStream(diagnosticFile, FileMode.Create, FileAccess.ReadWrite);
|
||||
writer = new StreamWriter(fs, Encoding.Default);
|
||||
writer.Write(textToBeWrittenToFile);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
_logger.Error(ex);
|
||||
isSuccessful = false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (writer != null)
|
||||
{
|
||||
writer.Close();
|
||||
fs.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//m_mainWindow.updateStatusBox("DONE\n");
|
||||
}
|
||||
|
||||
return isSuccessful;
|
||||
}
|
||||
public static string GetCodeIndentation(int indentMultiples)
|
||||
{
|
||||
string indentUnit = " ";
|
||||
string indentation = string.Empty;
|
||||
|
||||
for (int i = 1; i <= indentMultiples; i++)
|
||||
indentation += indentUnit;
|
||||
|
||||
return indentation;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,588 @@
|
||||
// **********************************************************************************************************
|
||||
// XmlParser.cs
|
||||
// 6/6/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using System.Xml.XPath;
|
||||
|
||||
namespace Raytheon.Instruments.XmlUtilities
|
||||
{
|
||||
public class XmlParser
|
||||
{
|
||||
public class CommonXmlElements
|
||||
{
|
||||
public List<string> fileIncludes = new List<string>();
|
||||
public string projectName = string.Empty;
|
||||
public string classification = string.Empty;
|
||||
public string fileHeader = string.Empty;
|
||||
}
|
||||
|
||||
public class XmlConstant
|
||||
{
|
||||
public string nameSpace = string.Empty;
|
||||
public List<string> comments = new List<string>();
|
||||
public string name = string.Empty;
|
||||
public string value = string.Empty;
|
||||
public string description = string.Empty;
|
||||
}
|
||||
|
||||
public class XmlEnumeration
|
||||
{
|
||||
public string nameSpace = string.Empty;
|
||||
public string description = string.Empty;
|
||||
public List<string> comments = new List<string>();
|
||||
//public Dictionary<string, string> enumKeyAndValuePairs = new Dictionary<string, string>();
|
||||
public List<XmlEnumItem> enumItems = new List<XmlEnumItem>();
|
||||
}
|
||||
|
||||
public class XmlEnumItem
|
||||
{
|
||||
public List<string> comments = new List<string>();
|
||||
public string name = string.Empty;
|
||||
public string value = string.Empty;
|
||||
}
|
||||
|
||||
public class XmlStructure
|
||||
{
|
||||
public string nameSpace = string.Empty;
|
||||
public string name = string.Empty;
|
||||
public List<string> comments = new List<string>();
|
||||
public List<XmlStructureItem> structDataItems = new List<XmlStructureItem>();
|
||||
}
|
||||
|
||||
public class XmlStructureItem
|
||||
{
|
||||
public string nameSpace = string.Empty;
|
||||
public List<string> comments = new List<string>();
|
||||
public string name = string.Empty;
|
||||
public string description = string.Empty;
|
||||
public string type = string.Empty;
|
||||
public string defaultVal = string.Empty;
|
||||
public string arrayLength = string.Empty;
|
||||
public string bits = string.Empty;
|
||||
}
|
||||
|
||||
public class XmlMbitMessage
|
||||
{
|
||||
public string nameSpace = string.Empty;
|
||||
public string name = string.Empty;
|
||||
public string label = string.Empty;
|
||||
public string instruLabel = string.Empty;
|
||||
public string description = string.Empty;
|
||||
public List<string> comments = new List<string>();
|
||||
|
||||
public List<XmlParser.XmlStructureItem> dataItems = new List<XmlParser.XmlStructureItem>();
|
||||
}
|
||||
|
||||
///===================================================================================
|
||||
/// XmlParser.getCommonElementsFromXml
|
||||
///===================================================================================
|
||||
/// <summary>
|
||||
/// Each XML file contains common elements such as header, includes, etc
|
||||
/// We want to parse it and save the common elements
|
||||
/// </summary>
|
||||
/// <param name="nav">navigator object that points to the current XML node we are at</param>
|
||||
/// <param name="commonElements">data structure that stores all the common elements of each XML file</param>
|
||||
///===================================================================================
|
||||
public static bool GetCommonElementsFromXml(XPathNavigator nav, CommonXmlElements commonElements)
|
||||
{
|
||||
bool isSuccessful = true;
|
||||
|
||||
if (string.Equals(nav.Name, "include", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (nav.MoveToFirstChild())
|
||||
{
|
||||
GetFileIncludes(nav, commonElements);
|
||||
|
||||
nav.MoveToParent();
|
||||
}
|
||||
}
|
||||
else if (string.Equals(nav.Name, "project", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
commonElements.projectName = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "classification", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
commonElements.classification = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "fileheader", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
commonElements.fileHeader = nav.Value;
|
||||
}
|
||||
else if (string.Equals(nav.Name, "packing", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
}
|
||||
else
|
||||
isSuccessful = false;
|
||||
|
||||
return isSuccessful;
|
||||
}
|
||||
|
||||
///===================================================================================
|
||||
/// XmlParser.getFileIncludes
|
||||
///===================================================================================
|
||||
/// <summary>
|
||||
/// Get the file includes specify by the XML file
|
||||
/// </summary>
|
||||
/// <param name="nav">navigator object that points to the current XML node we are at</param>
|
||||
/// <param name="commonElements">data structure that stores all the common elements of each XML file</param>
|
||||
///===================================================================================
|
||||
public static void GetFileIncludes(XPathNavigator nav, CommonXmlElements commonElements)
|
||||
{
|
||||
do
|
||||
{
|
||||
commonElements.fileIncludes.Add(nav.Value.Trim());
|
||||
|
||||
} while (nav.MoveToNext());
|
||||
}
|
||||
|
||||
///===================================================================================
|
||||
/// XmlParser.getConstant
|
||||
///===================================================================================
|
||||
/// <summary>
|
||||
/// Parse the symbolic constant defined by the XML
|
||||
/// </summary>
|
||||
/// <param name="nav">navigator object that points to the current XML node we are at</param>
|
||||
/// <param name="nameSpace">the XML file name that defines this constant</param>
|
||||
/// <param name="xmlConstants">the Dictionary that stores this constant information</param>
|
||||
/// <param name="duplicateConstants">the Dictioanry that stores duplicate constant definitions</param>
|
||||
///===================================================================================
|
||||
public static void GetConstant(XPathNavigator nav, string nameSpace, List<XmlConstant> xmlConstants, Dictionary<string, List<string>> duplicateConstants)
|
||||
{
|
||||
XmlConstant tempXmlConstant = new XmlConstant();
|
||||
|
||||
if (nav.MoveToFirstChild())
|
||||
{
|
||||
do
|
||||
{
|
||||
if (string.Equals(nav.Name, "name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
tempXmlConstant.name = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "description", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
tempXmlConstant.description = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "value", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
tempXmlConstant.value = nav.Value.Trim();
|
||||
}
|
||||
else if (nav.Name.Length > 0)
|
||||
{
|
||||
throw new XmlParsingException("Unknown element \"" + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + "\" on line " + ((IXmlLineInfo)nav).LineNumber.ToString());
|
||||
}
|
||||
|
||||
} while (nav.MoveToNext());
|
||||
|
||||
nav.MoveToParent();
|
||||
}
|
||||
|
||||
if (tempXmlConstant.name.Length > 0)
|
||||
{
|
||||
tempXmlConstant.nameSpace = nameSpace;
|
||||
xmlConstants.Add(tempXmlConstant);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new XmlParsingException("Child element \"name\" not found for node \"" + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + "\" on line " + ((IXmlLineInfo)nav).LineNumber.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
///===================================================================================
|
||||
/// XmlParser.getEnumeration
|
||||
///===================================================================================
|
||||
/// <summary>
|
||||
/// Parse the enumeration type defined by the XML
|
||||
/// </summary>
|
||||
/// <param name="nav">navigator object that points to the current XML node we are at</param>
|
||||
/// <param name="nameSpace">the XML file name that defines this enumeration type</param>
|
||||
/// <param name="xmlEnum">data structure that stores enumeration data</param>
|
||||
/// <param name="duplicateEnums">the Dictioanry that stores duplicate enumeration type</param>
|
||||
///===================================================================================
|
||||
public static void GetEnumeration(XPathNavigator nav, string nameSpace, Dictionary<string, XmlEnumeration> xmlEnums, Dictionary<string, List<string>> duplicateEnums)
|
||||
{
|
||||
string enumTypeName = string.Empty;
|
||||
string tempEnumTypeName = "temp";
|
||||
Dictionary<string, XmlEnumeration> tempXmlEnums = new Dictionary<string, XmlEnumeration>
|
||||
{
|
||||
[tempEnumTypeName] = new XmlEnumeration()
|
||||
};
|
||||
tempXmlEnums[tempEnumTypeName].nameSpace = nameSpace;
|
||||
|
||||
if (nav.MoveToFirstChild())
|
||||
{
|
||||
do
|
||||
{
|
||||
if (string.Equals(nav.Name, "name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
enumTypeName = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "description", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
tempXmlEnums[tempEnumTypeName].description = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "comment", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
tempXmlEnums[tempEnumTypeName].comments.Add(nav.Value.Trim());
|
||||
}
|
||||
else if (string.Equals(nav.Name, "item", StringComparison.OrdinalIgnoreCase) || string.Equals(nav.Name, "enum_item", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (nav.MoveToFirstChild())
|
||||
{
|
||||
GetEnumItem(nav, tempXmlEnums[tempEnumTypeName]);
|
||||
|
||||
nav.MoveToParent();
|
||||
}
|
||||
}
|
||||
else if (nav.Name.Length > 0)
|
||||
{
|
||||
throw new XmlParsingException("Unknown element \"" + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + "\" on line " + ((IXmlLineInfo)nav).LineNumber.ToString());
|
||||
}
|
||||
|
||||
} while (nav.MoveToNext());
|
||||
|
||||
nav.MoveToParent();
|
||||
}
|
||||
|
||||
if (enumTypeName.Length > 0)
|
||||
{
|
||||
if (xmlEnums.ContainsKey(enumTypeName))
|
||||
{
|
||||
// save file name the defines this message that is a duplicate
|
||||
if (!duplicateEnums.ContainsKey(enumTypeName))
|
||||
{
|
||||
duplicateEnums[enumTypeName] = new List<string>();
|
||||
}
|
||||
|
||||
int index2 = duplicateEnums[enumTypeName].FindIndex(f => string.Equals(f, nameSpace + ".xml", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (index2 < 0)
|
||||
duplicateEnums[enumTypeName].Add(nameSpace + ".xml");
|
||||
|
||||
// see if the official structure is already in the duplicate list
|
||||
int index3 = duplicateEnums[enumTypeName].FindIndex(f => string.Equals(f, xmlEnums[enumTypeName].nameSpace + ".xml", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// if the official structure is not in the duplicate list, we want to save it in the duplicate list
|
||||
if (index3 < 0)
|
||||
{
|
||||
duplicateEnums[enumTypeName].Add(xmlEnums[enumTypeName].nameSpace + ".xml");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlEnums[enumTypeName] = tempXmlEnums[tempEnumTypeName];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new XmlParsingException("Child element \"name\" not found for node \"" + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + "\" on line " + ((IXmlLineInfo)nav).LineNumber.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
///===================================================================================
|
||||
/// XmlParser.getEnumItem
|
||||
///===================================================================================
|
||||
/// <summary>
|
||||
/// Parse each enumerated key/value pair
|
||||
/// </summary>
|
||||
/// <param name="nav">navigator object that points to the current XML node we are at</param>
|
||||
/// <param name="xmlEnum">data structure that stores enumeration data</param>
|
||||
///===================================================================================
|
||||
public static void GetEnumItem(XPathNavigator nav, XmlEnumeration xmlEnum)
|
||||
{
|
||||
XmlEnumItem enumItem = new XmlEnumItem();
|
||||
|
||||
do
|
||||
{
|
||||
if (string.Equals(nav.Name, "name", StringComparison.OrdinalIgnoreCase) || string.Equals(nav.Name, "item_name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
enumItem.name = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "value", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
enumItem.value = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "comment", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
enumItem.comments.Add(nav.Value.Trim());
|
||||
}
|
||||
else if (nav.Name.Length > 0)
|
||||
{
|
||||
throw new XmlParsingException("Unknown element \"" + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + "\" on line " + ((IXmlLineInfo)nav).LineNumber.ToString());
|
||||
}
|
||||
|
||||
} while (nav.MoveToNext());
|
||||
|
||||
xmlEnum.enumItems.Add(enumItem);
|
||||
}
|
||||
|
||||
public static void GetStructure(XPathNavigator nav, string nameSpace, Dictionary<string, XmlStructure> xmlStructures, List<string> comments, Dictionary<string, List<string>> duplicateStructures)
|
||||
{
|
||||
string structureTypeName = string.Empty;
|
||||
string tempStructureTypeName = "temp";
|
||||
Dictionary<string, XmlStructure> tempXmlStructures = new Dictionary<string, XmlStructure>();
|
||||
|
||||
tempXmlStructures[tempStructureTypeName] = new XmlStructure();
|
||||
tempXmlStructures[tempStructureTypeName].nameSpace = nameSpace;
|
||||
|
||||
if (nav.MoveToFirstChild())
|
||||
{
|
||||
do
|
||||
{
|
||||
if (string.Equals(nav.Name, "name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
structureTypeName = nav.Value.Trim();
|
||||
|
||||
if (comments != null && comments.Count > 0)
|
||||
{
|
||||
tempXmlStructures[tempStructureTypeName].comments = new List<string>(comments);
|
||||
}
|
||||
}
|
||||
else if (string.Equals(nav.Name, "comment", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
tempXmlStructures[tempStructureTypeName].comments.Add(nav.Value.Trim());
|
||||
}
|
||||
else if (string.Equals(nav.Name, "item", StringComparison.OrdinalIgnoreCase) || string.Equals(nav.Name, "struct_item", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (nav.MoveToFirstChild())
|
||||
{
|
||||
XmlStructureItem structureItem = new XmlStructureItem();
|
||||
structureItem.nameSpace = nameSpace;
|
||||
GetStructureItem(nav, structureItem);
|
||||
|
||||
tempXmlStructures[tempStructureTypeName].structDataItems.Add(structureItem);
|
||||
|
||||
nav.MoveToParent();
|
||||
}
|
||||
}
|
||||
else if (nav.Name.Length > 0)
|
||||
{
|
||||
throw new XmlParsingException("Unknown element \"" + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + "\" on line " + ((IXmlLineInfo)nav).LineNumber.ToString());
|
||||
}
|
||||
|
||||
} while (nav.MoveToNext());
|
||||
|
||||
nav.MoveToParent();
|
||||
}
|
||||
|
||||
if (structureTypeName.Length > 0)
|
||||
{
|
||||
if (xmlStructures.ContainsKey(structureTypeName))
|
||||
{
|
||||
// save file name the defines this message that is a duplicate
|
||||
if (!duplicateStructures.ContainsKey(structureTypeName))
|
||||
{
|
||||
duplicateStructures[structureTypeName] = new List<string>();
|
||||
}
|
||||
|
||||
int index2 = duplicateStructures[structureTypeName].FindIndex(f => string.Equals(f, nameSpace + ".xml", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (index2 < 0)
|
||||
duplicateStructures[structureTypeName].Add(nameSpace + ".xml");
|
||||
|
||||
// see if the official structure is already in the duplicate list
|
||||
int index3 = duplicateStructures[structureTypeName].FindIndex(f => string.Equals(f, xmlStructures[structureTypeName].nameSpace + ".xml", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// if the official structure is not in the duplicate list, we want to save it in the duplicate list
|
||||
if (index3 < 0)
|
||||
{
|
||||
duplicateStructures[structureTypeName].Add(xmlStructures[structureTypeName].nameSpace + ".xml");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlStructures[structureTypeName] = tempXmlStructures[tempStructureTypeName];
|
||||
xmlStructures[structureTypeName].name = structureTypeName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new XmlParsingException("Child element \"name\" not found for node \"" + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + "\" on line " + ((IXmlLineInfo)nav).LineNumber.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
///===================================================================================
|
||||
/// XmlParser.getStructureItem
|
||||
///===================================================================================
|
||||
/// <summary>
|
||||
/// Parse the data structure defined by the XML
|
||||
/// </summary>
|
||||
/// <param name="nav">navigator object that points to the current XML node we are at</param>
|
||||
/// <param name="xmlStructureItem">data structure that stores all data members of the data structure</param>
|
||||
///===================================================================================
|
||||
public static void GetStructureItem(XPathNavigator nav, XmlStructureItem xmlStructureItem)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (string.Equals(nav.Name, "name", StringComparison.OrdinalIgnoreCase) || string.Equals(nav.Name, "item_name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
xmlStructureItem.name = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "type", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
xmlStructureItem.type = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "default", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
xmlStructureItem.defaultVal = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "arrayLength", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
xmlStructureItem.arrayLength = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "comment", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
xmlStructureItem.comments.Add(nav.Value.Trim());
|
||||
}
|
||||
else if (string.Equals(nav.Name, "description", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
xmlStructureItem.description = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "bits", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
xmlStructureItem.bits = nav.Value.Trim();
|
||||
}
|
||||
else if (nav.Name.Length > 0)
|
||||
{
|
||||
throw new XmlParsingException("Unknown element \"" + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + "\" on line " + ((IXmlLineInfo)nav).LineNumber.ToString());
|
||||
}
|
||||
|
||||
} while (nav.MoveToNext());
|
||||
}
|
||||
|
||||
///===================================================================================
|
||||
/// XmlParser.getMbitMessage
|
||||
///===================================================================================
|
||||
/// <summary>
|
||||
/// Parse the message defined by the XML
|
||||
/// </summary>
|
||||
/// <param name="nav">navigator object that points to the current XML node we are at</param>
|
||||
/// <param name="nameSpace">the XML file name that defines this message</param>
|
||||
/// <param name="mbitMessages">list of messages defined by XML</param>
|
||||
/// <param name="duplicateMbitMessages">the Dictioanry that stores duplicate messages</param>
|
||||
///===================================================================================
|
||||
public static void GetMbitMessage(XPathNavigator nav, string nameSpace, List<XmlMbitMessage> mbitMessages, Dictionary<string, List<string>> duplicateMbitMessages)
|
||||
{
|
||||
var mbitMsg = new XmlMbitMessage()
|
||||
{
|
||||
nameSpace = nameSpace
|
||||
};
|
||||
|
||||
if (nav.MoveToFirstChild())
|
||||
{
|
||||
do
|
||||
{
|
||||
if (string.Equals(nav.Name, "name", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mbitMsg.name = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "label", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mbitMsg.label = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "instrulabel", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mbitMsg.instruLabel = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "description", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mbitMsg.description = nav.Value.Trim();
|
||||
}
|
||||
else if (string.Equals(nav.Name, "comment", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mbitMsg.comments.Add(nav.Value.Trim());
|
||||
}
|
||||
else if (string.Equals(nav.Name, "item", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(nav.Name, "struct_item", StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(nav.Name, "msg_item", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (nav.MoveToFirstChild())
|
||||
{
|
||||
XmlStructureItem structureItem = new XmlStructureItem()
|
||||
{
|
||||
nameSpace = nameSpace
|
||||
};
|
||||
GetStructureItem(nav, structureItem);
|
||||
|
||||
mbitMsg.dataItems.Add(structureItem);
|
||||
|
||||
nav.MoveToParent();
|
||||
}
|
||||
}
|
||||
else if (nav.Name.Length > 0)
|
||||
{
|
||||
throw new XmlParsingException("Unknown element \"" + nav.OuterXml.Substring(0, nav.OuterXml.IndexOf(">") + 1) + "\" on line " + ((IXmlLineInfo)nav).LineNumber.ToString());
|
||||
}
|
||||
|
||||
} while (nav.MoveToNext());
|
||||
|
||||
nav.MoveToParent();
|
||||
|
||||
int index = mbitMessages.FindIndex(f => string.Equals(f.name, mbitMsg.name, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
// save file name the defines this message that is a duplicate
|
||||
if (!duplicateMbitMessages.ContainsKey(mbitMsg.name))
|
||||
{
|
||||
duplicateMbitMessages[mbitMsg.name] = new List<string>();
|
||||
}
|
||||
|
||||
int index3 = duplicateMbitMessages[mbitMsg.name].FindIndex(f => string.Equals(f, nameSpace + ".xml", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (index3 < 0)
|
||||
duplicateMbitMessages[mbitMsg.name].Add(nameSpace + ".xml");
|
||||
|
||||
// see if the official message is already in the duplicate list
|
||||
int index2 = duplicateMbitMessages[mbitMsg.name].FindIndex(f => string.Equals(f, mbitMessages[index].nameSpace + ".xml", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// if the official message is not in the duplicate list, we want to save it in the duplicate list
|
||||
if (index2 < 0)
|
||||
{
|
||||
duplicateMbitMessages[mbitMsg.name].Add(mbitMessages[index].nameSpace + ".xml");
|
||||
}
|
||||
|
||||
// the existing message is defined in an xml file other than MsgsMc.xml. At this time, we want the messages in MsgsMc.xml to take precedence over other xml files.
|
||||
// Why is the same message being defined in multiple xml files?
|
||||
if (!string.Equals(mbitMessages[index].nameSpace, "msgsmc", StringComparison.OrdinalIgnoreCase) && string.Equals(nameSpace, "msgsmc", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mbitMessages.RemoveAt(index);
|
||||
mbitMessages.Add(mbitMsg);
|
||||
}
|
||||
}
|
||||
else
|
||||
mbitMessages.Add(mbitMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// **********************************************************************************************************
|
||||
// XmlParsingException.cs
|
||||
// 6/6/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
using System;
|
||||
|
||||
namespace Raytheon.Instruments.XmlUtilities
|
||||
{
|
||||
class XmlParsingException : SystemException
|
||||
{
|
||||
///===================================================================================
|
||||
/// CodeGenerator.XmlParsingException
|
||||
///===================================================================================
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="message">description of the exception</param>
|
||||
///===================================================================================
|
||||
public XmlParsingException(string message)
|
||||
: base(message)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,123 @@
|
||||
// **********************************************************************************************************
|
||||
// CMessage.cs
|
||||
// 6/1/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
//\\<UnlimitedRights>
|
||||
//----------------------------------------------------------------------------//
|
||||
// Copyright %(copyright)s Raytheon Company. //
|
||||
// This software was developed pursuant to Contract Number %(contractNumber)s //
|
||||
// with the U.S. government. The U.S. government's rights in and to this //
|
||||
// copyrighted software are as specified in DFARS 252.227-7014 which was made //
|
||||
// part of the above contract. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\UnlimitedRights>
|
||||
|
||||
//\\<EximUndetermined>
|
||||
//----------------------------------------------------------------------------//
|
||||
// WARNING - This document contains technical data and / or technology whose //
|
||||
// export or disclosure to Non-U.S. Persons, wherever located, is restricted //
|
||||
// by the International Traffic in Arms Regulations (ITAR) (22 C.F.R. //
|
||||
// Section 120-130) or the Export Administration Regulations (EAR) (15 C.F.R. //
|
||||
// Section 730-774). This document CANNOT be exported (e.g., provided to a //
|
||||
// supplier outside of the United States) or disclosed to a Non-U.S. Person, //
|
||||
// wherever located, until a final jurisdiction and classification //
|
||||
// determination has been completed and approved by Raytheon, and any //
|
||||
// required U.S. Government approvals have been obtained. Violations are //
|
||||
// subject to severe criminal penalties. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\EximUndetermined>
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raytheon.Instruments.coeCSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Message: compatability option; This class provides a message object option that is compatible
|
||||
/// with what was used in COE 3.x. This is also the format generated by CMAT.
|
||||
/// </summary>
|
||||
public abstract class CMessage : coeMessage, IDisposable
|
||||
{
|
||||
protected CMessage(uint size) : this(size, 0) { }
|
||||
protected CMessage(uint size, uint label) : this(size, label, 0) { }
|
||||
protected CMessage(uint size, uint label, int priority) : base((int)size, label, priority) { }
|
||||
|
||||
~CMessage()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
new public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
new protected void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
abstract public byte[] serialize();
|
||||
abstract public bool deserialize(byte[] stream);
|
||||
|
||||
override public void Serialize()
|
||||
{
|
||||
byte[] data = serialize();
|
||||
if (data.Length > 0)
|
||||
{
|
||||
Marshal.Copy(data, 0, m_UnmanagedBuffer, data.Length);
|
||||
Size = (uint)data.Length;
|
||||
}
|
||||
}
|
||||
|
||||
override public void Deserialize()
|
||||
{
|
||||
byte[] data = copyFromMessageBuffer();
|
||||
deserialize(data);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
1361
Source/TSRealLib/HAL/Implementations/BIT/COEComm/coeCSharp/coe.cs
Normal file
1361
Source/TSRealLib/HAL/Implementations/BIT/COEComm/coeCSharp/coe.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,138 @@
|
||||
// **********************************************************************************************************
|
||||
// coeDataInterchange.cs
|
||||
// 6/1/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
//\\<UnlimitedRights>
|
||||
//----------------------------------------------------------------------------//
|
||||
// Copyright %(copyright)s Raytheon Company. //
|
||||
// This software was developed pursuant to Contract Number %(contractNumber)s //
|
||||
// with the U.S. government. The U.S. government's rights in and to this //
|
||||
// copyrighted software are as specified in DFARS 252.227-7014 which was made //
|
||||
// part of the above contract. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\UnlimitedRights>
|
||||
|
||||
//\\<EximUndetermined>
|
||||
//----------------------------------------------------------------------------//
|
||||
// WARNING - This document contains technical data and / or technology whose //
|
||||
// export or disclosure to Non-U.S. Persons, wherever located, is restricted //
|
||||
// by the International Traffic in Arms Regulations (ITAR) (22 C.F.R. //
|
||||
// Section 120-130) or the Export Administration Regulations (EAR) (15 C.F.R. //
|
||||
// Section 730-774). This document CANNOT be exported (e.g., provided to a //
|
||||
// supplier outside of the United States) or disclosed to a Non-U.S. Person, //
|
||||
// wherever located, until a final jurisdiction and classification //
|
||||
// determination has been completed and approved by Raytheon, and any //
|
||||
// required U.S. Government approvals have been obtained. Violations are //
|
||||
// subject to severe criminal penalties. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\EximUndetermined>
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raytheon.Instruments.coeCSharp
|
||||
{
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
internal struct DataInterchangeManagedCodeFormatType
|
||||
{
|
||||
public DataInterchangeManagedCodeFormatType(coeDataInterchange.FormatType format)
|
||||
{
|
||||
m_Repetition = format.m_Repetition;
|
||||
m_FormatLength = format.m_FormatLength;
|
||||
m_Format = format.m_Format;
|
||||
}
|
||||
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
internal uint m_Repetition;
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
internal uint m_FormatLength;
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
internal uint m_Format;
|
||||
}
|
||||
|
||||
public class coeDataInterchange
|
||||
{
|
||||
public const int LABEL_SIZE = 40;
|
||||
|
||||
public class FormatType
|
||||
{
|
||||
public FormatType(string fieldName,
|
||||
uint repetition,
|
||||
uint length,
|
||||
char format)
|
||||
{
|
||||
m_FieldName = fieldName;
|
||||
m_Repetition = repetition;
|
||||
m_FormatLength = length;
|
||||
m_Format = format;
|
||||
}
|
||||
|
||||
public string m_FieldName;
|
||||
public uint m_Repetition;
|
||||
public uint m_FormatLength;
|
||||
public char m_Format;
|
||||
}
|
||||
|
||||
public class FormatPacketType
|
||||
{
|
||||
public FormatPacketType(string name,
|
||||
uint msgSize,
|
||||
uint numItems,
|
||||
FormatType[] format)
|
||||
{
|
||||
m_Name = name;
|
||||
m_NumberItems = numItems;
|
||||
m_DataByteSize = msgSize;
|
||||
m_Format = format;
|
||||
}
|
||||
|
||||
public string m_Name;
|
||||
public uint m_NumberItems;
|
||||
public uint m_DataByteSize;
|
||||
public FormatType[] m_Format;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
// **********************************************************************************************************
|
||||
// coeDataInterchangePackets.cs
|
||||
// 6/1/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
//\\<UnlimitedRights>
|
||||
//----------------------------------------------------------------------------//
|
||||
// Copyright %(copyright)s Raytheon Company. //
|
||||
// This software was developed pursuant to Contract Number %(contractNumber)s //
|
||||
// with the U.S. government. The U.S. government's rights in and to this //
|
||||
// copyrighted software are as specified in DFARS 252.227-7014 which was made //
|
||||
// part of the above contract. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\UnlimitedRights>
|
||||
|
||||
//\\<EximUndetermined>
|
||||
//----------------------------------------------------------------------------//
|
||||
// WARNING - This document contains technical data and / or technology whose //
|
||||
// export or disclosure to Non-U.S. Persons, wherever located, is restricted //
|
||||
// by the International Traffic in Arms Regulations (ITAR) (22 C.F.R. //
|
||||
// Section 120-130) or the Export Administration Regulations (EAR) (15 C.F.R. //
|
||||
// Section 730-774). This document CANNOT be exported (e.g., provided to a //
|
||||
// supplier outside of the United States) or disclosed to a Non-U.S. Person, //
|
||||
// wherever located, until a final jurisdiction and classification //
|
||||
// determination has been completed and approved by Raytheon, and any //
|
||||
// required U.S. Government approvals have been obtained. Violations are //
|
||||
// subject to severe criminal penalties. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\EximUndetermined>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raytheon.Instruments.coeCSharp
|
||||
{
|
||||
//
|
||||
//
|
||||
//
|
||||
// Data Interchange Packet
|
||||
//
|
||||
//
|
||||
//
|
||||
public class coeDataInterchangePackets
|
||||
{
|
||||
private Dictionary<uint, IntPtr> _packets;
|
||||
public coe.CallBackDelegate _delegate;
|
||||
private GCHandle _GCdelegate;
|
||||
|
||||
internal coeDataInterchangePackets()
|
||||
{
|
||||
_packets = new Dictionary<uint, IntPtr>();
|
||||
_delegate = new coe.CallBackDelegate(Find);
|
||||
_GCdelegate = GCHandle.Alloc(_delegate);
|
||||
}
|
||||
|
||||
~coeDataInterchangePackets()
|
||||
{
|
||||
foreach (KeyValuePair<uint, IntPtr> entry in _packets)
|
||||
{
|
||||
Marshal.FreeHGlobal(entry.Value);
|
||||
}
|
||||
_GCdelegate.Free();
|
||||
}
|
||||
|
||||
internal IntPtr Find(uint Label)
|
||||
{
|
||||
_packets.TryGetValue(Label, out IntPtr packetArray);
|
||||
return packetArray;
|
||||
}
|
||||
|
||||
private void FormatString(byte[] dataBuffer, ref uint StartingIndex, string Name)
|
||||
{
|
||||
uint index;
|
||||
for (index = 0; index < Name.Length && index < 39; index++)
|
||||
{
|
||||
dataBuffer[StartingIndex++] = (byte)Name[(int)index];
|
||||
}
|
||||
for (; index < 40; index++)
|
||||
{
|
||||
dataBuffer[StartingIndex++] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void FormatUint(byte[] dataBuffer,
|
||||
ref uint StartingIndex,
|
||||
uint DataValue)
|
||||
{
|
||||
dataBuffer[StartingIndex++] = (byte)((DataValue) & 0xFF);
|
||||
dataBuffer[StartingIndex++] = (byte)((DataValue >> 8) & 0xFF);
|
||||
dataBuffer[StartingIndex++] = (byte)((DataValue >> 16) & 0xFF);
|
||||
dataBuffer[StartingIndex++] = (byte)((DataValue >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
internal IntPtr Add(uint Label, coeDataInterchange.FormatPacketType packet)
|
||||
{
|
||||
IntPtr packetArray = IntPtr.Zero;
|
||||
if ((packet.m_NumberItems > 0) && (!_packets.TryGetValue(Label, out packetArray)))
|
||||
{
|
||||
int sizeOfInterchangeStructure = (int)(52 + (packet.m_NumberItems * 52));
|
||||
packetArray = Marshal.AllocHGlobal(sizeOfInterchangeStructure);
|
||||
byte[] dataArray = new byte[sizeOfInterchangeStructure];
|
||||
// Format the byte array with the data
|
||||
uint dataArrayIndex = 0;
|
||||
FormatString(dataArray, ref dataArrayIndex, packet.m_Name);
|
||||
FormatUint(dataArray, ref dataArrayIndex, packet.m_NumberItems);
|
||||
FormatUint(dataArray, ref dataArrayIndex, packet.m_DataByteSize);
|
||||
FormatUint(dataArray, ref dataArrayIndex, (uint)((IntPtr)(packetArray.ToInt32() + 52)));
|
||||
for (int count = 0; count < packet.m_NumberItems; count++)
|
||||
{
|
||||
FormatString(dataArray, ref dataArrayIndex, packet.m_Format[count].m_FieldName);
|
||||
FormatUint(dataArray, ref dataArrayIndex, packet.m_Format[count].m_Repetition);
|
||||
FormatUint(dataArray, ref dataArrayIndex, packet.m_Format[count].m_FormatLength);
|
||||
FormatUint(dataArray, ref dataArrayIndex, packet.m_Format[count].m_Format);
|
||||
}
|
||||
Marshal.Copy(dataArray, 0, packetArray, sizeOfInterchangeStructure);
|
||||
_packets.Add(Label, packetArray);
|
||||
}
|
||||
return packetArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
// **********************************************************************************************************
|
||||
// coeEndpoint.cs
|
||||
// 6/1/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
//\\<UnlimitedRights>
|
||||
//----------------------------------------------------------------------------//
|
||||
// Copyright %(copyright)s Raytheon Company. //
|
||||
// This software was developed pursuant to Contract Number %(contractNumber)s //
|
||||
// with the U.S. government. The U.S. government's rights in and to this //
|
||||
// copyrighted software are as specified in DFARS 252.227-7014 which was made //
|
||||
// part of the above contract. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\UnlimitedRights>
|
||||
|
||||
//\\<EximUndetermined>
|
||||
//----------------------------------------------------------------------------//
|
||||
// WARNING - This document contains technical data and / or technology whose //
|
||||
// export or disclosure to Non-U.S. Persons, wherever located, is restricted //
|
||||
// by the International Traffic in Arms Regulations (ITAR) (22 C.F.R. //
|
||||
// Section 120-130) or the Export Administration Regulations (EAR) (15 C.F.R. //
|
||||
// Section 730-774). This document CANNOT be exported (e.g., provided to a //
|
||||
// supplier outside of the United States) or disclosed to a Non-U.S. Person, //
|
||||
// wherever located, until a final jurisdiction and classification //
|
||||
// determination has been completed and approved by Raytheon, and any //
|
||||
// required U.S. Government approvals have been obtained. Violations are //
|
||||
// subject to severe criminal penalties. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\EximUndetermined>
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raytheon.Instruments.coeCSharp
|
||||
{
|
||||
//
|
||||
//
|
||||
//
|
||||
// Endpoint
|
||||
//
|
||||
//
|
||||
//
|
||||
public class coeEndpoint : IDisposable
|
||||
{
|
||||
#region DLLImports
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Endpoint_Create_Dynamic_With_Domain")]
|
||||
private static extern IntPtr OE_Endpoint_Create_Dynamic_With_Domain(IntPtr Name,
|
||||
coe.ScopeType Scope,
|
||||
IntPtr Router,
|
||||
uint Domain,
|
||||
uint MaximumTransmitMessages,
|
||||
uint MaximumReceiveMessages,
|
||||
uint MaximumTransmitMessageSize,
|
||||
uint MaximumReceiveMessageSize,
|
||||
IntPtr ApplicationContext,
|
||||
out coe.Status Status);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Endpoint_Delete")]
|
||||
private static extern coe.Status OE_Endpoint_Delete(IntPtr _obj);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Endpoint_Associate")]
|
||||
private static extern coe.Status OE_Endpoint_Associate(IntPtr _obj,
|
||||
IntPtr Event,
|
||||
TriggerType Trigger);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Endpoint_Send_Labeled")]
|
||||
private static extern coe.Status OE_Endpoint_Send_Labeled(IntPtr _obj,
|
||||
IntPtr Message,
|
||||
uint Options,
|
||||
uint Handling_Policy);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Endpoint_Peek")]
|
||||
private static extern coe.Status OE_Endpoint_Peek(IntPtr _obj,
|
||||
out uint Message_Label,
|
||||
out uint Message_Size,
|
||||
out int Message_Priority);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Endpoint_Wait")]
|
||||
private static extern coe.Status OE_Endpoint_Wait(IntPtr _obj,
|
||||
int Timeout);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Endpoint_Receive")]
|
||||
private static extern coe.Status OE_Endpoint_Receive(IntPtr _obj,
|
||||
ref IntPtr Message,
|
||||
uint Handling_Policy,
|
||||
int Timeout,
|
||||
IntPtr Source);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Endpoint_Register_Ex2")]
|
||||
private static extern coe.Status OE_Endpoint_Register_Ex2(IntPtr _obj,
|
||||
uint Label,
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)]
|
||||
coe.CallBackDelegate callbackD);
|
||||
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Endpoint_Deregister")]
|
||||
private static extern coe.Status OE_Endpoint_Deregister(IntPtr _obj,
|
||||
uint Label);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Endpoint_Empty")]
|
||||
private static extern coe.Status OE_Endpoint_Empty(IntPtr _obj);
|
||||
|
||||
#endregion
|
||||
|
||||
public enum TriggerType : int
|
||||
{
|
||||
DATA_RECEIVED = 0,
|
||||
BUFFER_EMPTY = 1,
|
||||
DATA_DISCARDED = 2
|
||||
};
|
||||
|
||||
private bool _disposed;
|
||||
private IntPtr _handle;
|
||||
private readonly coeEvent[] _events;
|
||||
private const int MaximumNumberOfEvents = 4;
|
||||
private int _numberOfEvents;
|
||||
|
||||
// Constant to be used for a non-queued endpoint
|
||||
public const uint NON_QUEUED_SIZE = 0;
|
||||
|
||||
public coeEndpoint(uint maxMessageSize, IntPtr router = default) : this(0, maxMessageSize, 0, router) { }
|
||||
public coeEndpoint(uint maxMessageSize, uint maxBufferMessages, IntPtr router = default)
|
||||
: this(0, maxMessageSize, maxBufferMessages, router) { }
|
||||
public coeEndpoint(uint domain, uint maxMessageSize, uint maxBufferMessages, IntPtr router = default)
|
||||
{
|
||||
_handle = OE_Endpoint_Create_Dynamic_With_Domain(IntPtr.Zero, coe.ScopeType.OE_Local, router, domain,
|
||||
maxBufferMessages, maxBufferMessages, maxMessageSize, maxMessageSize, IntPtr.Zero, out coe.Status oe_status);
|
||||
if (oe_status != coe.Status.SUCCESS)
|
||||
{
|
||||
_handle = IntPtr.Zero;
|
||||
throw new Exception("Unable to create OE_Endpoint. Error = " + oe_status);
|
||||
}
|
||||
else
|
||||
{
|
||||
_numberOfEvents = 0;
|
||||
_events = new coeEvent[MaximumNumberOfEvents];
|
||||
}
|
||||
}
|
||||
|
||||
~coeEndpoint()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
}
|
||||
if (_handle != IntPtr.Zero)
|
||||
{
|
||||
for (int index = 0; index < _numberOfEvents; index++)
|
||||
{
|
||||
_events[index].Disable();
|
||||
}
|
||||
OE_Endpoint_Delete(_handle);
|
||||
_handle = IntPtr.Zero;
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
public IntPtr Handle
|
||||
{
|
||||
get { return _handle; }
|
||||
}
|
||||
|
||||
public coe.Status Register(uint label)
|
||||
{
|
||||
coe.Status status = OE_Endpoint_Register_Ex2(_handle, label, null);
|
||||
return status;
|
||||
}
|
||||
|
||||
public coe.Status Register(uint label, coeDataInterchange.FormatPacketType packet)
|
||||
{
|
||||
|
||||
coe._dataInterchangePackets.Add(label, packet);
|
||||
coe.Status status = OE_Endpoint_Register_Ex2(_handle, label, coe._dataInterchangePackets._delegate);
|
||||
return status;
|
||||
}
|
||||
|
||||
public coe.Status Deregister(uint label)
|
||||
{
|
||||
coe.Status status = OE_Endpoint_Deregister(_handle, label);
|
||||
return status;
|
||||
}
|
||||
|
||||
public coe.Status Send(coeMessage message)
|
||||
{
|
||||
return Send(message, 0);
|
||||
}
|
||||
|
||||
public coe.Status Send(coeMessage message, uint options)
|
||||
{
|
||||
message.Serialize();
|
||||
return OE_Endpoint_Send_Labeled(_handle, message.Handle, options, 0);
|
||||
}
|
||||
|
||||
public coe.Status Peek(out uint message_Label,
|
||||
out uint message_Size,
|
||||
out int message_Priority)
|
||||
{
|
||||
coe.Status status;
|
||||
status = OE_Endpoint_Peek(_handle, out uint messageLabel, out uint messageSize, out int messagePriority);
|
||||
message_Label = messageLabel;
|
||||
message_Size = messageSize;
|
||||
message_Priority = messagePriority;
|
||||
return status;
|
||||
}
|
||||
|
||||
public coe.Status Wait(int timeout)
|
||||
{
|
||||
return OE_Endpoint_Wait(_handle, timeout);
|
||||
}
|
||||
|
||||
public coe.Status Clear()
|
||||
{
|
||||
return OE_Endpoint_Empty(_handle);
|
||||
}
|
||||
|
||||
public coe.Status Receive(coeMessage message, int timeout)
|
||||
{
|
||||
coe.Status Status;
|
||||
IntPtr coeMessageHandle = message != null ? message.Handle : IntPtr.Zero;
|
||||
Status = OE_Endpoint_Receive(_handle, ref coeMessageHandle, 0, timeout, IntPtr.Zero);
|
||||
if (Status == coe.Status.SUCCESS)
|
||||
{
|
||||
message.Deserialize();
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
public coe.Status Receive(coeMessage message)
|
||||
{
|
||||
return Receive(message, coe.OE_Wait_Forever);
|
||||
}
|
||||
|
||||
public coe.Status Associate(coeEventFlag eventFlag, uint mask, TriggerType trigger)
|
||||
{
|
||||
coe.Status status;
|
||||
|
||||
if (_numberOfEvents >= MaximumNumberOfEvents)
|
||||
{
|
||||
status = coe.Status.FAILED_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
_events[_numberOfEvents] = new coeEvent();
|
||||
_events[_numberOfEvents].SetNotification(eventFlag, mask);
|
||||
status = OE_Endpoint_Associate(_handle, _events[_numberOfEvents].Handle, trigger);
|
||||
if (status == coe.Status.SUCCESS)
|
||||
{
|
||||
status = _events[_numberOfEvents].Enable();
|
||||
_numberOfEvents++;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
// **********************************************************************************************************
|
||||
// coeEvent.cs
|
||||
// 6/1/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
//\\<UnlimitedRights>
|
||||
//----------------------------------------------------------------------------//
|
||||
// Copyright %(copyright)s Raytheon Company. //
|
||||
// This software was developed pursuant to Contract Number %(contractNumber)s //
|
||||
// with the U.S. government. The U.S. government's rights in and to this //
|
||||
// copyrighted software are as specified in DFARS 252.227-7014 which was made //
|
||||
// part of the above contract. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\UnlimitedRights>
|
||||
|
||||
//\\<EximUndetermined>
|
||||
//----------------------------------------------------------------------------//
|
||||
// WARNING - This document contains technical data and / or technology whose //
|
||||
// export or disclosure to Non-U.S. Persons, wherever located, is restricted //
|
||||
// by the International Traffic in Arms Regulations (ITAR) (22 C.F.R. //
|
||||
// Section 120-130) or the Export Administration Regulations (EAR) (15 C.F.R. //
|
||||
// Section 730-774). This document CANNOT be exported (e.g., provided to a //
|
||||
// supplier outside of the United States) or disclosed to a Non-U.S. Person, //
|
||||
// wherever located, until a final jurisdiction and classification //
|
||||
// determination has been completed and approved by Raytheon, and any //
|
||||
// required U.S. Government approvals have been obtained. Violations are //
|
||||
// subject to severe criminal penalties. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\EximUndetermined>
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raytheon.Instruments.coeCSharp
|
||||
{
|
||||
//
|
||||
//
|
||||
//
|
||||
// Event
|
||||
//
|
||||
//
|
||||
//
|
||||
public class coeEvent : IDisposable
|
||||
{
|
||||
|
||||
#region DLLImports
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Event_Create_Dynamic")]
|
||||
private static extern IntPtr OE_Event_Create_Dynamic(IntPtr Name,
|
||||
PersistenceType Persistence,
|
||||
int Priority,
|
||||
IntPtr ApplicationContext,
|
||||
out coe.Status Status);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Event_Delete")]
|
||||
public static extern coe.Status OE_Event_Delete(IntPtr _obj);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Event_Enable")]
|
||||
private static extern coe.Status OE_Event_Enable(IntPtr _obj);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Event_Disable")]
|
||||
private static extern coe.Status OE_Event_Disable(IntPtr _obj);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Event_Set_Event_Flag_Notification")]
|
||||
private static extern coe.Status OE_Event_Set_Event_Flag_Notification(IntPtr _obj,
|
||||
IntPtr EventFlag,
|
||||
uint Mask);
|
||||
#endregion
|
||||
|
||||
public enum PersistenceType : int
|
||||
{
|
||||
ONE_SHOT = 0,
|
||||
ENDURING = 1
|
||||
}
|
||||
private bool _disposed = false;
|
||||
private IntPtr _handle = IntPtr.Zero;
|
||||
|
||||
public coeEvent() : this(PersistenceType.ENDURING, 0) { }
|
||||
public coeEvent(PersistenceType persistence) : this(persistence, 0) { }
|
||||
public coeEvent(int priority) : this(PersistenceType.ENDURING, priority) { }
|
||||
public coeEvent(PersistenceType persistence, int priority)
|
||||
{
|
||||
_handle = OE_Event_Create_Dynamic(IntPtr.Zero, persistence, priority, IntPtr.Zero, out coe.Status oe_status);
|
||||
if (oe_status != coe.Status.SUCCESS)
|
||||
{
|
||||
_handle = IntPtr.Zero;
|
||||
throw new Exception("Unable to create OE_Event. Error = " + oe_status);
|
||||
}
|
||||
}
|
||||
|
||||
~coeEvent()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed) return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
}
|
||||
if (_handle != IntPtr.Zero)
|
||||
{
|
||||
OE_Event_Delete(_handle);
|
||||
_handle = IntPtr.Zero;
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
internal IntPtr Handle
|
||||
{
|
||||
get { return _handle; }
|
||||
}
|
||||
|
||||
public coe.Status Enable()
|
||||
{
|
||||
return OE_Event_Enable(_handle);
|
||||
}
|
||||
|
||||
public coe.Status Disable()
|
||||
{
|
||||
return OE_Event_Disable(_handle);
|
||||
}
|
||||
|
||||
public coe.Status SetNotification(coeEventFlag eventFlag, uint mask)
|
||||
{
|
||||
return OE_Event_Set_Event_Flag_Notification(_handle, eventFlag.Handle, mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
// **********************************************************************************************************
|
||||
// coeEventFlag.cs
|
||||
// 6/1/2022
|
||||
// NGI - Next Generation Interceptor
|
||||
//
|
||||
// Contract No. HQ0856-21-C-0003/1022000209
|
||||
//
|
||||
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
|
||||
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
|
||||
//
|
||||
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
|
||||
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
|
||||
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
|
||||
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
|
||||
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
|
||||
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
|
||||
//
|
||||
// CONTROLLED BY: MISSILE DEFENSE AGENCY
|
||||
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
|
||||
// CUI CATEGORY: CTI
|
||||
// DISTRIBUTION/DISSEMINATION CONTROL: F
|
||||
// POC: Alex Kravchenko (1118268)
|
||||
// **********************************************************************************************************
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
//\\<UnlimitedRights>
|
||||
//----------------------------------------------------------------------------//
|
||||
// Copyright %(copyright)s Raytheon Company. //
|
||||
// This software was developed pursuant to Contract Number %(contractNumber)s //
|
||||
// with the U.S. government. The U.S. government's rights in and to this //
|
||||
// copyrighted software are as specified in DFARS 252.227-7014 which was made //
|
||||
// part of the above contract. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\UnlimitedRights>
|
||||
|
||||
//\\<EximUndetermined>
|
||||
//----------------------------------------------------------------------------//
|
||||
// WARNING - This document contains technical data and / or technology whose //
|
||||
// export or disclosure to Non-U.S. Persons, wherever located, is restricted //
|
||||
// by the International Traffic in Arms Regulations (ITAR) (22 C.F.R. //
|
||||
// Section 120-130) or the Export Administration Regulations (EAR) (15 C.F.R. //
|
||||
// Section 730-774). This document CANNOT be exported (e.g., provided to a //
|
||||
// supplier outside of the United States) or disclosed to a Non-U.S. Person, //
|
||||
// wherever located, until a final jurisdiction and classification //
|
||||
// determination has been completed and approved by Raytheon, and any //
|
||||
// required U.S. Government approvals have been obtained. Violations are //
|
||||
// subject to severe criminal penalties. //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\EximUndetermined>
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raytheon.Instruments.coeCSharp
|
||||
{
|
||||
//
|
||||
//
|
||||
//
|
||||
// Event Flag
|
||||
//
|
||||
//
|
||||
//
|
||||
public class coeEventFlag : IDisposable
|
||||
{
|
||||
|
||||
#region DLLImports
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Event_Flag_Create_Dynamic")]
|
||||
private static extern IntPtr OE_Event_Flag_Create_Dynamic(IntPtr Name,
|
||||
coe.ScopeType Scope,
|
||||
uint InitialMask,
|
||||
IntPtr ApplicationContext,
|
||||
out coe.Status Status);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Event_Flag_Delete")]
|
||||
private static extern coe.Status OE_Event_Flag_Delete(IntPtr _obj);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Event_Flag_Set")]
|
||||
private static extern coe.Status OE_Event_Flag_Set(IntPtr _obj,
|
||||
uint Mask);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Event_Flag_Clear")]
|
||||
private static extern coe.Status OE_Event_Flag_Clear(IntPtr _obj,
|
||||
uint Mask);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Event_Flag_Peek_Mask")]
|
||||
private static extern coe.Status OE_Event_Flag_Peek_Mask(IntPtr _obj,
|
||||
out uint Mask);
|
||||
|
||||
[DllImport(coe.coeDLL, CallingConvention = CallingConvention.Cdecl, EntryPoint = "OE_Event_Flag_Wait")]
|
||||
private static extern coe.Status OE_Event_Flag_Wait(IntPtr _obj,
|
||||
uint Mask,
|
||||
uint ResetMask,
|
||||
WaitPolicyType PolicyType,
|
||||
int TimeInterval,
|
||||
out uint CurrentMask);
|
||||
|
||||
#endregion
|
||||
|
||||
private bool _disposed = false;
|
||||
private IntPtr _handle = IntPtr.Zero;
|
||||
|
||||
public enum WaitPolicyType : int
|
||||
{
|
||||
WAIT_FOR_ALL = 0,
|
||||
WAIT_FOR_ANY = 1
|
||||
}
|
||||
|
||||
public coeEventFlag()
|
||||
{
|
||||
_handle = OE_Event_Flag_Create_Dynamic(IntPtr.Zero, coe.ScopeType.OE_Local, 0, IntPtr.Zero, out coe.Status oe_status);
|
||||
if (oe_status != coe.Status.SUCCESS)
|
||||
{
|
||||
_handle = IntPtr.Zero;
|
||||
throw new Exception("Unable to create OE_Event_Flag. Error = " + oe_status);
|
||||
}
|
||||
}
|
||||
|
||||
~coeEventFlag()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
}
|
||||
if (_handle != IntPtr.Zero)
|
||||
{
|
||||
OE_Event_Flag_Delete(_handle);
|
||||
_handle = IntPtr.Zero;
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
internal IntPtr Handle
|
||||
{
|
||||
get { return _handle; }
|
||||
}
|
||||
|
||||
public coe.Status Set(uint mask)
|
||||
{
|
||||
return OE_Event_Flag_Set(_handle, mask);
|
||||
}
|
||||
|
||||
public coe.Status Clear(uint mask)
|
||||
{
|
||||
return OE_Event_Flag_Clear(_handle, mask);
|
||||
}
|
||||
|
||||
public coe.Status Peek(out uint mask)
|
||||
{
|
||||
coe.Status status;
|
||||
status = OE_Event_Flag_Peek_Mask(_handle, out uint currentMask);
|
||||
mask = currentMask;
|
||||
return status;
|
||||
}
|
||||
|
||||
public coe.Status Wait(uint mask,
|
||||
uint resetMask,
|
||||
WaitPolicyType waitPolicy,
|
||||
int timeout,
|
||||
out uint currentMask)
|
||||
{
|
||||
coe.Status status;
|
||||
status = OE_Event_Flag_Wait(_handle, mask, resetMask, waitPolicy, timeout, out uint returnedMask);
|
||||
currentMask = returnedMask;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//\\<Unclassified>
|
||||
//----------------------------------------------------------------------------//
|
||||
// UNCLASSIFIED //
|
||||
//----------------------------------------------------------------------------//
|
||||
//\\<\Unclassified>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user