Operating system for OpenComputers
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

72 行
1.3KB

  1. local lz = require "lzss"
  2. local buffer = require "buffer"
  3. lz16 = {}
  4. local function cint(n,l)
  5. local t={}
  6. for i = 0, 7 do
  7. t[i+1] = (n >> (i * 8)) & 0xFF
  8. end
  9. return string.reverse(string.char(table.unpack(t)):sub(1,l))
  10. end
  11. local function toint(s)
  12. local n = 0
  13. local i = 1
  14. for p in s:gmatch(".") do
  15. n = n << 8
  16. n = n | string.byte(p)
  17. i=i+1
  18. end
  19. return n
  20. end
  21. local function readBuffer(fi)
  22. local stream = {}
  23. if fi:read(4) ~= "lz16" then
  24. return false, "not an lz16 archive"
  25. end
  26. function stream.read()
  27. local len = toint(fi:read(2) or "\0\0")
  28. if len < 1 then
  29. return nil
  30. end
  31. coroutine.yield()
  32. return lz.decompress(fi:read(len))
  33. end
  34. function stream.close()
  35. fi:close()
  36. end
  37. return buffer.new("rb",stream)
  38. end
  39. local function writeBuffer(fo)
  40. local stream = {}
  41. function stream:write(data)
  42. local cblock = lz.compress(data)
  43. fo:write(cint(cblock:len(),2)..cblock)
  44. return cblock:len()+2
  45. end
  46. function stream.close()
  47. fo:close()
  48. end
  49. fo:write("lz16") -- write header
  50. return buffer.new("wb",stream)
  51. end
  52. function lz16.buffer(stream)
  53. if stream.mode.w then
  54. return writeBuffer(stream)
  55. end
  56. return readBuffer(stream)
  57. end
  58. function lz16.open(fname, mode)
  59. local f = io.open(fname, mode)
  60. if not f then return false end
  61. f.mode.b = true
  62. return lz16.buffer(f)
  63. end
  64. return lz16