Search code examples
pythonparsingconstruct

Library construct, struct("string"/anythingElse) issue


Construct is a parsing library to parse hex datas. After reading the data, you first have to define the map and then parse it. You can find an example below;

....
data, addr = self.s.recvfrom(1024)

c = Struct("sync"/Int16ul, "ID"/Float32l)

x = c.parse(data)

print(x.sync)
print(x.ID)

My problem here is I'am reading the data types, for our example Int16ul and Float32l from a list named "varBytes" programatically and their type is "str" as expected. Data names "sync" and "ID" is also in a list named "varNames". Below is what I have tried;

c = Struct(varNames[0]/varBytes[0],varNames[1]/varBytes[1])

This is not working. How can I solve this problem?


Solution

  • varBytes[0] is a string where as what you need is the Int16ul object from the construct module.

    You need to turn the string into the object you can do this getting the object by its name with getattr applied to the module construct:

    varNames[0]/getattr(construct, varBytes[0])
    

    So your example becomes:

    import construct
    from construct import Struct
    
    c = Struct(varNames[0]/getattr(construct, varBytes[0]),
               varNames[1]/getattr(construct, varBytes[1]))
    

    To build the argument list from the pair of lists, one can apply Struct to a list:

    c = Struct(*[varName/getattr(construct, varByte) 
                 for varName, varByte in zip(varNames, varBytes)])
    

    This uses zip as using indexes makes for index errors.