[sldev-commits] r1020 - projects/2008/pyogp/pyogp.lib.base/branches/mrtopf-message-refactoring/pyogp/lib/base/message

tao.takashi at svn.secondlife.com tao.takashi at svn.secondlife.com
Sun Aug 10 12:31:30 PDT 2008


Author: tao.takashi
Date: 2008-08-10 14:31:30 -0500 (Sun, 10 Aug 2008)
New Revision: 1020

Added:
   projects/2008/pyogp/pyogp.lib.base/branches/mrtopf-message-refactoring/pyogp/lib/base/message/udpserializer.py
Trac: http://svn.secondlife.com/trac/linden/changeset/1020
Log:
added a separate serializer which can be used as any other serializer in pyogp:

serializer = ISerialization(msg)
return serializer.serialize()

This also works on UDP message with this adapter.




Added: projects/2008/pyogp/pyogp.lib.base/branches/mrtopf-message-refactoring/pyogp/lib/base/message/udpserializer.py
===================================================================
--- projects/2008/pyogp/pyogp.lib.base/branches/mrtopf-message-refactoring/pyogp/lib/base/message/udpserializer.py	                        (rev 0)
+++ projects/2008/pyogp/pyogp.lib.base/branches/mrtopf-message-refactoring/pyogp/lib/base/message/udpserializer.py	2008-08-10 19:31:30 UTC (rev 1020)
@@ -0,0 +1,128 @@
+import grokcore.component as grok
+import struct
+
+
+from interfaces import IUDPMessage
+from pyogp.lib.base.interfaces import ISerialization
+from pyogp.lib.base.message.data_packer import DataPacker
+from pyogp.lib.base.message.message_types import MsgType, MsgBlockType
+from pyogp.lib.base.message.message_types import MsgFrequency, EndianType, sizeof
+
+
+class UDPSerializer(grok.Adapter):
+    """a serializer for a UDP Message"""
+    
+    grok.implements(ISerialization)
+    grok.context(IUDPMessage)
+    
+    def __init__(self, message):
+        """initialize this adapter"""
+        self.message = message
+        self.packer = DataPacker()
+
+    
+    def content_type(self):
+        """return the content type
+        
+        this is more a dummy function here as it's not supposed to be used
+        in an HTTP context
+        
+        """
+        return "udp"
+    
+    
+    def serialize(self):
+        """ Builds the message by serializing the data. Creates a packet ready
+            to be sent. """
+        
+        #doesn't build in the header flags, sequence number, or data offset
+        msg_buffer = ''
+        bytes = 0
+        
+        # convenience stuff
+        msg = self.message
+        tmpl = msg.template
+  
+        #don't need to pack the frequency and message number. The template
+        #stores it because it doesn't change per template.
+        pack_freq_num = tmpl.msg_num_hex
+        msg_buffer += pack_freq_num
+        bytes += len(pack_freq_num)
+
+        for block in tmpl.get_blocks():
+            packed_block, block_size = self.build_block(block)
+            msg_buffer += packed_block
+            bytes += block_size
+
+        return msg_buffer
+    
+        # TODO: find out if we need "bytes"
+        
+        #return msg_buffer, bytes
+
+    def build_block(self, template_block):
+        block_buffer = ''
+        bytes = 0
+        msg = self.message
+
+        block_list = msg.get_block(template_block.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.type == MsgBlockType.MBT_MULTIPLE:
+            if template_block.number != message_block.block_number:
+                raise Exception('Block ' + template_block.name + ' is type MBT_MULTIPLE \
+                          but only has data stored for ' + str(block_count) + ' out of its ' + \
+                          template_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.type == MsgBlockType.MBT_VARIABLE:
+            block_buffer += struct.pack('>B', message_block.block_number)
+            bytes += 1            
+
+        for block in block_list:
+            for v in template_block.get_variables(): #message_block.get_variables():
+                #this mapping has to occur to make sure the data is written in correct order
+                variable = message_block.get_variable(v.name)
+                var_size  = variable.size
+
+                if var_size == -1:
+                    raise Exception('Variable ' + variable.name + ' in block ' + \
+                        message_block.name + ' of message ' + message_data.name + \
+                        ' wasn"t set prior to buildMessage call')
+
+                #if its a VARIABLE type, we have to write in the size of the data
+                if variable.type == MsgType.MVT_VARIABLE:
+                    data_size = template_block.get_variable(variable.name).size
+                    if data_size == 1:
+                        block_buffer += self.packer.pack_data(var_size, MsgType.MVT_U8)
+                        #block_buffer += struct.pack('>B', var_size)
+                    elif data_size == 2:
+                        block_buffer += self.packer.pack_data(var_size, MsgType.MVT_U16)
+                        #block_buffer += struct.pack('>H', var_size)
+                    elif data_size == 4:
+                        block_buffer += self.packer.pack_data(var_size, MsgType.MVT_U32)
+                        #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.data != None and var_size > 0:
+                    data = self.packer.pack_data(variable.data, variable.type)
+                    block_buffer += data
+                    bytes += len(data)
+
+        return block_buffer, bytes
+
+    
+    
\ No newline at end of file



More information about the sldev-commits mailing list