Exercise 10: Introduction to concrete message coding

Python struct module http://docs.python.org/library/struct.html for coding basic types

  • gives codings only for basic types, complex types (lists etc.) have to formed by hand using basic types

Task A

Create simple encode and decode functions for a arbitrary message with struct module.

Task B

Create encode and decode functions for a message with list of 8-bit strings content.

Results

Task A

exer01a/main.py

'''
Exercise 10 Task A

Create simple encode and decode functions for a arbitrary message with struct module. 
'''

import logging
log = logging.getLogger(__name__)
import struct 

def buftohex(buf):
  hexseq = str()
  for octet in buf:
    hexseq += "%02x" % ord(octet)
  return hexseq

class Message(object):
  def __init__(self):
    self.type = 1
    self.size = None
    self.value = 1.2

def encode(msg):
  msg.size = struct.calcsize("HHf")
  buf = struct.pack("HHf",msg.type,msg.size,msg.value)
  return buf

def decode(buf):
  type,size,value = struct.unpack("HHf",buf)
  msg = Message()
  msg.type = type
  msg.size = size
  msg.value = value
  return msg

def run():
  msg = Message()
  buf = encode(msg)
  print buftohex(buf)
  msg2 = decode(buf)
  print msg2.type, msg2.size, msg2.value
  

if __name__ == '__main__':
  logging.basicConfig(level=logging.DEBUG)
  run()

Task B

exer01b/main.py

'''
Exercise 10 Task B

Create encode and decode functions for a message with list of 8-bit strings content. 
'''

import logging
log = logging.getLogger(__name__)
import struct 

######################################################################

def buftohex(buf):
  hexseq = str()
  for octet in buf:
    hexseq += "%02x" % ord(octet)
  return hexseq

######################################################################

class Message(object):
  def __init__(self):
    self.type = None
    self.size = 0

class StrListMessage(Message):
  def __init__(self):
    super(StrListMessage,self).__init__()
    self.type = 2 
    self.strlist = list()

  def encode(self):
    """ Return buf
    """
    ## define size
    size = 0
    size += struct.calcsize("HH") # type, size
    size += struct.calcsize("H") # list size
    for s in self.strlist:
      size += struct.calcsize("H") # string lenght field
      size += len(s)        
    self.size = size
    ##
    buf = str()
    buf += struct.pack("HH", self.type, self.size)
    buf += struct.pack("H", len(self.strlist))
    for s in self.strlist:
      buf += struct.pack("H", len(s))
      buf += s
    return buf
  
  def decode(self,buf):
    self.type, self.size = struct.unpack("HH",buf[0:4])
    listsize, = struct.unpack("H",buf[4:6])
    offset = 6
    for i in range(0,listsize):
      strsize, = struct.unpack("H",buf[offset:offset+2])
      offset += 2
      self.strlist.append(buf[offset:offset+strsize])
      offset += strsize

  def dump(self):
    log.debug("StrListMessage:")
    log.debug("  type: %d" % self.type)
    log.debug("  size: %d" % self.size)
    for s in self.strlist:
      log.debug("  " + s)
      
######################################################################

def run():
  msg = StrListMessage()
  msg.strlist.append("test string")
  msg.strlist.append("another test string")
  msg.strlist.append("string 3")
  msg.dump()
  ## encoding
  buf = msg.encode()
  log.debug("Coded buf: " + buftohex(buf))
  ## decoding
  msg2 = StrListMessage()
  msg2.decode(buf)
  msg2.dump()
  

if __name__ == '__main__':
  logging.basicConfig(level=logging.DEBUG)
  run()
Last modified: 2013/07/01 14:42