// ********************************************************************************************************** // serializationSupport.cs // 6/1/2022 // NGI - Next Generation Interceptor // // Contract No. HQ0856-21-C-0003/1022000209 // // THIS DOCUMENT DOES NOT CONTAIN TECHNOLOGY OR TECHNICAL DATA CONTROLLED UNDER EITHER THE U.S. // INTERNATIONAL TRAFFIC IN ARMS REGULATIONS OR THE U.S. EXPORT ADMINISTRATION REGULATIONS. // // RAYTHEON PROPRIETARY: THIS DOCUMENT CONTAINS DATA OR INFORMATION PROPRIETARY TO RAYTHEON // COMPANY AND IS RESTRICTED TO USE ONLY BY PERSONS AUTHORIZED BY RAYTHEON COMPANY IN WRITING TO USE IT. // DISCLOSURE TO UNAUTHORIZED PERSONS WOULD LIKELY CAUSE SUBSTANTIAL COMPETITIVE HARM TO RAYTHEON // COMPANY'S BUSINESS POSITION. NEITHER SAID DOCUMENT NOR ITS CONTENTS SHALL BE FURNISHED OR DISCLOSED // TO OR COPIED OR USED BY PERSONS OUTSIDE RAYTHEON COMPANY WITHOUT THE EXPRESS WRITTEN APPROVAL OF // RAYTHEON COMPANY. // // UNPUBLISHED WORK - COPYRIGHT RAYTHEON COMPANY. // // DESTRUCTION NOTICE: FOR CLASSIFIED DOCUMENTS FOLLOW THE PROCEDURES IN DOD 5220.22-M, // NATIONAL INDUSTRIAL SECURITY PROGRAM OPERATING MANUAL, FEBRUARY 2006, // INCORPORATING CHANGE 1, MARCH 28, 2013, CHAPTER 5, SECTION 7, OR DODM 5200.01-VOLUME 3, // DOD INFORMATION SECURITY PROGRAM: PROTECTION OF CLASSIFIED INFORMATION, ENCLOSURE 3, // SECTION 17. FOR CONTROLLED UNCLASSIFIED INFORMATION FOLLOW THE PROCEDURES IN DODM 5200.01-VOLUME 4, // INFORMATION SECURITY PROGRAM: CONTROLLED UNCLASSIFIED INFORMATION. // // CONTROLLED BY: MISSILE DEFENSE AGENCY // CONTROLLED BY: GROUND-BASED MIDCOURSE DEFENSE PROGRAM OFFICE // CUI CATEGORY: CTI // DISTRIBUTION/DISSEMINATION CONTROL: F // POC: Alex Kravchenko (1118268) // ********************************************************************************************************** //\\ //----------------------------------------------------------------------------// // UNCLASSIFIED // //----------------------------------------------------------------------------// //\\<\Unclassified> //\\ //----------------------------------------------------------------------------// // Copyright %(copyright)s Raytheon Company. // // This software was developed pursuant to Contract Number %(contractNumber)s // // with the U.S. government. The U.S. government's rights in and to this // // copyrighted software are as specified in DFARS 252.227-7014 which was made // // part of the above contract. // //----------------------------------------------------------------------------// //\\<\UnlimitedRights> //\\ //----------------------------------------------------------------------------// // WARNING - This document contains technical data and / or technology whose // // export or disclosure to Non-U.S. Persons, wherever located, is restricted // // by the International Traffic in Arms Regulations (ITAR) (22 C.F.R. // // Section 120-130) or the Export Administration Regulations (EAR) (15 C.F.R. // // Section 730-774). This document CANNOT be exported (e.g., provided to a // // supplier outside of the United States) or disclosed to a Non-U.S. Person, // // wherever located, until a final jurisdiction and classification // // determination has been completed and approved by Raytheon, and any // // required U.S. Government approvals have been obtained. Violations are // // subject to severe criminal penalties. // //----------------------------------------------------------------------------// //\\<\EximUndetermined> using System; using System.Reflection; namespace Raytheon.Common.Coe { // // // // Serialization Support // // // public class serializationSupport { public static int getPayloadSize(object target, Type targetType, ref int size) { FieldInfo[] fields = targetType.GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo field in fields) { getFieldSize(field, target, ref size); } return size; } public static int getFieldSize(FieldInfo field, object target, ref int size) { if (field.FieldType == typeof(char) || field.FieldType == typeof(byte) || field.FieldType == typeof(byte) || field.FieldType == typeof(sbyte)) { size += 1; } else if (field.FieldType == typeof(char[]) || field.FieldType == typeof(byte[]) || field.FieldType == typeof(byte[]) || field.FieldType == typeof(sbyte[])) { byte[] values = (byte[])field.GetValue(target); size += 1 * ((Array)field.GetValue(target)).Length; } else if (field.FieldType == typeof(short) || field.FieldType == typeof(ushort) || field.FieldType == typeof(short) || field.FieldType == typeof(ushort)) { alignIndex(ref size, 2); size += 2; } else if (field.FieldType == typeof(short[]) || field.FieldType == typeof(ushort[]) || field.FieldType == typeof(short[]) || field.FieldType == typeof(ushort[])) { alignIndex(ref size, 2); size += 2 * ((Array)field.GetValue(target)).Length; } else if (field.FieldType == typeof(int) || field.FieldType == typeof(uint) || field.FieldType == typeof(int) || field.FieldType == typeof(uint) || field.FieldType == typeof(float)) { alignIndex(ref size, 4); size += 4; } else if (field.FieldType == typeof(int[]) || field.FieldType == typeof(uint[]) || field.FieldType == typeof(int[]) || field.FieldType == typeof(uint[]) || field.FieldType == typeof(float[])) { alignIndex(ref size, 4); size += 4 * ((Array)field.GetValue(target)).Length; } else if (field.FieldType == typeof(long) || field.FieldType == typeof(ulong) || field.FieldType == typeof(long) || field.FieldType == typeof(ulong) || field.FieldType == typeof(double)) { alignIndex(ref size, 8); size += 8; } else if (field.FieldType == typeof(long[]) || field.FieldType == typeof(ulong[]) || field.FieldType == typeof(long[]) || field.FieldType == typeof(ulong[]) || field.FieldType == typeof(double[])) { alignIndex(ref size, 8); size += 8 * ((Array)field.GetValue(target)).Length; } else if (field.FieldType.IsArray) // Array of classes { alignIndex(ref size, 4); Array targetArray = (Array)field.GetValue(target); int arraySize = targetArray.Length; object[] objectArray = (object[])field.GetValue(target); var arrayElementType = objectArray.GetType().GetElementType(); for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { object arrayItem = objectArray[arrayIndex]; Type arrayItemType = arrayItem.GetType(); FieldInfo[] subfields = arrayItemType.GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo subfield in subfields) { Type subfieldType = subfield.GetType(); Type elementType = subfield.FieldType.GetElementType(); getFieldSize(subfield, arrayItem, ref size); } } } else // Class { alignIndex(ref size, 4); object objectItem = field.GetValue(target); FieldInfo[] subfields = field.FieldType.GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo subfield in subfields) { Type subfieldType = subfield.GetType(); Type elementType = subfield.FieldType.GetElementType(); getFieldSize(subfield, objectItem, ref size); } } return size; } public static void alignIndex(ref int dataBufferIndex, int alignment) { int indexMisalignment = dataBufferIndex % alignment; if (indexMisalignment > 0) { dataBufferIndex += alignment - indexMisalignment; } } public static void serializeField(FieldInfo field, byte[] dataBuffer, ref int dataBufferIndex, object target) { Type fieldType = field.GetType(); object fieldObject = field.GetValue(target); if (field.FieldType == typeof(char) || field.FieldType == typeof(byte) || field.FieldType == typeof(byte) || field.FieldType == typeof(sbyte)) { byte value = Convert.ToByte(field.GetValue(target)); dataBuffer[dataBufferIndex++] = (byte)(value & 0xFF); } else if (field.FieldType == typeof(char[])) { char[] values = (char[])field.GetValue(target); foreach (char value in values) { dataBuffer[dataBufferIndex++] = (byte)(value & 0xFF); } } else if (field.FieldType == typeof(byte[]) || field.FieldType == typeof(byte[]) || field.FieldType == typeof(sbyte[])) { byte[] values = (byte[])field.GetValue(target); foreach (byte value in values) { dataBuffer[dataBufferIndex++] = (byte)(value & 0xFF); } } else if (field.FieldType == typeof(short) || field.FieldType == typeof(ushort) || field.FieldType == typeof(short) || field.FieldType == typeof(ushort)) { alignIndex(ref dataBufferIndex, 2); ushort value = Convert.ToUInt16(field.GetValue(target)); dataBuffer[dataBufferIndex++] = (byte)(value & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 8 & 0xFF); } else if (field.FieldType == typeof(short[]) || field.FieldType == typeof(ushort[]) || field.FieldType == typeof(short[]) || field.FieldType == typeof(ushort[])) { alignIndex(ref dataBufferIndex, 2); ushort[] values = (ushort[])field.GetValue(target); foreach (char value in values) { dataBuffer[dataBufferIndex++] = (byte)(value & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 8 & 0xFF); } } else if (field.FieldType == typeof(int) || field.FieldType == typeof(uint) || field.FieldType == typeof(int) || field.FieldType == typeof(uint)) { alignIndex(ref dataBufferIndex, 4); uint value = Convert.ToUInt32(field.GetValue(target)); dataBuffer[dataBufferIndex++] = (byte)(value & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 8 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 16 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 24 & 0xFF); } else if (field.FieldType == typeof(float)) { alignIndex(ref dataBufferIndex, 4); float floatValue = (float)field.GetValue(target); byte[] valueArray = BitConverter.GetBytes(floatValue); dataBuffer[dataBufferIndex++] = valueArray[0]; dataBuffer[dataBufferIndex++] = valueArray[1]; dataBuffer[dataBufferIndex++] = valueArray[2]; dataBuffer[dataBufferIndex++] = valueArray[3]; } else if (field.FieldType == typeof(int[]) || field.FieldType == typeof(uint[]) || field.FieldType == typeof(int[]) || field.FieldType == typeof(uint[])) { alignIndex(ref dataBufferIndex, 4); uint[] values = (uint[])field.GetValue(target); foreach (uint value in values) { dataBuffer[dataBufferIndex++] = (byte)(value & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 8 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 16 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 24 & 0xFF); } } else if (field.FieldType == typeof(float[])) { alignIndex(ref dataBufferIndex, 4); float[] values = (float[])field.GetValue(target); foreach (float floatValue in values) { byte[] valueArray = BitConverter.GetBytes(floatValue); dataBuffer[dataBufferIndex++] = valueArray[0]; dataBuffer[dataBufferIndex++] = valueArray[1]; dataBuffer[dataBufferIndex++] = valueArray[2]; dataBuffer[dataBufferIndex++] = valueArray[3]; } } else if (field.FieldType == typeof(long) || field.FieldType == typeof(ulong) || field.FieldType == typeof(long) || field.FieldType == typeof(ulong)) { alignIndex(ref dataBufferIndex, 8); ulong value = Convert.ToUInt64(field.GetValue(target)); dataBuffer[dataBufferIndex++] = (byte)(value & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 8 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 16 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 24 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 32 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 40 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 48 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 56 & 0xFF); } else if (field.FieldType == typeof(double)) { alignIndex(ref dataBufferIndex, 8); double doubleValue = (double)field.GetValue(target); byte[] valueArray = BitConverter.GetBytes(doubleValue); dataBuffer[dataBufferIndex++] = valueArray[0]; dataBuffer[dataBufferIndex++] = valueArray[1]; dataBuffer[dataBufferIndex++] = valueArray[2]; dataBuffer[dataBufferIndex++] = valueArray[3]; dataBuffer[dataBufferIndex++] = valueArray[4]; dataBuffer[dataBufferIndex++] = valueArray[5]; dataBuffer[dataBufferIndex++] = valueArray[6]; dataBuffer[dataBufferIndex++] = valueArray[7]; } else if (field.FieldType == typeof(long[]) || field.FieldType == typeof(ulong[]) || field.FieldType == typeof(long[]) || field.FieldType == typeof(ulong[])) { alignIndex(ref dataBufferIndex, 8); ulong[] values = (ulong[])field.GetValue(target); foreach (ulong value in values) { dataBuffer[dataBufferIndex++] = (byte)(value & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 8 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 16 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 24 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 32 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 40 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 48 & 0xFF); dataBuffer[dataBufferIndex++] = (byte)(value >> 56 & 0xFF); } } else if (field.FieldType == typeof(double[])) { alignIndex(ref dataBufferIndex, 8); double[] values = (double[])field.GetValue(target); foreach (double doubleValue in values) { byte[] valueArray = BitConverter.GetBytes(doubleValue); dataBuffer[dataBufferIndex++] = valueArray[0]; dataBuffer[dataBufferIndex++] = valueArray[1]; dataBuffer[dataBufferIndex++] = valueArray[2]; dataBuffer[dataBufferIndex++] = valueArray[3]; dataBuffer[dataBufferIndex++] = valueArray[4]; dataBuffer[dataBufferIndex++] = valueArray[5]; dataBuffer[dataBufferIndex++] = valueArray[6]; dataBuffer[dataBufferIndex++] = valueArray[7]; } } else if (field.FieldType.IsArray) // Array of classes { alignIndex(ref dataBufferIndex, 4); Array targetArray = (Array)field.GetValue(target); int arraySize = targetArray.Length; object[] objectArray = (object[])field.GetValue(target); Type arrayElementType = objectArray.GetType().GetElementType(); for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { object arrayItem = objectArray[arrayIndex]; Type arrayItemType = arrayItem.GetType(); FieldInfo[] subfields = arrayItemType.GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo subfield in subfields) { Type subfieldType = subfield.GetType(); Type elementType = subfield.FieldType.GetElementType(); serializeField(subfield, dataBuffer, ref dataBufferIndex, arrayItem); } } } else // Class { alignIndex(ref dataBufferIndex, 4); FieldInfo[] subfields = fieldObject.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo subfield in subfields) { Type subfieldType = subfield.GetType(); Type elementType = subfield.FieldType.GetElementType(); serializeField(subfield, dataBuffer, ref dataBufferIndex, fieldObject); } } } public static void deserializeField(FieldInfo field, byte[] dataBuffer, ref int dataBufferIndex, object target) { Type fieldType = field.GetType(); object fieldObject = field.GetValue(target); if (field.FieldType == typeof(char)) { char value = Convert.ToChar(dataBuffer[dataBufferIndex++]); field.SetValue(target, value); } else if (field.FieldType == typeof(byte) || field.FieldType == typeof(byte)) { byte value = dataBuffer[dataBufferIndex++]; field.SetValue(target, value); } else if (field.FieldType == typeof(sbyte)) { sbyte value = Convert.ToSByte(dataBuffer[dataBufferIndex++]); field.SetValue(target, value); } else if (field.FieldType == typeof(char[])) { char[] values = (char[])field.GetValue(target); for (int index = 0; index < values.Length; index++) { values[index] = (char)dataBuffer[dataBufferIndex++]; } field.SetValue(target, values); } else if (field.FieldType == typeof(byte[]) || field.FieldType == typeof(byte[])) { byte[] values = (byte[])field.GetValue(target); for (int index = 0; index < values.Length; index++) { values[index] = dataBuffer[dataBufferIndex++]; } field.SetValue(target, values); } else if (field.FieldType == typeof(sbyte[])) { sbyte[] values = (sbyte[])field.GetValue(target); for (int index = 0; index < values.Length; index++) { values[index] = (sbyte)dataBuffer[dataBufferIndex++]; } field.SetValue(target, values); } else if (field.FieldType == typeof(short) || field.FieldType == typeof(ushort) || field.FieldType == typeof(short) || field.FieldType == typeof(ushort)) { alignIndex(ref dataBufferIndex, 2); ushort value = (ushort)(dataBuffer[dataBufferIndex++] + (ushort)(dataBuffer[dataBufferIndex++] << 8)); if (field.FieldType == typeof(short) || field.FieldType == typeof(short)) { field.SetValue(target, Convert.ToInt16(value)); } else { field.SetValue(target, value); } } else if (field.FieldType == typeof(short[]) || field.FieldType == typeof(ushort[]) || field.FieldType == typeof(short[]) || field.FieldType == typeof(ushort[])) { alignIndex(ref dataBufferIndex, 2); ushort[] values = (ushort[])field.GetValue(target); for (int index = 0; index < values.Length; index++) { values[index] = (ushort)(dataBuffer[dataBufferIndex++] + (ushort)(dataBuffer[dataBufferIndex++] << 8)); } field.SetValue(target, values); } else if (field.FieldType == typeof(int) || field.FieldType == typeof(uint) || field.FieldType == typeof(int) || field.FieldType == typeof(uint)) { alignIndex(ref dataBufferIndex, 4); uint value = dataBuffer[dataBufferIndex++] + ((uint)dataBuffer[dataBufferIndex++] << 8) + ((uint)dataBuffer[dataBufferIndex++] << 16) + ((uint)dataBuffer[dataBufferIndex++] << 24); if (field.FieldType == typeof(int) || field.FieldType == typeof(int)) { field.SetValue(target, Convert.ToInt32(value)); } else { field.SetValue(target, value); } } else if (field.FieldType == typeof(int[]) || field.FieldType == typeof(uint[]) || field.FieldType == typeof(int[]) || field.FieldType == typeof(uint[])) { alignIndex(ref dataBufferIndex, 4); uint[] values = (uint[])field.GetValue(target); for (int index = 0; index < values.Length; index++) { values[index] = dataBuffer[dataBufferIndex++] + ((uint)dataBuffer[dataBufferIndex++] << 8) + ((uint)dataBuffer[dataBufferIndex++] << 16) + ((uint)dataBuffer[dataBufferIndex++] << 24); } field.SetValue(target, values); } else if (field.FieldType == typeof(float)) { alignIndex(ref dataBufferIndex, 4); float singleValue = BitConverter.ToSingle(dataBuffer, dataBufferIndex); dataBufferIndex += 4; field.SetValue(target, singleValue); } else if (field.FieldType == typeof(float[])) { alignIndex(ref dataBufferIndex, 4); float[] values = (float[])field.GetValue(target); for (int index = 0; index < values.Length; index++) { values[index] = BitConverter.ToSingle(dataBuffer, dataBufferIndex); dataBufferIndex += 4; } field.SetValue(target, values); } else if (field.FieldType == typeof(long) || field.FieldType == typeof(ulong) || field.FieldType == typeof(long) || field.FieldType == typeof(ulong)) { alignIndex(ref dataBufferIndex, 8); uint value = dataBuffer[dataBufferIndex++] + ((uint)dataBuffer[dataBufferIndex++] << 8) + ((uint)dataBuffer[dataBufferIndex++] << 16) + ((uint)dataBuffer[dataBufferIndex++] << 24) + ((uint)dataBuffer[dataBufferIndex++] << 32) + ((uint)dataBuffer[dataBufferIndex++] << 40) + ((uint)dataBuffer[dataBufferIndex++] << 48) + ((uint)dataBuffer[dataBufferIndex++] << 56); if (field.FieldType == typeof(long) || field.FieldType == typeof(long)) { field.SetValue(target, Convert.ToInt64(value)); } else { field.SetValue(target, value); } } else if (field.FieldType == typeof(long[]) || field.FieldType == typeof(ulong[]) || field.FieldType == typeof(long[]) || field.FieldType == typeof(ulong[])) { alignIndex(ref dataBufferIndex, 8); ulong[] values = (ulong[])field.GetValue(target); for (int index = 0; index < values.Length; index++) { values[index] = dataBuffer[dataBufferIndex++] + ((uint)dataBuffer[dataBufferIndex++] << 8) + ((uint)dataBuffer[dataBufferIndex++] << 16) + ((uint)dataBuffer[dataBufferIndex++] << 24) + ((uint)dataBuffer[dataBufferIndex++] << 32) + ((uint)dataBuffer[dataBufferIndex++] << 40) + ((uint)dataBuffer[dataBufferIndex++] << 48) + ((uint)dataBuffer[dataBufferIndex++] << 56); } field.SetValue(target, values); } else if (field.FieldType == typeof(double)) { alignIndex(ref dataBufferIndex, 8); field.SetValue(target, BitConverter.ToDouble(dataBuffer, dataBufferIndex)); dataBufferIndex += 8; } else if (field.FieldType == typeof(double[])) { alignIndex(ref dataBufferIndex, 8); double[] values = (double[])field.GetValue(target); for (int index = 0; index < values.Length; index++) { values[index] = BitConverter.ToDouble(dataBuffer, dataBufferIndex); dataBufferIndex += 8; } field.SetValue(target, values); } else if (field.FieldType.IsArray) { alignIndex(ref dataBufferIndex, 4); Array targetArray = (Array)field.GetValue(target); int arraySize = targetArray.Length; object[] objectArray = (object[])field.GetValue(target); Type arrayElementType = objectArray.GetType().GetElementType(); for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { object arrayItem = objectArray[arrayIndex]; Type arrayItemType = arrayItem.GetType(); FieldInfo[] subfields = arrayItemType.GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo subfield in subfields) { Type subfieldType = subfield.GetType(); Type elementType = subfield.FieldType.GetElementType(); deserializeField(subfield, dataBuffer, ref dataBufferIndex, arrayItem); } } } else { alignIndex(ref dataBufferIndex, 4); FieldInfo[] subfields = fieldObject.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (FieldInfo subfield in subfields) { Type subfieldType = subfield.GetType(); object subfieldObject = subfield.GetValue(fieldObject); Type elementType = subfield.FieldType.GetElementType(); deserializeField(subfield, dataBuffer, ref dataBufferIndex, fieldObject); } } } } } //\\ //----------------------------------------------------------------------------// // UNCLASSIFIED // //----------------------------------------------------------------------------// //\\<\Unclassified>