@@ -6,12 +6,25 @@ if not LIB then print("Please run unzip instead") os.exit(1) end
66--- @param z boolean Is this deflate64
77function inflate (r , w , z )
88
9- -- Z = size of sliding window
10- -- b = buffer
11- -- p = position
12- -- bb = bit buffer
13- -- bc = bit count
14- local Z , b , p , bb , bc = z and 65536 or 32768 , " " , 1 , 0 , 0
9+ -- Z = size of sliding window
10+ -- b = buffer
11+ -- p = position
12+ -- bb = bit buffer
13+ -- bc = bit count
14+ -- op = output position
15+ -- kg = keep going (in a loop)
16+ -- o = list of 4096-byte strings that make up the output and sliding window
17+ -- oc = current string being built
18+ -- os = total size of all strings in 'o'
19+ -- lex = length base & extra bits (pairs of bytes)
20+ -- dix = distance extra bits (1 byte per entry)
21+ -- dib = distance base (packed 32-bit LE)
22+ local Z , b , p , bb , bc , op , kg , o , oc , os , lex , dix , dib = z and 65536 or 32768 , " " , 1 , 0 , 0 , 0 , 1 , {}, " " , 0 ,
23+ -- lex, dix, dib packed strings
24+
25+ " \3\0\4\0\5\0\6\0\7\0\8\0\9\0\10\0\11\1\13\1\15\1\17\1\19\2\23\2\27\2\31\2\35\3\43\3\51\3\59\3\67\4\83\4\99\4\115\4\131\5\163\5\195\5\227\5\2\0 " ,
26+ " \0\0\0\0\1\1\2\2\3\3\4\4\5\5\6\6\7\7\8\8\9\9\10\10\11\11\12\12\13\13\14\14\15\15\16\16\17\17\18\18\19\19\20\20\21\21\22\22\23\23\24\24\25\25\26\26\27\27\28\28\29\29\30\30 " ,
27+ " \1\0\0\0\2\0\0\0\3\0\0\0\4\0\0\0\5\0\0\0\7\0\0\0\9\0\0\0\13\0\0\0\17\0\0\0\25\0\0\0\33\0\0\0\49\0\0\0\65\0\0\0\97\0\0\0\129\0\0\0\193\0\0\0\1\1\0\0\129\1\0\0\1\2\0\0\1\3\0\0\1\4\0\0\1\6\0\0\1\8\0\0\1\12\0\0\1\16\0\0\1\24\0\0\1\32\0\0\1\48\0\0\1\64\0\0\1\96\0\0\1\128\0\0\1\192\0\0\1\0\1\0\1\128\1\0\1\0\2\0\1\128\2\0\1\0\4\0\1\128\4\0\1\0\8\0\1\128\8\0\1\0\16\0\1\128\16\0\1\0\32\0\1\128\32\0\1\0\64\0\1\128\64\0\1\0\128\0\1\128\128\0\1\0\0\1\1\128\0\1\1\0\0\2\1\128\0\2\1\0\0\4\1\128\0\4\1\0\0\8\1\128\0\8\1\0\0\16\1\128\0\16\1\0\0\32\1\128\0\32\1\0\0\64\1\128\0\64\1\0\0\128\1\128\0\128\1\0\0\0\192 "
1528
1629 --- Internal buffer refill function.
1730 --- @return number Zero on error , otherwise the buffer has been filled.
@@ -50,22 +63,25 @@ function inflate(r, w, z)
5063 return v
5164 end
5265
53- -- op = output position
54- -- kg = keep going (in a loop)
55- -- o = output buffer that also acts like a sliding window
56- local op , kg , o = 0 , 1 , " "
57-
5866 --- Appends a decoded byte to the output buffer and updates the sliding window history.
5967 --- @param by number The byte value (0-255 ) to append.
6068 function ab (by )
6169 op = op + 1
62- o = o .. string.char (by )
63- if # o > Z + 4096 then -- Flush what has exceeded the sliding window
70+ oc = oc .. string.char (by )
71+
72+ if # oc >= 4096 then
73+ o [# o + 1 ] = oc
74+ os = os + # oc
75+ oc = " "
76+
77+ -- If window exceeds limit, write and discard the oldest chunk
78+ if os > Z then
6479
65- -- c = cut
66- local c = # o - Z
67- w (o :sub (1 , c ))
68- o = o :sub (c + 1 )
80+ -- ot = old table of 4096 bytes that have shifted out of the sliding window
81+ local ot = table.remove (o , 1 )
82+ os = os - # ot
83+ w (ot )
84+ end
6985 end
7086 end
7187
@@ -144,15 +160,6 @@ function inflate(r, w, z)
144160 error (" !Huffman" , 0 )
145161 end
146162
147- -- lex = length base & extra bits (pairs of bytes)
148- -- dix = distance extra bits (1 byte per entry)
149- -- dib = distance base (packed 32-bit LE)
150- local lex , dix , dib =
151-
152- " \3\0\4\0\5\0\6\0\7\0\8\0\9\0\10\0\11\1\13\1\15\1\17\1\19\2\23\2\27\2\31\2\35\3\43\3\51\3\59\3\67\4\83\4\99\4\115\4\131\5\163\5\195\5\227\5\2\0 " ,
153- " \0\0\0\0\1\1\2\2\3\3\4\4\5\5\6\6\7\7\8\8\9\9\10\10\11\11\12\12\13\13\14\14\15\15\16\16\17\17\18\18\19\19\20\20\21\21\22\22\23\23\24\24\25\25\26\26\27\27\28\28\29\29\30\30 " ,
154- " \1\0\0\0\2\0\0\0\3\0\0\0\4\0\0\0\5\0\0\0\7\0\0\0\9\0\0\0\13\0\0\0\17\0\0\0\25\0\0\0\33\0\0\0\49\0\0\0\65\0\0\0\97\0\0\0\129\0\0\0\193\0\0\0\1\1\0\0\129\1\0\0\1\2\0\0\1\3\0\0\1\4\0\0\1\6\0\0\1\8\0\0\1\12\0\0\1\16\0\0\1\24\0\0\1\32\0\0\1\48\0\0\1\64\0\0\1\96\0\0\1\128\0\0\1\192\0\0\1\0\1\0\1\128\1\0\1\0\2\0\1\128\2\0\1\0\4\0\1\128\4\0\1\0\8\0\1\128\8\0\1\0\16\0\1\128\16\0\1\0\32\0\1\128\32\0\1\0\64\0\1\128\64\0\1\0\128\0\1\128\128\0\1\0\0\1\1\128\0\1\1\0\0\2\1\128\0\2\1\0\0\4\1\128\0\4\1\0\0\8\1\128\0\8\1\0\0\16\1\128\0\16\1\0\0\32\1\128\0\32\1\0\0\64\1\128\0\64\1\0\0\128\1\128\0\128\1\0\0\0\192 "
155-
156163 while kg > 0 do
157164
158165 -- f = final
@@ -274,7 +281,26 @@ function inflate(r, w, z)
274281 for _ = 1 , l do
275282
276283 -- c = character
277- local c = o :sub (# o - dv + 1 , # o - dv + 1 )
284+ local c
285+
286+ if dv <= # oc then -- Target is in the currently building chunk
287+ c = oc :sub (# oc - dv + 1 , # oc - dv + 1 )
288+ else -- Target is in one of the completed chunks
289+
290+ -- of = offset
291+ -- co = coff
292+ local of , co = os - (dv - # oc ), 0
293+ for i = 1 , # o do
294+ if of < co + # o [i ] then
295+
296+ -- n = position
297+ local n = of - co + 1
298+ c = o [i ]:sub (n , n )
299+ break
300+ end
301+ co = co + # o [i ]
302+ end
303+ end
278304 ab (c :byte ())
279305 end
280306 end
@@ -287,7 +313,7 @@ function inflate(r, w, z)
287313 if f == 1 then kg = 0 end
288314 end
289315
290- if # o > 0 then -- End of file, flush remaining output to disk
291- w (o ) o = " "
292- end
316+ -- Flush remaining data
317+ for i = 1 , # o do w (o [ i ]) end
318+ if # oc > 0 then w ( oc ) end
293319end
0 commit comments