2012-02-29 21 views
1

を消費し、私はパースだデータは、フラグが設定されている場合にのみ意味を持つフィールドがあります。Pythonは構築 - Pythonの<a href="http://construct.wikispaces.com/" rel="nofollow">construct</a>ライブラリで任意のフィールドのデータ

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

したがって、私はどのような場合でも、データを消費するが、唯一のフラグの値に基づいて、フィールドの値を設定したいと思います。例えば

、構造が(誤って)として定義されている場合:

データについて
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}) 

Iは、以下を試してみました:

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

しかし、パディング()はそうように、フィールド内の生データを置く:

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

ありがとうございました

答えて

0

多分あなたはアダプタsimiシーケンスのためのLengthValueAdapterにLAR

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") 
) 
1

私は私が正しくあなたの問題を理解している場合わかりません。あなたの問題がパディングがintとしてパースされていない場合、IFThenElseは必要ありません。フラグの解析されたコンテナをコード内でチェックし、optional_dataフィールドを無視することができます。

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

あなたの問題はあなたが名前オプションのデータはフラグがフラグが設定されていない場合、あなたは2 Ifsに

を定義する必要が設​​定されているが、名前のダミーを使用する場合にのみ使用したいということであれば
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") 
) 
関連する問題

 関連する問題