Skip to content

Commit 0183f9b

Browse files
committed
Move inflate code into its own file.
1 parent 3048053 commit 0183f9b

File tree

4 files changed

+139
-137
lines changed

4 files changed

+139
-137
lines changed

util/UNZIP.LUA renamed to arch/INFLATE.LUA

Lines changed: 5 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
#!/usr/bin/env lua
2-
3-
---Halt and catch fire if E is set
4-
function D() if E then error(E, 0) end end
5-
61
---New bit stream
7-
function nbs(r)
2+
local function nbs(r)
83

94
-- b = buffer
105
-- p = position
@@ -48,7 +43,7 @@ function nbs(r)
4843
end
4944

5045
---Reverse bits
51-
function rv(x, bits)
46+
local function rv(x, bits)
5247
local y = 0
5348

5449
for _ = 1, bits do
@@ -60,7 +55,7 @@ function rv(x, bits)
6055
end
6156

6257
---Make huffman
63-
function mh(lengths)
58+
local function mh(lengths)
6459

6560
-- m = maximum length
6661
-- c = counts
@@ -96,7 +91,7 @@ function mh(lengths)
9691
end
9792

9893
---Read huffman
99-
function rh(bs, h)
94+
local function rh(bs, h)
10095

10196
-- c = code
10297
local c = 0
@@ -114,7 +109,7 @@ end
114109
---Inflate a deflated file inside a zip
115110
---@param r function The reader function
116111
---@param w function The writer function
117-
function inf(r, w)
112+
function inflate(r, w)
118113

119114
-- bs = bit stream
120115
-- op = output position
@@ -277,129 +272,3 @@ function inf(r, w)
277272

278273
F()
279274
end
280-
281-
function crc32(s, c)
282-
283-
-- x = maximum
284-
-- c = crc number
285-
local x = 0xFFFFFFFF
286-
c = (c or 0) ~ x
287-
288-
for i = 1, #s do
289-
c = c ~ s:byte(i)
290-
for _ = 1, 8 do c = (c >> 1) ~ (0xEDB88320 & (-(c & 1))) end
291-
end
292-
293-
return c ~ x
294-
end
295-
296-
function unzip(p)
297-
298-
-- C = read chunk size
299-
-- f = file
300-
local C, f = 4096
301-
302-
f, E = io.open(p, "rb") D()
303-
304-
-- R = read bytes
305-
local function R(n)
306-
local s, E = f:read(n) D()
307-
return s
308-
end
309-
310-
local function S(n) f:seek("cur", n) end
311-
312-
---Read the next 2 bytes in the file as a 16-bit little endian number
313-
local function R16() local a, b = R(2):byte(1, 2) return a + b * 256 end
314-
315-
---Read the next 4 bytes in the file as a 32-bit little endian number
316-
local function R32() local a, b, c, d = R(4):byte(1, 4) return a + b * 256 + c * 65536 + d * 16777216 end
317-
318-
while true do
319-
320-
-- s = signature
321-
-- v = version needed
322-
-- fl = flags
323-
-- cm = method
324-
-- cr = Expected crc32 checksum
325-
-- cs = Compressed size
326-
-- us = Uncompressed size
327-
-- nl = Length of file name
328-
-- el = Extra length in the file name
329-
-- os = The output stream
330-
-- di = directory
331-
-- of = output file
332-
-- re = remaining bytes
333-
-- cr = crc32 checksum
334-
local s, v, fl, cm, cr, cs, us, nl, el, fn, os, di, of, re = f:read(4)
335-
if not s or #s < 4 then break end
336-
if s ~= "PK\3\4" then break end
337-
338-
v , E = R16() D() -- version
339-
fl, E = R16() D() -- flags
340-
cm, E = R16() D() -- method
341-
S(4) -- skip modification time and date
342-
cr, E = R32() D() -- crc32
343-
cs, E = R32() D() -- compressed size
344-
us, E = R32() D() -- uncompressed size
345-
nl, E = R16() D() -- name length
346-
el, E = R16() D() -- extra name length
347-
348-
fn, E = R(nl) D() -- filename
349-
if el > 0 then S(el) end
350-
351-
print("Extracting: " .. fn)
352-
353-
re, cr = cs, 0
354-
355-
---Read compressed data in chunks
356-
local function RC()
357-
if re <= 0 then return nil end
358-
359-
-- c = chunk
360-
local c = f:read(math.min(C, re))
361-
if c then re = re - #c end
362-
return c
363-
end
364-
365-
-- Setup output file
366-
di = fn:match("(.+)/")
367-
if di and os.execute then
368-
os.execute('mkdir -p "'.. di ..'"')
369-
end
370-
371-
of, E = io.open(fn, "wb") D()
372-
373-
if of then
374-
---Write decompressed data and update CRC
375-
---@param c string The chunk of decompressed data to write to the file
376-
local function W(c)
377-
cr = crc32(c, cr)
378-
of:write(c)
379-
end
380-
381-
if cm == 0 then -- uncompressed file
382-
while re > 0 do
383-
local c = RC()
384-
if c then W(c) else break end
385-
end
386-
elseif cm == 8 then -- deflated file
387-
inf(RC, W)
388-
else
389-
print("!Unsupported")
390-
end
391-
392-
of:close()
393-
394-
if cr ~= cr then print("!CRC") end
395-
end
396-
end
397-
398-
f:close()
399-
end
400-
401-
if #arg < 1 then
402-
print((arg[-1] or "?") .. " " .. (arg[0] or "?") .. " file[.zip]")
403-
os.exit(1)
404-
end
405-
unzip(arg[1])

