Advertisement
JohnAdams1145

gunzip.lua

Aug 2nd, 2016
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 48.85 KB | None | 0 0
  1.  
  2. local index_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
  3. local arg = {...}
  4.  
  5. if shell then
  6.     arg[0] = shell.getRunningProgram()
  7. elseif not arg[0] then
  8.     arg[0] = "gunzip"
  9. end
  10. local computercraft = false
  11. if not io.stdin then
  12.     io.stdin = io.input()
  13. end
  14. if not fs then
  15.     fs = {}
  16.     function fs.makeDir()
  17.         -- nothing
  18.         return 1
  19.     end
  20. end
  21. if not io.stdout then
  22.     io.stdout = io.output()
  23. end
  24. if not io.stderr then
  25.     io.stderr = io.output()
  26. end
  27. if not os.exit then
  28.     os.exit = error
  29. end
  30. if os.loadAPI then
  31.     computercraft = true
  32. end
  33. if not os.remove then
  34.     os.remove = function (t) fs.delete(t) return true end
  35. end
  36. function to_binary(integer)
  37.     local remaining = tonumber(integer)
  38.     local bin_bits = ''
  39.  
  40.     for i = 7, 0, -1 do
  41.         local current_power = math.pow(2, i)
  42.  
  43.         if remaining >= current_power then
  44.             bin_bits = bin_bits .. '1'
  45.             remaining = remaining - current_power
  46.         else
  47.             bin_bits = bin_bits .. '0'
  48.         end
  49.     end
  50.  
  51.     return bin_bits
  52. end
  53.  
  54. function from_binary(bin_bits)
  55.     return tonumber(bin_bits, 2)
  56. end
  57.  
  58.  
  59. function to_base64(to_encode)
  60.     local bit_pattern = ''
  61.     local encoded = ''
  62.     local trailing = ''
  63.  
  64.     for i = 1, string.len(to_encode) do
  65.         bit_pattern = bit_pattern .. to_binary(string.byte(string.sub(to_encode, i, i)))
  66.     end
  67.  
  68.     -- Check the number of bytes. If it's not evenly divisible by three,
  69.     -- zero-pad the ending & append on the correct number of ``=``s.
  70.     if math.mod(string.len(bit_pattern), 3) == 2 then
  71.         trailing = '=='
  72.         bit_pattern = bit_pattern .. '0000000000000000'
  73.     elseif math.mod(string.len(bit_pattern), 3) == 1 then
  74.         trailing = '='
  75.         bit_pattern = bit_pattern .. '00000000'
  76.     end
  77.  
  78.     for i = 1, string.len(bit_pattern), 6 do
  79.         local byte = string.sub(bit_pattern, i, i+5)
  80.         local offset = tonumber(from_binary(byte))
  81.         encoded = encoded .. string.sub(index_table, offset+1, offset+1)
  82.     end
  83.  
  84.     return string.sub(encoded, 1, -1 - string.len(trailing)) .. trailing
  85. end
  86.  
  87.  
  88. function from_base64(to_decode)
  89.     local padded = to_decode:gsub("%s", "")
  90.     local unpadded = padded:gsub("=", "")
  91.     local bit_pattern = ''
  92.     local decoded = ''
  93.  
  94.     for i = 1, string.len(unpadded) do
  95.         local char = string.sub(to_decode, i, i)
  96.         local offset, _ = string.find(index_table, char)
  97.         if offset == nil then
  98.              error("Invalid character '" .. char .. "' found.")
  99.         end
  100.  
  101.         bit_pattern = bit_pattern .. string.sub(to_binary(offset-1), 3)
  102.     end
  103.  
  104.     for i = 1, string.len(bit_pattern), 8 do
  105.         local byte = string.sub(bit_pattern, i, i+7)
  106.         decoded = decoded .. string.char(from_binary(byte))
  107.     end
  108.  
  109.     local padding_length = padded:len()-unpadded:len()
  110.  
  111.     if (padding_length == 1 or padding_length == 2) then
  112.         decoded = decoded:sub(1,-2)
  113.     end
  114.     return decoded
  115. end
  116. function optparse()
  117.     --[[
  118.  
  119.     LUA MODULE
  120.  
  121.       pythonic.optparse - Lua-based partial reimplementation of Python's
  122.           optparse [2-3] command-line parsing module.
  123.  
  124.     SYNOPSIS
  125.  
  126.       local OptionParser = require "pythonic.optparse" . OptionParser
  127.       local opt = OptionParser{usage="%prog [options] [gzip-file...]",
  128.                                version="foo 1.23", add_help_option=false}
  129.       opt.add_option{"-h", "--help", action="store_true", dest="help",
  130.                      help="give this help"}
  131.       opt.add_option{
  132.         "-f", "--force", dest="force", action="store_true",
  133.         help="force overwrite of output file"}
  134.  
  135.       local options, args = opt.parse_args()
  136.  
  137.       if options.help then opt.print_help(); os.exit(1) end
  138.       if options.force then print 'f' end
  139.       for _, name in ipairs(args) do print(name) end
  140.          
  141.     DESCRIPTION
  142.  
  143.       This library provides a command-line parsing[1] similar to Python optparse [2-3].
  144.  
  145.       Note: Python also supports getopt [4].
  146.  
  147.     STATUS
  148.      
  149.       This module is fairly basic but could be expanded.
  150.      
  151.     API
  152.  
  153.       See source code and also compare to Python's docs [2,3] for details because
  154.       the following documentation is incomplete.
  155.      
  156.       opt = OptionParser {usage=usage, version=version, add_help_option=add_help_option}
  157.      
  158.         Create command line parser.
  159.      
  160.       opt.add_options{shortflag, longflag, action=action, metavar=metavar, dest=dest, help=help}
  161.      
  162.         Add command line option specification.  This may be called multiple times.
  163.      
  164.       opt.parse_args() --> options, args
  165.      
  166.         Perform argument parsing.
  167.      
  168.     DEPENDENCIES
  169.  
  170.       None (other than Lua 5.1 or 5.2)
  171.      
  172.     REFERENCES
  173.  
  174.       [1] http://lua-users.org/wiki/CommandLineParsing
  175.       [2] http://docs.python.org/lib/optparse-defining-options.html
  176.       [3] http://blog.doughellmann.com/2007/08/pymotw-optparse.html
  177.       [4] http://docs.python.org/lib/module-getopt.html
  178.  
  179.     LICENSE
  180.  
  181.       (c) 2008-2011 David Manura.  Licensed under the same terms as Lua (MIT).
  182.  
  183.       Permission is hereby granted, free of charge, to any person obtaining a copy
  184.       of this software and associated documentation files (the "Software"), to deal
  185.       in the Software without restriction, including without limitation the rights
  186.       to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  187.       copies of the Software, and to permit persons to whom the Software is
  188.       furnished to do so, subject to the following conditions:
  189.  
  190.       The above copyright notice and this permission notice shall be included in
  191.       all copies or substantial portions of the Software.
  192.  
  193.       THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  194.       IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  195.       FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
  196.       AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  197.       LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  198.       OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  199.       THE SOFTWARE.
  200.       (end license)
  201.  
  202.      --]]
  203.  
  204.      local M = {_TYPE='module', _NAME='pythonic.optparse', _VERSION='0.3.20111128'}
  205.      
  206.     local ipairs = ipairs
  207.     local unpack = table.unpack
  208.     local io = io
  209.     local table = table
  210.     local os = os
  211.     local arg = arg
  212.  
  213.  
  214.     local function OptionParser(t)
  215.       local usage = t.usage
  216.       --local version = t.version
  217.  
  218.       local o = {}
  219.       local option_descriptions = {}
  220.       local option_of = {}
  221.  
  222.       function o.fail(s) -- extension
  223.         io.stderr:write(s .. '\n')
  224.         os.exit(1)
  225.       end
  226.  
  227.       function o.add_option(optdesc)
  228.         option_descriptions[#option_descriptions+1] = optdesc
  229.         for _,v in ipairs(optdesc) do
  230.           option_of[v] = optdesc
  231.         end
  232.       end
  233.       function o.parse_args()
  234.         -- expand options (e.g. "--input=file" -> "--input", "file")
  235.         local arg = {unpack(arg)}
  236.         for i=#arg,1,-1 do local v = arg[i]
  237.           local flag, val = v:match('^(%-%-%w+)=(.*)')
  238.           if flag then
  239.             arg[i] = flag
  240.             table.insert(arg, i+1, val)
  241.           end
  242.         end
  243.  
  244.         local options = {}
  245.         local args = {}
  246.         local i = 1
  247.         while i <= #arg do local v = arg[i]
  248.           local optdesc = option_of[v]
  249.           if optdesc then
  250.             local action = optdesc.action
  251.             local val
  252.             if action == 'store' or action == nil then
  253.               i = i + 1
  254.               val = arg[i]
  255.               if not val then o.fail('option requires an argument ' .. v) end
  256.             elseif action == 'store_true' then
  257.               val = true
  258.             elseif action == 'store_false' then
  259.               val = false
  260.             end
  261.             options[optdesc.dest] = val
  262.           else
  263.             if v:match('^%-') then o.fail('invalid option ' .. v) end
  264.             args[#args+1] = v
  265.           end
  266.           i = i + 1
  267.         end
  268.         if options.help then
  269.           o.print_help()
  270.           os.exit()
  271.         end
  272.         if options.version then
  273.           print(t.version+"\n")
  274.           os.exit()
  275.         end
  276.         return options, args
  277.       end
  278.  
  279.       local function flags_str(optdesc)
  280.         local sflags = {}
  281.         local action = optdesc.action
  282.         for _,flag in ipairs(optdesc) do
  283.           local sflagend
  284.           if action == nil or action == 'store' then
  285.             local metavar = optdesc.metavar or optdesc.dest:upper()
  286.             sflagend = #flag == 2 and ' ' .. metavar
  287.                                   or  '=' .. metavar
  288.           else
  289.             sflagend = ''
  290.           end
  291.           sflags[#sflags+1] = flag .. sflagend
  292.         end
  293.         return table.concat(sflags, ', ')
  294.       end
  295.  
  296.       function o.print_help()
  297.         print("Usage: " .. usage:gsub('%%prog', arg[0]) .. "\n")
  298.         print("\n")
  299.         print("Options:\n")
  300.         local maxwidth = 0
  301.         for _,optdesc in ipairs(option_descriptions) do
  302.           maxwidth = math.max(maxwidth, #flags_str(optdesc))
  303.         end
  304.         for _,optdesc in ipairs(option_descriptions) do
  305.           print("  " .. ('%-'..maxwidth..'s  '):format(flags_str(optdesc))
  306.                           .. optdesc.help .. "\n")
  307.         end
  308.       end
  309.       if t.add_help_option == nil or t.add_help_option == true then
  310.         o.add_option{"--help", action="store_true", dest="help",
  311.                      help="show this help message and exit"}
  312.       end
  313.       if t.version then
  314.         o.add_option{"--version", action="store_true", dest="version",
  315.                      help="output version info."}
  316.       end
  317.       return o
  318.     end
  319.  
  320.  
  321.     M.OptionParser = OptionParser
  322.  
  323.  
  324.     return M
  325.  
  326. end
  327. function numberlua()
  328.     --[[
  329.  
  330.     LUA MODULE
  331.  
  332.       bit.numberlua - Bitwise operations implemented in pure Lua as numbers,
  333.         with Lua 5.2 'bit32' and (LuaJIT) LuaBitOp 'bit' compatibility interfaces.
  334.  
  335.     --]]
  336.     local M = {_TYPE='module', _NAME='bit.numberlua', _VERSION='0.3.1.20120131'}
  337.  
  338.     local floor = math.floor
  339.  
  340.     local MOD = 2^32
  341.     local MODM = MOD-1
  342.  
  343.     local function memoize(f)
  344.       local mt = {}
  345.       local t = setmetatable({}, mt)
  346.       function mt:__index(k)
  347.         local v = f(k); t[k] = v
  348.         return v
  349.       end
  350.       return t
  351.     end
  352.  
  353.     local function make_bitop_uncached(t, m)
  354.       local function bitop(a, b)
  355.         local res,p = 0,1
  356.         while a ~= 0 and b ~= 0 do
  357.           local am, bm = a%m, b%m
  358.           res = res + t[am][bm]*p
  359.           a = (a - am) / m
  360.           b = (b - bm) / m
  361.           p = p*m
  362.         end
  363.         res = res + (a+b)*p
  364.         return res
  365.       end
  366.       return bitop
  367.     end
  368.  
  369.     local function make_bitop(t)
  370.       local op1 = make_bitop_uncached(t,2^1)
  371.       local op2 = memoize(function(a)
  372.         return memoize(function(b)
  373.           return op1(a, b)
  374.         end)
  375.       end)
  376.       return make_bitop_uncached(op2, 2^(t.n or 1))
  377.     end
  378.  
  379.     -- ok?  probably not if running on a 32-bit int Lua number type platform
  380.     function M.tobit(x)
  381.       return x % 2^32
  382.     end
  383.  
  384.     M.bxor = make_bitop {[0]={[0]=0,[1]=1},[1]={[0]=1,[1]=0}, n=4}
  385.     local bxor = M.bxor
  386.  
  387.     function M.bnot(a)   return MODM - a end
  388.     local bnot = M.bnot
  389.  
  390.     function M.band(a,b) return ((a+b) - bxor(a,b))/2 end
  391.     local band = M.band
  392.  
  393.     function M.bor(a,b)  return MODM - band(MODM - a, MODM - b) end
  394.     local bor = M.bor
  395.  
  396.     local lshift, rshift -- forward declare
  397.  
  398.     function M.rshift(a,disp) -- Lua5.2 insipred
  399.       if disp < 0 then return lshift(a,-disp) end
  400.       return floor(a % 2^32 / 2^disp)
  401.     end
  402.     rshift = M.rshift
  403.  
  404.     function M.lshift(a,disp) -- Lua5.2 inspired
  405.       if disp < 0 then return rshift(a,-disp) end
  406.       return (a * 2^disp) % 2^32
  407.     end
  408.     lshift = M.lshift
  409.  
  410.     function M.tohex(x, n) -- BitOp style
  411.       n = n or 8
  412.       local up
  413.       if n <= 0 then
  414.         if n == 0 then return '' end
  415.         up = true
  416.         n = - n
  417.       end
  418.       x = band(x, 16^n-1)
  419.       return ('%0'..n..(up and 'X' or 'x')):format(x)
  420.     end
  421.     local tohex = M.tohex
  422.  
  423.     function M.extract(n, field, width) -- Lua5.2 inspired
  424.       width = width or 1
  425.       return band(rshift(n, field), 2^width-1)
  426.     end
  427.     local extract = M.extract
  428.  
  429.     function M.replace(n, v, field, width) -- Lua5.2 inspired
  430.       width = width or 1
  431.       local mask1 = 2^width-1
  432.       v = band(v, mask1) -- required by spec?
  433.       local mask = bnot(lshift(mask1, field))
  434.       return band(n, mask) + lshift(v, field)
  435.     end
  436.     local replace = M.replace
  437.  
  438.     function M.bswap(x)  -- BitOp style
  439.       local a = band(x, 0xff); x = rshift(x, 8)
  440.       local b = band(x, 0xff); x = rshift(x, 8)
  441.       local c = band(x, 0xff); x = rshift(x, 8)
  442.       local d = band(x, 0xff)
  443.       return lshift(lshift(lshift(a, 8) + b, 8) + c, 8) + d
  444.     end
  445.     local bswap = M.bswap
  446.  
  447.     function M.rrotate(x, disp)  -- Lua5.2 inspired
  448.       disp = disp % 32
  449.       local low = band(x, 2^disp-1)
  450.       return rshift(x, disp) + lshift(low, 32-disp)
  451.     end
  452.     local rrotate = M.rrotate
  453.  
  454.     function M.lrotate(x, disp)  -- Lua5.2 inspired
  455.       return rrotate(x, -disp)
  456.     end
  457.     local lrotate = M.lrotate
  458.  
  459.     M.rol = M.lrotate  -- LuaOp inspired
  460.     M.ror = M.rrotate  -- LuaOp insipred
  461.  
  462.  
  463.     function M.arshift(x, disp) -- Lua5.2 inspired
  464.       local z = rshift(x, disp)
  465.       if x >= 0x80000000 then z = z + lshift(2^disp-1, 32-disp) end
  466.       return z
  467.     end
  468.     local arshift = M.arshift
  469.  
  470.     function M.btest(x, y) -- Lua5.2 inspired
  471.       return band(x, y) ~= 0
  472.     end
  473.  
  474.     --
  475.     -- Start Lua 5.2 "bit32" compat section.
  476.     --
  477.  
  478.     M.bit32 = {} -- Lua 5.2 'bit32' compatibility
  479.  
  480.  
  481.     local function bit32_bnot(x)
  482.       return (-1 - x) % MOD
  483.     end
  484.     M.bit32.bnot = bit32_bnot
  485.  
  486.     local function bit32_bxor(a, b, c, ...)
  487.       local z
  488.       if b then
  489.         a = a % MOD
  490.         b = b % MOD
  491.         z = bxor(a, b)
  492.         if c then
  493.           z = bit32_bxor(z, c, ...)
  494.         end
  495.         return z
  496.       elseif a then
  497.         return a % MOD
  498.       else
  499.         return 0
  500.       end
  501.     end
  502.     M.bit32.bxor = bit32_bxor
  503.  
  504.     local function bit32_band(a, b, c, ...)
  505.       local z
  506.       if b then
  507.         a = a % MOD
  508.         b = b % MOD
  509.         z = ((a+b) - bxor(a,b)) / 2
  510.         if c then
  511.           z = bit32_band(z, c, ...)
  512.         end
  513.         return z
  514.       elseif a then
  515.         return a % MOD
  516.       else
  517.         return MODM
  518.       end
  519.     end
  520.     M.bit32.band = bit32_band
  521.  
  522.     local function bit32_bor(a, b, c, ...)
  523.       local z
  524.       if b then
  525.         a = a % MOD
  526.         b = b % MOD
  527.         z = MODM - band(MODM - a, MODM - b)
  528.         if c then
  529.           z = bit32_bor(z, c, ...)
  530.         end
  531.         return z
  532.       elseif a then
  533.         return a % MOD
  534.       else
  535.         return 0
  536.       end
  537.     end
  538.     M.bit32.bor = bit32_bor
  539.  
  540.     function M.bit32.btest(...)
  541.       return bit32_band(...) ~= 0
  542.     end
  543.  
  544.     function M.bit32.lrotate(x, disp)
  545.       return lrotate(x % MOD, disp)
  546.     end
  547.  
  548.     function M.bit32.rrotate(x, disp)
  549.       return rrotate(x % MOD, disp)
  550.     end
  551.  
  552.     function M.bit32.lshift(x,disp)
  553.       if disp > 31 or disp < -31 then return 0 end
  554.       return lshift(x % MOD, disp)
  555.     end
  556.  
  557.     function M.bit32.rshift(x,disp)
  558.       if disp > 31 or disp < -31 then return 0 end
  559.       return rshift(x % MOD, disp)
  560.     end
  561.  
  562.     function M.bit32.arshift(x,disp)
  563.       x = x % MOD
  564.       if disp >= 0 then
  565.         if disp > 31 then
  566.           return (x >= 0x80000000) and MODM or 0
  567.         else
  568.           local z = rshift(x, disp)
  569.           if x >= 0x80000000 then z = z + lshift(2^disp-1, 32-disp) end
  570.           return z
  571.         end
  572.       else
  573.         return lshift(x, -disp)
  574.       end
  575.     end
  576.  
  577.     function M.bit32.extract(x, field, ...)
  578.       local width = ... or 1
  579.       if field < 0 or field > 31 or width < 0 or field+width > 32 then error 'out of range' end
  580.       x = x % MOD
  581.       return extract(x, field, ...)
  582.     end
  583.  
  584.     function M.bit32.replace(x, v, field, ...)
  585.       local width = ... or 1
  586.       if field < 0 or field > 31 or width < 0 or field+width > 32 then error 'out of range' end
  587.       x = x % MOD
  588.       v = v % MOD
  589.       return replace(x, v, field, ...)
  590.     end
  591.  
  592.  
  593.     --
  594.     -- Start LuaBitOp "bit" compat section.
  595.     --
  596.  
  597.     M.bit = {} -- LuaBitOp "bit" compatibility
  598.  
  599.     function M.bit.tobit(x)
  600.       x = x % MOD
  601.       if x >= 0x80000000 then x = x - MOD end
  602.       return x
  603.     end
  604.     local bit_tobit = M.bit.tobit
  605.  
  606.     function M.bit.tohex(x, ...)
  607.       return tohex(x % MOD, ...)
  608.     end
  609.  
  610.     function M.bit.bnot(x)
  611.       return bit_tobit(bnot(x % MOD))
  612.     end
  613.  
  614.     local function bit_bor(a, b, c, ...)
  615.       if c then
  616.         return bit_bor(bit_bor(a, b), c, ...)
  617.       elseif b then
  618.         return bit_tobit(bor(a % MOD, b % MOD))
  619.       else
  620.         return bit_tobit(a)
  621.       end
  622.     end
  623.     M.bit.bor = bit_bor
  624.  
  625.     local function bit_band(a, b, c, ...)
  626.       if c then
  627.         return bit_band(bit_band(a, b), c, ...)
  628.       elseif b then
  629.         return bit_tobit(band(a % MOD, b % MOD))
  630.       else
  631.         return bit_tobit(a)
  632.       end
  633.     end
  634.     M.bit.band = bit_band
  635.  
  636.     local function bit_bxor(a, b, c, ...)
  637.       if c then
  638.         return bit_bxor(bit_bxor(a, b), c, ...)
  639.       elseif b then
  640.         return bit_tobit(bxor(a % MOD, b % MOD))
  641.       else
  642.         return bit_tobit(a)
  643.       end
  644.     end
  645.     M.bit.bxor = bit_bxor
  646.  
  647.     function M.bit.lshift(x, n)
  648.       return bit_tobit(lshift(x % MOD, n % 32))
  649.     end
  650.  
  651.     function M.bit.rshift(x, n)
  652.       return bit_tobit(rshift(x % MOD, n % 32))
  653.     end
  654.  
  655.     function M.bit.arshift(x, n)
  656.       return bit_tobit(arshift(x % MOD, n % 32))
  657.     end
  658.  
  659.     function M.bit.rol(x, n)
  660.       return bit_tobit(lrotate(x % MOD, n % 32))
  661.     end
  662.  
  663.     function M.bit.ror(x, n)
  664.       return bit_tobit(rrotate(x % MOD, n % 32))
  665.     end
  666.  
  667.     function M.bit.bswap(x)
  668.       return bit_tobit(bswap(x % MOD))
  669.     end
  670.  
  671.     return M
  672. end
  673. function crc32lua()
  674.     --[[
  675.  
  676.     LUA MODULE
  677.  
  678.       digest.crc32 - CRC-32 checksum implemented entirely in Lua.
  679.  
  680.     --]]
  681.  
  682.  
  683.     local M = {_TYPE='module', _NAME='digest.crc32', _VERSION='0.3.20111128'}
  684.  
  685.     local type = type
  686.     --local require = require
  687.     local setmetatable = setmetatable
  688.  
  689.     --[[
  690.      Requires the first module listed that exists, else raises like `require`.
  691.      If a non-string is encountered, it is returned.
  692.      Second return value is module name loaded (or '').
  693.      
  694.     local function requireany(...)
  695.       local errs = {}
  696.       for _,name in ipairs{...} do
  697.         if type(name) ~= 'string' then return name, '' end
  698.         local ok, mod = pcall(require, name)
  699.         if ok then return mod, name end
  700.         errs[#errs+1] = mod
  701.       end
  702.       error(table.concat(errs, '\n'), 2)
  703.     end
  704.     --]]
  705.  
  706.     --local bit, name_ = requireany('bit', 'bit32', 'bit.numberlua')
  707.     local bit = numberlua()
  708.     local bxor = bit.bxor
  709.     local bnot = bit.bnot
  710.     local band = bit.band
  711.     local rshift = bit.rshift
  712.  
  713.     -- CRC-32-IEEE 802.3 (V.42)
  714.     local POLY = 0xEDB88320
  715.  
  716.     -- Memoize function pattern (like http://lua-users.org/wiki/FuncTables ).
  717.     local function memoize(f)
  718.       local mt = {}
  719.       local t = setmetatable({}, mt)
  720.       function mt:__index(k)
  721.         local v = f(k); t[k] = v
  722.         return v
  723.       end
  724.       return t
  725.     end
  726.  
  727.     -- CRC table.
  728.     local crc_table = memoize(function(i)
  729.       local crc = i
  730.       for _=1,8 do
  731.         local b = band(crc, 1)
  732.         crc = rshift(crc, 1)
  733.         if b == 1 then crc = bxor(crc, POLY) end
  734.       end
  735.       return crc
  736.     end)
  737.  
  738.  
  739.     function M.crc32_byte(byte, crc)
  740.       crc = bnot(crc or 0)
  741.       local v1 = rshift(crc, 8)
  742.       local v2 = crc_table[bxor(crc % 256, byte)]
  743.       return bnot(bxor(v1, v2))
  744.     end
  745.     local M_crc32_byte = M.crc32_byte
  746.  
  747.  
  748.     function M.crc32_string(s, crc)
  749.       crc = crc or 0
  750.       for i=1,#s do
  751.         crc = M_crc32_byte(s:byte(i), crc)
  752.       end
  753.       return crc
  754.     end
  755.     local M_crc32_string = M.crc32_string
  756.  
  757.  
  758.     function M.crc32(s, crc)
  759.       if type(s) == 'string' then
  760.         return M_crc32_string(s, crc)
  761.       else
  762.         return M_crc32_byte(s, crc)
  763.       end
  764.     end
  765.  
  766.  
  767.     M.bit = bit  -- bit library used
  768.  
  769.  
  770.     return M
  771. end
  772. function deflatelua()
  773.     --[[
  774.  
  775.     LUA MODULE
  776.  
  777.       compress.deflatelua - deflate (and gunzip/zlib) implemented in Lua.
  778.  
  779.     --]]
  780.  
  781.     local M = {_TYPE='module', _NAME='compress.deflatelua', _VERSION='0.3.20111128'}
  782.  
  783.     local assert = assert
  784.     local error = error
  785.     local ipairs = ipairs
  786.     local pairs = pairs
  787.     local print = print
  788.     --local require = require
  789.     local tostring = tostring
  790.     local type = type
  791.     local setmetatable = setmetatable
  792.     local io = io
  793.     local math = math
  794.     local table_sort = table.sort
  795.     local math_max = math.max
  796.     local string_char = string.char
  797.  
  798.     --[[
  799.      Requires the first module listed that exists, else raises like `require`.
  800.      If a non-string is encountered, it is returned.
  801.      Second return value is module name loaded (or '').
  802.      
  803.     local function requireany(...)
  804.       local errs = {}
  805.       for i = 1, select('#', ...) do local name = select(i, ...)
  806.         if type(name) ~= 'string' then return name, '' end
  807.         local ok, mod = pcall(require, name)
  808.         if ok then return mod, name end
  809.         errs[#errs+1] = mod
  810.       end
  811.       error(table.concat(errs, '\n'), 2)
  812.     end
  813.     --]]
  814.  
  815.  
  816.     --local crc32 = require "digest.crc32lua" . crc32_byte
  817.     local crc32 = crc32lua() . crc32_byte
  818.     --local bit, name_ = requireany('bit', 'bit32', 'bit.numberlua', nil)
  819.     local bit = numberlua()
  820.  
  821.     local DEBUG = false
  822.  
  823.     -- Whether to use `bit` library functions in current module.
  824.     -- Unlike the crc32 library, it doesn't make much difference in this module.
  825.     local NATIVE_BITOPS = (bit ~= nil)
  826.  
  827.     local band, lshift, rshift
  828.     if NATIVE_BITOPS then
  829.       band = bit.band
  830.       lshift = bit.lshift
  831.       rshift = bit.rshift
  832.     end
  833.  
  834.  
  835.     local function warn(s)
  836.       io.stderr:write(s, '\n')
  837.     end
  838.  
  839.  
  840.     local function debug(...)
  841.       print('DEBUG', ...)
  842.     end
  843.  
  844.  
  845.     local function runtime_error(s, level)
  846.       level = level or 1
  847.       error({s}, level+1)
  848.     end
  849.  
  850.  
  851.     local function make_outstate(outbs)
  852.       local outstate = {}
  853.       outstate.outbs = outbs
  854.       outstate.window = {}
  855.       outstate.window_pos = 1
  856.       return outstate
  857.     end
  858.  
  859.  
  860.     local function output(outstate, byte)
  861.       -- debug('OUTPUT:', s)
  862.       local window_pos = outstate.window_pos
  863.       outstate.outbs(byte)
  864.       outstate.window[window_pos] = byte
  865.       outstate.window_pos = window_pos % 32768 + 1  -- 32K
  866.     end
  867.  
  868.  
  869.     local function noeof(val)
  870.       return assert(val, 'unexpected end of file')
  871.     end
  872.  
  873.  
  874.     local function hasbit(bits, bit)
  875.       return bits % (bit + bit) >= bit
  876.     end
  877.  
  878.  
  879.     local function memoize(f)
  880.       local mt = {}
  881.       local t = setmetatable({}, mt)
  882.       function mt:__index(k)
  883.         local v = f(k)
  884.         t[k] = v
  885.         return v
  886.       end
  887.       return t
  888.     end
  889.  
  890.  
  891.     -- small optimization (lookup table for powers of 2)
  892.     local pow2 = memoize(function(n) return 2^n end)
  893.  
  894.     --local tbits = memoize(
  895.     --  function(bits)
  896.     --    return memoize( function(bit) return getbit(bits, bit) end )
  897.     --  end )
  898.  
  899.  
  900.     -- weak metatable marking objects as bitstream type
  901.     local is_bitstream = setmetatable({}, {__mode='k'})
  902.  
  903.  
  904.     -- DEBUG
  905.     -- prints LSB first
  906.     --[[
  907.     local function bits_tostring(bits, nbits)
  908.       local s = ''
  909.       local tmp = bits
  910.       local function f()
  911.         local b = tmp % 2 == 1 and 1 or 0
  912.         s = s .. b
  913.         tmp = (tmp - b) / 2
  914.       end
  915.       if nbits then
  916.         for i=1,nbits do f() end
  917.       else
  918.         while tmp ~= 0 do f() end
  919.       end
  920.  
  921.       return s
  922.     end
  923.     --]]
  924.  
  925.     local function bytestream_from_file(fh)
  926.       local o = {}
  927.       function o:read()
  928.         local sb = fh:read(1)
  929.         if not computercraft and sb then return sb:byte() end
  930.         return sb
  931.       end
  932.       return o
  933.     end
  934.  
  935.  
  936.     local function bytestream_from_string(s)
  937.       local i = 1
  938.       local o = {}
  939.       function o:read()
  940.         local by
  941.         if i <= #s then
  942.           by = s:byte(i)
  943.           i = i + 1
  944.         end
  945.         return by
  946.       end
  947.       return o
  948.     end
  949.  
  950.  
  951.     local function bytestream_from_function(f)
  952.       local i = 0
  953.       local buffer = ''
  954.       local o = {}
  955.       function o:read()
  956.         i = i + 1
  957.         if i > #buffer then
  958.           buffer = f()
  959.           if not buffer then return end
  960.           i = 1
  961.         end
  962.         return buffer:byte(i,i)
  963.       end
  964.       return o
  965.     end
  966.  
  967.  
  968.     local function bitstream_from_bytestream(bys)
  969.       local buf_byte = 0
  970.       local buf_nbit = 0
  971.       local o = {}
  972.  
  973.       function o:nbits_left_in_byte()
  974.         return buf_nbit
  975.       end
  976.  
  977.       if NATIVE_BITOPS then
  978.         function o:read(nbits)
  979.           nbits = nbits or 1
  980.           while buf_nbit < nbits do
  981.             local byte = bys:read()
  982.             if not byte then return end  -- note: more calls also return nil
  983.             buf_byte = buf_byte + lshift(byte, buf_nbit)
  984.             buf_nbit = buf_nbit + 8
  985.           end
  986.           local bits
  987.           if nbits == 0 then
  988.             bits = 0
  989.           elseif nbits == 32 then
  990.             bits = buf_byte
  991.             buf_byte = 0
  992.           else
  993.             bits = band(buf_byte, rshift(0xffffffff, 32 - nbits))
  994.             buf_byte = rshift(buf_byte, nbits)
  995.           end
  996.           buf_nbit = buf_nbit - nbits
  997.           return bits
  998.         end
  999.       else
  1000.         function o:read(nbits)
  1001.           nbits = nbits or 1
  1002.           while buf_nbit < nbits do
  1003.             local byte = bys:read()
  1004.             if not byte then return end  -- note: more calls also return nil
  1005.             buf_byte = buf_byte + pow2[buf_nbit] * byte
  1006.             buf_nbit = buf_nbit + 8
  1007.           end
  1008.           local m = pow2[nbits]
  1009.           local bits = buf_byte % m
  1010.           buf_byte = (buf_byte - bits) / m
  1011.           buf_nbit = buf_nbit - nbits
  1012.           return bits
  1013.         end
  1014.       end
  1015.      
  1016.       is_bitstream[o] = true
  1017.  
  1018.       return o
  1019.     end
  1020.  
  1021.  
  1022.     local function get_bitstream(o)
  1023.       local bs
  1024.       if is_bitstream[o] then
  1025.         return o
  1026.       elseif io.type(o) == 'file' then
  1027.         bs = bitstream_from_bytestream(bytestream_from_file(o))
  1028.       elseif type(o) == 'string' then
  1029.         bs = bitstream_from_bytestream(bytestream_from_string(o))
  1030.       elseif type(o) == 'function' then
  1031.         bs = bitstream_from_bytestream(bytestream_from_function(o))
  1032.       else
  1033.         runtime_error 'unrecognized type'
  1034.       end
  1035.       return bs
  1036.     end
  1037.  
  1038.  
  1039.     local function get_obytestream(o)
  1040.       local bs
  1041.       if io.type(o) == 'file' then
  1042.         bs = function(sbyte) if computercraft then o:write(sbyte) else o:write(string_char(sbyte)) end end
  1043.       elseif type(o) == 'function' then
  1044.         bs = o
  1045.       else
  1046.         runtime_error('unrecognized type: ' .. tostring(o))
  1047.       end
  1048.       return bs
  1049.     end
  1050.  
  1051.  
  1052.     local function HuffmanTable(init, is_full)
  1053.       local t = {}
  1054.       if is_full then
  1055.         for val,nbits in pairs(init) do
  1056.           if nbits ~= 0 then
  1057.             t[#t+1] = {val=val, nbits=nbits}
  1058.             --debug('*',val,nbits)
  1059.           end
  1060.         end
  1061.       else
  1062.         for i=1,#init-2,2 do
  1063.           local firstval, nbits, nextval = init[i], init[i+1], init[i+2]
  1064.           --debug(val, nextval, nbits)
  1065.           if nbits ~= 0 then
  1066.             for val=firstval,nextval-1 do
  1067.               t[#t+1] = {val=val, nbits=nbits}
  1068.             end
  1069.           end
  1070.         end
  1071.       end
  1072.       table_sort(t, function(a,b)
  1073.         return a.nbits == b.nbits and a.val < b.val or a.nbits < b.nbits
  1074.       end)
  1075.  
  1076.       -- assign codes
  1077.       local code = 1  -- leading 1 marker
  1078.       local nbits = 0
  1079.       for i,s in ipairs(t) do
  1080.         if s.nbits ~= nbits then
  1081.           code = code * pow2[s.nbits - nbits]
  1082.           nbits = s.nbits
  1083.         end
  1084.         s.code = code
  1085.         --debug('huffman code:', i, s.nbits, s.val, code, bits_tostring(code))
  1086.         code = code + 1
  1087.       end
  1088.  
  1089.       local minbits = math.huge
  1090.       local look = {}
  1091.       for i,s in ipairs(t) do
  1092.         minbits = math.min(minbits, s.nbits)
  1093.         look[s.code] = s.val
  1094.       end
  1095.  
  1096.       --for _,o in ipairs(t) do
  1097.       --  debug(':', o.nbits, o.val)
  1098.       --end
  1099.  
  1100.       -- function t:lookup(bits) return look[bits] end
  1101.  
  1102.       local msb = NATIVE_BITOPS and function(bits, nbits)
  1103.         local res = 0
  1104.         for i=1,nbits do
  1105.           res = lshift(res, 1) + band(bits, 1)
  1106.           bits = rshift(bits, 1)
  1107.         end
  1108.         return res
  1109.       end or function(bits, nbits)
  1110.         local res = 0
  1111.         for i=1,nbits do
  1112.           local b = bits % 2
  1113.           bits = (bits - b) / 2
  1114.           res = res * 2 + b
  1115.         end
  1116.         return res
  1117.       end
  1118.      
  1119.       local tfirstcode = memoize(
  1120.         function(bits) return pow2[minbits] + msb(bits, minbits) end)
  1121.  
  1122.       function t:read(bs)
  1123.         local code = 1 -- leading 1 marker
  1124.         local nbits = 0
  1125.         while 1 do
  1126.           if nbits == 0 then  -- small optimization (optional)
  1127.             code = tfirstcode[noeof(bs:read(minbits))]
  1128.             nbits = nbits + minbits
  1129.           else
  1130.             local b = noeof(bs:read())
  1131.             nbits = nbits + 1
  1132.             code = code * 2 + b   -- MSB first
  1133.             --[[NATIVE_BITOPS
  1134.             code = lshift(code, 1) + b   -- MSB first
  1135.             --]]
  1136.           end
  1137.           --debug('code?', code, bits_tostring(code))
  1138.           local val = look[code]
  1139.           if val then
  1140.             --debug('FOUND', val)
  1141.             return val
  1142.           end
  1143.         end
  1144.       end
  1145.  
  1146.       return t
  1147.     end
  1148.  
  1149.  
  1150.     local function parse_gzip_header(bs)
  1151.       -- local FLG_FTEXT = 2^0
  1152.       local FLG_FHCRC = 2^1
  1153.       local FLG_FEXTRA = 2^2
  1154.       local FLG_FNAME = 2^3
  1155.       local FLG_FCOMMENT = 2^4
  1156.  
  1157.       local id1 = bs:read(8)
  1158.       local id2 = bs:read(8)
  1159.       if id1 ~= 31 or id2 ~= 139 then
  1160.         runtime_error 'not in gzip format'
  1161.       end
  1162.       local cm = bs:read(8)  -- compression method
  1163.       local flg = bs:read(8) -- FLaGs
  1164.       local mtime = bs:read(32) -- Modification TIME
  1165.       local xfl = bs:read(8) -- eXtra FLags
  1166.       local os = bs:read(8) -- Operating System
  1167.  
  1168.       if DEBUG then
  1169.         debug("CM=", cm)
  1170.         debug("FLG=", flg)
  1171.         debug("MTIME=", mtime)
  1172.         -- debug("MTIME_str=",os.date("%Y-%m-%d %H:%M:%S",mtime)) -- non-portable
  1173.         debug("XFL=", xfl)
  1174.         debug("OS=", os)
  1175.       end
  1176.  
  1177.       if not os then runtime_error 'invalid header' end
  1178.  
  1179.       if hasbit(flg, FLG_FEXTRA) then
  1180.         local xlen = bs:read(16)
  1181.         local extra = 0
  1182.         for i=1,xlen do
  1183.           extra = bs:read(8)
  1184.         end
  1185.         if not extra then runtime_error 'invalid header' end
  1186.       end
  1187.  
  1188.       local function parse_zstring(bs)
  1189.         repeat
  1190.           local by = bs:read(8)
  1191.           if not by then runtime_error 'invalid header' end
  1192.         until by == 0
  1193.       end
  1194.  
  1195.       if hasbit(flg, FLG_FNAME) then
  1196.         parse_zstring(bs)
  1197.       end
  1198.  
  1199.       if hasbit(flg, FLG_FCOMMENT) then
  1200.         parse_zstring(bs)
  1201.       end
  1202.  
  1203.       if hasbit(flg, FLG_FHCRC) then
  1204.         local crc16 = bs:read(16)
  1205.         if not crc16 then runtime_error 'invalid header' end
  1206.         -- IMPROVE: check CRC.  where is an example .gz file that
  1207.         -- has this set?
  1208.         if DEBUG then
  1209.           debug("CRC16=", crc16)
  1210.         end
  1211.       end
  1212.     end
  1213.  
  1214.     local function parse_zlib_header(bs)
  1215.       local cm = bs:read(4) -- Compression Method
  1216.       local cinfo = bs:read(4) -- Compression info
  1217.       local fcheck = bs:read(5) -- FLaGs: FCHECK (check bits for CMF and FLG)
  1218.       local fdict = bs:read(1) -- FLaGs: FDICT (present dictionary)
  1219.       local flevel = bs:read(2) -- FLaGs: FLEVEL (compression level)
  1220.       local cmf = cinfo * 16  + cm -- CMF (Compresion Method and flags)
  1221.       local flg = fcheck + fdict * 32 + flevel * 64 -- FLaGs
  1222.      
  1223.       if cm ~= 8 then -- not "deflate"
  1224.         runtime_error("unrecognized zlib compression method: " + cm)
  1225.       end
  1226.       if cinfo > 7 then
  1227.         runtime_error("invalid zlib window size: cinfo=" + cinfo)
  1228.       end
  1229.       local window_size = 2^(cinfo + 8)
  1230.      
  1231.       if (cmf*256 + flg) %  31 ~= 0 then
  1232.         runtime_error("invalid zlib header (bad fcheck sum)")
  1233.       end
  1234.      
  1235.       if fdict == 1 then
  1236.         runtime_error("FIX:TODO - FDICT not currently implemented")
  1237.         local dictid_ = bs:read(32)
  1238.       end
  1239.      
  1240.       return window_size
  1241.     end
  1242.  
  1243.     local function parse_huffmantables(bs)
  1244.         local hlit = bs:read(5)  -- # of literal/length codes - 257
  1245.         local hdist = bs:read(5) -- # of distance codes - 1
  1246.         local hclen = noeof(bs:read(4)) -- # of code length codes - 4
  1247.  
  1248.         local ncodelen_codes = hclen + 4
  1249.         local codelen_init = {}
  1250.         local codelen_vals = {
  1251.           16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
  1252.         for i=1,ncodelen_codes do
  1253.           local nbits = bs:read(3)
  1254.           local val = codelen_vals[i]
  1255.           codelen_init[val] = nbits
  1256.         end
  1257.         local codelentable = HuffmanTable(codelen_init, true)
  1258.  
  1259.         local function decode(ncodes)
  1260.           local init = {}
  1261.           local nbits
  1262.           local val = 0
  1263.           while val < ncodes do
  1264.             local codelen = codelentable:read(bs)
  1265.             --FIX:check nil?
  1266.             local nrepeat
  1267.             if codelen <= 15 then
  1268.               nrepeat = 1
  1269.               nbits = codelen
  1270.               --debug('w', nbits)
  1271.             elseif codelen == 16 then
  1272.               nrepeat = 3 + noeof(bs:read(2))
  1273.               -- nbits unchanged
  1274.             elseif codelen == 17 then
  1275.               nrepeat = 3 + noeof(bs:read(3))
  1276.               nbits = 0
  1277.             elseif codelen == 18 then
  1278.               nrepeat = 11 + noeof(bs:read(7))
  1279.               nbits = 0
  1280.             else
  1281.               error 'ASSERT'
  1282.             end
  1283.             for i=1,nrepeat do
  1284.               init[val] = nbits
  1285.               val = val + 1
  1286.             end
  1287.           end
  1288.           local huffmantable = HuffmanTable(init, true)
  1289.           return huffmantable
  1290.         end
  1291.  
  1292.         local nlit_codes = hlit + 257
  1293.         local ndist_codes = hdist + 1
  1294.  
  1295.         local littable = decode(nlit_codes)
  1296.         local disttable = decode(ndist_codes)
  1297.  
  1298.         return littable, disttable
  1299.     end
  1300.  
  1301.  
  1302.     local tdecode_len_base
  1303.     local tdecode_len_nextrabits
  1304.     local tdecode_dist_base
  1305.     local tdecode_dist_nextrabits
  1306.     local function parse_compressed_item(bs, outstate, littable, disttable)
  1307.       local val = littable:read(bs)
  1308.       --debug(val, val < 256 and string_char(val))
  1309.       if val < 256 then -- literal
  1310.         output(outstate, val)
  1311.       elseif val == 256 then -- end of block
  1312.         return true
  1313.       else
  1314.         if not tdecode_len_base then
  1315.           local t = {[257]=3}
  1316.           local skip = 1
  1317.           for i=258,285,4 do
  1318.             for j=i,i+3 do t[j] = t[j-1] + skip end
  1319.             if i ~= 258 then skip = skip * 2 end
  1320.           end
  1321.           t[285] = 258
  1322.           tdecode_len_base = t
  1323.           --for i=257,285 do debug('T1',i,t[i]) end
  1324.         end
  1325.         if not tdecode_len_nextrabits then
  1326.           local t = {}
  1327.           if NATIVE_BITOPS then
  1328.             for i=257,285 do
  1329.               local j = math_max(i - 261, 0)
  1330.               t[i] = rshift(j, 2)
  1331.             end
  1332.           else
  1333.             for i=257,285 do
  1334.               local j = math_max(i - 261, 0)
  1335.               t[i] = (j - (j % 4)) / 4
  1336.             end
  1337.           end
  1338.           t[285] = 0
  1339.           tdecode_len_nextrabits = t
  1340.           --for i=257,285 do debug('T2',i,t[i]) end
  1341.         end
  1342.         local len_base = tdecode_len_base[val]
  1343.         local nextrabits = tdecode_len_nextrabits[val]
  1344.         local extrabits = bs:read(nextrabits)
  1345.         local len = len_base + extrabits
  1346.  
  1347.         if not tdecode_dist_base then
  1348.           local t = {[0]=1}
  1349.           local skip = 1
  1350.           for i=1,29,2 do
  1351.             for j=i,i+1 do t[j] = t[j-1] + skip end
  1352.             if i ~= 1 then skip = skip * 2 end
  1353.           end
  1354.           tdecode_dist_base = t
  1355.           --for i=0,29 do debug('T3',i,t[i]) end
  1356.         end
  1357.         if not tdecode_dist_nextrabits then
  1358.           local t = {}
  1359.           if NATIVE_BITOPS then
  1360.             for i=0,29 do
  1361.               local j = math_max(i - 2, 0)
  1362.               t[i] = rshift(j, 1)
  1363.             end
  1364.           else
  1365.             for i=0,29 do
  1366.               local j = math_max(i - 2, 0)
  1367.               t[i] = (j - (j % 2)) / 2
  1368.             end
  1369.           end
  1370.           tdecode_dist_nextrabits = t
  1371.           --for i=0,29 do debug('T4',i,t[i]) end
  1372.         end
  1373.         local dist_val = disttable:read(bs)
  1374.         local dist_base = tdecode_dist_base[dist_val]
  1375.         local dist_nextrabits = tdecode_dist_nextrabits[dist_val]
  1376.         local dist_extrabits = bs:read(dist_nextrabits)
  1377.         local dist = dist_base + dist_extrabits
  1378.  
  1379.         --debug('BACK', len, dist)
  1380.         for i=1,len do
  1381.           local pos = (outstate.window_pos - 1 - dist) % 32768 + 1  -- 32K
  1382.           output(outstate, assert(outstate.window[pos], 'invalid distance'))
  1383.         end
  1384.       end
  1385.       return false
  1386.     end
  1387.  
  1388.  
  1389.     local function parse_block(bs, outstate)
  1390.       local bfinal = bs:read(1)
  1391.       local btype = bs:read(2)
  1392.  
  1393.       local BTYPE_NO_COMPRESSION = 0
  1394.       local BTYPE_FIXED_HUFFMAN = 1
  1395.       local BTYPE_DYNAMIC_HUFFMAN = 2
  1396.       local BTYPE_RESERVED_ = 3
  1397.  
  1398.       if DEBUG then
  1399.         debug('bfinal=', bfinal)
  1400.         debug('btype=', btype)
  1401.       end
  1402.  
  1403.       if btype == BTYPE_NO_COMPRESSION then
  1404.         bs:read(bs:nbits_left_in_byte())
  1405.         local len = bs:read(16)
  1406.         local nlen_ = noeof(bs:read(16))
  1407.  
  1408.         for i=1,len do
  1409.           local by = noeof(bs:read(8))
  1410.           output(outstate, by)
  1411.         end
  1412.       elseif btype == BTYPE_FIXED_HUFFMAN or btype == BTYPE_DYNAMIC_HUFFMAN then
  1413.         local littable, disttable
  1414.         if btype == BTYPE_DYNAMIC_HUFFMAN then
  1415.           littable, disttable = parse_huffmantables(bs)
  1416.         else
  1417.           littable  = HuffmanTable {0,8, 144,9, 256,7, 280,8, 288,nil}
  1418.           disttable = HuffmanTable {0,5, 32,nil}
  1419.         end
  1420.  
  1421.         repeat
  1422.           local is_done = parse_compressed_item(
  1423.             bs, outstate, littable, disttable)
  1424.         until is_done
  1425.       else
  1426.         runtime_error 'unrecognized compression type'
  1427.       end
  1428.  
  1429.       return bfinal ~= 0
  1430.     end
  1431.  
  1432.  
  1433.     function M.inflate(t)
  1434.       local bs = get_bitstream(t.input)
  1435.       local outbs = get_obytestream(t.output)
  1436.       local outstate = make_outstate(outbs)
  1437.  
  1438.       repeat
  1439.         local is_final = parse_block(bs, outstate)
  1440.       until is_final
  1441.     end
  1442.     local inflate = M.inflate
  1443.  
  1444.  
  1445.     function M.gunzip(t)
  1446.       local bs = get_bitstream(t.input)
  1447.       local outbs = get_obytestream(t.output)
  1448.       local disable_crc = t.disable_crc
  1449.       if disable_crc == nil then disable_crc = false end
  1450.       parse_gzip_header(bs)
  1451.       local data_crc32 = 0
  1452.  
  1453.       inflate{input=bs, output=
  1454.         disable_crc and outbs or
  1455.           function(byte)
  1456.             data_crc32 = crc32(byte, data_crc32)
  1457.             outbs(byte)
  1458.           end
  1459.       }
  1460.       bs:read(bs:nbits_left_in_byte())
  1461.       local expected_crc32 = bs:read(32)
  1462.       local isize = bs:read(32) -- ignored
  1463.       if DEBUG then
  1464.         debug('crc32=', expected_crc32)
  1465.         debug('isize=', isize)
  1466.       end
  1467.      
  1468.       if not disable_crc and data_crc32 then
  1469.         if data_crc32 ~= expected_crc32 then
  1470.           runtime_error('invalid compressed data--crc error')
  1471.         end    
  1472.       end
  1473.      
  1474.       if bs:read() then
  1475.         warn 'trailing garbage ignored'
  1476.       end
  1477.     end
  1478.  
  1479.  
  1480.     function M.adler32(byte, crc)
  1481.       local s1 = crc % 65536
  1482.       local s2 = (crc - s1) / 65536
  1483.       s1 = (s1 + byte) % 65521
  1484.       s2 = (s2 + s1) % 65521
  1485.       return s2*65536 + s1
  1486.     end -- 65521 is the largest prime smaller than 2^16
  1487.  
  1488.  
  1489.     function M.inflate_zlib(t)
  1490.       local bs = get_bitstream(t.input)
  1491.       local outbs = get_obytestream(t.output)
  1492.       local disable_crc = t.disable_crc
  1493.       if disable_crc == nil then disable_crc = false end
  1494.      
  1495.       local window_size_ = parse_zlib_header(bs)
  1496.      
  1497.       local data_adler32 = 1
  1498.      
  1499.       inflate{input=bs, output=
  1500.         disable_crc and outbs or
  1501.           function(byte)
  1502.             data_adler32 = M.adler32(byte, data_adler32)
  1503.             outbs(byte)
  1504.           end
  1505.       }
  1506.  
  1507.       bs:read(bs:nbits_left_in_byte())
  1508.      
  1509.       local b3 = bs:read(8)
  1510.       local b2 = bs:read(8)
  1511.       local b1 = bs:read(8)
  1512.       local b0 = bs:read(8)
  1513.       local expected_adler32 = ((b3*256 + b2)*256 + b1)*256 + b0
  1514.       if DEBUG then
  1515.         debug('alder32=', expected_adler32)
  1516.       end
  1517.       if not disable_crc then
  1518.         if data_adler32 ~= expected_adler32 then
  1519.           runtime_error('invalid compressed data--crc error')
  1520.         end    
  1521.       end
  1522.       if bs:read() then
  1523.         warn 'trailing garbage ignored'
  1524.       end
  1525.     end
  1526.  
  1527.  
  1528.     return M
  1529.  
  1530. end
  1531.  
  1532. function dirlib()
  1533.     --- Generic utilities for handling pathnames.
  1534.     local dir = {}
  1535.  
  1536.     dir.separator = "/"
  1537.  
  1538.     --- Strip the path off a path+filename.
  1539.     -- @param pathname string: A path+name, such as "/a/b/c"
  1540.     -- or "\a\b\c".
  1541.     -- @return string: The filename without its path, such as "c".
  1542.     function dir.base_name(pathname)
  1543.        assert(type(pathname) == "string")
  1544.  
  1545.        local base = pathname:gsub("[/\\]*$", ""):match(".*[/\\]([^/\\]*)")
  1546.        return base or pathname
  1547.     end
  1548.  
  1549.     --- Strip the name off a path+filename.
  1550.     -- @param pathname string: A path+name, such as "/a/b/c".
  1551.     -- @return string: The filename without its path, such as "/a/b".
  1552.     -- For entries such as "/a/b/", "/a" is returned. If there are
  1553.     -- no directory separators in input, "" is returned.
  1554.     function dir.dir_name(pathname)
  1555.        assert(type(pathname) == "string")
  1556.        return (pathname:gsub("/*$", ""):match("(.*)[/]+[^/]*")) or ""
  1557.     end
  1558.  
  1559.     --- Describe a path in a cross-platform way.
  1560.     -- Use this function to avoid platform-specific directory
  1561.     -- separators in other modules. Removes trailing slashes from
  1562.     -- each component given, to avoid repeated separators.
  1563.     -- Separators inside strings are kept, to handle URLs containing
  1564.     -- protocols.
  1565.     -- @param ... strings representing directories
  1566.     -- @return string: a string with a platform-specific representation
  1567.     -- of the path.
  1568.     function dir.path(...)
  1569.        local t = {...}
  1570.        while t[1] == "" do
  1571.           table.remove(t, 1)
  1572.        end
  1573.        return (table.concat(t, "/"):gsub("([^:])/+", "%1/"):gsub("^/+", "/"):gsub("/*$", ""))
  1574.     end
  1575.  
  1576.     --- Split protocol and path from an URL or local pathname.
  1577.     -- URLs should be in the "protocol://path" format.
  1578.     -- For local pathnames, "file" is returned as the protocol.
  1579.     -- @param url string: an URL or a local pathname.
  1580.     -- @return string, string: the protocol, and the pathname without the protocol.
  1581.     function dir.split_url(url)
  1582.        assert(type(url) == "string")
  1583.        
  1584.        local protocol, pathname = url:match("^([^:]*)://(.*)")
  1585.        if not protocol then
  1586.           protocol = "file"
  1587.           pathname = url
  1588.        end
  1589.        return protocol, pathname
  1590.     end
  1591.  
  1592.     --- Normalize a url or local path.
  1593.     -- URLs should be in the "protocol://path" format. System independent
  1594.     -- forward slashes are used, removing trailing and double slashes
  1595.     -- @param url string: an URL or a local pathname.
  1596.     -- @return string: Normalized result.
  1597.     function dir.normalize(name)
  1598.        local protocol, pathname = dir.split_url(name)
  1599.        pathname = pathname:gsub("\\", "/"):gsub("(.)/*$", "%1"):gsub("//", "/")
  1600.        if protocol ~= "file" then pathname = protocol .."://"..pathname end
  1601.        return pathname
  1602.     end
  1603.  
  1604.     return dir
  1605. end
  1606.  
  1607. function untar()
  1608.     --- A pure-Lua implementation of untar (unpacking .tar archives)
  1609.     local tar = {}
  1610.  
  1611.     local dir = dirlib()
  1612.     local blocksize = 512
  1613.  
  1614.     local function get_typeflag(flag)
  1615.        if flag == "0" or flag == "\0" then return "file"
  1616.        elseif flag == "1" then return "link"
  1617.        elseif flag == "2" then return "symlink" -- "reserved" in POSIX, "symlink" in GNU
  1618.        elseif flag == "3" then return "character"
  1619.        elseif flag == "4" then return "block"
  1620.        elseif flag == "5" then return "directory"
  1621.        elseif flag == "6" then return "fifo"
  1622.        elseif flag == "7" then return "contiguous" -- "reserved" in POSIX, "contiguous" in GNU
  1623.        elseif flag == "x" then return "next file"
  1624.        elseif flag == "g" then return "global extended header"
  1625.        elseif flag == "L" then return "long name"
  1626.        elseif flag == "K" then return "long link name"
  1627.        end
  1628.        return "unknown"
  1629.     end
  1630.  
  1631.     local function octal_to_number(octal)
  1632.        local exp = 0
  1633.        local number = 0
  1634.        for i = #octal,1,-1 do
  1635.           local digit = tonumber(octal:sub(i,i))
  1636.           if digit then
  1637.              number = number + (digit * 8^exp)
  1638.              exp = exp + 1
  1639.           end
  1640.        end
  1641.        return number
  1642.     end
  1643.  
  1644.     local function checksum_header(block)
  1645.        local sum = 256
  1646.        for i = 1,148 do
  1647.           sum = sum + (block:byte(i) or 0)
  1648.        end
  1649.        for i = 157,500 do
  1650.           sum = sum + (block:byte(i) or 0)
  1651.        end
  1652.        return sum
  1653.     end
  1654.  
  1655.     local function nullterm(s)
  1656.        return s:match("^[^%z]*")
  1657.     end
  1658.  
  1659.     local function read_header_block(block)
  1660.        local header = {}
  1661.        header.name = nullterm(block:sub(1,100))
  1662.        header.mode = nullterm(block:sub(101,108))
  1663.        header.uid = octal_to_number(nullterm(block:sub(109,116)))
  1664.        header.gid = octal_to_number(nullterm(block:sub(117,124)))
  1665.        header.size = octal_to_number(nullterm(block:sub(125,136)))
  1666.        header.mtime = octal_to_number(nullterm(block:sub(137,148)))
  1667.        header.chksum = octal_to_number(nullterm(block:sub(149,156)))
  1668.        header.typeflag = get_typeflag(block:sub(157,157))
  1669.        header.linkname = nullterm(block:sub(158,257))
  1670.        header.magic = block:sub(258,263)
  1671.        header.version = block:sub(264,265)
  1672.        header.uname = nullterm(block:sub(266,297))
  1673.        header.gname = nullterm(block:sub(298,329))
  1674.        header.devmajor = octal_to_number(nullterm(block:sub(330,337)))
  1675.        header.devminor = octal_to_number(nullterm(block:sub(338,345)))
  1676.        header.prefix = block:sub(346,500)
  1677.        if header.magic ~= "ustar " and header.magic ~= "ustar\0" then
  1678.           return false, "Invalid header magic "..header.magic
  1679.        end
  1680.        if header.version ~= "00" and header.version ~= " \0" then
  1681.           return false, "Unknown version "..header.version
  1682.        end
  1683.        if not checksum_header(block) == header.chksum then
  1684.           return false, "Failed header checksum"
  1685.        end
  1686.        return header
  1687.     end
  1688.    
  1689.     local function bytestream_from_file(fh)
  1690.       if not fh then
  1691.         return nil
  1692.       end
  1693.       local o = {}
  1694.       function o:read_single()
  1695.         local sb = fh:read(1)
  1696.         if not computercraft and sb then return sb:byte() end
  1697.         return sb
  1698.       end
  1699.       function o:read(num)
  1700.         if o.finished then
  1701.             return nil
  1702.         end
  1703.         local buf = {}
  1704.         for i=1, num do
  1705.             local b_read = o:read_single()
  1706.             if not b_read then
  1707.                 o.finished = true
  1708.                 break
  1709.             end
  1710.             buf[#buf+1] = string.char(b_read)
  1711.         end
  1712.         return table.concat(buf)
  1713.       end
  1714.       function o:close()
  1715.         fh:close()
  1716.       end
  1717.       return o
  1718.     end
  1719.  
  1720.     function tar.untar(filename, destdir)
  1721.        assert(type(filename) == "string")
  1722.        assert(type(destdir) == "string")
  1723.        local tar_handle = bytestream_from_file(io.open(filename, "rb"))
  1724.        if not tar_handle then return nil, "Error opening file "..filename end
  1725.        
  1726.        local long_name, long_link_name
  1727.        while true do
  1728.           local block
  1729.           repeat
  1730.              block = tar_handle:read(blocksize)
  1731.           until (not block) or checksum_header(block) > 256
  1732.           if not block then break end
  1733.           local header, err = read_header_block(block)
  1734.           if not header then
  1735.              error(err)
  1736.           end
  1737.  
  1738.           local file_data = tar_handle:read(math.ceil(header.size / blocksize) * blocksize):sub(1,header.size)
  1739.          
  1740.           if header.typeflag == "long name" then
  1741.              long_name = nullterm(file_data)
  1742.           elseif header.typeflag == "long link name" then
  1743.              long_link_name = nullterm(file_data)
  1744.           else
  1745.              if long_name then
  1746.                 header.name = long_name
  1747.                 long_name = nil
  1748.              end
  1749.              if long_link_name then
  1750.                 header.name = long_link_name
  1751.                 long_link_name = nil
  1752.              end
  1753.           end
  1754.           local pathname = dir.path(destdir, header.name)
  1755.          
  1756.           if header.typeflag == "directory" then
  1757.              local ok, err = fs.makeDir(pathname)
  1758.              if not ok and not fs.combine then return nil, err end
  1759.           elseif header.typeflag == "file" then
  1760.              local dirname = dir.dir_name(pathname)
  1761.              if dirname ~= "" then
  1762.                 local ok, err = fs.makeDir(dirname)
  1763.                 if not ok and not fs.combine then return nil, err end
  1764.              end
  1765.              local file_handle = io.open(pathname, "wb")
  1766.              if not computercraft then
  1767.                 file_handle:write(file_data)
  1768.              else
  1769.                 for i = 1, #file_data do
  1770.                     local c = file_data:sub(i,i)
  1771.                     file_handle:write(c:byte())
  1772.                 end
  1773.              end
  1774.              file_handle:close()
  1775.              --fs.set_time(pathname, header.mtime)
  1776.              if fs.chmod then
  1777.                 fs.chmod(pathname, header.mode)
  1778.              end
  1779.           end
  1780.           --[[
  1781.           for k,v in pairs(header) do
  1782.              util.printout("[\""..tostring(k).."\"] = "..(type(v)=="number" and v or "\""..v:gsub("%z", "\\0").."\""))
  1783.           end
  1784.           util.printout()
  1785.           --]]
  1786.        end
  1787.        tar_handle:close()
  1788.        return true
  1789.     end
  1790.  
  1791.     return tar
  1792. end
  1793. function gunziplua()
  1794.     local assert = assert
  1795.     local error = error
  1796.     local ipairs = ipairs
  1797.     local xpcall = xpcall
  1798.     local type = type
  1799.     local io = io
  1800.     local os = os
  1801.     local string = string
  1802.     --local debug = require "debug"
  1803.     --os.loadAPI('debug')
  1804.     if not debug then
  1805.         debug = {}
  1806.         debug.traceback = function() return 1 end
  1807.     end
  1808.     local tar = untar()
  1809.     local debug_traceback = debug.traceback
  1810.     local _G = _G
  1811.  
  1812.     --local DEFLATE = require "compress.deflatelua"
  1813.     local DEFLATE = deflatelua()
  1814.  
  1815.     --local OptionParser = require "pythonic.optparse" . OptionParser
  1816.     local OptionParser = optparse().OptionParser
  1817.  
  1818.     local version = '0.1'
  1819.  
  1820.  
  1821.     local function runtime_assert(val, msg)
  1822.       if not val then error({msg}, val) end
  1823.       return val
  1824.     end
  1825.  
  1826.  
  1827.     local function runtime_error(s, level)
  1828.       level = level or 1
  1829.       error({s}, level+1)
  1830.     end
  1831.  
  1832.  
  1833.     local function file_exists(filename)
  1834.       local fh = io.open(filename)
  1835.       if fh then fh:close(); return true end
  1836.       return false
  1837.     end
  1838.  
  1839.  
  1840.     -- Run gunzip command, given command-line arguments.
  1841.     local function call(...)
  1842.       local opt = OptionParser{usage="%prog [options] [gzip-file...]",
  1843.                                version=string.format("gunzip %s", version),
  1844.                                add_help_option=false}
  1845.       opt.add_option{"-h", "--help", action="store_true", dest="help",
  1846.                      help="give this help"}
  1847.       opt.add_option{
  1848.         "-c", "--stdout", dest="stdout", action="store_true",
  1849.         help="write on standard output, keep original files unchanged"}
  1850.       opt.add_option{
  1851.         "-f", "--force", dest="force", action="store_true",
  1852.         help="force overwrite of output file"}
  1853.       opt.add_option{
  1854.         "--disable-crc", dest="disable_crc", action="store_true",
  1855.         help="skip CRC check (faster performance)"}
  1856.       opt.add_option{"-b", "--decode-base64", dest="base64", action="store_true",
  1857.         help="decode file from base64 before decompression"}
  1858.       opt.add_option{"-x", "--untar", dest="untar", metavar="DIR",
  1859.         help="untars the input file into the specified directory"}
  1860.      
  1861.       local options, args = opt.parse_args()
  1862.       local gzipfiles = args
  1863.  
  1864.       if options.help then
  1865.         opt.print_help()
  1866.         os.exit()
  1867.       end
  1868.       if options.untar then
  1869.         local out_dir = options.untar
  1870.         if out_dir == "" then
  1871.             out_dir = "."
  1872.         end
  1873.         for _, my_file in pairs(gzipfiles) do
  1874.             local res, err = tar.untar(my_file,out_dir)
  1875.             if err then
  1876.                 error(err)
  1877.             end
  1878.         end
  1879.         gzipfiles = {}
  1880.         os.exit()
  1881.       end
  1882.       local ok, err = xpcall(function()
  1883.         local outfile_of = {}
  1884.         local out_of = {}
  1885.  
  1886.         for _,gzipfile in ipairs(gzipfiles) do
  1887.           local base = gzipfile:match('(.+)%.[gG][zZ]$')
  1888.           if not base then
  1889.             runtime_error(gzipfile .. ': unknown suffix')
  1890.           end
  1891.           if (options.base64) then
  1892.               local fh1 = gzipfile and runtime_assert(io.open(gzipfile, 'r')) or assert(io.stdin)
  1893.               local content = fh1:read("*a")
  1894.               fh1:close()
  1895.               local newfile = gzipfile .. ".decode.gz"
  1896.               content = string.gsub(content, "%s", "")
  1897.               local decoded = from_base64(content)
  1898.                 if not computercraft then
  1899.                     local fh2 = newfile and runtime_assert(io.open(newfile, 'wb'))
  1900.                     fh2:write(decoded)
  1901.                     fh2:close()
  1902.                 else
  1903.                     local fh2 = io.open(newfile, 'wb')
  1904.                     for i=1, #decoded do
  1905.                       local b = string.byte(decoded:sub(i, i))
  1906.                       fh2:write(b+0)
  1907.                     end
  1908.                     fh2:close()
  1909.                 end
  1910.               gzipfile = newfile
  1911.               gzipfiles[_] = newfile
  1912.           end
  1913.           outfile_of[gzipfile] = base
  1914.  
  1915.           out_of[gzipfile] =
  1916.             (options.stdout or not gzipfile) and assert(io.stdout)
  1917.             or outfile_of[gzipfile]
  1918.  
  1919.           if type(out_of[gzipfile]) == 'string' then
  1920.             if file_exists(out_of[gzipfile]) then
  1921.               io.stderr:write(out_of[gzipfile] ..
  1922.                 ' already exists; do you wish to overwrite(y or n)? ')
  1923.               if not io.stdin:read'*l':match'^[yY]' then
  1924.                 runtime_error 'not overwritten'
  1925.               end
  1926.             end
  1927.           end
  1928.         end
  1929.  
  1930.         for _,gzipfile in ipairs(gzipfiles) do
  1931.           local fh = gzipfile and runtime_assert(io.open(gzipfile, 'rb'))
  1932.                      or assert(io.stdin)
  1933.           local ofh = type(out_of[gzipfile]) == 'string' and
  1934.             runtime_assert(io.open(out_of[gzipfile], 'wb'))
  1935.             or out_of[gzipfile]
  1936.           DEFLATE.gunzip {input=fh, output=ofh,
  1937.             disable_crc=options.disable_crc}
  1938.             fh:close()
  1939.             ofh:close()
  1940.         end
  1941.         if not options.stdout then
  1942.           for _,gzipfile in ipairs(gzipfiles) do
  1943.             assert(os.remove(gzipfile))
  1944.           end
  1945.         end
  1946.        
  1947.       end, debug_traceback)
  1948.       if not ok then
  1949.         if type(err) == 'table' then err = err[1] end
  1950.         io.stderr:write('error: ' .. err, '\n')
  1951.       end
  1952.     end
  1953.  
  1954.  
  1955.     return call
  1956. end
  1957.  
  1958. --[[
  1959. -- gunziplua command-line utility
  1960. package.path = '../lua-digest-crc32lua/lmod/?.lua;' .. package.path
  1961. package.path = '../lua-pythonic-optparse/lmod/?.lua;' .. package.path
  1962. package.path = '../lua-bit-numberlua/lmod/?.lua;' .. package.path
  1963. package.path = 'lmod/?.lua;' .. package.path
  1964. --require 'bin.gunziplua' (...)
  1965. --]]
  1966. local mod0000 = gunziplua()(...)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement