我需要读取一个二进制文件,其中字节数组的大小取决于可选值以及常数。我如何使用Preon实现这一目标?
似乎字节数组大小计算不能是条件的,即。 size =“adaptationFieldControl == 0b10 || adaptationFieldControl == 0b11?184-adaptationFieldLength:184”
使用方法(请参阅下面的示例)计算动态大小会使Preon失败并显示为:org.codehaus.preon.el.BindingException:无法为绑定数据创建绑定,称为getPayloadLength。
public class packet {
@BoundNumber(size = "2")
byte adaptationFieldControl;
/**
* Returns the size of the payload if present in the packet
* @return size corrected for adaptation fields
*/
public int getPayloadLength() {
if(isAdaptationFieldsPresent()) {
return 188 - (4+adaptationFieldLength);
}
return 188-4;
}
@If("adaptationFieldControl==0b10 || adaptationFieldControl==0b11")
@BoundNumber(size="8")
short adaptationFieldLength;
@If("adaptationFieldControl==0b01 || adaptationFieldControl==0b11")
@BoundList(size="payloadLength")
byte[] payload;
...
答案 0 :(得分:0)
Preon使用语言“Limbo”来实现表达式评估。在Limbo中,求值为true的表达式将取值“1”(和假“0”)。
结果表达式:
size=adaptationFieldControl==0b10 || adaptationFieldControl==0b11
? 184-adaptationFieldLength : 184
可能采取以下形式:
size=184-(adaptationFieldControl==0b10||adaptationFieldControl==0b11)
*adaptationFieldLength
我对它进行了测试,不幸的是它接近方法大小不接受它。我得到了例外:
org.codehaus.preon.el.InvalidExpressionException: NoViableAltException(18@[])
它认为只有“@If”注释才能理解逻辑标记。
作为一种解决方法,我建议你定义两个前缀为“@If”注释的字段,然后实现一个get方法,测试两个字段为“null”并返回“非null”注释。
答案 1 :(得分:0)
除非我完全弄错,否则@If
注释实际上会阻止该字段在所有处注册如果条件为false。因此,根据Preon的说法, 没有名为addaptationFieldLenght
的字段。那,Preon现在已经可以绑定到方法了。技术上没有什么可以阻止它实现,但我想确保你总是可以生成一个合理的文件格式的HTML描述,如果隐藏在方法体内的逻辑,你不能把它变成文档。
如果你有一些复杂的逻辑根本不适合Limbo表达式,你最好为它创建一个Codec
。这样,您可以确保您的逻辑也记录在生成的文件格式的描述中。