Created
August 18, 2016 09:18
-
-
Save Arachnid/4bf0dc27432e325505ca7b06f6366114 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library LZF { | |
function decompress(bytes memory compressed, bytes memory decompressed) internal { | |
uint ip; | |
uint in_end; | |
uint op; | |
assembly { | |
// OP points to the current output location in memory | |
op := add(decompressed, 32) | |
// IP actually points to 31 bytes before the desired location, so | |
// MLOADs work correctly | |
ip := add(compressed, 1) | |
in_end := add(ip, mload(compressed)) | |
} | |
while(ip < in_end) { | |
uint ctrl; | |
assembly { | |
// ctrl = *ip; | |
ctrl := and(mload(ip), 0xff) | |
} | |
ip += 1; | |
if(ctrl < 0x20) { | |
ctrl++; | |
assembly { | |
// memcpy(op, ip + 31, ctrl); | |
call(1000, 4, 0, add(ip, 31), ctrl, op, ctrl) | |
pop | |
} | |
op += ctrl; | |
ip += ctrl; | |
} else { | |
uint len = ctrl / 0x20; | |
uint ref = op - ((ctrl & 0x1F) * 256) - 1; | |
if(len == 7) { | |
assembly { | |
// len += *ip; | |
len := add(len, and(mload(ip), 0xff)) | |
} | |
ip += 1; | |
} | |
assembly { | |
// ref -= *ip; | |
ref := sub(ref, and(mload(ip), 0xff)) | |
} | |
ip += 1; | |
len += 2; | |
if(op >= ref + len) { | |
// Disjoint; copy as a block | |
assembly { | |
// memcpy(op, ref, len); | |
call(1000, 4, 0, ref, len, op, len) | |
pop | |
} | |
op += len; | |
} else { | |
// Overlapping; copy byte-by-byte | |
while(len-- > 0) { | |
assembly { | |
mstore8(op, mload(sub(ref, 31))) | |
} | |
op += 1; | |
ref += 1; | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment