与Preon二进制解析器的循环依赖关系

时间:2014-01-27 21:40:16

标签: java parsing preon

我有一对要解析的二进制文件,它们彼此依赖。我正在使用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中)。

我该如何处理这种循环依赖?我错过了一招吗?

1 个答案:

答案 0 :(得分:0)

我发现了这个问题的部分解决方案。我非常强烈地认为@BoundList的size属性是 required ,但是当我查看Preon源时,我发现它不是。由于有问题的二进制偏移文件只有 偏移量,并且没有其他数据,因此我可以安全地保留未指定的大小。 Preon很好地处理未知列表大小:)

我希望在我正在解析的其他六个文件中,我没有发现这样的另一个循环依赖。