Files
GenericTeProgramLibrary/Source/TSRealLib/Common/Raytheon.Common/COE/MessagingUtilities/MessageData.cs
2025-10-24 15:18:11 -07:00

605 lines
19 KiB
C#

// **********************************************************************************************************
// MessageData.cs
// 5/18/2022
// NGI - Next Generation Interceptor
//
// Contract No. HQ0856-21-C-0003/1022000209
//
// THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S.
// INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS.
//
// RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION PROPRIETARY TO RAYTHEON
// COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT.
// DISCLOSURE TO UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO RAYTHEON
// COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS CONTENTS SHALL BE FURNISHED OR DISCLOSED
// TO OR COPIED OR USED BY PERSONS OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF
// RAYTHEON COMPANY.
//
// UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY.
//
// DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M,
// NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006,
// INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3,
// DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3,
// SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4,
// INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION.
//
// CONTROLLED BY: MISSILE DEFENSE AGENCY
// CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE
// CUI CATEGORY: CTI
// DISTRIBUTION/DISSEMINATION CONTROL: F
// POC: Alex Kravchenko (1118268)
// **********************************************************************************************************
using System;
using System.Collections.Generic;
using System.IO;
namespace Raytheon.Common.Coe
{
public class MessageData : ICloneable
{
public string FieldName;
public string FieldType;
public string FieldValue;
public string FieldArrayValue;
public string FieldDefaultValue;
public string FieldMaxValue;
public string FieldMinValue;
public string FieldBitValue;
public string FieldInstruType;
public string Variable;
public string MaxOffset;
public string MinOffset;
public string VerifyType;
public bool isSelected;
public bool isArray;
public bool isStructure;
public bool isArrayOfStructures;
public bool isEnum;
public bool usesRegister;
public bool isValid;
public bool useRange;
public int arrayLength;
public uint imageWidth;
public uint imageHeight;
public uint imagePixelSize;
public ulong bitMask;
public bool expanded;
public int depth;
public byte[] imageBuffer;
public uint imageBufferSize;
public MessageData[] MessageArray;
public delegate coe.Status ReadImageDelegate
(
string filename,
uint columns,
uint rows,
uint pixel_size,
byte[] buffer
);
private MessageXmlDocument m_Icd;
internal int m_BitCounter = 0; // used to calculate the bit mask
internal static Dictionary<string, ReadImageDelegate> m_ReadFunctions = null;
public bool LogData { get; set; }
private MessageData() { }
private MessageData(MessageXmlDocument Icd)
{
FieldName = null;
FieldType = null;
FieldValue = null;
FieldArrayValue = null;
FieldDefaultValue = null;
FieldMaxValue = null;
FieldMinValue = null;
FieldBitValue = null;
Variable = null;
MaxOffset = null;
MinOffset = null;
VerifyType = null;
isSelected = false;
isArray = false;
isStructure = false;
isArrayOfStructures = false;
usesRegister = false;
useRange = false;
arrayLength = 0;
imageWidth = 0;
imageHeight = 0;
imagePixelSize = 0;
bitMask = 0;
expanded = false;
depth = 0;
imageBufferSize = 0;
imageBuffer = null;
m_Icd = Icd;
}
public MessageData(string fieldname,
string fieldtype,
string fieldvalue,
string fielddefaultvalue,
MessageXmlDocument Icd,
bool logData = true) :
this(Icd)
{
FieldName = fieldname;
FieldType = fieldtype;
FieldValue = fieldvalue;
LogData = logData;
SetInstruType(null);
SetDefaultValue(fielddefaultvalue);
}
public MessageData(string fieldname,
string fieldtype,
string fieldvalue,
string fielddefaultvalue,
string fieldmaxvalue,
string fieldminvalue,
MessageXmlDocument Icd) :
this(fieldname, fieldtype, fieldvalue, fielddefaultvalue, Icd)
{
SetMaxValue(fieldmaxvalue);
SetMinValue(fieldminvalue);
}
public string FormattedValue
{
get { return FormatValue(FieldValue); }
}
public string FormattedMinValue
{
get { return FormatValue(FieldMinValue); }
}
public string FormattedMaxValue
{
get { return FormatValue(FieldMaxValue); }
}
public static string ImageFileReadTypes
{
get
{
string fileTypes = "";
if (m_ReadFunctions == null) return null;
foreach (string type in m_ReadFunctions.Keys)
{
if (fileTypes != "")
fileTypes += "|";
fileTypes += type.ToUpper() + " files (*." + type.ToLower() + ")|*." + type.ToLower();
}
return fileTypes;
}
}
public void AddReadExtension(string extension, ReadImageDelegate readFunc)
{
if (m_ReadFunctions == null)
m_ReadFunctions = new Dictionary<string, ReadImageDelegate>();
if (m_ReadFunctions.ContainsKey(extension))
m_ReadFunctions[extension] = readFunc;
else
m_ReadFunctions.Add(extension, readFunc);
}
public void UpdateImage()
{
if (FieldInstruType == "P")
{
if (File.Exists(FieldValue))
{
string extension = FieldValue.Substring(FieldValue.LastIndexOf(".") + 1);
m_ReadFunctions[extension](FieldValue,
imageWidth,
imageHeight,
imagePixelSize,
imageBuffer);
}
else
{
// TODO add error message
//MessageBox.Show("Unable to open file " + FieldValue +
// " to populate " + FieldName,
// "File Read Error",
// MessageBoxButtons.OK,
// MessageBoxIcon.Error);
FieldValue = "";
for (int i = 0; i < imageBuffer.Length; i++)
{
imageBuffer[i] = 0;
}
}
}
}
public void SetDefaultValue(string fieldDefaultValue)
{
// Initialize uninitialized value
if (fieldDefaultValue == null)
{
fieldDefaultValue = "";
}
if ((FieldType == "char") && (fieldDefaultValue.Contains("\"")))
{
FieldInstruType = "S";
}
FieldDefaultValue = RemoveCharFromString(fieldDefaultValue, '\"');
}
public void SetMaxValue(string fieldmaxvalue)
{
if (fieldmaxvalue == null) return; /* Bad argument */
if ((FieldType == "char") && (fieldmaxvalue.Contains("\"")))
{
FieldInstruType = "S";
}
FieldMaxValue = RemoveCharFromString(fieldmaxvalue, '\"');
}
public void SetMinValue(string fieldminvalue)
{
if (fieldminvalue == null) return; /* Bad argument */
if ((FieldType == "char") && (fieldminvalue.Contains("\"")))
{
FieldInstruType = "S";
}
FieldMinValue = RemoveCharFromString(fieldminvalue, '\"');
}
public void SetBitValue(int bits)
{
int size = (int)Message.GetTypeSize(FieldType, isEnum, LogData);
// Determine the bitMask
if (bits == 0)
{
m_BitCounter = 0;
FieldBitValue = null;
}
else
{
FieldBitValue = bits.ToString();
// If bits overflow across the type boundary, then
// they start at the next boundary.
//
// MSDN :
// "Note that nYear is 8 bits long and would overflow
// the word boundary of the declared type, unsigned short.
// Therefore, it is begun at the beginning of a
// new unsigned short."
if (m_BitCounter + bits > size * 8)
{
m_BitCounter = 0;
}
// 2^bits-1 will give a bit mask with bit# of 1's
// ex: bits = 5, bitMask = 11111
bitMask = (ulong)Math.Pow(2, (double)bits) - 1;
// We must slide the bitMask left to put it in place
bitMask <<= m_BitCounter;
m_BitCounter += bits;
// If we have used all the bits in the type that was defined, then
// restart the counter
if (m_BitCounter == size * 8)
m_BitCounter = 0;
}
if (bitMask == 0xffffff)
{
bitMask = 0;
}
}
public void SetArraySize(int size)
{
char result;
arrayLength = size; // Save the size
if (!isArray && !isStructure)
{
// Don't handle strings as arrays
if ((FieldInstruType != "S") && (FieldInstruType != "P"))
{
isArray = true;
MessageArray = new MessageData[size];
// If the field type is char or unsigned char and the default value
// exists and is a string then write one char of the string to
// each element of the array
if ((FieldType == "char" || FieldType == "unsigned char") &&
FieldDefaultValue != null &&
!Parse.Try(FieldDefaultValue, out result))
{
for (uint index = 0; index < size; index++)
{
//Only the elements that are required to spell out the string should
//receive default values.
if (index < FieldDefaultValue.Length)
{
MessageArray[index] = new MessageData(FieldName + "[" + index + "]",
FieldType, FieldValue, FieldDefaultValue[(int)index].ToString(),
FieldMaxValue, FieldMinValue, m_Icd);
MessageArray[index].FieldInstruType = FieldInstruType;
}
else
{
MessageArray[index] = new MessageData(FieldName + "[" + index + "]",
FieldType, FieldValue, "0",
FieldMaxValue, FieldMinValue, m_Icd);
MessageArray[index].FieldInstruType = FieldInstruType;
}
MessageArray[index].depth = depth + 1;
}
}
else
{
for (uint index = 0; index < size; index++)
{
MessageArray[index] = new MessageData(FieldName + "[" + index + "]",
FieldType, FieldValue, FieldDefaultValue, FieldMaxValue,
FieldMinValue, m_Icd);
MessageArray[index].FieldInstruType = FieldInstruType;
MessageArray[index].depth = depth + 1;
}
}
}
}
}
public void SetStructureSize(int size)
{
if (!isArray && !isStructure)
{
isStructure = true;
MessageArray = new MessageData[size];
for (uint index = 0; index < size; index++)
{
MessageArray[index] = new MessageData(FieldName + ".", null, null, null, m_Icd);
}
}
}
internal void SetInstruType(string Type)
{
if (Type != null)
{
FieldInstruType = Type;
// Ensure 'S' is used properly
if ((Type == "S") && (FieldType != "char"))
{
return; /* << EXIT >> */
}
}
else
{
if ((FieldType != null) &&
((FieldType.Trim() == "float") || (FieldType.Trim() == "double")))
{
FieldInstruType = "F";
}
else
{
FieldInstruType = "I";
}
}
}
internal void SetPixelSize()
{
// Only do this if the user did not define a size
if (imagePixelSize == 0)
{
switch (FieldType)
{
case "char":
case "unsigned char":
case "unsignedchar":
imagePixelSize = 1;
break;
case "short":
case "unsigned short":
case "unsignedshort":
imagePixelSize = 2;
break;
case "int":
case "unsigned int":
case "unsignedint":
case "unsigned":
case "boolean":
case "address":
case "float":
imagePixelSize = 4;
break;
case "double":
case "long long":
case "longlong":
case "unsigned long long":
case "unsignedlonglong":
imagePixelSize = 8;
break;
default:
if (isEnum)
{
imagePixelSize = 4;
}
else // Error case
{
imagePixelSize = 1;
}
break;
}
}
}
private string FormatValue(string Value)
{
if ((Value == null) || (Value == ""))
{
return "";
}
else // Value exists
{
if (isEnum == false)
{
if (FieldInstruType == "I")
{
// This is being represented as a decimal
if (Parse.Try(Value, out long dec) == true)
{
return dec.ToString();
}
}
else if (FieldInstruType == "F")
{
// This is being represented as floating point
if (Parse.Try(Value, out double flt) == true)
{
return flt.ToString();
}
}
else if ((FieldInstruType == "X") ||
(FieldInstruType == "B") ||
(FieldInstruType == "T"))
{
// This is being represented as a hexadecimal value
if (Parse.Try(Value, out long hex) == true)
{
return "0x" + hex.ToString("X");
}
}
else if (FieldInstruType == "N")
{
// This is being represented as a binary number
if (Parse.Try(Value, out long bin) == true)
{
return Convert.ToString(bin, 2) + "b";
}
}
// else InstruType == 'S' or 'P' or anything else return the value
}
else // This value is an enumeration
{
Dictionary<string, string> enums = m_Icd.GetEnumerations(FieldType);
if (enums.ContainsValue(Value) == true)
{
foreach (KeyValuePair<string, string> pair in enums)
{
if (pair.Value.Trim() == Value.Trim())
{
return pair.Key;
}
}
}
}
}
return Value; // If nothing above applies, simply return the value string
}
private String RemoveCharFromString(String str, char c)
{
if (str == null) return null; // Handle null case
int index = str.IndexOf(c);
while (index != -1)
{
str = str.Remove(index, 1);
index = str.IndexOf(c);
}
return str;
}
#region ICloneable Members
public object Clone()
{
MessageData clone = new MessageData();
clone.FieldName = FieldName;
clone.FieldType = FieldType;
clone.FieldValue = FieldValue;
clone.FieldArrayValue = FieldArrayValue;
clone.FieldDefaultValue = FieldDefaultValue;
clone.FieldMaxValue = FieldMaxValue;
clone.FieldMinValue = FieldMinValue;
clone.FieldBitValue = FieldBitValue;
clone.FieldInstruType = FieldInstruType;
clone.Variable = Variable;
clone.MaxOffset = MaxOffset;
clone.MinOffset = MinOffset;
clone.VerifyType = VerifyType;
clone.isSelected = isSelected;
clone.isArray = isArray;
clone.isStructure = isStructure;
clone.isArrayOfStructures = isArrayOfStructures;
clone.isEnum = isEnum;
clone.usesRegister = usesRegister;
clone.isValid = isValid;
clone.useRange = useRange;
clone.arrayLength = arrayLength;
clone.bitMask = bitMask;
clone.expanded = expanded;
clone.depth = depth;
clone.m_Icd = m_Icd;
clone.imageWidth = imageWidth;
clone.imageHeight = imageHeight;
clone.imagePixelSize = imagePixelSize;
clone.imageBufferSize = imageBufferSize;
if (imageBufferSize > 0)
{
clone.imageBuffer = new byte[imageBufferSize];
imageBuffer.CopyTo(clone.imageBuffer, 0);
}
if (MessageArray == null)
{
clone.MessageArray = null;
}
else
{
clone.MessageArray = new MessageData[MessageArray.Length];
for (int i = 0; i < MessageArray.Length; i++)
{
clone.MessageArray[i] = (MessageData)MessageArray[i].Clone();
}
}
return clone;
}
#endregion
}
}