3

I'm trying to receive some data with sockets, and then unpack the data to work on it.

In input, i have a binary string : "MsgID - Sender - Size - Time1 - Time2 - Resrv - bool1 - bool2"

Here is the format : "H - H - L - f - I - L - 'bool' - 'bool'"

When I receive the data, I have to unpack it with this line :

messageEnaKill = struct.unpack('!HHLfIL??', messageEnaKill_raw)

And then I have to work on the boolean values (the last 2 ones). The fact is I don't know the format for boolean values, is it a char ('c') or something ?

My second problem is that I have to check the binary boolean if it is True or False. How can I do that ? is this code true :

if msg[0] == bin(True):

considering "msg[0]" the boolean data from the "unpack".

Thanks for the support !

2 Answers 2

4

from struct documentation:

The '?' conversion code corresponds to the _Bool type defined by C99. If this type is not available, it is simulated using a char. In standard mode, it is always represented by one byte.

The ? type will be unpacked as a bool type:

>>> type(struct.unpack('?','c')[0])
<type 'bool'>

Any value other than null character ('\0') will be True. So you can follow the suggestion from Jan Vlcinsky. Your solution depends on what data you receive. If a null byte means False and other byte True, then you can continue using ? unpacking as a simplest solution.

So to check if your first boolean in a message is true use this test:

messageEnaKill = struct.unpack('!HHLfIL??', messageEnaKill_raw)
if(messageEnaKill[7]==True):
    # do something
Sign up to request clarification or add additional context in comments.

2 Comments

Ok, so I keep the line : messageEnaKill = struct.unpack('!HHLfIL??', messageEnaKill_raw) And to check if it's true, this should work ? : if msg[0] != 0:
updated my answer, not sure if the msg would work i don't know what buffer it is. But if it was the byte that holds the boolean it could work.
1

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

  1. turn set of booleans into an integer
  2. 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

  1. unpack into expected structure, booleans being represented s single integer
  2. 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

5 Comments

Ok, Are you suggesting encode into integer before sending it ? or after the "unpack" line ? I don't get it
@tutur29 Added to my answer (the conversion turns into 2 step process)
Your last line in the response is my problem. I receive the data with a socket with this line : messageEnaKill_raw, adresseEnaKill = connexion.recvfrom(1024) And I know I have boolean data to receive in it, but I don't manage it before.
@tutur29 In that case is my solution not applicable. I will edit title of your question reversing order to "Binary to boolean". Anyway, it was nice exercise for me with struct (never used that before).
You're wright, Anyway thank you for your time @Jan Vlcinsky (this might be useful in other cases)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.