Changeset 3159

Show
Ignore:
Timestamp:
07/17/08 02:51:18 (5 years ago)
Author:
getxsick
Message:

Finally, i implemented bits-packing into bytes.
Should works for every protocols, it takes care about length of fields etc.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branch/UMPA/umpa/protocols/base.py

    r3143 r3159  
    2323 
    2424from umpa import utils 
     25 
     26BYTE = 8 
    2527 
    2628class Field(object): 
     
    4244        """Check if a value is not bigger than expected. 
    4345        """ 
     46        # FIXME: what with src.addr or others non-numeric? 
    4447        if 2**self.bits > val: 
    4548            return True 
    4649        else: 
    4750            return False 
    48  
    49     def _pack(self): 
    50         val = self.get() 
    51  
    52         if self.bits <= 8: 
    53             bits = struct.pack('!B', val) 
    54         elif self.bits > 8 and self.bits <= 16: 
    55             bits = struct.pack('!H', val) 
    56         elif self.bits > 16 and self.bits <= 32: 
    57             bits = struct.pack('!I', val) 
    58         else: 
    59             raise UMPAException, 'Fields with ' + self.bits + \ 
    60                                 ' bits are not supported' 
    61  
    62         return bits 
    6351 
    6452    def fillout(self): 
     
    182170    def get_raw(self): 
    183171        """Return raw bits of the protocol's object.""" 
    184         #XXX: i will try to write general get_raw method for all subclasses 
    185         # i mean that it should be unnecessary to overwrite it by subclasses  
    186  
    187         # get all fields in binary mode 
    188         header_unpack = [ self._fields[field].fillout() 
    189                         for field in self._ordered_fields ] 
    190         # pack all binaries fields together 
    191         header_pack = "".join(header_pack) 
    192  
     172 
     173        # The deal: we join all value's fields into one big number 
     174        # (with taking care about amount of bits). 
     175        # then we devide the number on byte-chunks 
     176        # and pack it by struct.pack() function 
     177        bit = 0 
     178        raw_value = 0 
     179        # lets make a biiiig number ;) 
     180        for field in reversed(self._ordered_fields): 
     181            raw_value |= self._fields[field].fillout() << bit 
     182            bit += self._fields[field].bits 
     183         
     184        # protocol should return byte-compatible length 
     185        if bit%BYTE != 0: 
     186            raise UMPAException, 'odd number of bits in ' + self.__name__ 
     187 
     188        # check how many bytes we need 
     189        bytes = bit/BYTE 
     190        # split the number on byte-chunks 
     191        l = [ (raw_value & (0xff << (BYTE*i))) >> BYTE*i 
     192                                    for i in reversed(xrange(bytes)) ] 
     193        # and pack it 
     194        header_pack = struct.pack('!' + 'B'*bytes, *l) 
    193195        return header_pack 
    194  
    195     def _stick_fields(self, *fields): 
    196         """Join fields together if length is not byte compatible. 
    197         """ 
    198196 
    199197    def _is_valid(self, field):