2

Pythonコンストラクトライブラリを使用すると、解析しているデータには、フラグが設定されている場合にのみ意味を持つフィールドがあります。

ただし、データ フィールドは常に存在します。

したがって、どのような場合でもデータを使用したいと思いますが、フラグの値に基づいてフィールド値を設定するだけです。

たとえば、構造体が (誤って) 次のように定義されている場合:

struct = Struct("struct",
    Flag("flag"),
    UBInt8("optional_data"),
    UBInt8("mandatory")
)

データについて:

>>> struct.parse("010203".decode("hex"))

結果は次のようになります。

Container({'flag': True, 'mandatory': 3, 'optional_data': 2})

データの場合:

>>> struct.parse("000203".decode("hex"))

望ましい結果は次のとおりです。

Container({'flag': False, 'mandatory': 3, 'optional_data': None})

私は次のことを試しました:

struct = Struct("struct",
    Flag("flag"),
    IfThenElse("optional_data", lambda ctx: ctx.flag,
        UBInt8("dummy"),
        Padding(1)
    ),
    UBInt8("mandatory")
)

ただし、 Padding() は次のように生データをフィールドに入れます。

>>> struct.parse("000203".decode("hex"))
Container({'flag': False, 'mandatory': 3, 'optional_data': '\x02'})

ありがとうございました

4

2 に答える 2

1

あなたの問題を正しく理解しているかどうかわかりません。問題がパディングが int として解析されないことだけである場合は、IFThenElse は必要ありません。コードで解析されたコンテナのフラグを確認し、optional_data フィールドを無視することを選択できます。

struct = Struct("struct",
    Flag("flag"),
    UBInt8("optional_data"),
    UBInt8("mandatory")
)

フラグが設定されている場合にのみ Optional Data という名前を使用し、フラグが設定されていない場合にダミーの名前を使用するという問題がある場合は、2 つの If を定義する必要があります。

struct = Struct("struct",
    Flag("flag"),
    If("optional_data", lambda ctx: ctx.flag,
        UBInt8("useful_byte"),
    ),
    If("dummy", lambda ctx: !ctx.flag,
        UBInt8("ignore_byte"),
    ),
    UBInt8("mandatory")
)
于 2012-06-10T17:24:39.660 に答える
0

おそらく、シーケンスの LengthValueAdapter に似たアダプターを使用できます

class LengthValueAdapter(Adapter):
"""
Adapter for length-value pairs. It extracts only the value from the 
pair, and calculates the length based on the value.
See PrefixedArray and PascalString.

Parameters:
* subcon - the subcon returning a length-value pair
"""
__slots__ = []
def _encode(self, obj, context):
    return (len(obj), obj)
def _decode(self, obj, context):
    return obj[1]

class OptionalDataAdapter(Adapter):
__slots__ = []
def _decode(self, obj, context):
  if context.flag:
    return obj
  else
    return None

そう

struct = Struct("struct",
    Flag("flag"),
    OptionalDataAdapter(UBInt8("optional_data")),
    UBInt8("mandatory")
)
于 2012-03-25T08:40:44.967 に答える