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

219 lines
6.6 KiB
C#

// **********************************************************************************************************
// 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.Common.Coe
{
// This is a generic class used to apply a bitfield to
// a value to get the desired value
class BitFieldGeneric<T> 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;
}
}
}