Хорошо, предположим, у меня это работает точно так, как ожидалось:
from enum import IntEnum
from contstruct import *
class Char(IntEnum):
START = 0xAB
STOP = 0xBC
ESC = 0xCD
MAPPING = Mapping(Byte, {x: x+1 for x in Char})
SLIP = GreedyRange(
Select(
FocusedSeq(
'x',
Const(Char.ESC, Byte),
Renamed(MAPPING, 'x')
),
Byte
)
)
Пример:
>>> buffer = bytes([0x00, 0xAB, 0xBC, 0xCD, 0xFF])
>>> SLIP.build(buffer)
b'\x00\xcd\xac\xcd\xbd\xcd\xce\xff’
И:
>>> from operator import eq
>>> all(map(eq, SLIP.parse(SLIP.build(buffer)), buffer))
True
Теперь мне нужно обернутькодирование / декодирование внутри другой структуры:
PROTOCOL = FocusedSeq(
'message',
Const(Char.START, Byte),
Renamed(SLIP, 'message'),
Const(Char.STOP, Byte)
)
Сборка работает точно так же, как и ожидалось:
>>> PROTOCOL.build(buffer)
b'\xab\x00\xcd\xac\xcd\xbd\xcd\xce\xff\xbc'
Однако при разборе GreedyRange
расходуется 1 слишком много байтов:
>>> PROTOCOL.parse(b'\xab\x00\xcd\xac\xcd\xbd\xcd\xce\xff\xbc')
construct.core.StreamError: stream read less than specified amount, expected 1, found 0
Как мне заставить GreedyRange
вернуть байт?