def a2b_hqx(space, ascii): """Decode .hqx coding. Returns (bin, done).""" # overestimate the resulting length res = StringBuilder(len(ascii)) done = 0 pending_value = 0 pending_bits = 0 for c in ascii: n = ord(table_a2b_hqx[ord(c)]) if n <= 0x3F: pending_value = (pending_value << 6) | n pending_bits += 6 if pending_bits == 24: # flush res.append(chr(pending_value >> 16)) res.append(chr((pending_value >> 8) & 0xff)) res.append(chr(pending_value & 0xff)) pending_value = 0 pending_bits = 0 elif n == FAIL: raise_Error(space, 'Illegal character') elif n == DONE: if pending_bits >= 8: res.append(chr(pending_value >> (pending_bits - 8))) if pending_bits >= 16: res.append(chr((pending_value >> (pending_bits - 16)) & 0xff)) done = 1 break #elif n == SKIP: pass else: if pending_bits > 0: raise_Incomplete(space, 'String has incomplete number of bytes') return space.newtuple([space.wrap(res.build()), space.wrap(done)])
def rledecode_hqx(space, hexbin): "Decode hexbin RLE-coded string." # that's a guesstimation of the resulting length res = StringBuilder(len(hexbin)) end = len(hexbin) i = 0 lastpushed = -1 while i < end: c = hexbin[i] i += 1 if c != '\x90': res.append(c) lastpushed = ord(c) else: if i == end: raise_Incomplete(space, 'String ends with the RLE code \x90') count = ord(hexbin[i]) - 1 i += 1 if count < 0: res.append('\x90') lastpushed = 0x90 else: if lastpushed < 0: raise_Error(space, 'String starts with the RLE code \x90') res.append_multiple_char(chr(lastpushed), count) return space.wrap(res.build())