diff --git a/lz16/liblz16.lua b/lz16/liblz16.lua new file mode 100644 index 0000000..140c4c1 --- /dev/null +++ b/lz16/liblz16.lua @@ -0,0 +1,78 @@ +local lz = require "lzss" +local buffer = require "buffer" + +lz16 = {} + +local function cint(n,l) + local t={} + for i = 0, 7 do + t[i+1] = (n >> (i * 8)) & 0xFF + end + return string.reverse(string.char(table.unpack(t)):sub(1,l)) +end +local function toint(s) + s=s or "" + local n = 0 + local i = 1 + while true do + local p = s:sub(i,i) + if p == "" then break end + local b = string.byte(p) + n = n << 8 + n = n | b + i=i+1 + end + return n +end + +local function readBuffer(fi) + local stream = {} + if fi:read(4) ~= "lz16" and not tO.f then + return false, "not an lz16 archive" + end + function stream.read() + local len = toint(fi:read(2) or "\0\0") + if len < 1 then + print("nothing") + coroutine.yield() + return nil + end + coroutine.yield() + return lz.decompress(fi:read(len)) + end + function stream.close() + fi:close() + end + return buffer.new("r",stream) +end + +local function writeBuffer(fo) + local stream = {} + function stream:write(data) + local cblock = lz.compress(data) + fo:write(cint(cblock:len(),2)..cblock) + return cblock:len()+2 + end + function stream.close() + fo:close() + end + fo:write("lz16") -- write header + return buffer.new("w",stream) +end + +function lz16.buffer(stream) + if stream.mode.w then + print("write") + return writeBuffer(stream) + end + return readBuffer(stream) +end + +function lz16.open(fname, mode) + local f = io.open(fname, mode) + if not f then return false end + f.mode.b = true + return lz16.buffer(f) +end + +return lz16