// ********************************************************************************************************** // BitFieldGeneric.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; namespace Raytheon.Instruments.MessagingUtilities { // This is a generic class used to apply a bitfield to // a value to get the desired value class BitFieldGeneric where T : IConvertible { protected long m_Value; // This is the value being operated on protected ulong m_Mask; public char ToChar() { return (char)m_Value; } public sbyte ToSByte() { return (sbyte)m_Value; } public short ToShort() { return (short)m_Value; } public int ToInt() { return (int)m_Value; } public long ToLong() { return (long)m_Value; } public ushort ToUShort() { return (ushort)m_Value; } public uint ToUInt() { return (uint)m_Value; } public ulong ToULong() { return (ulong)m_Value; } public BitFieldGeneric(T value, ulong bitMask) { m_Mask = bitMask; try { m_Value = ApplyBitMask((ulong)value.ToInt64(null), bitMask); } catch { m_Value = ApplyBitMask(value.ToUInt64(null), bitMask); } } public BitFieldGeneric(string value, ulong bitMask) { m_Mask = bitMask; if(string.IsNullOrEmpty(value)) { value = "0"; } if (Parse.Try(value, out m_Value) == true) { m_Value = PrepareWithBitMask(m_Value, bitMask); } else { throw new Exception("Unable to parse value = " + value); } } // count the number of 1 bits in a ulong int BitCount(ulong x) { int n = 0; if (x > 0) do ++n; while ((x &= x - 1) > 1); return n; } // Check to see if the MSB is set after accounting for // the mask. If it is, then the number should be converted // to display a negative number public void ToSigned() { if (m_Mask > 0) { // See if the sign bit is set int numbits = BitCount(m_Mask); if (m_Value > (Math.Pow(2, numbits - 1))) { // If it is, take the two's complement m_Value = (~m_Value) + 1; // Mask off the leading F's from the conversion ulong mask = 1; for (int i = 0; i < numbits - 1; i++) { mask = (mask << 1) + 1; } m_Value = (long)(((ulong)m_Value) & mask); // Add the negative sign m_Value = -m_Value; } } } public override string ToString() { return m_Value.ToString(); } public void BitOR(T value) { long orValue = value.ToInt64(null); m_Value |= orValue; } private long PrepareWithBitMask(long val, ulong bitMask) { ulong value = (ulong)val; ulong mask = bitMask; if (bitMask != 0) { if ((mask & 1) != 1) { while (((mask >> 1) & 1) != 1) //shift mask to LSB { mask >>= 1; } mask >>= 1; // one last shift not done by loop } value &= mask; // ensure value is contained in the same # of bits as the mask // Shift the value back to its proper spot in the memory while (mask != bitMask) { value <<= 1; mask <<= 1; } } return (long)value; } private long ApplyBitMask(ulong val, ulong bitMask) { ulong value = val; if (bitMask != 0) // Apply the bit field { value &= bitMask; // Shift until the bitmask resides in the LSB if ((bitMask & 1) != 1) { while (((bitMask >> 1) & 1) != 1) { value >>= 1; bitMask >>= 1; } // We need one more shift after leaving the while loop value >>= 1; } } return (long)value; } } }