def decode(self, mem, addr, shift): """Decoding algorithm of Huffman coding. Decode a Huffman-encoded bit string and return a decoded character. Args: mem (mmap): The ROM image. addr (int): The initial address to read the variable length-bit string. shift (int): The initial shift bit of the address. Returns: An instance of tuple (addr, shift, value), where `addr` and `shift` is the next location to read, and `value` is the character code decoded from the Huffman tree. """ # Test preconditions assert addr & 0xFF000000 == 0 assert shift & 0xFFFFFF00 == 0 huffman_on, huffman_off = self.huffman_on, self.huffman_off node = self.huffman_root from_cpu_addr = self.mapper.from_cpu read_size = self.decoding_read_size # Traverse the Huffman tree downward beginning at the root node. while True: # The message is a variable length-bit string. # We take successive bits from the initial `addr`. mem.seek(from_cpu_addr(addr)) bit = get_int(mem.read(read_size), 0, read_size) & shift addr, shift = self._do_next_location(addr, shift) if bit: node = get_int(huffman_on, node, 2) else: node = get_int(huffman_off, node, 2) if self._do_is_leaf_node(node): break node = self._do_next_node(node) return addr, shift, node & self.decoding_mask
def test_get_int(self): """Test function dqutils.bit.get_int.""" targets = ((0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06), b'\x00\x01\x02\x03\x04\x05\x06',) for data in targets: self.assertEqual(get_int(data, 0, 1), 0x00) self.assertEqual(get_int(data, 1, 1), 0x01) self.assertEqual(get_int(data, 0, 2), 0x0100) self.assertEqual(get_int(data, 6, 2), 0x0006) self.assertEqual(get_int(data, 0, 3), 0x020100) self.assertEqual(get_int(data, 5, 3), 0x000605) self.assertEqual(get_int(data, 6, 3), 0x000006)
def test_get_int_empty(self): """Test function dqutils.bit.get_int in case of empty value is passed. """ self.assertEqual(get_int(b'', 6, 3), 0) self.assertEqual(get_int([], 6, 3), 0)
def _do_get_value(self, byte_string): return get_int(byte_string, self.offset, 3)