确定字节的模式

本文关键字:模式 字节 | 更新日期: 2023-09-27 18:06:18

我得到一个字节,它定义了另一个值的类型。

该字节称为值信息字段(VIF)

我有一个这样的列表:

VIF list http://img24.imageshack.us/img24/2061/viflist.jpg

现在我必须确定数据的类型和指数。我的第一次尝试,看起来像这样:

    private bool DefineType() 
    {
        byte basicMask = 224;   
        byte basicTimeMask = 88;
        byte[] powerMask = {80,72}; // 0101 0000,0100 1000
        byte[] volumneFlowMask = {64,56,48};  //0100 0000, 0011 1000, 0011 0000
        byte MassFlowMask = 40; //0010 1000
        byte[] temperatureMask = {36, 32, 28, 24}; //0010 0100, 0010 0000, 0001 1100, 0001 1000
        byte PressureMask = 20; // 0001 0100
        byte AveragingDurationMask = 12; // 0000 1100
        byte ActualityDurationMask = 8; //0000 1000
        byte TimePointMask = 18;//0001 0010
        byte BusAddressMask = 5; //0000 0101
        byte ReservedMask = 16;  //0001 0000
        byte EnhancedMask = 0x06; // 0000 0110
        byte[] ExtensionMask = {2 ,4}; //0000 0010,0000 0100
        byte FabricationMask = 7;
        if ((_VIF & basicMask) == 0)
        {
            return CheckBit(_VIF, 4) ? DefineMassVolumne() : DefineEnergy();
        }
        if ((_VIF & basicTimeMask) == 0)
        {
            DefineTime();
            return true;
        }
        if (((_VIF & powerMask[0]) == 0) | ((_VIF & powerMask[1]) == 0)) 
        {
            if (CheckBit(_VIF, 3)) 
            {
                _mUnit = eUnit.W;
                _exponent = GetExponent() - 3;
                return true;
            }
            _mUnit = eUnit.J_H;
            _exponent = GetExponent();
            return true;
        }
        if (((_VIF & volumneFlowMask[0]) == 0) | ((_VIF & volumneFlowMask[1]) == 0) | ((_VIF & volumneFlowMask[2]) == 0)) 
        {
            DefineVolumneFlow();
            return true;
        }
        if ((_VIF & MassFlowMask) == 0) 
        {
            _mUnit = eUnit.kg_h;
            _exponent = GetExponent() - 3;
            return true;
        }
        if (temperatureMask.Any(mask => (_VIF & mask) == 0))
        {
            DefineTemperature(); return true;
        }
        if ((_VIF & PressureMask) == 0) 
        {
            _mUnit = eUnit.bar;
            _exponent = Get2DigitExponent() - 3;
            return true;
        }
        if ((_VIF & AveragingDurationMask) == 0)
        {
            mTimeType = TimeType.AveragingDuration;
            SetTimeRange();
            return true;
        }
        if ((_VIF & ActualityDurationMask) == 0)
        {
            mTimeType = TimeType.ActualityDuration;
            SetTimeRange();
            return true;
        }
        if ((_VIF & TimePointMask) == 0)
        {
            mTimeType = TimeType.TimePoint;
            if (CheckBit(_VIF, 0))
            {
                _mUnit = eUnit.DateTime;
                _exponent = 0;
                return true;
            }
            _mUnit = eUnit.Date;
            _exponent = 0;
            return true;
        }
        if ((_VIF & FabricationMask) == 0)
        {
            _mUnit = eUnit.Fabrication;
            _exponent = 0;
            return true;
        }
        if ((_VIF & BusAddressMask) == 0) 
        {
            _mUnit = eUnit.BusAddress;
            _exponent = 0;
            return true;
        }
        if ((_VIF & ReservedMask) == 0) 
        {
            _mUnit = eUnit.Reserved;
            _exponent = 0;
            return true;
        }
        if ((_VIF & EnhancedMask) == 0)
        {
            _mUnit = eUnit.Enhanced;
            return true;
        }
        foreach (Byte b in ExtensionMask)
        {
            if ((_VIF & b) == 0)
            {
                _mUnit = eUnit.Extension;
                return true;
            }
        }
        throw new Exception("VIF Code  does not exist!");
    }

它是这样工作的,但我对这种尝试不是很满意。代码很难管理,效率也不高。有没有更好/更聪明的方法?

确定字节的模式

// You can decouple check functions and actuall logic by 
// introducing predicate per item type, then try to figure out whether you can
// abstract each block inside `if(predicate()) { ...here.. }` 
// into the separate factories using `Func<,>`
// Check predicate
Predicate<int> actualityDurationCheck = (vif) => 
                                        (vif & ActualityDurationMask) == 0;
if (actualityDurationCheck(_VIF))
{
    mTimeType = TimeType.ActualityDuration;
    SetTimeRange();
}

然后你可以进一步创建一些checkFactories提供程序,如:

   Predicate<int> checkFactory;
   IDictionary<ItemType, Predicate<int>> checkFactoryProvider = new ...
   if (checkFactoryProvider.ContainsKey(ItemType.ActualityDurationMask)
   {
        checkFactory = checkFactoryProvider[ItemType.ActualityDurationMask];
   }
    // check for nulls ets
    if (checkFactory (_VIF))
    {
        mTimeType = TimeType.ActualityDuration;
        SetTimeRange();
    }

基本上你最终会得到一些干净的循环,比如(伪代码)

bool processed = false;
foreach(var checkFactory in availableFactories)
{
  if (checkFactory(VIF))
  {
     var processingFactory = processingFactories.Resolve(ItemType);
     processingFactory.Process(VIF);
     processed = true;
  }
}