| 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 |
| 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) |