I am trying to use struct.unpack() to take apart a data record that ends with an ASCII string.
The record (it happens to be a TomTom ov2 record) has this format (stored little-endian):
- 1 byte
- 4 byte int for total record size (including this field)
- 4 byte int
- 4 byte int
- variable-length string, null-terminated
unpack() requires that the string’s length be included in the format you pass it. I can use the second field and the known size of the rest of the record — 13 bytes — to get the string length:
str_len = struct.unpack("<xi", record[:5])[0] - 13
fmt = "<biii{0}s".format(str_len)
then proceed with the full unpacking, but since the string is null-terminated, I really wish unpack() would do it for me. It’d also be nice to have this should I run across a struct that doesn’t include its own size.
How can I make that happen?
The size-less record is fairly easy to handle, actually, since
struct.calcsize()will tell you the length it expects. You can use that and the actual length of the data to construct a new format string forunpack()that includes the correct string length.This function is just a wrapper for
unpack(), allowing a new format character in the last position that will drop the terminal NUL: