util-sac.lmt /size: 8209 b    last modification: 2023-12-21 09:44
1if not modules then modules = { } end modules ['util-sac'] = {
2    version   = 1.001,
3    optimize  = true,
4    comment   = "companion to luat-lib.mkiv",
5    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
6    copyright = "PRAGMA ADE / ConTeXt Development Team",
7    license   = "see context related readme files"
8}
9
10
11local byte, sub = string.byte, string.sub
12local tonumber = tonumber
13
14utilities         = utilities or { }
15local streams     = { }
16utilities.streams = streams
17
18function streams.open(filename,zerobased)
19    local f = filename and io.loaddata(filename)
20    if f then
21        return { f, 1, #f, zerobased or false }
22    end
23end
24
25function streams.openstring(f,zerobased)
26    if f then
27        return { f, 1, #f, zerobased or false }
28    end
29end
30
31function streams.getstring(f)
32    if f then
33        return f[1]
34    end
35end
36
37function streams.close()
38    -- dummy
39end
40
41function streams.size(f)
42    return f and f[3] or 0
43end
44
45streams.getsize = streams.size
46
47function streams.setposition(f,i)
48    if f[4] then
49        -- zerobased
50        if i <= 0 then
51            f[2] = 1
52        else
53            f[2] = i + 1
54        end
55    else
56        if i <= 1 then
57            f[2] = 1
58        else
59            f[2] = i
60        end
61    end
62end
63
64function streams.getposition(f)
65    if f[4] then
66        -- zerobased
67        return f[2] - 1
68    else
69        return f[2]
70    end
71end
72
73function streams.look(f,n,chars)
74    local b = f[2]
75    local e = b + n - 1
76    if chars then
77        return sub(f[1],b,e)
78    else
79        return byte(f[1],b,e)
80    end
81end
82
83function streams.skip(f,n)
84    f[2] = f[2] + n
85end
86
87--
88
89function streams.readbyte(f)
90    local i = f[2]
91    f[2] = i + 1
92    return byte(f[1],i)
93end
94
95function streams.readbytes(f,n)
96    local i = f[2]
97    local j = i + n
98    f[2] = j
99    return byte(f[1],i,j-1)
100end
101
102function streams.readbytetable(f,n)
103    local i = f[2]
104    local j = i + n
105    f[2] = j
106    return { byte(f[1],i,j-1) }
107end
108
109function streams.skipbytes(f,n)
110    f[2] = f[2] + n
111end
112
113function streams.readchar(f)
114    local i = f[2]
115    f[2] = i + 1
116    return sub(f[1],i,i)
117end
118
119function streams.readstring(f,n)
120    local i = f[2]
121    local j = i + n
122    f[2] = j
123    return sub(f[1],i,j-1)
124end
125
126function streams.skipshort(f,n) f[2] = f[2] + 2*(n or 1) end
127function streams.skiplong (f,n) f[2] = f[2] + 4*(n or 1) end
128
129local readcardinal1 = sio.readcardinal1
130local readcardinal2 = sio.readcardinal2
131local readcardinal3 = sio.readcardinal3
132local readcardinal4 = sio.readcardinal4
133
134function streams.readcardinal1(f) local i = f[2] f[2] = i + 1 return readcardinal1(f[1],i) end
135function streams.readcardinal2(f) local i = f[2] f[2] = i + 2 return readcardinal2(f[1],i) end
136function streams.readcardinal3(f) local i = f[2] f[2] = i + 3 return readcardinal3(f[1],i) end
137function streams.readcardinal4(f) local i = f[2] f[2] = i + 4 return readcardinal4(f[1],i) end
138
139local readcardinal1le = sio.readcardinal1le
140local readcardinal2le = sio.readcardinal2le
141local readcardinal3le = sio.readcardinal3le
142local readcardinal4le = sio.readcardinal4le
143
144function streams.readcardinal1le(f) local i = f[2] f[2] = i + 1 return readcardinal1le(f[1],i) end
145function streams.readcardinal2le(f) local i = f[2] f[2] = i + 2 return readcardinal2le(f[1],i) end
146function streams.readcardinal3le(f) local i = f[2] f[2] = i + 3 return readcardinal3le(f[1],i) end
147function streams.readcardinal4le(f) local i = f[2] f[2] = i + 4 return readcardinal4le(f[1],i) end
148
149local readinteger1 = sio.readinteger1
150local readinteger2 = sio.readinteger2
151local readinteger3 = sio.readinteger3
152local readinteger4 = sio.readinteger4
153
154function streams.readinteger1(f) local i = f[2] f[2] = i + 1 return readinteger1(f[1],i) end
155function streams.readinteger2(f) local i = f[2] f[2] = i + 2 return readinteger2(f[1],i) end
156function streams.readinteger3(f) local i = f[2] f[2] = i + 3 return readinteger3(f[1],i) end
157function streams.readinteger4(f) local i = f[2] f[2] = i + 4 return readinteger4(f[1],i) end
158
159local readinteger1le = sio.readinteger1le
160local readinteger2le = sio.readinteger2le
161local readinteger3le = sio.readinteger3le
162local readinteger4le = sio.readinteger4le
163
164function streams.readinteger1le(f) local i = f[2] f[2] = i + 1 return readinteger1le(f[1],i) end
165function streams.readinteger2le(f) local i = f[2] f[2] = i + 2 return readinteger2le(f[1],i) end
166function streams.readinteger3le(f) local i = f[2] f[2] = i + 3 return readinteger3le(f[1],i) end
167function streams.readinteger4le(f) local i = f[2] f[2] = i + 4 return readinteger4le(f[1],i) end
168
169local readfixed2 = sio.readfixed2
170local readfixed4 = sio.readfixed4
171local read2dot14 = sio.read2dot14
172
173function streams.readfixed2(f) local i = f[2] f[2] = i + 2 return readfixed2(f[1],i) end
174function streams.readfixed4(f) local i = f[2] f[2] = i + 4 return readfixed4(f[1],i) end
175function streams.read2dot14(f) local i = f[2] f[2] = i + 2 return read2dot14(f[1],i) end
176
177local readcstring = sio.readcstring
178local readcline   = sio.readcline
179
180function streams.readcstring(f)
181    local s, p = readcstring(f[1],f[2])
182    f[2] = p
183    return s
184end
185
186function streams.readcline(f,n)
187    local s, p = readcline(f[1],f[2])
188    f[2] = p
189    return s
190end
191
192local readbytes     = sio.readbytes
193local readbytetable = sio.readbytetable
194
195function streams.readbytes(f,n)
196    local i = f[2]
197    local s = f[3]
198    local p = i + n
199    if p > s then
200        f[2] = s + 1
201    else
202        f[2] = p
203    end
204    return readbytes(f[1],i,n)
205end
206
207function streams.readbytetable(f,n)
208    local i = f[2]
209    local s = f[3]
210    local p = i + n
211    if p > s then
212        f[2] = s + 1
213    else
214        f[2] = p
215    end
216    return readbytetable(f[1],i,n)
217end
218
219streams.readbyte       = streams.readcardinal1
220streams.readsignedbyte = streams.readinteger1
221streams.readcardinal1  = streams.readcardinal1
222streams.readcardinal   = streams.readcardinal1
223streams.readinteger    = streams.readinteger1
224streams.readinteger1   = streams.readinteger1
225
226local readcardinaltable = sio.readcardinaltable
227local readintegertable  = sio.readintegertable
228
229function utilities.streams.readcardinaltable(f,n,b)
230    local i = f[2]
231    local s = f[3]
232    local p = i + n * b
233    if p > s then
234        f[2] = s + 1
235    else
236        f[2] = p
237    end
238    return readcardinaltable(f[1],i,n,b)
239end
240
241function utilities.streams.readintegertable(f,n,b)
242    local i = f[2]
243    local s = f[3]
244    local p = i +  n * b
245    if p > s then
246        f[2] = s + 1
247    else
248        f[2] = p
249    end
250    return readintegertable(f[1],i,n,b)
251end
252
253-- For practical reasons we put this here. It's less efficient but ok when we don't
254-- have much access.
255
256local files = utilities.files
257
258if files then
259
260    local openfile     = files.open
261    local openstream   = streams.open
262    local openstring   = streams.openstring
263
264    local setmetatable = setmetatable
265
266    function io.newreader(str,method)
267        local f, m
268        if method == "string" then
269            f = openstring(str,true)
270            m = streams
271        elseif method == "stream" then
272            f = openstream(str,true)
273            m = streams
274        else
275            f = openfile(str,"rb")
276            m = files
277        end
278        if f then
279            local t = { }
280            setmetatable(t, {
281                __index = function(t,k)
282                    local r = m[k]
283                    if k == "close" then
284                        if f then
285                            m.close(f)
286                            f = nil
287                        end
288                        return function() end
289                    elseif r then
290                        local v = function(_,a,b) return r(f,a,b) end
291                        t[k] = v
292                        return v
293                    else
294                        print("unknown key",k)
295                    end
296                end
297            } )
298            return t
299        end
300    end
301
302end
303
304streams.tocardinal1   = sio.tocardinal1
305streams.tocardinal2   = sio.tocardinal2
306streams.tocardinal3   = sio.tocardinal3
307streams.tocardinal4   = sio.tocardinal4
308
309streams.tocardinal1le = sio.tocardinal1le
310streams.tocardinal2le = sio.tocardinal2le
311streams.tocardinal3le = sio.tocardinal3le
312streams.tocardinal4le = sio.tocardinal4le
313