From 58b7dfe85b124eaccc2d2f1018d9e4bc881acbbd Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Thu, 5 Dec 2019 19:41:53 +0100 Subject: 2019-12-05 18:54:00 --- tex/context/base/mkiv/l-gzip.lua | 191 ++++++++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 64 deletions(-) (limited to 'tex/context/base/mkiv/l-gzip.lua') diff --git a/tex/context/base/mkiv/l-gzip.lua b/tex/context/base/mkiv/l-gzip.lua index 31466bde8..f141b5ebb 100644 --- a/tex/context/base/mkiv/l-gzip.lua +++ b/tex/context/base/mkiv/l-gzip.lua @@ -5,39 +5,77 @@ if not modules then modules = { } end modules ['l-gzip'] = { license = "see context related readme files" } -if gzip then +-- We only have a few official methods here: +-- +-- local decompressed = gzip.load (filename) +-- local resultsize = gzip.save (filename,compresslevel) +-- local compressed = gzip.compress (str,compresslevel) +-- local decompressed = gzip.decompress (str) +-- local iscompressed = gzip.compressed (str) +-- local suffix, okay = gzip.suffix (filename) +-- +-- In LuaMetaTeX we have only xzip which implements a very few methods: +-- +-- compress (str,level,method,window,memory,strategy) +-- decompress (str,window) +-- adler32 (str,checksum) +-- crc32 (str,checksum) +-- +-- Special window values are: +-- +-- flate : - 15 +-- zlib : 15 +-- gzip : 15 | 16 +-- auto : 15 | 32 + +gzip = gzip or { } -- so in luatex we keep the old ones too + +if not zlib then + zlib = xzip -- in luametatex we shadow the old one +elseif not xzip then + xzip = zlib +end + +if zlib then - local suffix, suffixes = file.suffix, file.suffixes + local suffix = file.suffix + local suffixes = file.suffixes + local find = string.find + local openfile = io.open + + local gzipwindow = 15 + 16 -- +16: gzip, +32: gzip|zlib + local gziplevel = 3 + local identifier = "^\x1F\x8B\x08" + + local compress = zlib.compress + local decompress = zlib.decompress function gzip.load(filename) - local f = io.open(filename,"rb") + local f = openfile(filename,"rb") if not f then -- invalid file - elseif suffix(filename) == "gz" then - f:close() - local g = gzip.open(filename,"rb") - if g then - local str = g:read("*all") - g:close() - return str - end else - local str = f:read("*all") + local data = f:read("*all") f:close() - return str + if data and data ~= "" then + if suffix(filename) == "gz" then + data = decompress(data,gzipwindow) + end + return data + end end end - function gzip.save(filename,data) + function gzip.save(filename,data,level) if suffix(filename) ~= "gz" then filename = filename .. ".gz" end - local f = io.open(filename,"wb") + local f = openfile(filename,"wb") if f then - local s = zlib.compress(data or "",9,nil,15+16) - f:write(s) + data = compress(data or "",level or gziplevel,nil,gzipwindow) + f:write(data) f:close() - return #s + return #data end end @@ -47,24 +85,6 @@ if gzip then return suffix, gzipped end -else - - -- todo: fallback on flate - -end - -if flate then - - local type = type - local find = string.find - - local compress = flate.gz_compress - local decompress = flate.gz_decompress - - local absmax = 128*1024*1024 - local initial = 64*1024 - local identifier = "^\x1F\x8B\x08" - function gzip.compressed(s) return s and find(s,identifier) end @@ -72,46 +92,89 @@ if flate then function gzip.compress(s,level) if s and not find(s,identifier) then -- the find check might go away if not level then - level = 3 + level = gziplevel elseif level <= 0 then return s elseif level > 9 then level = 9 end - return compress(s,level) or s + return compress(s,level or gziplevel,nil,gzipwindow) or s end end - function gzip.decompress(s,size,iterate) + function gzip.decompress(s) if s and find(s,identifier) then - if type(size) ~= "number" then - size = initial - end - if size > absmax then - size = absmax - end - if type(iterate) == "number" then - max = size * iterate - elseif iterate == nil or iterate == true then - iterate = true - max = absmax - end - if max > absmax then - max = absmax - end - while true do - local d = decompress(s,size) - if d then - return d - end - size = 2 * size - if not iterate or size > max then - return false - end - end + return decompress(s,gzipwindow) else return s end end end + +-- In luametatex we can use this one but it doesn't look like there wil be stream +-- support so for now we still use zlib (the performance difference is not that +-- spectacular in our usage. + +-- if flate then +-- +-- local type = type +-- local find = string.find +-- +-- local compress = flate.gz_compress +-- local decompress = flate.gz_decompress +-- +-- local absmax = 128*1024*1024 +-- local initial = 64*1024 +-- local identifier = "^\x1F\x8B\x08" +-- +-- function gzip.compressed(s) +-- return s and find(s,identifier) +-- end +-- +-- function gzip.compress(s,level) +-- if s and not find(s,identifier) then -- the find check might go away +-- if not level then +-- level = 3 +-- elseif level <= 0 then +-- return s +-- elseif level > 9 then +-- level = 9 +-- end +-- return compress(s,level) or s +-- end +-- end +-- +-- function gzip.decompress(s,size,iterate) +-- if s and find(s,identifier) then +-- if type(size) ~= "number" then +-- size = initial +-- end +-- if size > absmax then +-- size = absmax +-- end +-- if type(iterate) == "number" then +-- max = size * iterate +-- elseif iterate == nil or iterate == true then +-- iterate = true +-- max = absmax +-- end +-- if max > absmax then +-- max = absmax +-- end +-- while true do +-- local d = decompress(s,size) +-- if d then +-- return d +-- end +-- size = 2 * size +-- if not iterate or size > max then +-- return false +-- end +-- end +-- else +-- return s +-- end +-- end +-- +-- end -- cgit v1.2.3