你可以用帕斯卡弦。Pascal字符串的前缀是长度,但标准struct包不支持可变长度的Pascal字符串。
下面是一些我编写的包装函数,它们看起来很有用。
以下是解包助手:def unpack_from(fmt, data, offset = 0):
(byte_order, fmt, args) = (fmt[0], fmt[1:], ()) if fmt and fmt[0] in ('@', '=', '', '!') else ('@', fmt, ())
fmt = filter(None, re.sub("p", "\tp\t", fmt).split('\t'))
for sub_fmt in fmt:
if sub_fmt == 'p':
(str_len,) = struct.unpack_from('B', data, offset)
sub_fmt = str(str_len + 1) + 'p'
sub_size = str_len + 1
else:
sub_fmt = byte_order + sub_fmt
sub_size = struct.calcsize(sub_fmt)
args += struct.unpack_from(sub_fmt, data, offset)
offset += sub_size
return args
这是包装助手:def pack(fmt, *args):
(byte_order, fmt, data) = (fmt[0], fmt[1:], '') if fmt and fmt[0] in ('@', '=', '', '!') else ('@', fmt, '')
fmt = filter(None, re.sub("p", "\tp\t", fmt).split('\t'))
for sub_fmt in fmt:
if sub_fmt == 'p':
(sub_args, args) = ((args[0],), args[1:]) if len(args) > 1 else ((args[0],), [])
sub_fmt = str(len(sub_args[0]) + 1) + 'p'
else:
(sub_args, args) = (args[:len(sub_fmt)], args[len(sub_fmt):])
sub_fmt = byte_order + sub_fmt
data += struct.pack(sub_fmt, *sub_args)
return data