def decode(self): if len(self) == 0: return '' # get the string buffer and reverse its bytes buf = ''.join([c for c in reversed(self())]) buflen = len(buf)*8 # use shtr to shift the string buffer buf = shtr(buf) # count number of chars and remove padding bits chars_num = buflen//7 buf = buf << buflen - (7*chars_num) # consume 7 bit by 7 bit chars = [] for i in range(chars_num): chars.append(buf.left_val(7)) buf = buf << 7 # revert back the list of decoded character and return it chars.reverse() return ''.join(map(chr, chars))
def map(self, string='', byte_offset=0): # pop each member of the initial csn1List # and see what we have # 1) CSN1FIELD -> map it directly # 2) dict -> conditions -> CSN1FIELD | dict | tuple # 3) tuple -> CSN1FIELD | dict # consume the string buffer bit per bit depending of the # csn1List member poped # # as a CSN1 field does not always start on a byte limit, # we need to keep track of the byte offset, # for solving padding (L | H) adequately # # in case CSN1 list is empty if len(self.csn1List) == 0: return # initialize the string buffer to be mapped self.BUF, self._buflen = shtr(string), len(string)*8 self._consumed, self._offset, self._map_exit = 0, byte_offset, False self.elementList = [] # # MAIN loop # go over the string, bit per bit index = 0 while (self._consumed + self._offset) < self._buflen: if self._map_exit: break # get csn1 fields 1 by 1 self._eval_csn1(self.csn1List[index]) index += 1 # when csn1List is empty, finish with padding if index >= len(self.csn1List): break # # TODO: the padding should only be done when instructed so in CSN1 remaining = self._buflen - (self._consumed + self._offset) if remaining: if self.dbg >= DBG: log(DBG, '(CSN1._eval_csn1_dict) bits are remaining unmapped') # clean temporary data del self.BUF, self._buflen, self._consumed, \ self._offset, self._map_exit