lots of work on the builder. serializer for message template data is in, building messages is in, now testing it all to make sure it works
This commit is contained in:
committed by
Salad Dais
parent
b56d100787
commit
81b556d67d
@@ -47,7 +47,8 @@ class MsgData():
|
||||
self.blocks = {}
|
||||
|
||||
def add_block(self, block):
|
||||
self.blocks[block.get_name()] = block
|
||||
self.blocks[block.get_name()] = []
|
||||
self.blocks[block.get_name()].append(block)
|
||||
|
||||
def get_blocks(self):
|
||||
return self.blocks
|
||||
@@ -64,7 +65,7 @@ class MsgBlockData():
|
||||
serialized and sent. """
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.total_size = 0
|
||||
self.size = 0
|
||||
self.variables = {}
|
||||
|
||||
def get_name(self):
|
||||
@@ -87,7 +88,10 @@ class MsgVariableData():
|
||||
serialized and sent """
|
||||
def __init__(self, name, tp):
|
||||
self.name = name
|
||||
self.total_size = 0
|
||||
#data_size holds info whether or not the variable is of type
|
||||
#MVT_VARIABLE
|
||||
self.data_size = 0
|
||||
self.size = -1
|
||||
self.lltype = tp
|
||||
self.data = None
|
||||
|
||||
@@ -101,7 +105,7 @@ class MsgVariableData():
|
||||
def get_data(self):
|
||||
return self.data
|
||||
|
||||
def get_total_size(self):
|
||||
def get_size(self):
|
||||
return self.total_size
|
||||
|
||||
def get_type(self):
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#standard libs
|
||||
import struct
|
||||
|
||||
#pyogp libs
|
||||
from pyogp.lib.base.message_template import MsgData, MsgBlockData, \
|
||||
MsgVariableData
|
||||
from pyogp.lib.base.message_types import MsgType
|
||||
import pyogp.lib.base.message_types
|
||||
#from pyogp.lib.base.message_types import MsgType, MsgBlockType, MsgFrequency
|
||||
from pyogp.lib.base.data_packer import DataPacker
|
||||
|
||||
class MessageTemplateBuilder():
|
||||
""" This class builds messages at its high level, that is, keeping
|
||||
@@ -17,6 +23,8 @@ class MessageTemplateBuilder():
|
||||
self.cur_msg_name = ''
|
||||
self.cur_block_name = ''
|
||||
|
||||
self.packer = DataPacker()
|
||||
|
||||
def get_current_message(self):
|
||||
return self.current_msg
|
||||
|
||||
@@ -31,13 +39,86 @@ class MessageTemplateBuilder():
|
||||
#and the blocks variables
|
||||
#serializer should adapt the interface of MsgData (whatever it is),
|
||||
#and implement ISerializer
|
||||
pass
|
||||
|
||||
def build_block(self):
|
||||
pass
|
||||
|
||||
def build_variable(self):
|
||||
pass
|
||||
#doesn't build in the header flags, sequence number, or data offset
|
||||
msg_buffer = ''
|
||||
bytes = 0
|
||||
|
||||
if self.current_template == None:
|
||||
#error
|
||||
return None
|
||||
|
||||
#don't need to pack the frequency and message number. The template
|
||||
#stores it because it doesn't change per template.
|
||||
pack_freq_num = self.current_template.get_message_hex_num()
|
||||
msg_buffer += pack_freq_num
|
||||
bytes += len(pack_freq_num)
|
||||
|
||||
#add some offset?
|
||||
|
||||
for block in self.current_template:
|
||||
packed_block, block_size = build_block(block, self.current_msg)
|
||||
msg_buffer += packed_block
|
||||
bytes += block_size
|
||||
|
||||
return msg_buffer, bytes
|
||||
|
||||
def build_block(self, template_block, message_data):
|
||||
block_buffer = ''
|
||||
bytes = 0
|
||||
|
||||
block_list = message_data.get_block(template_block.get_name())
|
||||
block_count = len(block_list)
|
||||
|
||||
message_block = block_list[0]
|
||||
|
||||
#multiple block type means there is a static number of these blocks
|
||||
#that make up this message, with the number stored in the template
|
||||
#don't need to add it to the buffer, because the message handlers that
|
||||
#receieve this know how many to read automatically
|
||||
if template_block.get_type() == MsgBlockType.MBT_MULTIPLE:
|
||||
if template_block.get_block_number() != message_block.get_block_number():
|
||||
raise Exception('Block ' + template_block.get_name() + ' is type MBT_MULTIPLE \
|
||||
but only has data stored for ' + str(block_count) + ' out of its ' + \
|
||||
template_block.get_block_number() + ' blocks')
|
||||
|
||||
#variable means the block variables can repeat, so we have to
|
||||
#mark how many blocks there are of this type that repeat, stored in
|
||||
#the data
|
||||
if template_block.get_type() == MsgBlockType.MBT_VARIABLE:
|
||||
block_buffer += struct.pack('>B', message_block.get_block_number())
|
||||
bytes += 1
|
||||
|
||||
for block in block_list:
|
||||
for variable in message_block.get_variables():
|
||||
var_size = variable.get_size()
|
||||
|
||||
if var_size == -1:
|
||||
raise Exception('Variable ' + variable.get_name() + ' in block ' + \
|
||||
message_block.get_name() + ' of message ' + message_data.get_name() + \
|
||||
' wasn"t set prior to buildMessage call')
|
||||
|
||||
data_size = variable.get_data_size()
|
||||
#variable's data_size represents whether or not it is of the type
|
||||
#MVT_VARIABLE. If it is positive, it is
|
||||
if data_size > 0:
|
||||
if data_size == 1:
|
||||
block_buffer += struct.pack('>B', var_size)
|
||||
elif data_size == 2:
|
||||
block_buffer += struct.pack('>H', var_size)
|
||||
elif data_size == 4:
|
||||
block_buffer += struct.pack('>I', var_size)
|
||||
else:
|
||||
raise Exception('Attempting to build variable with unknown size \
|
||||
of ' + str(var_size))
|
||||
|
||||
bytes += data_size
|
||||
|
||||
#make sure there IS data to pack
|
||||
if variable.get_data() != None and var_size > 0:
|
||||
data = self.packer.pack_data(variable.get_data())
|
||||
block_buffer += data
|
||||
bytes += len(data)
|
||||
|
||||
def new_message(self, message_name):
|
||||
""" Creates a new packet where data can be added to it. Note, the variables
|
||||
@@ -55,7 +136,8 @@ class MessageTemplateBuilder():
|
||||
|
||||
def next_block(self, block_name):
|
||||
self.current_block = self.current_template.get_block(block_name)
|
||||
#error check
|
||||
#if it doesn't exist, create a new block (may be a VARIABLE or MULTIPLE type
|
||||
#block
|
||||
|
||||
self.cur_block_name = block_name
|
||||
|
||||
@@ -63,34 +145,17 @@ class MessageTemplateBuilder():
|
||||
var_data = MsgVariableData(variable.get_name(), variable.get_type())
|
||||
self.current_block.add_variable(var_data)
|
||||
|
||||
def add_data(self, var_name, data, data_size):
|
||||
self.check_size(var_name, data_size)
|
||||
self.current_block.add_data(var_name, data, data_size)
|
||||
def add_data(self, var_name, data, data_type):
|
||||
""" the data type is passed in to make sure that the programmer is aware of
|
||||
what type (and therefore size) of the data that is being passed in. """
|
||||
self.__check_size(var_name, data_type)
|
||||
self.current_block.add_data(var_name, data, data_type)
|
||||
|
||||
def check_size(self, var_name, data, data_size):
|
||||
def __check_size(self, var_name, data, data_type):
|
||||
block = self.template_list[cur_msg_name].get_block(self.cur_block_name)
|
||||
data_size = MsgType.sizeof(data_type)
|
||||
size = block.get_variable(var_name).get_size()
|
||||
if size != data_size:
|
||||
#warning
|
||||
#for now, exception
|
||||
raise Exception('Variable size isn"t the same as the variable size')
|
||||
|
||||
def add_bool(self, var_name, bool_data):
|
||||
self.add_data(var_name, bool_data, MsgType.sizeof(MsgType.MVT_BOOL))
|
||||
|
||||
"""class IMessageSerializer():
|
||||
implements ISerializer
|
||||
adapts MessageData
|
||||
|
||||
#goes through MessageData and builds a byte string that can be sent over
|
||||
#UDP or tcp
|
||||
serialize (pack_message, build_message)
|
||||
|
||||
#goes through each block of the message data
|
||||
pack_block
|
||||
|
||||
#goes through each block of the message variables, creating a byte-code
|
||||
#string to return
|
||||
pack_variable"""
|
||||
|
||||
|
||||
|
||||
@@ -4,19 +4,29 @@ class MsgBlockType():
|
||||
MBT_VARIABLE = range(3)
|
||||
|
||||
#pack flags
|
||||
#= '\x80'
|
||||
#= '\x80'
|
||||
#= '\x40'
|
||||
#= '\x20'
|
||||
#= '\x10'
|
||||
#= '\x00'
|
||||
class PackFlags():
|
||||
LL_ZERO_CODE_FLAG = '\x80'
|
||||
LL_RELIABLE_FLAG = '\x40'
|
||||
LL_RESENT_FLAG = '\x20'
|
||||
LL_ACK_FLAG = '\x10'
|
||||
LL_NONE = '\x00'
|
||||
LL_ZERO_CODE_FLAG, \
|
||||
LL_RELIABLE_FLAG, \
|
||||
LL_RESENT_FLAG, \
|
||||
LL_ACK_FLAG, \
|
||||
LL_NONE = range(5)
|
||||
|
||||
#frequency for messages
|
||||
#= '\xFF\xFF\xFF'
|
||||
#= '\xFF\xFF'
|
||||
#= '\xFF'
|
||||
#= ''
|
||||
class MsgFrequency():
|
||||
FIXED_FREQUENCY_MESSAGE = '\xFF\xFF\xFF'
|
||||
LOW_FREQUENCY_MESSAGE = '\xFF\xFF'
|
||||
MEDIUM_FREQUENCY_MESSAGE = '\xFF'
|
||||
HIGH_FREQUENCY_MESSAGE = ''
|
||||
FIXED_FREQUENCY_MESSAGE, \
|
||||
LOW_FREQUENCY_MESSAGE, \
|
||||
MEDIUM_FREQUENCY_MESSAGE, \
|
||||
HIGH_FREQUENCY_MESSAGE = range(4)
|
||||
|
||||
class MsgTrust():
|
||||
LL_TRUSTED, \
|
||||
@@ -61,45 +71,45 @@ class MsgType():
|
||||
MVT_IP_ADDR, \
|
||||
MVT_IP_PORT = range(20)
|
||||
|
||||
#TODO should this be changed? Less switch-style and more object-style?
|
||||
def sizeof(var):
|
||||
if var == MsgType.MVT_FIXED:
|
||||
return -1
|
||||
elif var == MsgType.MVT_VARIABLE:
|
||||
return -1
|
||||
elif var == MsgType.MVT_U8:
|
||||
return 1
|
||||
elif var == MsgType.MVT_U16:
|
||||
return 2
|
||||
elif var == MsgType.MVT_U32:
|
||||
return 4
|
||||
elif var == MsgType.MVT_U64:
|
||||
return 8
|
||||
elif var == MsgType.MVT_S8:
|
||||
return 1
|
||||
elif var == MsgType.MVT_S16:
|
||||
return 2
|
||||
elif var == MsgType.MVT_S32:
|
||||
return 4
|
||||
elif var == MsgType.MVT_S64:
|
||||
return 8
|
||||
elif var == MsgType.MVT_F32:
|
||||
return 4
|
||||
elif var == MsgType.MVT_F64:
|
||||
return 8
|
||||
elif var == MsgType.MVT_LLVector3:
|
||||
return 12
|
||||
elif var == MsgType.MVT_LLVector3d:
|
||||
return 24
|
||||
elif var == MsgType.MVT_LLVector4:
|
||||
return 16
|
||||
elif var == MsgType.MVT_LLQuaternion:
|
||||
return 12
|
||||
elif var == MsgType.MVT_LLUUID:
|
||||
return 16
|
||||
elif var == MsgType.MVT_BOOL:
|
||||
return 1
|
||||
elif var == MsgType.MVT_IP_ADDR:
|
||||
return 4
|
||||
elif var == MsgType.MVT_IP_PORT:
|
||||
return 2
|
||||
#TODO should this be changed? Less switch-style and more object-style?
|
||||
def sizeof(var):
|
||||
if var == MsgType.MVT_FIXED:
|
||||
return -1
|
||||
elif var == MsgType.MVT_VARIABLE:
|
||||
return -1
|
||||
elif var == MsgType.MVT_U8:
|
||||
return 1
|
||||
elif var == MsgType.MVT_U16:
|
||||
return 2
|
||||
elif var == MsgType.MVT_U32:
|
||||
return 4
|
||||
elif var == MsgType.MVT_U64:
|
||||
return 8
|
||||
elif var == MsgType.MVT_S8:
|
||||
return 1
|
||||
elif var == MsgType.MVT_S16:
|
||||
return 2
|
||||
elif var == MsgType.MVT_S32:
|
||||
return 4
|
||||
elif var == MsgType.MVT_S64:
|
||||
return 8
|
||||
elif var == MsgType.MVT_F32:
|
||||
return 4
|
||||
elif var == MsgType.MVT_F64:
|
||||
return 8
|
||||
elif var == MsgType.MVT_LLVector3:
|
||||
return 12
|
||||
elif var == MsgType.MVT_LLVector3d:
|
||||
return 24
|
||||
elif var == MsgType.MVT_LLVector4:
|
||||
return 16
|
||||
elif var == MsgType.MVT_LLQuaternion:
|
||||
return 12
|
||||
elif var == MsgType.MVT_LLUUID:
|
||||
return 16
|
||||
elif var == MsgType.MVT_BOOL:
|
||||
return 1
|
||||
elif var == MsgType.MVT_IP_ADDR:
|
||||
return 4
|
||||
elif var == MsgType.MVT_IP_PORT:
|
||||
return 2
|
||||
|
||||
Reference in New Issue
Block a user