arch/UNZIP.LUA

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env lua
2+
3+
package.path = package.path .. ";?.LUA" --In case of a case sensitive operating system
4+
5+
---Halt and catch fire if E is set
6+
function D() if E then error(E, 0) end end
7+
8+
function crc32(s, c)
9+
10+
-- x = maximum
11+
-- c = crc number
12+
local x = 0xFFFFFFFF
13+
c = (c or 0) ~ x
14+
15+
for i = 1, #s do
16+
c = c ~ s:byte(i)
17+
for _ = 1, 8 do c = (c >> 1) ~ (0xEDB88320 & (-(c & 1))) end
18+
end
19+
20+
return c ~ x
21+
end
22+
23+
function unzip(p)
24+
25+
-- C = read chunk size
26+
-- f = file
27+
local C, f = 4096
28+
29+
f, E = io.open(p, "rb") D()
30+
31+
-- R = read bytes
32+
local function R(n)
33+
local s, E = f:read(n) D()
34+
return s
35+
end
36+
37+
local function S(n) f:seek("cur", n) end
38+
39+
---Read the next 2 bytes in the file as a 16-bit little endian number
40+
local function R16() local a, b = R(2):byte(1, 2) return a + b * 256 end
41+
42+
---Read the next 4 bytes in the file as a 32-bit little endian number
43+
local function R32() local a, b, c, d = R(4):byte(1, 4) return a + b * 256 + c * 65536 + d * 16777216 end
44+
45+
while true do
46+
47+
-- s = signature
48+
-- v = version needed
49+
-- fl = flags
50+
-- cm = method
51+
-- cr = Expected crc32 checksum
52+
-- cs = Compressed size
53+
-- us = Uncompressed size
54+
-- nl = Length of file name
55+
-- el = Extra length in the file name
56+
-- os = The output stream
57+
-- di = directory
58+
-- of = output file
59+
-- re = remaining bytes
60+
-- cr = crc32 checksum
61+
local s, v, fl, cm, cr, cs, us, nl, el, fn, os, di, of, re = f:read(4)
62+
if not s or #s < 4 then break end
63+
if s ~= "PK\3\4" then break end
64+
65+
v , E = R16() D() -- version
66+
fl, E = R16() D() -- flags
67+
cm, E = R16() D() -- method
68+
S(4) -- skip modification time and date
69+
cr, E = R32() D() -- crc32
70+
cs, E = R32() D() -- compressed size
71+
us, E = R32() D() -- uncompressed size
72+
nl, E = R16() D() -- name length
73+
el, E = R16() D() -- extra name length
74+
75+
fn, E = R(nl) D() -- filename
76+
if el > 0 then S(el) end
77+
78+
print("Extracting: " .. fn)
79+
80+
re, cr = cs, 0
81+
82+
---Read compressed data in chunks
83+
local function RC()
84+
if re <= 0 then return nil end
85+
86+
-- c = chunk
87+
local c = f:read(math.min(C, re))
88+
if c then re = re - #c end
89+
return c
90+
end
91+
92+
-- Setup output file
93+
di = fn:match("(.+)/")
94+
if di and os.execute then
95+
os.execute('mkdir -p "'.. di ..'"')
96+
end
97+
98+
of, E = io.open(fn, "wb") D()
99+
100+
if of then
101+
---Write decompressed data and update CRC
102+
---@param c string The chunk of decompressed data to write to the file
103+
local function W(c)
104+
cr = crc32(c, cr)
105+
of:write(c)
106+
end
107+
108+
if cm == 0 then -- uncompressed file
109+
while re > 0 do
110+
local c = RC()
111+
if c then W(c) else break end
112+
end
113+
elseif cm == 8 and pcall(require, "INFLATE") then -- deflated file
114+
inflate(RC, W)
115+
else
116+
print("!Unsupported")
117+
end
118+
119+
of:close()
120+
121+
if cr ~= cr then print("!CRC") end
122+
end
123+
end
124+
125+
f:close()
126+
end
127+
128+
if #arg < 1 then
129+
print((arg[-1] or "?") .. " " .. (arg[0] or "?") .. " file[.zip]")
130+
os.exit(1)
131+
end
132+
unzip(arg[1])

meta/test/unzip/INFLATE.LUA

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../arch/INFLATE.LUA

meta/test/unzip/UNZIP.LUA

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
../../../util/UNZIP.LUA
1+
../../../arch/UNZIP.LUA

0 commit comments

Comments
 (0)