1if not modules then modules = { } end modules ['util-fil'] = {
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
10local tonumber = tonumber
11local byte = string.byte
12local char = string.char
13
14
15
16
17
18
19
20utilities = utilities or { }
21local files = { }
22utilities.files = files
23
24
25
26local zerobased = { }
27
28function files.open(filename,zb)
29 local f = io.open(filename,"rb")
30 if f then
31 zerobased[f] = zb or false
32 end
33 return f
34end
35
36function files.close(f)
37 zerobased[f] = nil
38 f:close()
39end
40
41function files.size(f)
42 local current = f:seek()
43 local size = f:seek("end")
44 f:seek("set",current)
45 return size
46end
47
48files.getsize = files.size
49
50function files.setposition(f,n)
51 if zerobased[f] then
52 f:seek("set",n)
53 else
54 f:seek("set",n - 1)
55 end
56end
57
58function files.getposition(f)
59 if zerobased[f] then
60 return f:seek()
61 else
62 return f:seek() + 1
63 end
64end
65
66function files.look(f,n,chars)
67 local p = f:seek()
68 local s = f:read(n)
69 f:seek("set",p)
70 if chars then
71 return s
72 else
73 return byte(s,1,#s)
74 end
75end
76
77function files.skip(f,n)
78 if n == 1 then
79 f:read(n)
80 else
81 f:seek("set",f:seek()+n)
82 end
83end
84
85function files.readbyte(f)
86 return byte(f:read(1))
87end
88
89function files.readbytes(f,n)
90 return byte(f:read(n),1,n)
91end
92
93function files.readbytetable(f,n)
94
95 local s = f:read(n or 1)
96 return { byte(s,1,#s) }
97end
98
99function files.readchar(f)
100 return f:read(1)
101end
102
103function files.readstring(f,n)
104 return f:read(n or 1)
105end
106
107function files.readinteger1(f)
108 local n = byte(f:read(1))
109 if n >= 0x80 then
110 return n - 0x100
111 else
112 return n
113 end
114end
115
116files.readcardinal1 = files.readbyte
117files.readcardinal = files.readcardinal1
118files.readinteger = files.readinteger1
119files.readsignedbyte = files.readinteger1
120
121function files.readcardinal2(f)
122 local a, b = byte(f:read(2),1,2)
123 return 0x100 * a + b
124end
125
126function files.readcardinal2le(f)
127 local b, a = byte(f:read(2),1,2)
128 return 0x100 * a + b
129end
130
131function files.readinteger2(f)
132 local a, b = byte(f:read(2),1,2)
133 if a >= 0x80 then
134 return 0x100 * a + b - 0x10000
135 else
136 return 0x100 * a + b
137 end
138end
139
140function files.readinteger2le(f)
141 local b, a = byte(f:read(2),1,2)
142 if a >= 0x80 then
143 return 0x100 * a + b - 0x10000
144 else
145 return 0x100 * a + b
146 end
147end
148
149function files.readcardinal3(f)
150 local a, b, c = byte(f:read(3),1,3)
151 return 0x10000 * a + 0x100 * b + c
152end
153
154function files.readcardinal3le(f)
155 local c, b, a = byte(f:read(3),1,3)
156 return 0x10000 * a + 0x100 * b + c
157end
158
159function files.readinteger3(f)
160 local a, b, c = byte(f:read(3),1,3)
161 if a >= 0x80 then
162 return 0x10000 * a + 0x100 * b + c - 0x1000000
163 else
164 return 0x10000 * a + 0x100 * b + c
165 end
166end
167
168function files.readinteger3le(f)
169 local c, b, a = byte(f:read(3),1,3)
170 if a >= 0x80 then
171 return 0x10000 * a + 0x100 * b + c - 0x1000000
172 else
173 return 0x10000 * a + 0x100 * b + c
174 end
175end
176
177function files.readcardinal4(f)
178 local a, b, c, d = byte(f:read(4),1,4)
179 return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
180end
181
182function files.readcardinal4le(f)
183 local d, c, b, a = byte(f:read(4),1,4)
184 return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
185end
186
187function files.readinteger4(f)
188 local a, b, c, d = byte(f:read(4),1,4)
189 if a >= 0x80 then
190 return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000
191 else
192 return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
193 end
194end
195
196function files.readinteger4le(f)
197 local d, c, b, a = byte(f:read(4),1,4)
198 if a >= 0x80 then
199 return 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000
200 else
201 return 0x1000000 * a + 0x10000 * b + 0x100 * c + d
202 end
203end
204
205function files.readfixed2(f)
206 local n1, n2 = byte(f:read(2),1,2)
207 if n1 >= 0x80 then
208 n1 = n1 - 0x100
209 end
210 return n1 + n2/0xFF
211end
212
213
214
215function files.readfixed4(f)
216 local a, b, c, d = byte(f:read(4),1,4)
217 local n1 = 0x100 * a + b
218 local n2 = 0x100 * c + d
219 if n1 >= 0x8000 then
220 n1 = n1 - 0x10000
221 end
222 return n1 + n2/0xFFFF
223end
224
225
226
227if bit32 then
228
229 local extract = bit32.extract
230 local band = bit32.band
231
232 function files.read2dot14(f)
233 local a, b = byte(f:read(2),1,2)
234 if a >= 0x80 then
235 local n = -(0x100 * a + b)
236 return - (extract(n,14,2) + (band(n,0x3FFF) / 16384.0))
237 else
238 local n = 0x100 * a + b
239 return (extract(n,14,2) + (band(n,0x3FFF) / 16384.0))
240 end
241 end
242
243end
244
245function files.skipshort(f,n)
246 f:read(2*(n or 1))
247end
248
249function files.skiplong(f,n)
250 f:read(4*(n or 1))
251end
252
253
254
255if bit32 then
256
257 local rshift = bit32.rshift
258
259 function files.writecardinal2(f,n)
260 local a = char(n % 256)
261 n = rshift(n,8)
262 local b = char(n % 256)
263 f:write(b,a)
264 end
265
266 function files.writecardinal4(f,n)
267 local a = char(n % 256)
268 n = rshift(n,8)
269 local b = char(n % 256)
270 n = rshift(n,8)
271 local c = char(n % 256)
272 n = rshift(n,8)
273 local d = char(n % 256)
274 f:write(d,c,b,a)
275 end
276
277 function files.writecardinal2le(f,n)
278 local a = char(n % 256)
279 n = rshift(n,8)
280 local b = char(n % 256)
281 f:write(a,b)
282 end
283
284 function files.writecardinal4le(f,n)
285 local a = char(n % 256)
286 n = rshift(n,8)
287 local b = char(n % 256)
288 n = rshift(n,8)
289 local c = char(n % 256)
290 n = rshift(n,8)
291 local d = char(n % 256)
292 f:write(a,b,c,d)
293 end
294
295else
296
297 local floor = math.floor
298
299 function files.writecardinal2(f,n)
300 local a = char(n % 256)
301 n = floor(n/256)
302 local b = char(n % 256)
303 f:write(b,a)
304 end
305
306 function files.writecardinal4(f,n)
307 local a = char(n % 256)
308 n = floor(n/256)
309 local b = char(n % 256)
310 n = floor(n/256)
311 local c = char(n % 256)
312 n = floor(n/256)
313 local d = char(n % 256)
314 f:write(d,c,b,a)
315 end
316
317 function files.writecardinal2le(f,n)
318 local a = char(n % 256)
319 n = floor(n/256)
320 local b = char(n % 256)
321 f:write(a,b)
322 end
323
324 function files.writecardinal4le(f,n)
325 local a = char(n % 256)
326 n = floor(n/256)
327 local b = char(n % 256)
328 n = floor(n/256)
329 local c = char(n % 256)
330 n = floor(n/256)
331 local d = char(n % 256)
332 f:write(a,b,c,d)
333 end
334
335end
336
337function files.writestring(f,s)
338 f:write(char(byte(s,1,#s)))
339end
340
341function files.writebyte(f,b)
342 f:write(char(b))
343end
344
345if fio and fio.readcardinal1 then
346
347 files.readcardinal1 = fio.readcardinal1
348 files.readcardinal2 = fio.readcardinal2
349 files.readcardinal3 = fio.readcardinal3
350 files.readcardinal4 = fio.readcardinal4
351
352 files.readcardinal1le = fio.readcardinal1le or files.readcardinal1le
353 files.readcardinal2le = fio.readcardinal2le or files.readcardinal2le
354 files.readcardinal3le = fio.readcardinal3le or files.readcardinal3le
355 files.readcardinal4le = fio.readcardinal4le or files.readcardinal4le
356
357 files.readinteger1 = fio.readinteger1
358 files.readinteger2 = fio.readinteger2
359 files.readinteger3 = fio.readinteger3
360 files.readinteger4 = fio.readinteger4
361
362 files.readinteger1le = fio.readinteger1le or files.readinteger1le
363 files.readinteger2le = fio.readinteger2le or files.readinteger2le
364 files.readinteger3le = fio.readinteger3le or files.readinteger3le
365 files.readinteger4le = fio.readinteger4le or files.readinteger4le
366
367 files.readfixed2 = fio.readfixed2
368 files.readfixed4 = fio.readfixed4
369 files.read2dot14 = fio.read2dot14
370 files.setposition = fio.setposition
371 files.getposition = fio.getposition
372
373 files.readbyte = files.readcardinal1
374 files.readsignedbyte = files.readinteger1
375 files.readcardinal = files.readcardinal1
376 files.readinteger = files.readinteger1
377
378 local skipposition = fio.skipposition
379 files.skipposition = skipposition
380
381 files.readbytes = fio.readbytes
382 files.readbytetable = fio.readbytetable
383
384 function files.skipshort(f,n)
385 skipposition(f,2*(n or 1))
386 end
387
388 function files.skiplong(f,n)
389 skipposition(f,4*(n or 1))
390 end
391
392end
393
394if fio and fio.writecardinal1 then
395
396 files.writecardinal1 = fio.writecardinal1
397 files.writecardinal2 = fio.writecardinal2
398 files.writecardinal3 = fio.writecardinal3
399 files.writecardinal4 = fio.writecardinal4
400
401 files.writecardinal1le = fio.writecardinal1le
402 files.writecardinal2le = fio.writecardinal2le
403 files.writecardinal3le = fio.writecardinal3le
404 files.writecardinal4le = fio.writecardinal4le
405
406 files.writeinteger1 = fio.writeinteger1 or fio.writecardinal1
407 files.writeinteger2 = fio.writeinteger2 or fio.writecardinal2
408 files.writeinteger3 = fio.writeinteger3 or fio.writecardinal3
409 files.writeinteger4 = fio.writeinteger4 or fio.writecardinal4
410
411 files.writeinteger1le = files.writeinteger1le or fio.writecardinal1le
412 files.writeinteger2le = files.writeinteger2le or fio.writecardinal2le
413 files.writeinteger3le = files.writeinteger3le or fio.writecardinal3le
414 files.writeinteger4le = files.writeinteger4le or fio.writecardinal4le
415
416end
417
418if fio and fio.readcardinaltable then
419
420 files.readcardinaltable = fio.readcardinaltable
421 files.readintegertable = fio.readintegertable
422
423else
424
425 local readcardinal1 = files.readcardinal1
426 local readcardinal2 = files.readcardinal2
427 local readcardinal3 = files.readcardinal3
428 local readcardinal4 = files.readcardinal4
429
430 function files.readcardinaltable(f,n,b)
431 local t = { }
432 if b == 1 then for i=1,n do t[i] = readcardinal1(f) end
433 elseif b == 2 then for i=1,n do t[i] = readcardinal2(f) end
434 elseif b == 3 then for i=1,n do t[i] = readcardinal3(f) end
435 elseif b == 4 then for i=1,n do t[i] = readcardinal4(f) end end
436 return t
437 end
438
439 local readinteger1 = files.readinteger1
440 local readinteger2 = files.readinteger2
441 local readinteger3 = files.readinteger3
442 local readinteger4 = files.readinteger4
443
444 function files.readintegertable(f,n,b)
445 local t = { }
446 if b == 1 then for i=1,n do t[i] = readinteger1(f) end
447 elseif b == 2 then for i=1,n do t[i] = readinteger2(f) end
448 elseif b == 3 then for i=1,n do t[i] = readinteger3(f) end
449 elseif b == 4 then for i=1,n do t[i] = readinteger4(f) end end
450 return t
451 end
452
453end
454 |