219 lines
6.6 KiB
C#
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.Instruments.MessagingUtilities
|
|
{
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
}
|