diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex/lualibs/lualibs-util-sac.lua')
-rw-r--r-- | Master/texmf-dist/tex/luatex/lualibs/lualibs-util-sac.lua | 582 |
1 files changed, 582 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-sac.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-sac.lua new file mode 100644 index 00000000000..36daef81673 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-sac.lua @@ -0,0 +1,582 @@ +if not modules then modules = { } end modules ['util-sac'] = { + version = 1.001, + optimize = true, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- experimental string access (some 3 times faster than file access when messing +-- with bytes) + +local byte, sub = string.byte, string.sub +local tonumber = tonumber + +utilities = utilities or { } +local streams = { } +utilities.streams = streams + +function streams.open(filename,zerobased) + local f = filename and io.loaddata(filename) + if f then + return { f, 1, #f, zerobased or false } + end +end + +function streams.openstring(f,zerobased) + if f then + return { f, 1, #f, zerobased or false } + end +end + +function streams.getstring(f) + if f then + return f[1] + end +end + +function streams.close() + -- dummy +end + +function streams.size(f) + return f and f[3] or 0 +end + +streams.getsize = streams.size + +function streams.setposition(f,i) + if f[4] then + -- zerobased + if i <= 0 then + f[2] = 1 + else + f[2] = i + 1 + end + else + if i <= 1 then + f[2] = 1 + else + f[2] = i + end + end +end + +function streams.getposition(f) + if f[4] then + -- zerobased + return f[2] - 1 + else + return f[2] + end +end + +function streams.look(f,n,chars) + local b = f[2] + local e = b + n - 1 + if chars then + return sub(f[1],b,e) + else + return byte(f[1],b,e) + end +end + +function streams.skip(f,n) + f[2] = f[2] + n +end + +function streams.readbyte(f) + local i = f[2] + f[2] = i + 1 + return byte(f[1],i) +end + +function streams.readbytes(f,n) + local i = f[2] + local j = i + n + f[2] = j + return byte(f[1],i,j-1) +end + +function streams.readbytetable(f,n) + local i = f[2] + local j = i + n + f[2] = j + return { byte(f[1],i,j-1) } +end + +function streams.skipbytes(f,n) + f[2] = f[2] + n +end + +function streams.readchar(f) + local i = f[2] + f[2] = i + 1 + return sub(f[1],i,i) +end + +function streams.readstring(f,n) + local i = f[2] + local j = i + n + f[2] = j + return sub(f[1],i,j-1) +end + +function streams.readinteger1(f) -- one byte + local i = f[2] + f[2] = i + 1 + local n = byte(f[1],i) + if n >= 0x80 then + return n - 0x100 + else + return n + end +end + +streams.readcardinal1 = streams.readbyte -- one byte +streams.readcardinal = streams.readcardinal1 +streams.readinteger = streams.readinteger1 + +function streams.readcardinal2(f) + local i = f[2] + local j = i + 1 + f[2] = j + 1 + local a, b = byte(f[1],i,j) + return 0x100 * a + b +end + +function streams.readcardinal2le(f) + local i = f[2] + local j = i + 1 + f[2] = j + 1 + local b, a = byte(f[1],i,j) + return 0x100 * a + b +end + +function streams.readinteger2(f) + local i = f[2] + local j = i + 1 + f[2] = j + 1 + local a, b = byte(f[1],i,j) + if a >= 0x80 then + return 0x100 * a + b - 0x10000 + else + return 0x100 * a + b + end +end + +function streams.readinteger2le(f) + local i = f[2] + local j = i + 1 + f[2] = j + 1 + local b, a = byte(f[1],i,j) + if a >= 0x80 then + return 0x100 * a + b - 0x10000 + else + return 0x100 * a + b + end +end + +function streams.readcardinal3(f) + local i = f[2] + local j = i + 2 + f[2] = j + 1 + local a, b, c = byte(f[1],i,j) + return 0x10000 * a + 0x100 * b + c +end + +function streams.readcardinal3le(f) + local i = f[2] + local j = i + 2 + f[2] = j + 1 + local c, b, a = byte(f[1],i,j) + return 0x10000 * a + 0x100 * b + c +end + +function streams.readinteger3(f) + local i = f[2] + local j = i + 3 + f[2] = j + 1 + local a, b, c = byte(f[1],i,j) + if a >= 0x80 then + return 0x10000 * a + 0x100 * b + c - 0x1000000 + else + return 0x10000 * a + 0x100 * b + c + end +end + +function streams.readinteger3le(f) + local i = f[2] + local j = i + 3 + f[2] = j + 1 + local c, b, a = byte(f[1],i,j) + if a >= 0x80 then + return 0x10000 * a + 0x100 * b + c - 0x1000000 + else + return 0x10000 * a + 0x100 * b + c + end +end + +function streams.readcardinal4(f) + local i = f[2] + local j = i + 3 + f[2] = j + 1 + local a, b, c, d = byte(f[1],i,j) + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d +end + +function streams.readcardinal4le(f) + local i = f[2] + local j = i + 3 + f[2] = j + 1 + local d, c, b, a = byte(f[1],i,j) + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d +end + +function streams.readinteger4(f) + local i = f[2] + local j = i + 3 + f[2] = j + 1 + local a, b, c, d = byte(f[1],i,j) + if a >= 0x80 then + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000 + else + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d + end +end + +function streams.readinteger4le(f) + local i = f[2] + local j = i + 3 + f[2] = j + 1 + local d, c, b, a = byte(f[1],i,j) + if a >= 0x80 then + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000 + else + return 0x1000000 * a + 0x10000 * b + 0x100 * c + d + end +end + +function streams.readfixed2(f) + local i = f[2] + local j = i + 1 + f[2] = j + 1 + local n1, n2 = byte(f[1],i,j) + if n1 >= 0x80 then + n1 = n1 - 0x100 + end + return n1 + n2/0xFF +end + +function streams.readfixed4(f) + local i = f[2] + local j = i + 3 + f[2] = j + 1 + local a, b, c, d = byte(f[1],i,j) + local n1 = 0x100 * a + b + local n2 = 0x100 * c + d + if n1 >= 0x8000 then + n1 = n1 - 0x10000 + end + return n1 + n2/0xFFFF +end + +if bit32 then + + local extract = bit32.extract + local band = bit32.band + + function streams.read2dot14(f) + local i = f[2] + local j = i + 1 + f[2] = j + 1 + local a, b = byte(f[1],i,j) + if a >= 0x80 then + local n = -(0x100 * a + b) + return - (extract(n,14,2) + (band(n,0x3FFF) / 16384.0)) + else + local n = 0x100 * a + b + return (extract(n,14,2) + (band(n,0x3FFF) / 16384.0)) + end + end + +end + +function streams.skipshort(f,n) + f[2] = f[2] + 2*(n or 1) +end + +function streams.skiplong(f,n) + f[2] = f[2] + 4*(n or 1) +end + +if sio and sio.readcardinal2 then + + local readcardinal1 = sio.readcardinal1 + local readcardinal2 = sio.readcardinal2 + local readcardinal3 = sio.readcardinal3 + local readcardinal4 = sio.readcardinal4 + local readinteger1 = sio.readinteger1 + local readinteger2 = sio.readinteger2 + local readinteger3 = sio.readinteger3 + local readinteger4 = sio.readinteger4 + local readfixed2 = sio.readfixed2 + local readfixed4 = sio.readfixed4 + local read2dot14 = sio.read2dot14 + local readbytes = sio.readbytes + local readbytetable = sio.readbytetable + + function streams.readcardinal1(f) + local i = f[2] + f[2] = i + 1 + return readcardinal1(f[1],i) + end + function streams.readcardinal2(f) + local i = f[2] + f[2] = i + 2 + return readcardinal2(f[1],i) + end + function streams.readcardinal3(f) + local i = f[2] + f[2] = i + 3 + return readcardinal3(f[1],i) + end + function streams.readcardinal4(f) + local i = f[2] + f[2] = i + 4 + return readcardinal4(f[1],i) + end + function streams.readinteger1(f) + local i = f[2] + f[2] = i + 1 + return readinteger1(f[1],i) + end + function streams.readinteger2(f) + local i = f[2] + f[2] = i + 2 + return readinteger2(f[1],i) + end + function streams.readinteger3(f) + local i = f[2] + f[2] = i + 3 + return readinteger3(f[1],i) + end + function streams.readinteger4(f) + local i = f[2] + f[2] = i + 4 + return readinteger4(f[1],i) + end + function streams.readfixed2(f) -- needs recent luatex + local i = f[2] + f[2] = i + 2 + return readfixed2(f[1],i) + end + function streams.readfixed4(f) -- needs recent luatex + local i = f[2] + f[2] = i + 4 + return readfixed4(f[1],i) + end + function streams.read2dot14(f) + local i = f[2] + f[2] = i + 2 + return read2dot14(f[1],i) + end + function streams.readbytes(f,n) + local i = f[2] + local s = f[3] + local p = i + n + if p > s then + f[2] = s + 1 + else + f[2] = p + end + return readbytes(f[1],i,n) + end + function streams.readbytetable(f,n) + local i = f[2] + local s = f[3] + local p = i + n + if p > s then + f[2] = s + 1 + else + f[2] = p + end + return readbytetable(f[1],i,n) + end + + streams.readbyte = streams.readcardinal1 + streams.readsignedbyte = streams.readinteger1 + streams.readcardinal = streams.readcardinal1 + streams.readinteger = streams.readinteger1 + +end + +if sio and sio.readcardinaltable then + + local readcardinaltable = sio.readcardinaltable + local readintegertable = sio.readintegertable + + function utilities.streams.readcardinaltable(f,n,b) + local i = f[2] + local s = f[3] + local p = i + n * b + if p > s then + f[2] = s + 1 + else + f[2] = p + end + return readcardinaltable(f[1],i,n,b) + end + + function utilities.streams.readintegertable(f,n,b) + local i = f[2] + local s = f[3] + local p = i + n * b + if p > s then + f[2] = s + 1 + else + f[2] = p + end + return readintegertable(f[1],i,n,b) + end + +else + + local readcardinal1 = streams.readcardinal1 + local readcardinal2 = streams.readcardinal2 + local readcardinal3 = streams.readcardinal3 + local readcardinal4 = streams.readcardinal4 + + function streams.readcardinaltable(f,n,b) + local i = f[2] + local s = f[3] + local p = i + n * b + if p > s then + f[2] = s + 1 + else + f[2] = p + end + local t = { } + if b == 1 then for i=1,n do t[i] = readcardinal1(f[1],i) end + elseif b == 2 then for i=1,n do t[i] = readcardinal2(f[1],i) end + elseif b == 3 then for i=1,n do t[i] = readcardinal3(f[1],i) end + elseif b == 4 then for i=1,n do t[i] = readcardinal4(f[1],i) end end + return t + end + + local readinteger1 = streams.readinteger1 + local readinteger2 = streams.readinteger2 + local readinteger3 = streams.readinteger3 + local readinteger4 = streams.readinteger4 + + function streams.readintegertable(f,n,b) + local i = f[2] + local s = f[3] + local p = i + n * b + if p > s then + f[2] = s + 1 + else + f[2] = p + end + local t = { } + if b == 1 then for i=1,n do t[i] = readinteger1(f[1],i) end + elseif b == 2 then for i=1,n do t[i] = readinteger2(f[1],i) end + elseif b == 3 then for i=1,n do t[i] = readinteger3(f[1],i) end + elseif b == 4 then for i=1,n do t[i] = readinteger4(f[1],i) end end + return t + end + +end + +-- For practical reasons we put this here. It's less efficient but ok when we don't +-- have much access. + +do + + local files = utilities.files + + if files then + + local openfile = files.open + local openstream = streams.open + local openstring = streams.openstring + + local setmetatable = setmetatable + + function io.newreader(str,method) + local f, m + if method == "string" then + f = openstring(str,true) + m = streams + elseif method == "stream" then + f = openstream(str,true) + m = streams + else + f = openfile(str,"rb") + m = files + end + if f then + local t = { } + setmetatable(t, { + __index = function(t,k) + local r = m[k] + if k == "close" then + -- maybe use __toclose + if f then + m.close(f) + f = nil + end + return function() end + elseif r then + local v = function(_,a,b) return r(f,a,b) end + t[k] = v + return v + else + print("unknown key",k) + end + end + } ) + return t + end + end + + end + +end + +if bit32 and not streams.tocardinal1 then + + local extract = bit32.extract + local char = string.char + + streams.tocardinal1 = char + function streams.tocardinal2(n) return char(extract( 8,8),extract( 0,8)) end + function streams.tocardinal3(n) return char(extract(16,8),extract( 8,8),extract(0,8)) end + function streams.tocardinal4(n) return char(extract(24,8),extract(16,8),extract(8,8),extract(0,8)) end + + streams.tocardinal1le = char + function streams.tocardinal2le(n) return char(extract(0,8),extract(8,8)) end + function streams.tocardinal3le(n) return char(extract(0,8),extract(8,8),extract(16,8)) end + function streams.tocardinal4le(n) return char(extract(0,8),extract(8,8),extract(16,8),extract(24,8)) end + +end + +if not streams.readcstring then + + local readchar = streams.readchar + local concat = table.concat + + function streams.readcstring(f) + local t = { } + while true do + local c = readchar(f) + if c and c ~= "\0" then + t[#t+1] = c + else + return concat(t) + end + end + end + +end |