1if 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
10
11
12local byte , sub = string . byte , string . sub
13local tonumber = tonumber
14
15utilities = utilities or { }
16local streams = { }
17utilities . streams = streams
18
19function 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
24end
25
26function streams . openstring ( f , zerobased )
27 if f then
28 return { f , 1 , # f , zerobased or false }
29 end
30end
31
32function streams . getstring ( f )
33 if f then
34 return f [ 1 ]
35 end
36end
37
38function streams . close ( )
39
40end
41
42function streams . size ( f )
43 return f and f [ 3 ] or 0
44end
45
46streams . getsize = streams . size
47
48function streams . setposition ( f , i )
49 if f [ 4 ] then
50
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
63end
64
65function streams . getposition ( f )
66 if f [ 4 ] then
67
68 return f [ 2 ] - 1
69 else
70 return f [ 2 ]
71 end
72end
73
74function 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
82end
83
84function streams . skip ( f , n )
85 f [ 2 ] = f [ 2 ] + n
86end
87
88function streams . readbyte ( f )
89 local i = f [ 2 ]
90 f [ 2 ] = i + 1
91 return byte ( f [ 1 ] , i )
92end
93
94function 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 )
99end
100
101function 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 ) }
106end
107
108function streams . skipbytes ( f , n )
109 f [ 2 ] = f [ 2 ] + n
110end
111
112function streams . readchar ( f )
113 local i = f [ 2 ]
114 f [ 2 ] = i + 1
115 return sub ( f [ 1 ] , i , i )
116end
117
118function 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 )
123end
124
125function streams . readinteger1 ( f )
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
134end
135
136streams . readcardinal1 = streams . readbyte
137streams . readcardinal = streams . readcardinal1
138streams . readinteger = streams . readinteger1
139
140function 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
146end
147
148function 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
154end
155
156function 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
166end
167
168function 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
178end
179
180function 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
186end
187
188function 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
194end
195
196function 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
206end
207
208function 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
218end
219
220function 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
226end
227
228function 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
234end
235
236function 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
246end
247
248function 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
258end
259
260function 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
270end
271
272function 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
282end
283
284if 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
303end
304
305function streams . skipshort ( f , n )
306 f [ 2 ] = f [ 2 ] + 2 * ( n or 1 )
307end
308
309function streams . skiplong ( f , n )
310 f [ 2 ] = f [ 2 ] + 4 * ( n or 1 )
311end
312
313if 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 )
370 local i = f [ 2 ]
371 f [ 2 ] = i + 2
372 return readfixed2 ( f [ 1 ] , i )
373 end
374 function streams . readfixed4 ( f )
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
412end
413
414if 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
443else
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
489end
490
491
492
493
494do
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
544end
545 |