0

相互に依存関係がある解析対象のバイナリ ファイルのペアがあります。Preonライブラリを使用しています。

ファイルの名前は rec.table および rec.offset です。一方は他方へのオフセット インデックスです (rec.offset ファイルの 32 ビット整数の行で、rec.table へのバイト オフセットを表します)。rec.offset の行数は、rec.table で使用可能なデータの 1 つ (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;
    }
}

これを実行すると、記事「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 バインディングを偽造してそれを参照することで、このエラーを回避できます。

上記でリンクした他の質問では、循環依存関係が 2 つのクラスにまたがっている状況がありますが、1 つのファイルを解析しているときに、2 つの別々のファイルを解析する必要があります。Wilfred Springer が言及したパッチ (PREON-9) は、既に github リポジトリ (PREON-48) に統合されていると思います。

この循環依存に対処するにはどうすればよいですか? 私はトリックを逃していますか?

4

1 に答える 1

0

この問題の部分的な解決策を見つけました。@BoundList の size 属性が必須という印象が強かったのですが、Preon のソースを見てみるとそうではありませんでした。問題のバイナリ オフセット ファイルにはオフセットのみがあり、その後に続く他のデータがないため、サイズを指定しないままにしても安全です。Preon は未知のリスト サイズを適切に処理します :)

私が解析している他の半ダースのファイルで、このような別の循環依存関係を発見しないことを願っています。

于 2014-01-28T17:22:30.240 に答える