确定字节的模式
本文关键字:模式 字节 | 更新日期: 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;
}
}