Guest User

zlua

a guest
May 14th, 2020
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.38 KB | None | 0 0
  1. --[[----------------------------------------------------------------------------
  2.     LZSS - encoder / decoder
  3.     This is free and unencumbered software released into the public domain.
  4.     Anyone is free to copy, modify, publish, use, compile, sell, or
  5.     distribute this software, either in source code form or as a compiled
  6.     binary, for any purpose, commercial or non-commercial, and by any
  7.     means.
  8.     In jurisdictions that recognize copyright laws, the author or authors
  9.     of this software dedicate any and all copyright interest in the
  10.     software to the public domain. We make this dedication for the benefit
  11.     of the public at large and to the detriment of our heirs and
  12.     successors. We intend this dedication to be an overt act of
  13.     relinquishment in perpetuity of all present and future rights to this
  14.     software under copyright law.
  15.     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16.     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17.     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  18.     IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19.     OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20.     ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21.     OTHER DEALINGS IN THE SOFTWARE.
  22.     For more information, please refer to <http://unlicense.org/>
  23. --]]----------------------------------------------------------------------------
  24. --------------------------------------------------------------------------------
  25. local M = {}
  26. local string, table = string, table
  27.  
  28. --------------------------------------------------------------------------------
  29. local POS_BITS = 12
  30. local LEN_BITS = 16 - POS_BITS
  31. local POS_SIZE = 1 << POS_BITS
  32. local LEN_SIZE = 1 << LEN_BITS
  33. local LEN_MIN = 3
  34.  
  35. --------------------------------------------------------------------------------
  36. function M.compress(input)
  37.     local offset, output = 1, {}
  38.     local window = ''
  39.  
  40.     local function search()
  41.         for i = LEN_SIZE + LEN_MIN - 1, LEN_MIN, -1 do
  42.             local str = string.sub(input, offset, offset + i - 1)
  43.             local pos = string.find(window, str, 1, true)
  44.             if pos then
  45.                 return pos, str
  46.             end
  47.         end
  48.     end
  49.  
  50.     while offset <= #input do
  51.         local flags, buffer = 0, {}
  52.  
  53.         for i = 0, 7 do
  54.             if offset <= #input then
  55.                 local pos, str = search()
  56.                 if pos and #str >= LEN_MIN then
  57.                     local tmp = ((pos - 1) << LEN_BITS) | (#str - LEN_MIN)
  58.                     buffer[#buffer + 1] = string.pack('>I2', tmp)
  59.                 else
  60.                     flags = flags | (1 << i)
  61.                     str = string.sub(input, offset, offset)
  62.                     buffer[#buffer + 1] = str
  63.                 end
  64.                 window = string.sub(window .. str, -POS_SIZE)
  65.                 offset = offset + #str
  66.             else
  67.                 break
  68.             end
  69.         end
  70.  
  71.         if #buffer > 0 then
  72.             output[#output + 1] = string.char(flags)
  73.             output[#output + 1] = table.concat(buffer)
  74.         end
  75.     end
  76.  
  77.     return table.concat(output)
  78. end
  79.  
  80. --------------------------------------------------------------------------------
  81. function M.decompress(input)
  82.     local offset, output = 1, {}
  83.     local window = ''
  84.  
  85.     while offset <= #input do
  86.         local flags = string.byte(input, offset)
  87.         offset = offset + 1
  88.  
  89.         for i = 1, 8 do
  90.             local str = nil
  91.             if (flags & 1) ~= 0 then
  92.                 if offset <= #input then
  93.                     str = string.sub(input, offset, offset)
  94.                     offset = offset + 1
  95.                 end
  96.             else
  97.                 if offset + 1 <= #input then
  98.                     local tmp = string.unpack('>I2', input, offset)
  99.                     offset = offset + 2
  100.                     local pos = (tmp >> LEN_BITS) + 1
  101.                     local len = (tmp & (LEN_SIZE - 1)) + LEN_MIN
  102.                     str = string.sub(window, pos, pos + len - 1)
  103.                 end
  104.             end
  105.             flags = flags >> 1
  106.             if str then
  107.                 output[#output + 1] = str
  108.                 window = string.sub(window .. str, -POS_SIZE)
  109.             end
  110.         end
  111.     end
  112.  
  113.     return table.concat(output)
  114. end
  115.  
  116. return {
  117.     mode = "rb",
  118.     loadfile = function(file, env)
  119.         local hand = package.filesystem.open(file, "rb")
  120.         local data = ""
  121.         local lc = " "
  122.         while lc and lc ~= "" do
  123.             lc = hand:read(math.huge)
  124.             data = data .. (lc or "")
  125.         end
  126.         hand:close()
  127.         return load(M.decompress(data:sub(5)), "="..file, "t", env)
  128.     end,
  129.     load = function(hand, env)
  130.         local data = ""
  131.         local lc = " "
  132.         while lc and lc ~= "" do
  133.             lc = hand:read(math.huge)
  134.             data = data .. (lc or "")
  135.         end
  136.         hand:close()
  137.         return load(M.decompress(data:sub(5)), "="..os.getenv("_"), env)
  138.     end,
  139.     info = function()
  140.         print("    Loads LZSS compressed Lua files.")
  141.     end,
  142.     version = "1.0"
  143. }
Add Comment
Please, Sign In to add comment