0

我有一对相互依赖的二进制文件要解析。我正在使用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

这个错误是指在偏移数组的大小属性中使用了recTable。与另一个问题一样,我可以通过提供一个常量大小或伪造一个简单的 @BoundNumber 绑定并引用它来克服这个错误。

在我上面链接的另一个问题中,用户遇到循环依赖跨两个类的情况,但是在解析一个文件时,我必须解析两个单独的文件。我假设 Wilfred Springer 提到的补丁(PREON-9)已经集成到 github 存储库(在 PREON-48)。

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

4

1 回答 1

0

我找到了这个问题的部分解决方案。我的印象非常深刻,@BoundList 的 size 属性是必需的,但是当我查看 Preon 源代码时,我发现它不是。由于所讨论的二进制偏移文件只有偏移量,并且没有其他数据,因此我可以安全地保持未指定大小。Preon 很好地处理未知列表大小:)

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

于 2014-01-28T17:22:30.240 回答