601 lines
21 KiB
C#
601 lines
21 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;
|
|
|
|
using Raytheon.Instruments.coeCSharp;
|
|
|
|
namespace Raytheon.Instruments.MessagingUtilities
|
|
{
|
|
public class MessageData : ICloneable
|
|
{
|
|
public string FieldName;
|
|
public string FieldType;
|
|
public string FieldValue;
|
|
public string FieldArrayValue;
|
|
public string FieldDefaultValue;
|
|
public string FieldMaxValue;
|
|
public string FieldMinValue;
|
|
public string FieldBitValue;
|
|
public string FieldInstruType;
|
|
public string Variable;
|
|
public string MaxOffset;
|
|
public string MinOffset;
|
|
public string VerifyType;
|
|
public bool isSelected;
|
|
public bool isArray;
|
|
public bool isStructure;
|
|
public bool isArrayOfStructures;
|
|
public bool isEnum;
|
|
public bool usesRegister;
|
|
public bool isValid;
|
|
public bool useRange;
|
|
public int arrayLength;
|
|
public uint imageWidth;
|
|
public uint imageHeight;
|
|
public uint imagePixelSize;
|
|
public ulong bitMask;
|
|
public bool expanded;
|
|
public int depth;
|
|
public byte[] imageBuffer;
|
|
public uint imageBufferSize;
|
|
public MessageData[] MessageArray;
|
|
|
|
public delegate coe.Status ReadImageDelegate
|
|
(
|
|
string filename,
|
|
uint columns,
|
|
uint rows,
|
|
uint pixel_size,
|
|
byte[] buffer
|
|
);
|
|
|
|
private MessageXmlDocument m_Icd;
|
|
|
|
internal int m_BitCounter = 0; // used to calculate the bit mask
|
|
|
|
internal static Dictionary<string, ReadImageDelegate> m_ReadFunctions = null;
|
|
private MessageData() { }
|
|
private MessageData(MessageXmlDocument Icd)
|
|
{
|
|
FieldName = null;
|
|
FieldType = null;
|
|
FieldValue = null;
|
|
FieldArrayValue = null;
|
|
FieldDefaultValue = null;
|
|
FieldMaxValue = null;
|
|
FieldMinValue = null;
|
|
FieldBitValue = null;
|
|
Variable = null;
|
|
MaxOffset = null;
|
|
MinOffset = null;
|
|
VerifyType = null;
|
|
isSelected = false;
|
|
isArray = false;
|
|
isStructure = false;
|
|
isArrayOfStructures = false;
|
|
usesRegister = false;
|
|
useRange = false;
|
|
arrayLength = 0;
|
|
imageWidth = 0;
|
|
imageHeight = 0;
|
|
imagePixelSize = 0;
|
|
bitMask = 0;
|
|
expanded = false;
|
|
depth = 0;
|
|
imageBufferSize = 0;
|
|
imageBuffer = null;
|
|
|
|
m_Icd = Icd;
|
|
}
|
|
|
|
public MessageData(string fieldname,
|
|
string fieldtype,
|
|
string fieldvalue,
|
|
string fielddefaultvalue,
|
|
MessageXmlDocument Icd) :
|
|
this(Icd)
|
|
{
|
|
FieldName = fieldname;
|
|
FieldType = fieldtype;
|
|
FieldValue = fieldvalue;
|
|
|
|
SetInstruType(null);
|
|
SetDefaultValue(fielddefaultvalue);
|
|
|
|
}
|
|
|
|
public MessageData(string fieldname,
|
|
string fieldtype,
|
|
string fieldvalue,
|
|
string fielddefaultvalue,
|
|
string fieldmaxvalue,
|
|
string fieldminvalue,
|
|
MessageXmlDocument Icd) :
|
|
this(fieldname, fieldtype, fieldvalue, fielddefaultvalue, Icd)
|
|
{
|
|
SetMaxValue(fieldmaxvalue);
|
|
SetMinValue(fieldminvalue);
|
|
}
|
|
|
|
public string FormattedValue
|
|
{
|
|
get { return FormatValue(FieldValue); }
|
|
}
|
|
public string FormattedMinValue
|
|
{
|
|
get { return FormatValue(FieldMinValue); }
|
|
}
|
|
public string FormattedMaxValue
|
|
{
|
|
get { return FormatValue(FieldMaxValue); }
|
|
}
|
|
|
|
public static string ImageFileReadTypes
|
|
{
|
|
get
|
|
{
|
|
string fileTypes = "";
|
|
if (m_ReadFunctions == null) return null;
|
|
foreach (string type in m_ReadFunctions.Keys)
|
|
{
|
|
if (fileTypes != "")
|
|
fileTypes += "|";
|
|
|
|
fileTypes += type.ToUpper() + " files (*." + type.ToLower() + ")|*." + type.ToLower();
|
|
}
|
|
|
|
return fileTypes;
|
|
}
|
|
}
|
|
|
|
public void AddReadExtension(string extension, ReadImageDelegate readFunc)
|
|
{
|
|
if (m_ReadFunctions == null)
|
|
m_ReadFunctions = new Dictionary<string, ReadImageDelegate>();
|
|
|
|
if (m_ReadFunctions.ContainsKey(extension))
|
|
m_ReadFunctions[extension] = readFunc;
|
|
else
|
|
m_ReadFunctions.Add(extension, readFunc);
|
|
}
|
|
|
|
public void UpdateImage()
|
|
{
|
|
if (FieldInstruType == "P")
|
|
{
|
|
if (File.Exists(FieldValue))
|
|
{
|
|
string extension = FieldValue.Substring(FieldValue.LastIndexOf(".") + 1);
|
|
m_ReadFunctions[extension](FieldValue,
|
|
imageWidth,
|
|
imageHeight,
|
|
imagePixelSize,
|
|
imageBuffer);
|
|
}
|
|
else
|
|
{
|
|
// TODO add error message
|
|
//MessageBox.Show("Unable to open file " + FieldValue +
|
|
// " to populate " + FieldName,
|
|
// "File Read Error",
|
|
// MessageBoxButtons.OK,
|
|
// MessageBoxIcon.Error);
|
|
FieldValue = "";
|
|
for (int i = 0; i < imageBuffer.Length; i++)
|
|
{
|
|
imageBuffer[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public void SetDefaultValue(string fieldDefaultValue)
|
|
{
|
|
// Initialize uninitialized value
|
|
if (fieldDefaultValue == null)
|
|
{
|
|
fieldDefaultValue = "";
|
|
}
|
|
|
|
if ((FieldType == "char") && (fieldDefaultValue.Contains("\"")))
|
|
{
|
|
FieldInstruType = "S";
|
|
}
|
|
|
|
FieldDefaultValue = RemoveCharFromString(fieldDefaultValue, '\"');
|
|
}
|
|
|
|
public void SetMaxValue(string fieldmaxvalue)
|
|
{
|
|
if (fieldmaxvalue == null) return; /* Bad argument */
|
|
|
|
if ((FieldType == "char") && (fieldmaxvalue.Contains("\"")))
|
|
{
|
|
FieldInstruType = "S";
|
|
}
|
|
|
|
FieldMaxValue = RemoveCharFromString(fieldmaxvalue, '\"');
|
|
}
|
|
|
|
public void SetMinValue(string fieldminvalue)
|
|
{
|
|
if (fieldminvalue == null) return; /* Bad argument */
|
|
|
|
if ((FieldType == "char") && (fieldminvalue.Contains("\"")))
|
|
{
|
|
FieldInstruType = "S";
|
|
}
|
|
|
|
FieldMinValue = RemoveCharFromString(fieldminvalue, '\"');
|
|
}
|
|
|
|
public void SetBitValue(int bits)
|
|
{
|
|
int size = (int)Message.GetTypeSize(FieldType, isEnum);
|
|
|
|
// Determine the bitMask
|
|
if (bits == 0)
|
|
{
|
|
m_BitCounter = 0;
|
|
FieldBitValue = null;
|
|
}
|
|
else
|
|
{
|
|
FieldBitValue = bits.ToString();
|
|
|
|
// If bits overflow across the type boundary, then
|
|
// they start at the next boundary.
|
|
//
|
|
// MSDN :
|
|
// "Note that nYear is 8 bits long and would overflow
|
|
// the word boundary of the declared type, unsigned short.
|
|
// Therefore, it is begun at the beginning of a
|
|
// new unsigned short."
|
|
if (m_BitCounter + bits > size * 8)
|
|
{
|
|
m_BitCounter = 0;
|
|
}
|
|
|
|
// 2^bits-1 will give a bit mask with bit# of 1's
|
|
// ex: bits = 5, bitMask = 11111
|
|
bitMask = (ulong)Math.Pow(2, (double)bits) - 1;
|
|
|
|
// We must slide the bitMask left to put it in place
|
|
bitMask <<= m_BitCounter;
|
|
m_BitCounter += bits;
|
|
|
|
// If we have used all the bits in the type that was defined, then
|
|
// restart the counter
|
|
if (m_BitCounter == size * 8)
|
|
m_BitCounter = 0;
|
|
}
|
|
|
|
if (bitMask == 0xffffff)
|
|
{
|
|
bitMask = 0;
|
|
}
|
|
}
|
|
|
|
public void SetArraySize(int size)
|
|
{
|
|
char result;
|
|
|
|
arrayLength = size; // Save the size
|
|
|
|
if (!isArray && !isStructure)
|
|
{
|
|
// Don't handle strings as arrays
|
|
if ((FieldInstruType != "S") && (FieldInstruType != "P"))
|
|
{
|
|
isArray = true;
|
|
|
|
MessageArray = new MessageData[size];
|
|
// If the field type is char or unsigned char and the default value
|
|
// exists and is a string then write one char of the string to
|
|
// each element of the array
|
|
if ((FieldType == "char" || FieldType == "unsigned char") &&
|
|
FieldDefaultValue != null &&
|
|
!Parse.Try(FieldDefaultValue, out result))
|
|
{
|
|
for (uint index = 0; index < size; index++)
|
|
{
|
|
//Only the elements that are required to spell out the string should
|
|
//receive default values.
|
|
if (index < FieldDefaultValue.Length)
|
|
{
|
|
MessageArray[index] = new MessageData(FieldName + "[" + index + "]",
|
|
FieldType, FieldValue, FieldDefaultValue[(int)index].ToString(),
|
|
FieldMaxValue, FieldMinValue, m_Icd);
|
|
MessageArray[index].FieldInstruType = FieldInstruType;
|
|
}
|
|
else
|
|
{
|
|
MessageArray[index] = new MessageData(FieldName + "[" + index + "]",
|
|
FieldType, FieldValue, "0",
|
|
FieldMaxValue, FieldMinValue, m_Icd);
|
|
MessageArray[index].FieldInstruType = FieldInstruType;
|
|
}
|
|
MessageArray[index].depth = depth + 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (uint index = 0; index < size; index++)
|
|
{
|
|
MessageArray[index] = new MessageData(FieldName + "[" + index + "]",
|
|
FieldType, FieldValue, FieldDefaultValue, FieldMaxValue,
|
|
FieldMinValue, m_Icd);
|
|
MessageArray[index].FieldInstruType = FieldInstruType;
|
|
MessageArray[index].depth = depth + 1;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetStructureSize(int size)
|
|
{
|
|
if (!isArray && !isStructure)
|
|
{
|
|
isStructure = true;
|
|
MessageArray = new MessageData[size];
|
|
for (uint index = 0; index < size; index++)
|
|
{
|
|
MessageArray[index] = new MessageData(FieldName + ".", null, null, null, m_Icd);
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void SetInstruType(string Type)
|
|
{
|
|
if (Type != null)
|
|
{
|
|
FieldInstruType = Type;
|
|
|
|
// Ensure 'S' is used properly
|
|
if ((Type == "S") && (FieldType != "char"))
|
|
{
|
|
return; /* << EXIT >> */
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((FieldType != null) &&
|
|
((FieldType.Trim() == "float") || (FieldType.Trim() == "double")))
|
|
{
|
|
FieldInstruType = "F";
|
|
}
|
|
else
|
|
{
|
|
FieldInstruType = "I";
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void SetPixelSize()
|
|
{
|
|
// Only do this if the user did not define a size
|
|
if (imagePixelSize == 0)
|
|
{
|
|
switch (FieldType)
|
|
{
|
|
case "char":
|
|
case "unsigned char":
|
|
case "unsignedchar":
|
|
imagePixelSize = 1;
|
|
break;
|
|
|
|
case "short":
|
|
case "unsigned short":
|
|
case "unsignedshort":
|
|
imagePixelSize = 2;
|
|
break;
|
|
|
|
case "int":
|
|
case "unsigned int":
|
|
case "unsignedint":
|
|
case "unsigned":
|
|
case "boolean":
|
|
case "address":
|
|
case "float":
|
|
imagePixelSize = 4;
|
|
break;
|
|
|
|
case "double":
|
|
case "long long":
|
|
case "longlong":
|
|
case "unsigned long long":
|
|
case "unsignedlonglong":
|
|
imagePixelSize = 8;
|
|
break;
|
|
|
|
default:
|
|
if (isEnum)
|
|
{
|
|
imagePixelSize = 4;
|
|
}
|
|
else // Error case
|
|
{
|
|
imagePixelSize = 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private string FormatValue(string Value)
|
|
{
|
|
if ((Value == null) || (Value == ""))
|
|
{
|
|
return "";
|
|
}
|
|
else // Value exists
|
|
{
|
|
if (isEnum == false)
|
|
{
|
|
if (FieldInstruType == "I")
|
|
{
|
|
// This is being represented as a decimal
|
|
if (Parse.Try(Value, out long dec) == true)
|
|
{
|
|
return dec.ToString();
|
|
}
|
|
}
|
|
else if (FieldInstruType == "F")
|
|
{
|
|
// This is being represented as floating point
|
|
if (Parse.Try(Value, out double flt) == true)
|
|
{
|
|
return flt.ToString();
|
|
}
|
|
}
|
|
else if ((FieldInstruType == "X") ||
|
|
(FieldInstruType == "B") ||
|
|
(FieldInstruType == "T"))
|
|
{
|
|
// This is being represented as a hexadecimal value
|
|
if (Parse.Try(Value, out long hex) == true)
|
|
{
|
|
return "0x" + hex.ToString("X");
|
|
}
|
|
}
|
|
else if (FieldInstruType == "N")
|
|
{
|
|
// This is being represented as a binary number
|
|
if (Parse.Try(Value, out long bin) == true)
|
|
{
|
|
return Convert.ToString(bin, 2) + "b";
|
|
}
|
|
}
|
|
// else InstruType == 'S' or 'P' or anything else return the value
|
|
}
|
|
else // This value is an enumeration
|
|
{
|
|
Dictionary<string, string> enums = m_Icd.GetEnumerations(FieldType);
|
|
if (enums.ContainsValue(Value) == true)
|
|
{
|
|
foreach (KeyValuePair<string, string> pair in enums)
|
|
{
|
|
if (pair.Value.Trim() == Value.Trim())
|
|
{
|
|
return pair.Key;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Value; // If nothing above applies, simply return the value string
|
|
}
|
|
|
|
private String RemoveCharFromString(String str, char c)
|
|
{
|
|
if (str == null) return null; // Handle null case
|
|
|
|
int index = str.IndexOf(c);
|
|
while (index != -1)
|
|
{
|
|
str = str.Remove(index, 1);
|
|
index = str.IndexOf(c);
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|
|
#region ICloneable Members
|
|
|
|
public object Clone()
|
|
{
|
|
MessageData clone = new MessageData();
|
|
|
|
clone.FieldName = FieldName;
|
|
clone.FieldType = FieldType;
|
|
clone.FieldValue = FieldValue;
|
|
clone.FieldArrayValue = FieldArrayValue;
|
|
clone.FieldDefaultValue = FieldDefaultValue;
|
|
clone.FieldMaxValue = FieldMaxValue;
|
|
clone.FieldMinValue = FieldMinValue;
|
|
clone.FieldBitValue = FieldBitValue;
|
|
clone.FieldInstruType = FieldInstruType;
|
|
clone.Variable = Variable;
|
|
clone.MaxOffset = MaxOffset;
|
|
clone.MinOffset = MinOffset;
|
|
clone.VerifyType = VerifyType;
|
|
clone.isSelected = isSelected;
|
|
clone.isArray = isArray;
|
|
clone.isStructure = isStructure;
|
|
clone.isArrayOfStructures = isArrayOfStructures;
|
|
clone.isEnum = isEnum;
|
|
clone.usesRegister = usesRegister;
|
|
clone.isValid = isValid;
|
|
clone.useRange = useRange;
|
|
clone.arrayLength = arrayLength;
|
|
clone.bitMask = bitMask;
|
|
clone.expanded = expanded;
|
|
clone.depth = depth;
|
|
clone.m_Icd = m_Icd;
|
|
clone.imageWidth = imageWidth;
|
|
clone.imageHeight = imageHeight;
|
|
clone.imagePixelSize = imagePixelSize;
|
|
clone.imageBufferSize = imageBufferSize;
|
|
if (imageBufferSize > 0)
|
|
{
|
|
clone.imageBuffer = new byte[imageBufferSize];
|
|
imageBuffer.CopyTo(clone.imageBuffer, 0);
|
|
}
|
|
|
|
if (MessageArray == null)
|
|
{
|
|
clone.MessageArray = null;
|
|
}
|
|
else
|
|
{
|
|
clone.MessageArray = new MessageData[MessageArray.Length];
|
|
for (int i = 0; i < MessageArray.Length; i++)
|
|
{
|
|
clone.MessageArray[i] = (MessageData)MessageArray[i].Clone();
|
|
}
|
|
}
|
|
|
|
return clone;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|