-
Notifications
You must be signed in to change notification settings - Fork 59
/
Uncompress.hx
72 lines (69 loc) · 1.71 KB
/
Uncompress.hx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package format.lz4;
class Uncompress {
public static function run( src : haxe.io.Bytes, srcPos : Int, srcLen : Int, out : haxe.io.Bytes, outPos : Int ) {
var outSave = outPos;
var srcEnd = srcPos + srcLen;
if( srcLen == 0 )
return 0;
#if flash
flash.Memory.select(out.getData());
#end
while( true ) {
var tk = src.get(srcPos++);
var litLen = tk >> 4;
var matchLen = tk & 15;
if( litLen == 15 ) {
var b;
do {
b = src.get(srcPos++);
litLen += b;
} while( b == 0xFF );
}
inline function write(v) {
#if flash
flash.Memory.setByte(outPos, v);
#else
out.set(outPos, v);
#end
outPos++;
}
switch( litLen ) {
case 0:
case 1:
write(src.get(srcPos++));
case 2:
write(src.get(srcPos++));
write(src.get(srcPos++));
case 3:
write(src.get(srcPos++));
write(src.get(srcPos++));
write(src.get(srcPos++));
default:
out.blit(outPos, src, srcPos, litLen);
outPos += litLen;
srcPos += litLen;
}
if( srcPos >= srcEnd ) break;
var offset = src.get(srcPos++);
offset |= src.get(srcPos++) << 8;
if( matchLen == 15 ) {
var b;
do {
b = src.get(srcPos++);
matchLen += b;
} while( b == 0xFF );
}
matchLen += 4;
if( matchLen >= 64 && matchLen <= offset ) {
out.blit(outPos, out, outPos - offset, matchLen);
outPos += matchLen;
} else {
var copyEnd = outPos + matchLen;
while( outPos < copyEnd )
write(#if flash flash.Memory.getByte(outPos - offset) #else out.get(outPos - offset) #end);
}
}
if( srcPos != srcEnd ) throw "Read too much data " + (srcPos - srcLen);
return outPos - outSave;
}
}