Feature (contd.): Variable Fields - defined a template function varyCounter to avoid duplicating code for different counter sizes

This commit is contained in:
Srivats P. 2015-05-31 19:46:16 +05:30
parent 77f5b124e7
commit 641a4f3c89

View File

@ -1058,124 +1058,76 @@ quint64 AbstractProtocol::lcm(quint64 u, quint64 v)
return (u * v)/gcd(u, v); return (u * v)/gcd(u, v);
} }
void AbstractProtocol::varyProtocolFrameValue(QByteArray &buf, int frameIndex, /*
const OstProto::VariableField &varField) const * XXX: varyCounter() is not a member of AbstractProtocol to avoid
* moving it into the header file and thereby keeping the header file
* clean
*/
template <typename T>
bool varyCounter(QString protocolName, QByteArray &buf, int frameIndex,
const OstProto::VariableField &varField)
{ {
int x = (frameIndex % varField.count()) * varField.step(); int x = (frameIndex % varField.count()) * varField.step();
// FIXME: use templates for duplicating code for quint8, quint16, quint32 T oldfv, newfv;
switch (varField.type()) {
case OstProto::VariableField::kCounter8: {
quint8 oldfv, newfv;
if ((varField.offset() + sizeof(quint8)) > quint8(buf.size())) if ((varField.offset() + sizeof(T)) > uint(buf.size()))
{ {
qWarning("%s varField ofs %d beyond protocol frame %d - skipping", qWarning("%s varField ofs %d beyond protocol frame %d - skipping",
qPrintable(shortName()), varField.offset(), buf.size()); qPrintable(protocolName), varField.offset(), buf.size());
goto _exit; return false;
} }
oldfv = *((uchar*)buf.constData() + varField.offset()); oldfv = *((T*)((uchar*)buf.constData() + varField.offset()));
switch(varField.mode()) if (sizeof(T) > sizeof(quint8))
{ oldfv = qFromBigEndian(oldfv);
switch(varField.mode())
{
case OstProto::VariableField::kIncrement: case OstProto::VariableField::kIncrement:
newfv = (oldfv & ~varField.mask()) newfv = (oldfv & ~varField.mask())
| ((varField.value() + x) & varField.mask()); | ((varField.value() + x) & varField.mask());
break; break;
case OstProto::VariableField::kDecrement: case OstProto::VariableField::kDecrement:
newfv = (oldfv & ~varField.mask()) newfv = (oldfv & ~varField.mask())
| ((varField.value() - x) & varField.mask()); | ((varField.value() - x) & varField.mask());
break; break;
case OstProto::VariableField::kRandom: case OstProto::VariableField::kRandom:
newfv = (oldfv & ~varField.mask()) newfv = (oldfv & ~varField.mask())
| ((varField.value() + qrand()) & varField.mask()); | ((varField.value() + qrand()) & varField.mask());
break; break;
default: default:
qWarning("%s Unsupported varField mode %d", qPrintable(shortName()), qWarning("%s Unsupported varField mode %d",
varField.mode()); qPrintable(protocolName), varField.mode());
} }
if (sizeof(T) == sizeof(quint8))
*((uchar*)buf.constData() + varField.offset()) = newfv; *((uchar*)buf.constData() + varField.offset()) = newfv;
qDebug("%s varField ofs %d oldfv %x newfv %x", qPrintable(shortName()), else
varField.offset(), oldfv, newfv);
break;
}
case OstProto::VariableField::kCounter16: {
quint16 oldfv, newfv;
if ((varField.offset() + sizeof(quint16)) > quint16(buf.size()))
{
qWarning("%s varField ofs %d beyond protocol frame %d - skipping",
qPrintable(shortName()), varField.offset(), buf.size());
goto _exit;
}
oldfv = qFromBigEndian<quint16>((uchar*)buf.constData()
+ varField.offset());
switch(varField.mode())
{
case OstProto::VariableField::kIncrement:
newfv = (oldfv & ~varField.mask())
| ((varField.value() + x) & varField.mask());
break;
case OstProto::VariableField::kDecrement:
newfv = (oldfv & ~varField.mask())
| ((varField.value() - x) & varField.mask());
break;
case OstProto::VariableField::kRandom:
newfv = (oldfv & ~varField.mask())
| ((varField.value() + qrand()) & varField.mask());
break;
default:
qWarning("%s Unsupported varField mode %d", qPrintable(shortName()),
varField.mode());
}
qToBigEndian(newfv, (uchar*)buf.constData() + varField.offset()); qToBigEndian(newfv, (uchar*)buf.constData() + varField.offset());
qDebug("%s varField ofs %d oldfv %x newfv %x", qPrintable(shortName()),
varField.offset(), oldfv, newfv); qDebug("%s varField ofs %d oldfv %x newfv %x",
qPrintable(protocolName), varField.offset(), oldfv, newfv);
return true;
}
void AbstractProtocol::varyProtocolFrameValue(QByteArray &buf, int frameIndex,
const OstProto::VariableField &varField) const
{
switch (varField.type()) {
case OstProto::VariableField::kCounter8:
varyCounter<quint8>(shortName(), buf, frameIndex, varField);
break; break;
} case OstProto::VariableField::kCounter16:
varyCounter<quint16>(shortName(), buf, frameIndex, varField);
case OstProto::VariableField::kCounter32: { break;
quint32 oldfv, newfv; case OstProto::VariableField::kCounter32:
varyCounter<quint32>(shortName(), buf, frameIndex, varField);
if ((varField.offset() + sizeof(quint32)) > quint32(buf.size()))
{
qWarning("%s varField ofs %d beyond protocol frame %d - skipping",
qPrintable(shortName()), varField.offset(), buf.size());
goto _exit;
}
oldfv = qFromBigEndian<quint32>((uchar*)buf.constData()
+ varField.offset());
switch(varField.mode())
{
case OstProto::VariableField::kIncrement:
newfv = (oldfv & ~varField.mask())
| ((varField.value() + x) & varField.mask());
break;
case OstProto::VariableField::kDecrement:
newfv = (oldfv & ~varField.mask())
| ((varField.value() - x) & varField.mask());
break;
case OstProto::VariableField::kRandom:
newfv = (oldfv & ~varField.mask())
| ((varField.value() + qrand()) & varField.mask());
break;
default:
qWarning("%s Unsupported varField mode %d", qPrintable(shortName()),
varField.mode());
}
qToBigEndian(newfv, (uchar*)buf.constData() + varField.offset());
qDebug("%s varField ofs %d oldfv %x newfv %x", qPrintable(shortName()),
varField.offset(), oldfv, newfv);
break; break;
}
default: default:
break; break;
} }
_exit:
return; return;
} }