You may decide to put multiple bits into one integer and pack/unpack that integer
To convert list of booleans, following functions might be of help:
def encode_booleans(bool_lst):
res = 0
for i, bval in enumerate(bool_lst):
res += int(bval) << i
return res
def decode_booleans(intval, bits):
res = []
for bit in xrange(bits):
mask = 1 << bit
res.append((intval & mask) == mask)
return res
To test it:
>>> blst = [True, False, True]
>>> encode_booleans(blst)
5
>>> decode_booleans(5, 3)
[True, False, True]
>>> decode_booleans(5, 10)
[True, False, True, False, False, False, False, False, False, False]
Encoding
Encoding is then done in two steps
- turn set of booleans into an integer
- create resulting structure to
pack using all the other types plus newly created integer
Decoding
Decoding goes also in two steps, just in oposite order
- unpack into expected structure, booleans being represented s single integer
- decode the integer into set of booleans
This assumes, you have encoding part under control.
Full example
Assuming import struct was done and the two functions above are defined:
>>> packform = "!HHLfILB"
>>> msg_id = 101
>>> sender = 22
>>> size = 1000
>>> time1 = 123.45
>>> time2 = 222
>>> bool1 = True
>>> bool2 = False
>>> bools_enc = encode_booleans([bool1, bool2])
>>> bools_enc
1
>>> resrv = 55
>>> msg_lst = [msg_id, sender, size, time1, time2, resrv, bools_enc]
>>> enc = struct.pack(packform, *msg_lst)
>>> enc
'\x00e\x00\x16\x00\x00\x03\xe8B\xf6\xe6f\x00\x00\x00\xde\x00\x00\x007\x01'
>>> decoded = struct.unpack(packform, enc)
>>> decoded
(101, 22, 1000, 123.44999694824219, 222, 55, 1)
>>> msg_lst
[101, 22, 1000, 123.45, 222, 55, 1]
>>> new_msg_id, new_sender, new_size, new_time1, new_time2, new_resrv, new_bools_enc = decoded
>>> new_bool1, new_bool2 = decode_booleans(new_bools_enc, 2)
>>> new_bool1
True
>>> new_bool2
False