Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- accepts: A0=p->src, A1=p->target, A2=sz
- 8C860004 LW A2,0004 (A0)
- 24840008 ADDIU A0,A0,0008
- 00C53021 ADDU A2,A2,A1
- @fill
- 24090080 ADDIU T1,R0,0080
- 90880000 LBU T0,0000 (A0)
- 24840001 ADDIU A0,A0,0001
- @dec
- 1120FFFC BEQ T1,R0,fill
- 01280824 AND AT,T1,T0
- 10200005 BEQ AT,R0,run
- 00094842 SRL T1,T1,0x1
- 90810000 LBU AT,0000 (A0)
- 24A50001 ADDIU A1,A1,0001
- 10000009 BEQ R0,R0,loop
- 24840001 ADDIU A0,A0,0001
- @run
- 90830000 LBU V1,0000 (A0)
- 90820001 LBU V0,0001 (A0)
- 24840002 ADDIU A0,A0,0002
- 00A23823 SUBU A3,A1,V0
- 2463FFFF ADDIU V1,V1,FFFF
- 90E1FFFF LBU AT,FFFF (A3)
- 24A50001 ADDIU A1,A1,0001
- 0461FFFB BGEZ V1,-5
- @loop
- A0A1FFFF SB AT,FFFF (A1)
- 14A6FFEE BNE A1,A2,dec
- 00000000 NOP
- 03E00008 JR RA
- 00000000 NOP
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- def _search(data, pos, sz, cap = 0x100):
- ml = min(cap, sz - pos)
- if ml < 3:
- return 0, 0
- mp = max(0, pos - 0x100)
- hitp, hitl = 0, 3
- if mp < pos:
- ## hl = _seqfind(data[mp:pos+hitl], hitl)
- hl = data[mp:pos+hitl].index(data[pos:pos+hitl])
- while hl < (pos - mp):
- while (hitl < ml) and (data[pos + hitl] == data[mp + hl + hitl]):
- hitl += 1
- mp += hl
- hitp = mp
- if hitl == ml:
- return hitp, hitl
- mp += 1
- hitl += 1
- if mp >= pos:
- break
- ## hl = _seqfind(data[mp:pos+hitl], hitl)
- hl = data[mp:pos+hitl].index(data[pos:pos+hitl])
- # If length less than 4, return miss.
- if hitl < 4:
- hitl = 1
- return hitp, hitl-1
- def encode(data:(bytes, bytearray)) -> bytes:
- """Encodes a bytes-like object as a bytes object.
- """
- from struct import Struct
- pat = Struct(">2L")
- cap = 0x100
- sz = len(data)
- itr = bytearray()
- cmds = itr
- ctrl = itr
- raws = itr
- # Keep current cmd position so stream mode trick works.
- cmdpos = 0
- cmds.append(0)
- pos, flag = 0, 0x80
- while pos < sz:
- hitp, hitl = _search(data, pos, sz, cap)
- if hitl < 3:
- # Push a raw if copying isn't possible.
- raws.append(data[pos])
- pos += 1
- else:
- tstp, tstl = _search(data, pos+1, sz, cap)
- if (hitl + 1) < tstl:
- raws.append(data[pos])
- pos += 1
- flag >>= 1
- if not flag:
- flag = 0x80
- cmdpos = len(cmds)
- cmds.append(0)
- hitl = tstl
- hitp = tstp
- cmds[cmdpos] |= flag
- e = pos - hitp - 1
- pos += hitl
- # Handle MIx first, then Yax conditions.
- hitl -= 1
- ctrl.append(hitl)
- ctrl.append(e)
- # Advance the flag and refill if required.
- flag >>= 1
- if not flag:
- flag = 0x80
- cmdpos = len(cmds)
- cmds.append(0)
- # If no cmds in final word, del it.
- if flag == 0x80:
- del cmds[cmdpos]
- # All three thingies should return the full bytearray.
- return b''.join((pat.pack(len(cmds) + 8, sz), cmds))
- def decode(data: (bytes, bytearray)) -> bytes:
- import struct
- cmp_sz, dec_sz = struct.unpack_from(">LL", data)
- src = iter(data[8:])
- f, c = 0, 0
- out = bytearray()
- while len(out) < dec_sz:
- if not f:
- f = 0x80
- c = next(src)
- if c & f:
- l = next(src) + 1
- p = next(src) + 1
- for i in range(l):
- out.append(out[-p])
- else:
- out.append(next(src))
- f >>= 1
- return bytes(out)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement