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" } 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.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 local readcardinal1 = sio.readcardinal1 local readcardinal2 = sio.readcardinal2 local readcardinal3 = sio.readcardinal3 local readcardinal4 = sio.readcardinal4 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 local readcardinal1le = sio.readcardinal1le local readcardinal2le = sio.readcardinal2le local readcardinal3le = sio.readcardinal3le local readcardinal4le = sio.readcardinal4le function streams.readcardinal1le(f) local i = f[2] f[2] = i + 1 return readcardinal1le(f[1],i) end function streams.readcardinal2le(f) local i = f[2] f[2] = i + 2 return readcardinal2le(f[1],i) end function streams.readcardinal3le(f) local i = f[2] f[2] = i + 3 return readcardinal3le(f[1],i) end function streams.readcardinal4le(f) local i = f[2] f[2] = i + 4 return readcardinal4le(f[1],i) end local readinteger1 = sio.readinteger1 local readinteger2 = sio.readinteger2 local readinteger3 = sio.readinteger3 local readinteger4 = sio.readinteger4 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 local readinteger1le = sio.readinteger1le local readinteger2le = sio.readinteger2le local readinteger3le = sio.readinteger3le local readinteger4le = sio.readinteger4le function streams.readinteger1le(f) local i = f[2] f[2] = i + 1 return readinteger1le(f[1],i) end function streams.readinteger2le(f) local i = f[2] f[2] = i + 2 return readinteger2le(f[1],i) end function streams.readinteger3le(f) local i = f[2] f[2] = i + 3 return readinteger3le(f[1],i) end function streams.readinteger4le(f) local i = f[2] f[2] = i + 4 return readinteger4le(f[1],i) end local readfixed2 = sio.readfixed2 local readfixed4 = sio.readfixed4 local read2dot14 = sio.read2dot14 function streams.readfixed2(f) local i = f[2] f[2] = i + 2 return readfixed2(f[1],i) end function streams.readfixed4(f) 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 local readcstring = sio.readcstring local readcline = sio.readcline function streams.readcstring(f) local s, p = readcstring(f[1],f[2]) f[2] = p return s end function streams.readcline(f,n) local s, p = readcline(f[1],f[2]) f[2] = p return s end local readbytes = sio.readbytes local readbytetable = sio.readbytetable 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.readcardinal1 = streams.readcardinal1 streams.readcardinal = streams.readcardinal1 streams.readinteger = streams.readinteger1 streams.readinteger1 = streams.readinteger1 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 -- For practical reasons we put this here. It's less efficient but ok when we don't -- have much access. 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 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 streams.tocardinal1 = sio.tocardinal1 streams.tocardinal2 = sio.tocardinal2 streams.tocardinal3 = sio.tocardinal3 streams.tocardinal4 = sio.tocardinal4 streams.tocardinal1le = sio.tocardinal1le streams.tocardinal2le = sio.tocardinal2le streams.tocardinal3le = sio.tocardinal3le streams.tocardinal4le = sio.tocardinal4le