Skip to content

Commit

Permalink
[python] fix binary unpacking for python 2.x and 3.x
Browse files Browse the repository at this point in the history
- unpack always returns a tuple, so take first value
- use bytearray instead of list for buffer
- preallocate bytearray with length of payload for speed
  • Loading branch information
flixr committed Jul 27, 2015
1 parent 26c0588 commit 02737f7
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 9 deletions.
6 changes: 3 additions & 3 deletions sw/lib/python/pprz_msg/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,15 @@ def binary_to_payload(self, data):
for idx, t in enumerate(self.fieldtypes):
bin_type = self.fieldbintypes(t)
if '[' in t:
array_length = int(struct.unpack('<B', data[msg_offset])[0])
array_length = data[msg_offset]
msg_offset += 1
array_value = []
for count in range(0, array_length):
array_value.append(struct.unpack('<' + bin_type[0], "".join(data[msg_offset:msg_offset + bin_type[1]])))
array_value.append(struct.unpack('<' + bin_type[0], data[msg_offset:msg_offset + bin_type[1]])[0])
msg_offset = msg_offset + bin_type[1]
values.append(array_value)
else:
value = struct.unpack('<' + bin_type[0], "".join(data[msg_offset:msg_offset + bin_type[1]]))
value = struct.unpack('<' + bin_type[0], data[msg_offset:msg_offset + bin_type[1]])[0]
msg_offset = msg_offset + bin_type[1]
values.append(value)
self.set_values(values)
Expand Down
15 changes: 9 additions & 6 deletions sw/lib/python/pprz_msg/pprz_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,19 @@ def reset_parser(self):

def parse_byte(self, c):
"""parse new byte, return True when a new full message is available"""
b = ord(c)
b = struct.unpack("<B", c)[0]
if self.state == PprzParserState.WaitSTX:
if b == STX:
self.state = PprzParserState.GotSTX
elif self.state == PprzParserState.GotSTX:
self.length = b - 4
self.buf = []
self.buf = bytearray(self.length)
self.ck_a = b % 256
self.ck_b = b % 256
self.idx = 0
self.state = PprzParserState.GotLength
elif self.state == PprzParserState.GotLength:
self.buf.append(c)
self.buf[self.idx] = b
self.ck_a = (self.ck_a + b) % 256
self.ck_b = (self.ck_b + self.ck_a) % 256
self.idx += 1
Expand All @@ -77,8 +77,8 @@ def get_buffer(self):

def unpack_pprz_msg(self, msg_class, data):
"""Unpack a raw PPRZ message"""
sender_id = ord(data[0])
msg_id = ord(data[1])
sender_id = data[0]
msg_id = data[1]
msg = PprzMessage(msg_class, msg_id)
msg.binary_to_payload(data[2:])
return sender_id, msg
Expand All @@ -92,7 +92,10 @@ def calculate_checksum(self, msg):
ck_b = 0
# start char not included in checksum for pprz protocol
for c in msg[1:]:
ck_a = (ck_a + ord(c)) % 256
# try to handle differences between python 2.x and 3.x
if isinstance(c, str):
c = struct.unpack("<B", c)[0]
ck_a = (ck_a + c) % 256
ck_b = (ck_b + ck_a) % 256
return ck_a, ck_b

Expand Down

0 comments on commit 02737f7

Please sign in to comment.