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