// ********************************************************************************************************** // 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 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(); 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 enums = m_Icd.GetEnumerations(FieldType); if (enums.ContainsValue(Value) == true) { foreach (KeyValuePair 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 } }