util-sac.lua /size: 12 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
util-sac
'
]
=
{
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
-- experimental string access (some 3 times faster than file access when messing
10
-- with bytes)
11 12
local
byte
,
sub
=
string
.
byte
,
string
.
sub
13
local
tonumber
=
tonumber
14 15
utilities
=
utilities
or
{
}
16
local
streams
=
{
}
17
utilities
.
streams
=
streams
18 19
function
streams
.
open
(
filename
,
zerobased
)
20
local
f
=
filename
and
io
.
loaddata
(
filename
)
21
if
f
then
22
return
{
f
,
1
,
#
f
,
zerobased
or
false
}
23
end
24
end
25 26
function
streams
.
openstring
(
f
,
zerobased
)
27
if
f
then
28
return
{
f
,
1
,
#
f
,
zerobased
or
false
}
29
end
30
end
31 32
function
streams
.
getstring
(
f
)
33
if
f
then
34
return
f
[
1
]
35
end
36
end
37 38
function
streams
.
close
(
)
39
-- dummy
40
end
41 42
function
streams
.
size
(
f
)
43
return
f
and
f
[
3
]
or
0
44
end
45 46
streams
.
getsize
=
streams
.
size
47 48
function
streams
.
setposition
(
f
,
i
)
49
if
f
[
4
]
then
50
-- zerobased
51
if
i
<
=
0
then
52
f
[
2
]
=
1
53
else
54
f
[
2
]
=
i
+
1
55
end
56
else
57
if
i
<
=
1
then
58
f
[
2
]
=
1
59
else
60
f
[
2
]
=
i
61
end
62
end
63
end
64 65
function
streams
.
getposition
(
f
)
66
if
f
[
4
]
then
67
-- zerobased
68
return
f
[
2
]
-
1
69
else
70
return
f
[
2
]
71
end
72
end
73 74
function
streams
.
look
(
f
,
n
,
chars
)
75
local
b
=
f
[
2
]
76
local
e
=
b
+
n
-
1
77
if
chars
then
78
return
sub
(
f
[
1
]
,
b
,
e
)
79
else
80
return
byte
(
f
[
1
]
,
b
,
e
)
81
end
82
end
83 84
function
streams
.
skip
(
f
,
n
)
85
f
[
2
]
=
f
[
2
]
+
n
86
end
87 88
function
streams
.
readbyte
(
f
)
89
local
i
=
f
[
2
]
90
f
[
2
]
=
i
+
1
91
return
byte
(
f
[
1
]
,
i
)
92
end
93 94
function
streams
.
readbytes
(
f
,
n
)
95
local
i
=
f
[
2
]
96
local
j
=
i
+
n
97
f
[
2
]
=
j
98
return
byte
(
f
[
1
]
,
i
,
j
-1
)
99
end
100 101
function
streams
.
readbytetable
(
f
,
n
)
102
local
i
=
f
[
2
]
103
local
j
=
i
+
n
104
f
[
2
]
=
j
105
return
{
byte
(
f
[
1
]
,
i
,
j
-1
)
}
106
end
107 108
function
streams
.
skipbytes
(
f
,
n
)
109
f
[
2
]
=
f
[
2
]
+
n
110
end
111 112
function
streams
.
readchar
(
f
)
113
local
i
=
f
[
2
]
114
f
[
2
]
=
i
+
1
115
return
sub
(
f
[
1
]
,
i
,
i
)
116
end
117 118
function
streams
.
readstring
(
f
,
n
)
119
local
i
=
f
[
2
]
120
local
j
=
i
+
n
121
f
[
2
]
=
j
122
return
sub
(
f
[
1
]
,
i
,
j
-1
)
123
end
124 125
function
streams
.
readinteger1
(
f
)
-- one byte
126
local
i
=
f
[
2
]
127
f
[
2
]
=
i
+
1
128
local
n
=
byte
(
f
[
1
]
,
i
)
129
if
n
>
=
0x80
then
130
return
n
-
0x100
131
else
132
return
n
133
end
134
end
135 136
streams
.
readcardinal1
=
streams
.
readbyte
-- one byte
137
streams
.
readcardinal
=
streams
.
readcardinal1
138
streams
.
readinteger
=
streams
.
readinteger1
139 140
function
streams
.
readcardinal2
(
f
)
141
local
i
=
f
[
2
]
142
local
j
=
i
+
1
143
f
[
2
]
=
j
+
1
144
local
a
,
b
=
byte
(
f
[
1
]
,
i
,
j
)
145
return
0x100
*
a
+
b
146
end
147 148
function
streams
.
readcardinal2le
(
f
)
149
local
i
=
f
[
2
]
150
local
j
=
i
+
1
151
f
[
2
]
=
j
+
1
152
local
b
,
a
=
byte
(
f
[
1
]
,
i
,
j
)
153
return
0x100
*
a
+
b
154
end
155 156
function
streams
.
readinteger2
(
f
)
157
local
i
=
f
[
2
]
158
local
j
=
i
+
1
159
f
[
2
]
=
j
+
1
160
local
a
,
b
=
byte
(
f
[
1
]
,
i
,
j
)
161
if
a
>
=
0x80
then
162
return
0x100
*
a
+
b
-
0x10000
163
else
164
return
0x100
*
a
+
b
165
end
166
end
167 168
function
streams
.
readinteger2le
(
f
)
169
local
i
=
f
[
2
]
170
local
j
=
i
+
1
171
f
[
2
]
=
j
+
1
172
local
b
,
a
=
byte
(
f
[
1
]
,
i
,
j
)
173
if
a
>
=
0x80
then
174
return
0x100
*
a
+
b
-
0x10000
175
else
176
return
0x100
*
a
+
b
177
end
178
end
179 180
function
streams
.
readcardinal3
(
f
)
181
local
i
=
f
[
2
]
182
local
j
=
i
+
2
183
f
[
2
]
=
j
+
1
184
local
a
,
b
,
c
=
byte
(
f
[
1
]
,
i
,
j
)
185
return
0x10000
*
a
+
0x100
*
b
+
c
186
end
187 188
function
streams
.
readcardinal3le
(
f
)
189
local
i
=
f
[
2
]
190
local
j
=
i
+
2
191
f
[
2
]
=
j
+
1
192
local
c
,
b
,
a
=
byte
(
f
[
1
]
,
i
,
j
)
193
return
0x10000
*
a
+
0x100
*
b
+
c
194
end
195 196
function
streams
.
readinteger3
(
f
)
197
local
i
=
f
[
2
]
198
local
j
=
i
+
3
199
f
[
2
]
=
j
+
1
200
local
a
,
b
,
c
=
byte
(
f
[
1
]
,
i
,
j
)
201
if
a
>
=
0x80
then
202
return
0x10000
*
a
+
0x100
*
b
+
c
-
0x1000000
203
else
204
return
0x10000
*
a
+
0x100
*
b
+
c
205
end
206
end
207 208
function
streams
.
readinteger3le
(
f
)
209
local
i
=
f
[
2
]
210
local
j
=
i
+
3
211
f
[
2
]
=
j
+
1
212
local
c
,
b
,
a
=
byte
(
f
[
1
]
,
i
,
j
)
213
if
a
>
=
0x80
then
214
return
0x10000
*
a
+
0x100
*
b
+
c
-
0x1000000
215
else
216
return
0x10000
*
a
+
0x100
*
b
+
c
217
end
218
end
219 220
function
streams
.
readcardinal4
(
f
)
221
local
i
=
f
[
2
]
222
local
j
=
i
+
3
223
f
[
2
]
=
j
+
1
224
local
a
,
b
,
c
,
d
=
byte
(
f
[
1
]
,
i
,
j
)
225
return
0x1000000
*
a
+
0x10000
*
b
+
0x100
*
c
+
d
226
end
227 228
function
streams
.
readcardinal4le
(
f
)
229
local
i
=
f
[
2
]
230
local
j
=
i
+
3
231
f
[
2
]
=
j
+
1
232
local
d
,
c
,
b
,
a
=
byte
(
f
[
1
]
,
i
,
j
)
233
return
0x1000000
*
a
+
0x10000
*
b
+
0x100
*
c
+
d
234
end
235 236
function
streams
.
readinteger4
(
f
)
237
local
i
=
f
[
2
]
238
local
j
=
i
+
3
239
f
[
2
]
=
j
+
1
240
local
a
,
b
,
c
,
d
=
byte
(
f
[
1
]
,
i
,
j
)
241
if
a
>
=
0x80
then
242
return
0x1000000
*
a
+
0x10000
*
b
+
0x100
*
c
+
d
-
0x100000000
243
else
244
return
0x1000000
*
a
+
0x10000
*
b
+
0x100
*
c
+
d
245
end
246
end
247 248
function
streams
.
readinteger4le
(
f
)
249
local
i
=
f
[
2
]
250
local
j
=
i
+
3
251
f
[
2
]
=
j
+
1
252
local
d
,
c
,
b
,
a
=
byte
(
f
[
1
]
,
i
,
j
)
253
if
a
>
=
0x80
then
254
return
0x1000000
*
a
+
0x10000
*
b
+
0x100
*
c
+
d
-
0x100000000
255
else
256
return
0x1000000
*
a
+
0x10000
*
b
+
0x100
*
c
+
d
257
end
258
end
259 260
function
streams
.
readfixed2
(
f
)
261
local
i
=
f
[
2
]
262
local
j
=
i
+
1
263
f
[
2
]
=
j
+
1
264
local
a
,
b
=
byte
(
f
[
1
]
,
i
,
j
)
265
if
a
>
=
0x80
then
266
return
tonumber
(
(
a
-
0x100
)
.
.
"
.
"
.
.
b
)
or
0
267
else
268
return
tonumber
(
(
a
)
.
.
"
.
"
.
.
b
)
or
0
269
end
270
end
271 272
function
streams
.
readfixed4
(
f
)
273
local
i
=
f
[
2
]
274
local
j
=
i
+
3
275
f
[
2
]
=
j
+
1
276
local
a
,
b
,
c
,
d
=
byte
(
f
[
1
]
,
i
,
j
)
277
if
a
>
=
0x80
then
278
return
tonumber
(
(
0x100
*
a
+
b
-
0x10000
)
.
.
"
.
"
.
.
(
0x100
*
c
+
d
)
)
or
0
279
else
280
return
tonumber
(
(
0x100
*
a
+
b
)
.
.
"
.
"
.
.
(
0x100
*
c
+
d
)
)
or
0
281
end
282
end
283 284
if
bit32
then
285 286
local
extract
=
bit32
.
extract
287
local
band
=
bit32
.
band
288 289
function
streams
.
read2dot14
(
f
)
290
local
i
=
f
[
2
]
291
local
j
=
i
+
1
292
f
[
2
]
=
j
+
1
293
local
a
,
b
=
byte
(
f
[
1
]
,
i
,
j
)
294
if
a
>
=
0x80
then
295
local
n
=
-
(
0x100
*
a
+
b
)
296
return
-
(
extract
(
n
,
14
,
2
)
+
(
band
(
n
,
0x3FFF
)
/
16384
.
0
)
)
297
else
298
local
n
=
0x100
*
a
+
b
299
return
(
extract
(
n
,
14
,
2
)
+
(
band
(
n
,
0x3FFF
)
/
16384
.
0
)
)
300
end
301
end
302 303
end
304 305
function
streams
.
skipshort
(
f
,
n
)
306
f
[
2
]
=
f
[
2
]
+
2
*
(
n
or
1
)
307
end
308 309
function
streams
.
skiplong
(
f
,
n
)
310
f
[
2
]
=
f
[
2
]
+
4
*
(
n
or
1
)
311
end
312 313
if
sio
and
sio
.
readcardinal2
then
314 315
local
readcardinal1
=
sio
.
readcardinal1
316
local
readcardinal2
=
sio
.
readcardinal2
317
local
readcardinal3
=
sio
.
readcardinal3
318
local
readcardinal4
=
sio
.
readcardinal4
319
local
readinteger1
=
sio
.
readinteger1
320
local
readinteger2
=
sio
.
readinteger2
321
local
readinteger3
=
sio
.
readinteger3
322
local
readinteger4
=
sio
.
readinteger4
323
local
readfixed2
=
sio
.
readfixed2
324
local
readfixed4
=
sio
.
readfixed4
325
local
read2dot14
=
sio
.
read2dot14
326
local
readbytes
=
sio
.
readbytes
327
local
readbytetable
=
sio
.
readbytetable
328 329
function
streams
.
readcardinal1
(
f
)
330
local
i
=
f
[
2
]
331
f
[
2
]
=
i
+
1
332
return
readcardinal1
(
f
[
1
]
,
i
)
333
end
334
function
streams
.
readcardinal2
(
f
)
335
local
i
=
f
[
2
]
336
f
[
2
]
=
i
+
2
337
return
readcardinal2
(
f
[
1
]
,
i
)
338
end
339
function
streams
.
readcardinal3
(
f
)
340
local
i
=
f
[
2
]
341
f
[
2
]
=
i
+
3
342
return
readcardinal3
(
f
[
1
]
,
i
)
343
end
344
function
streams
.
readcardinal4
(
f
)
345
local
i
=
f
[
2
]
346
f
[
2
]
=
i
+
4
347
return
readcardinal4
(
f
[
1
]
,
i
)
348
end
349
function
streams
.
readinteger1
(
f
)
350
local
i
=
f
[
2
]
351
f
[
2
]
=
i
+
1
352
return
readinteger1
(
f
[
1
]
,
i
)
353
end
354
function
streams
.
readinteger2
(
f
)
355
local
i
=
f
[
2
]
356
f
[
2
]
=
i
+
2
357
return
readinteger2
(
f
[
1
]
,
i
)
358
end
359
function
streams
.
readinteger3
(
f
)
360
local
i
=
f
[
2
]
361
f
[
2
]
=
i
+
3
362
return
readinteger3
(
f
[
1
]
,
i
)
363
end
364
function
streams
.
readinteger4
(
f
)
365
local
i
=
f
[
2
]
366
f
[
2
]
=
i
+
4
367
return
readinteger4
(
f
[
1
]
,
i
)
368
end
369
function
streams
.
readfixed2
(
f
)
-- needs recent luatex
370
local
i
=
f
[
2
]
371
f
[
2
]
=
i
+
2
372
return
readfixed2
(
f
[
1
]
,
i
)
373
end
374
function
streams
.
readfixed4
(
f
)
-- needs recent luatex
375
local
i
=
f
[
2
]
376
f
[
2
]
=
i
+
4
377
return
readfixed4
(
f
[
1
]
,
i
)
378
end
379
function
streams
.
read2dot4
(
f
)
380
local
i
=
f
[
2
]
381
f
[
2
]
=
i
+
2
382
return
read2dot4
(
f
[
1
]
,
i
)
383
end
384
function
streams
.
readbytes
(
f
,
n
)
385
local
i
=
f
[
2
]
386
local
s
=
f
[
3
]
387
local
p
=
i
+
n
388
if
p
>
s
then
389
f
[
2
]
=
s
+
1
390
else
391
f
[
2
]
=
p
392
end
393
return
readbytes
(
f
[
1
]
,
i
,
n
)
394
end
395
function
streams
.
readbytetable
(
f
,
n
)
396
local
i
=
f
[
2
]
397
local
s
=
f
[
3
]
398
local
p
=
i
+
n
399
if
p
>
s
then
400
f
[
2
]
=
s
+
1
401
else
402
f
[
2
]
=
p
403
end
404
return
readbytetable
(
f
[
1
]
,
i
,
n
)
405
end
406 407
streams
.
readbyte
=
streams
.
readcardinal1
408
streams
.
readsignedbyte
=
streams
.
readinteger1
409
streams
.
readcardinal
=
streams
.
readcardinal1
410
streams
.
readinteger
=
streams
.
readinteger1
411 412
end
413 414
if
sio
and
sio
.
readcardinaltable
then
415 416
local
readcardinaltable
=
sio
.
readcardinaltable
417
local
readintegertable
=
sio
.
readintegertable
418 419
function
utilities
.
streams
.
readcardinaltable
(
f
,
n
,
b
)
420
local
i
=
f
[
2
]
421
local
s
=
f
[
3
]
422
local
p
=
i
+
n
*
b
423
if
p
>
s
then
424
f
[
2
]
=
s
+
1
425
else
426
f
[
2
]
=
p
427
end
428
return
readcardinaltable
(
f
[
1
]
,
i
,
n
,
b
)
429
end
430 431
function
utilities
.
streams
.
readintegertable
(
f
,
n
,
b
)
432
local
i
=
f
[
2
]
433
local
s
=
f
[
3
]
434
local
p
=
i
+
n
*
b
435
if
p
>
s
then
436
f
[
2
]
=
s
+
1
437
else
438
f
[
2
]
=
p
439
end
440
return
readintegertable
(
f
[
1
]
,
i
,
n
,
b
)
441
end
442 443
else
444 445
local
readcardinal1
=
streams
.
readcardinal1
446
local
readcardinal2
=
streams
.
readcardinal2
447
local
readcardinal3
=
streams
.
readcardinal3
448
local
readcardinal4
=
streams
.
readcardinal4
449 450
function
streams
.
readcardinaltable
(
f
,
n
,
b
)
451
local
i
=
f
[
2
]
452
local
s
=
f
[
3
]
453
local
p
=
i
+
n
*
b
454
if
p
>
s
then
455
f
[
2
]
=
s
+
1
456
else
457
f
[
2
]
=
p
458
end
459
local
t
=
{
}
460
if
b
=
=
1
then
for
i
=
1
,
n
do
t
[
i
]
=
readcardinal1
(
f
[
1
]
,
i
)
end
461
elseif
b
=
=
2
then
for
i
=
1
,
n
do
t
[
i
]
=
readcardinal2
(
f
[
1
]
,
i
)
end
462
elseif
b
=
=
3
then
for
i
=
1
,
n
do
t
[
i
]
=
readcardinal3
(
f
[
1
]
,
i
)
end
463
elseif
b
=
=
4
then
for
i
=
1
,
n
do
t
[
i
]
=
readcardinal4
(
f
[
1
]
,
i
)
end
end
464
return
t
465
end
466 467
local
readinteger1
=
streams
.
readinteger1
468
local
readinteger2
=
streams
.
readinteger2
469
local
readinteger3
=
streams
.
readinteger3
470
local
readinteger4
=
streams
.
readinteger4
471 472
function
streams
.
readintegertable
(
f
,
n
,
b
)
473
local
i
=
f
[
2
]
474
local
s
=
f
[
3
]
475
local
p
=
i
+
n
*
b
476
if
p
>
s
then
477
f
[
2
]
=
s
+
1
478
else
479
f
[
2
]
=
p
480
end
481
local
t
=
{
}
482
if
b
=
=
1
then
for
i
=
1
,
n
do
t
[
i
]
=
readinteger1
(
f
[
1
]
,
i
)
end
483
elseif
b
=
=
2
then
for
i
=
1
,
n
do
t
[
i
]
=
readinteger2
(
f
[
1
]
,
i
)
end
484
elseif
b
=
=
3
then
for
i
=
1
,
n
do
t
[
i
]
=
readinteger3
(
f
[
1
]
,
i
)
end
485
elseif
b
=
=
4
then
for
i
=
1
,
n
do
t
[
i
]
=
readinteger4
(
f
[
1
]
,
i
)
end
end
486
return
t
487
end
488 489
end
490 491
-- For practical reasons we put this here. It's less efficient but ok when we don't
492
-- have much access.
493 494
do
495 496
local
files
=
utilities
.
files
497 498
if
files
then
499 500
local
openfile
=
files
.
open
501
local
openstream
=
streams
.
open
502
local
openstring
=
streams
.
openstring
503 504
local
setmetatable
=
setmetatable
505 506
function
io
.
newreader
(
str
,
method
)
507
local
f
,
m
508
if
method
=
=
"
string
"
then
509
f
=
openstring
(
str
)
510
m
=
streams
511
elseif
method
=
=
"
stream
"
then
512
f
=
openstream
(
str
)
513
m
=
streams
514
else
515
f
=
openfile
(
str
,
"
rb
"
)
516
m
=
files
517
end
518
if
f
then
519
local
t
=
{
}
520
setmetatable
(
t
,
{
521
__index
=
function
(
t
,
k
)
522
local
r
=
m
[
k
]
523
if
k
=
=
"
close
"
then
524
if
f
then
525
m
.
close
(
f
)
526
f
=
nil
527
end
528
return
function
(
)
end
529
elseif
r
then
530
local
v
=
function
(
_
,
a
,
b
)
return
r
(
f
,
a
,
b
)
end
531
t
[
k
]
=
v
532
return
v
533
else
534
print
(
"
unknown key
"
,
k
)
535
end
536
end
537
}
)
538
return
t
539
end
540
end
541 542
end
543 544
end
545