summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/l-gzip.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/l-gzip.lua')
-rw-r--r--tex/context/base/mkiv/l-gzip.lua191
1 files changed, 127 insertions, 64 deletions
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