Bit Masking in C#, converting from enum to byte []

1.2k Views Asked by At

I have a question regarding bit masking which I am completely new to. In the application there is currently means of taking a byte[] of addresses and from them determining which alarms (bools) are true of false.

I am looking to reverse this. I would have a list of properties (bool) and based on which ones are true, I would create an address.

Is there an easy built-in method for doing this?

Any help would be much appreciated. Below I have attached my code for getting which flags are enabled in an address.

public struct DeviceStatus
{
    [Flags]
    public enum DeviceStatusMasks
    {
        None = 0x0,
        EmergencyButton = 0x00000001,
        StartButton = 0x02,
        Door1Interlock = 0x04,
        Door2Interlock = 0x08,
        AccessPanelInterlock = 0x10,
        TubeTemperature = 0x20,
        SystemTemperature = 0x40,
        DeviceTouchScreenError = 0x80,
        FlashValueCorrupt = 0x100,
        VoltageRailError3_3V = 0x200,
        VoltageRailError5V = 0x400,
        VoltageRailError24V = 0x800,
        HvPsuWarmUpTimerElapsed = 0x1000,
        // ReSharper disable InconsistentNaming
        kVValueOutsideRange = 0x2000,
        mAValueOutsideRange = 0x4000,
        // ReSharper restore InconsistentNaming
        PreheatValueError = 0x8000,
        FilamentCurrentError = 0x10000,
        KeySwitchOff = 0x00020000,
        StandbyButtonPressed = 0x40000,
        ErrorTrapState = 0x80000,
        PcCommunicationFailure = 0x100000
    }


    public   DeviceStatus(byte[] value)
    {
        RawValue = (DeviceStatusMasks)BitConverter.ToInt32(value.Reverse().ToArray(), 0);
    }

    #region Public Properties

    public bool CriticalError => EmergencyButtonPressed | TubeTemperatureHigh | SystemTemperatureHigh;

    public bool EmergencyButtonPressed => RawValue.HasFlag(DeviceStatusMasks.EmergencyButton);

    public bool StartButtonPressed => RawValue.HasFlag(DeviceStatusMasks.StartButton);

    public bool Door1InterlockOpen => RawValue.HasFlag(DeviceStatusMasks.Door1Interlock);

    public bool Door2InterlockOpen => RawValue.HasFlag(DeviceStatusMasks.Door2Interlock);

    public bool AccessPanelInterlockOpen => RawValue.HasFlag(DeviceStatusMasks.AccessPanelInterlock);

    public bool TubeTemperatureHigh => RawValue.HasFlag(DeviceStatusMasks.TubeTemperature);

    public bool SystemTemperatureHigh => RawValue.HasFlag(DeviceStatusMasks.SystemTemperature);

    public bool DeviceTouchScreenError => RawValue.HasFlag(DeviceStatusMasks.DeviceTouchScreenError);

    public bool FlashValueCorrupt => RawValue.HasFlag(DeviceStatusMasks.FlashValueCorrupt);

    public bool VoltageRailError3_3V => RawValue.HasFlag(DeviceStatusMasks.VoltageRailError3_3V);

    public bool VoltageRailError5V => RawValue.HasFlag(DeviceStatusMasks.VoltageRailError5V);

    public bool VoltageRailError24V => RawValue.HasFlag(DeviceStatusMasks.VoltageRailError24V);

    public bool HvPsuWarmUpTimerElapsed => RawValue.HasFlag(DeviceStatusMasks.HvPsuWarmUpTimerElapsed);

    // ReSharper disable InconsistentNaming
    public bool kVValueOutsideRange => RawValue.HasFlag(DeviceStatusMasks.kVValueOutsideRange);

    public bool mAValueOutsideRange => RawValue.HasFlag(DeviceStatusMasks.mAValueOutsideRange);

    // ReSharper restore InconsistentNaming

    public bool PreheatValueError => RawValue.HasFlag(DeviceStatusMasks.PreheatValueError);

    public bool FilamentCurrentError => RawValue.HasFlag(DeviceStatusMasks.FilamentCurrentError);

    public bool KeySwitchOff => RawValue.HasFlag(DeviceStatusMasks.KeySwitchOff);

    public bool StandbyButtonPressed => RawValue.HasFlag(DeviceStatusMasks.StandbyButtonPressed);

    public bool ErrorTrapState => RawValue.HasFlag(DeviceStatusMasks.ErrorTrapState);

    public bool PcCommunicationFailure => RawValue.HasFlag(DeviceStatusMasks.PcCommunicationFailure);

    public bool HasNoStatus
    {
        get
        {
            return !(StandbyButtonPressed | Door1InterlockOpen | Door2InterlockOpen | AccessPanelInterlockOpen | KeySwitchOff | CriticalError);
        }
    }
    #endregion

    public DeviceStatusMasks RawValue { get; }
1

There are 1 best solutions below

0
On

It sounds like are trying to convert an OR-ed together set of bit-flags back into an enum array. You can do that with the BitArray class, along with a bit of math, as follows:

void Main()
{
    var value = Sample.A | Sample.B;
    var bits = new BitArray(new[] { (int)value });

    var enumValues = Enumerable.Range(0, bits.Length).Select(n =>
        ((Sample)(bits[n] ? Math.Pow(2, n) : 0)));
}

enum Sample
{
    A = 0x1,
    B = 0x2,
    C = 0x4
}