0

Let's say I have:

numResults (Int16ul)
resultItems[numResults]

where the resultItems is constructed like:

ID (does not always increase)
strLen
my_str[strLen]

Now I understand, that I have to use RepeatUntil but how the repeathandler is supposed to work swooshes right over my head.

Edit:

I now added debug print statements.

What I have (not working):

import construct as ct
from pprint import pprint

def repeat_handler( x, lst, ctx):
    pprint(f'{x=}, {lst=}, {ctx=}')
    pprint(f'{ctx.numResults=}, {x["ID"]=}')
    return ctx.numResults==x["ID"]

format = ct.Struct(
    'numResults' / ct.Int16ul,
    'resultItem' / ct.RepeatUntil(repeat_handler,
                       ct.Struct(
                            'ID'     / ct.Int16ul,
                            'strLen' / ct.Int16ul,
                            'my_str'    / ct.PascalString(ct.Computed(ct.this.strLen) , 'ISO-8859-1'),
                       ),
          ),
)

Please can you explain to me, how the repeat_handler is supposed to work, so that it iterates over all the resultItems?

Edit2: got it working for rising ID, but how to do without rising ID?

d = dict(numResults=2, resultItem=[ dict(ID=0, strLen=3, my_str='abc'),
                                    dict(ID=1, strLen=3, my_str='abc'),
                                    dict(ID=2, strLen=3, my_str='abc')]
)

f= format.build(d)
pprint(f)
pprint(format.parse(f))

Thank you kind stranger for your time!

1 Answers1

0

The repeat_handler should return this: return ctx._index==(ctx.numResults(-1))

Also for the Pascal String I had to multiply times two and fix the encoding: ct.PascalString(ct.Computed(ct.this.strLen*2) , 'utf-16-le'

Remember kids, a well rested brain is your best ally :)