我有一对要解析的二进制文件,它们彼此依赖。我正在使用Preon库。
这些文件名为rec.table和rec.offset。一个是另一个的偏移索引(rec.offset文件行32位整数,表示字节偏移到rec.table)。 rec.offset中的行数取决于rec.table中可用的一个数据(recordCount字段)。我需要提供偏移条目列表的大小,我需要使用该列表来访问记录条目,如下面的@BoundList情况所示。
我有以下设置:
package bytecodeparsing;
import org.codehaus.preon.annotation.BoundList;
import org.codehaus.preon.annotation.BoundNumber;
public class RecTable {
// Using this instead of 'outer' due to circular dependencies
@SuppressWarnings("unused") // Actually used in Preon expression below
private RecOffsets recOffsets;
@BoundNumber int version;
@BoundList(size="4") byte[] pad; // 4 byte pad to ignore.
@BoundNumber long recordCount;
// offset is in RecOffsets, which must then be an outer class of this, but that class needs to know how many entries there
// are, which is the recordCount value here. Circular dependencies?
@BoundList(offset="recOffsets.offsets[index]", size="recordCount") Rec[] recs;
public void setDependencies(RecOffsets recOffsets) {
this.recOffsets = recOffsets;
}
}
和
package bytecodeparsing;
import org.codehaus.preon.annotation.BoundList;
import org.codehaus.preon.annotation.BoundNumber;
public class RecOffsets {
@SuppressWarnings("unused") // Actually used in Preon expression below
private RecTable recTable; // maybe use this instead of 'outer' due to circular dependencies?
@BoundList(size="RecTable.recordCount+1") long[] offsets;
public void setDependencies(RecTable recTable) {
this.recTable = recTable;
}
}
当我运行此操作时,出现类似于帖子“Parsing variable record lengths in Preon”中报告的错误:
org.codehaus.preon.CodecConstructionException: Failed to construct codec.
at org.codehaus.preon.codec.ArrayCodecFactory.getSizeExpression(ArrayCodecFactory.java:152)
at org.codehaus.preon.codec.ArrayCodecFactory.create(ArrayCodecFactory.java:93)
at org.codehaus.preon.codec.CompoundCodecFactory.create(CompoundCodecFactory.java:59)
at org.codehaus.preon.DefaultCodecFactory$DecoratingCodecFactory.create(DefaultCodecFactory.java:266)
at org.codehaus.preon.codec.ObjectCodecFactory.harvestBindings(ObjectCodecFactory.java:184)
at org.codehaus.preon.codec.ObjectCodecFactory.createCodec(ObjectCodecFactory.java:129)
at org.codehaus.preon.codec.ObjectCodecFactory.create(ObjectCodecFactory.java:112)
at org.codehaus.preon.codec.CachingCodecFactory.create(CachingCodecFactory.java:130)
at org.codehaus.preon.codec.CompoundCodecFactory.create(CompoundCodecFactory.java:59)
at org.codehaus.preon.DefaultCodecFactory$DecoratingCodecFactory.create(DefaultCodecFactory.java:266)
at org.codehaus.preon.DefaultCodecFactory.create(DefaultCodecFactory.java:137)
at org.codehaus.preon.DefaultCodecFactory.create(DefaultCodecFactory.java:65)
at org.codehaus.preon.DefaultCodecFactory.create(DefaultCodecFactory.java:60)
at org.codehaus.preon.Codecs.create(Codecs.java:279)
at bytecodeparsing.PreonParsing.create(PreonParsing.java:76)
at bytecodeparsing.PreonParsing.<init>(PreonParsing.java:51)
Caused by: org.codehaus.preon.el.BindingException: Failed to create binding for bound data called recTable
at org.codehaus.preon.codec.BindingsContext.selectAttribute(BindingsContext.java:101)
at org.codehaus.preon.el.ImplicitsContext.selectAttribute(ImplicitsContext.java:52)
at org.codehaus.preon.el.LimboWalker.vexpr(LimboWalker.java:667)
at org.codehaus.preon.el.LimboWalker.vexpr(LimboWalker.java:488)
at org.codehaus.preon.el.Expressions.arithmetic(Expressions.java:125)
at org.codehaus.preon.el.Expressions.createInteger(Expressions.java:102)
at org.codehaus.preon.codec.ArrayCodecFactory.getSizeExpression(ArrayCodecFactory.java:148)
... 19 more
此错误指的是在offset数组的size属性中使用recTable。和另一个问题一样,我可以通过提供一个常量大小,或伪造一个简单的@BoundNumber绑定并引用它来解决这个错误。
在我上面链接的另一个问题中,用户的情况是循环依赖是跨两个类,但在解析一个文件时,我必须解析两个单独的文件。我假设Wilfred Springer提到的补丁(PREON-9)已经集成到github存储库中(在PREON-48中)。
我该如何处理这种循环依赖?我错过了一招吗?
答案 0 :(得分:0)
我发现了这个问题的部分解决方案。我非常强烈地认为@BoundList的size属性是 required ,但是当我查看Preon源时,我发现它不是。由于有问题的二进制偏移文件只有 偏移量,并且没有其他数据,因此我可以安全地保留未指定的大小。 Preon很好地处理未知列表大小:)
我希望在我正在解析的其他六个文件中,我没有发现这样的另一个循环依赖。