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)
4843end
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)
6055end
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)
9691end
9792
9893--- Read huffman
99- function rh (bs , h )
94+ local function rh (bs , h )
10095
10196 -- c = code
10297 local c = 0
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 ()
279274end
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 ])
0 commit comments