pythonconstruct

Python Construct - How to use a bitwise construct inside a struct


I have this problem that I can't figure out how to solve and was wondering if anyone has a hint for me.

This is a simplified example:

from construct import Struct, Enum, Byte, Switch, this, Flag

one_protocol = Struct(
    "enable" / Flag
)

protocol = Struct(
    "type" / Enum(
        Byte,
        one=0xA2,
        two=0x02,
    ),
    "data" / Switch(
        this.type,
        {
            "one": one_protocol
        }
    ),
)

input_1 = "A201"
input_2 = "A202"
print(protocol.parse(bytes.fromhex(input_1)))
print(protocol.parse(bytes.fromhex(input_2)))

And it works as expected. The output is:

Container:
    type = (enum) one 162
    data = Container:
        enable = True
Container:
    type = (enum) one 162
    data = Container:
        enable = True

The problem is that I want my one_protocol to work in bit level. More specifically, I want the enable field to reflect the value of the first bit and not the whole byte. In other words, I want to get enable = False for input_2.

I know that BitStruct cannot be nested. But anyway, I have tried replacing the first Struct with Bitstruct and also replace Flag with Bitwise(Flag).

Any idea?


Solution

  • Construct's author here.

    There is no reason why oneprotocol cannot be a BitStruct. You cannot nest Bitwise in another Bitwise but that is not the case here.

    You cannot use Bitwise(Flag) because Bitwise will expect all 8 bits (or a multiple of 8 bits) to be consumed while Flag only takes one.

    You also cannot make protocol a BitStruct because then enum will not work properly, unless you wrap it with Bytewise or something.