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]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user