1 | unit Cache;
|
---|
2 |
|
---|
3 | INTERFACE
|
---|
4 |
|
---|
5 | uses dos,crt;
|
---|
6 |
|
---|
7 | CONST
|
---|
8 | maxcachefiles=10;
|
---|
9 | mincacheamount=1024;
|
---|
10 | maxcacheamount=63488;
|
---|
11 | cerrorok=0;
|
---|
12 | cerrornotinfile=1;
|
---|
13 | cerrortoomanyfiles=2;
|
---|
14 | cerrorclosed=3;
|
---|
15 | cerrornomemory=4;
|
---|
16 | cerrorcacheamount=5;
|
---|
17 | cerrorother=99;
|
---|
18 |
|
---|
19 | type
|
---|
20 | cachefile=1..MaxCacheFiles;
|
---|
21 | topentype=(corewrite,coreset,coappend);
|
---|
22 | tbitpos=BYTE;
|
---|
23 | tbitsize=BYTE;
|
---|
24 |
|
---|
25 | var cacheioresult:BYTE;
|
---|
26 |
|
---|
27 | FUNCTION cachefilepos(nr:CacheFile):LONGINT;
|
---|
28 | FUNCTION cacheeof(nr:CacheFile):BOOLEAN;
|
---|
29 | PROCEDURE cacheseek(nr:CacheFile;Pos:LONGINT);
|
---|
30 | PROCEDURE cacherewrite(var nr:CacheFile;fname:STRING; cache:word);
|
---|
31 | PROCEDURE cachereset(var nr:CacheFile;fname:STRING; cache:word);
|
---|
32 | PROCEDURE cacheappend(var nr:CacheFile;fname:STRING; cache:word);
|
---|
33 | PROCEDURE cacheerase(fname:STRING);
|
---|
34 | PROCEDURE cacheclose(var nr:CacheFile);
|
---|
35 | PROCEDURE cacheclose1(var nr:CacheFile);
|
---|
36 | PROCEDURE cacheread(nr:CacheFile; var value:BYTE);
|
---|
37 | PROCEDURE cachereadext(nr:CacheFile; var value; l:word);
|
---|
38 | PROCEDURE cachewrite(nr:CacheFile;value:BYTE);
|
---|
39 | PROCEDURE cachewriteext(nr:CacheFile; var value; l:word);
|
---|
40 | PROCEDURE cachewritestring(nr:CacheFile; var value; l:word);
|
---|
41 | PROCEDURE cacheexit;
|
---|
42 | FUNCTION cacheopen(fname:STRING;task:topentype;cacheamount:word):BYTE;
|
---|
43 | PROCEDURE CacheGetFTime(nr:CacheFile; var year,month,day,hour,min,sec:WORD);
|
---|
44 | FUNCTION Cachefilesize(nr:CacheFile):LONGINT;
|
---|
45 | PROCEDURE CacheInit;
|
---|
46 |
|
---|
47 | IMPLEMENTATION
|
---|
48 |
|
---|
49 | type
|
---|
50 | treadorwrite=(_Read,_Write);
|
---|
51 | BufferPointer=^PBufferPointer;
|
---|
52 | PBufferPointer=ARRAY[0..65500] OF BYTE;
|
---|
53 |
|
---|
54 | var
|
---|
55 | filedata:ARRAY[0..MaxCacheFiles] OF
|
---|
56 | RECORD
|
---|
57 | block,lblock:LONGINT;
|
---|
58 | offset,loffset:LONGINT;
|
---|
59 | bitpos:tbitpos;
|
---|
60 | changed:BOOLEAN;
|
---|
61 | p:BufferPointer;
|
---|
62 | maxcachemem:LONGINT;
|
---|
63 | f:FILE;
|
---|
64 | END;
|
---|
65 |
|
---|
66 | PROCEDURE cacheinit;
|
---|
67 |
|
---|
68 | var i:CacheFile;
|
---|
69 |
|
---|
70 | BEGIN
|
---|
71 | FOR i:=1 to maxcachefiles DO with filedata[i] DO p:=NIL;
|
---|
72 | cacheioresult:=cerrorok;
|
---|
73 | END;
|
---|
74 |
|
---|
75 | PROCEDURE CacheGetFTime(nr:CacheFile;var year,month,day,hour,min,sec:WORD);
|
---|
76 | VAR time:LONGINT;
|
---|
77 | dt:datetime;
|
---|
78 | BEGIN
|
---|
79 | {$i-}
|
---|
80 | GetFTime(filedata[nr].f,time);
|
---|
81 | {$i+}
|
---|
82 | IF doserror=0 THEN
|
---|
83 | BEGIN
|
---|
84 | cacheioresult:=cerrorok;
|
---|
85 | Unpacktime(time,dt);
|
---|
86 | year:=dt.year;
|
---|
87 | month:=dt.month;
|
---|
88 | day:=dt.day;
|
---|
89 | hour:=dt.hour;
|
---|
90 | min:=dt.min;
|
---|
91 | sec:=dt.sec;
|
---|
92 | END
|
---|
93 | ELSE cacheioresult:=cerrorclosed;
|
---|
94 | END;
|
---|
95 |
|
---|
96 | PROCEDURE expand(nr:CacheFile);
|
---|
97 | BEGIN
|
---|
98 | with filedata[nr] DO
|
---|
99 | BEGIN
|
---|
100 | inc(loffset);
|
---|
101 | IF loffset=maxcachemem THEN
|
---|
102 | BEGIN
|
---|
103 | inc(lblock);
|
---|
104 | loffset:=0;
|
---|
105 | END;
|
---|
106 | END;
|
---|
107 | END;
|
---|
108 |
|
---|
109 | FUNCTION cachefilepos(nr:CacheFile):LONGINT;
|
---|
110 | BEGIN
|
---|
111 | with filedata[nr] DO cachefilepos:=block*maxcachemem+offset;
|
---|
112 | END;
|
---|
113 |
|
---|
114 | FUNCTION Cachefilesize(nr:CacheFile):LONGINT;
|
---|
115 | BEGIN
|
---|
116 | with filedata[nr] DO
|
---|
117 | cachefilesize:=lblock*maxcachemem+loffset;
|
---|
118 | END;
|
---|
119 |
|
---|
120 | PROCEDURE cblockio(nr:CacheFile;
|
---|
121 | blocknr:BYTE; task:treadorwrite);
|
---|
122 | var l:LONGINT;
|
---|
123 | po:LONGINT;
|
---|
124 | BEGIN
|
---|
125 | with filedata[nr] DO
|
---|
126 | BEGIN
|
---|
127 | IF changed THEN
|
---|
128 | BEGIN
|
---|
129 | changed:=FALSE;
|
---|
130 | cblockio(nr,block,_Write);
|
---|
131 | IF cacheioresult>cerrorok THEN Exit;
|
---|
132 | END;
|
---|
133 | IF blocknr=lblock THEN l:=loffset
|
---|
134 | ELSE l:=maxcachemem;
|
---|
135 | po:=maxcachemem;
|
---|
136 | po:=po*blocknr;
|
---|
137 | {$i-}
|
---|
138 | Seek(f,po);
|
---|
139 | {$i+}
|
---|
140 | cacheioresult:=ioresult;
|
---|
141 | IF l>0 THEN IF cacheioresult=0 THEN
|
---|
142 | BEGIN
|
---|
143 | CASE task OF
|
---|
144 | {$i-}
|
---|
145 | _Write:BlockWrite(f,p^,l);
|
---|
146 | _Read :BlockRead(f,p^,l);
|
---|
147 | {$i+}
|
---|
148 | END; {case}
|
---|
149 | cacheioresult:=ioresult;
|
---|
150 | END;
|
---|
151 | END;
|
---|
152 | END;
|
---|
153 |
|
---|
154 |
|
---|
155 | FUNCTION cacheeof(nr:CacheFile):BOOLEAN;
|
---|
156 | BEGIN
|
---|
157 | with filedata[nr] DO cacheeof:=(offset=loffset)AND(block=lblock);
|
---|
158 | END;
|
---|
159 |
|
---|
160 |
|
---|
161 | PROCEDURE cacheseek(nr:CacheFile;Pos:LONGINT);
|
---|
162 | var
|
---|
163 | pblock:Word;
|
---|
164 | poffset:word;
|
---|
165 | BEGIN
|
---|
166 | cacheioresult:=cerrorok;
|
---|
167 | with filedata[nr] DO
|
---|
168 | BEGIN
|
---|
169 | pblock:=Pos DIV maxcachemem;
|
---|
170 | poffset:=Pos MOD maxcachemem;
|
---|
171 | IF Pos>loffset+maxcachemem*lblock
|
---|
172 | THEN
|
---|
173 | BEGIN
|
---|
174 | cacheioresult:=cerrornotinfile;
|
---|
175 | Exit;
|
---|
176 | END;
|
---|
177 | IF pblock<>block THEN cblockio(nr,pblock,_Read);
|
---|
178 | bitpos:=0;
|
---|
179 | offset:=poffset;
|
---|
180 | block:=pblock;
|
---|
181 | END;
|
---|
182 | END;
|
---|
183 |
|
---|
184 | PROCEDURE cacheseekbit(nr:CacheFile;
|
---|
185 | bit:tbitpos);
|
---|
186 | BEGIN
|
---|
187 | with filedata[nr] DO
|
---|
188 | BEGIN
|
---|
189 | bitpos:=bit;
|
---|
190 | IF cacheeof(nr) THEN expand(nr);
|
---|
191 | END;
|
---|
192 | END;
|
---|
193 |
|
---|
194 | FUNCTION cacheopen(fname:STRING;task:topentype;cacheamount:word):BYTE;
|
---|
195 | var
|
---|
196 | l:LONGINT;
|
---|
197 | nr:BYTE;
|
---|
198 | LABEL l1;
|
---|
199 | BEGIN
|
---|
200 | nr:=1;
|
---|
201 | cacheioresult:=cerrorok;
|
---|
202 | while(filedata[nr].p<>NIL)AND(nr<=maxcachefiles+1) DO inc(nr);
|
---|
203 | IF nr>maxcachefiles THEN
|
---|
204 | BEGIN
|
---|
205 | cacheioresult:=cerrortoomanyfiles;
|
---|
206 | Exit;
|
---|
207 | END;
|
---|
208 | cacheopen:=nr;
|
---|
209 |
|
---|
210 | IF(cacheamount>maxcacheamount)OR(cacheamount<mincacheamount)
|
---|
211 | THEN
|
---|
212 | BEGIN
|
---|
213 | cacheioresult:=cerrorcacheamount;
|
---|
214 | Exit;
|
---|
215 | END;
|
---|
216 | with filedata[nr] DO
|
---|
217 | BEGIN
|
---|
218 | maxcachemem:=cacheamount;
|
---|
219 | IF maxavail<maxcachemem THEN
|
---|
220 | BEGIN
|
---|
221 | l1:
|
---|
222 | runerror(255);
|
---|
223 | END;
|
---|
224 | Assign(f,fname);
|
---|
225 | changed:=FALSE;
|
---|
226 | bitpos:=0;
|
---|
227 | {$i-}
|
---|
228 | CASE task OF
|
---|
229 | corewrite:Rewrite(f,1);
|
---|
230 | coAppend,coreset:Reset(f,1);
|
---|
231 | END; {case}
|
---|
232 | {$i+}
|
---|
233 | cacheioresult:=ioresult;
|
---|
234 | IF cacheioresult>cerrorok THEN Exit;
|
---|
235 | l:=filesize(f);
|
---|
236 | lblock:=l DIV maxcachemem;
|
---|
237 | loffset:=l MOD maxcachemem;
|
---|
238 | IF maxavail<maxcachemem THEN RunError(0);
|
---|
239 | getmem(p,maxcachemem);
|
---|
240 | IF p=NIL THEN
|
---|
241 | BEGIN
|
---|
242 | WriteLn('memallocseg Pointer is NIL');
|
---|
243 | GOTO l1;
|
---|
244 | END;
|
---|
245 | IF task<>coappend THEN
|
---|
246 | BEGIN
|
---|
247 | cblockio(nr,0,_Read);
|
---|
248 | block:=0;
|
---|
249 | offset:=0;
|
---|
250 | END
|
---|
251 | ELSE
|
---|
252 | BEGIN
|
---|
253 | cblockio(nr,lblock,_Read);
|
---|
254 | block:=lblock;
|
---|
255 | offset:=loffset;
|
---|
256 | END;
|
---|
257 | END;
|
---|
258 | END;
|
---|
259 |
|
---|
260 |
|
---|
261 | PROCEDURE cacherewrite(var nr:CacheFile;
|
---|
262 | fname:STRING; cache:word);
|
---|
263 | BEGIN
|
---|
264 | nr:=cacheopen(fname,corewrite,cache);
|
---|
265 | END;
|
---|
266 |
|
---|
267 |
|
---|
268 | PROCEDURE cachereset(var nr:CacheFile;fname:STRING; cache:word);
|
---|
269 | BEGIN
|
---|
270 | nr:=cacheopen(fname,coreset,cache);
|
---|
271 | END;
|
---|
272 |
|
---|
273 |
|
---|
274 | PROCEDURE cacheappend(var nr:CacheFile;fname:STRING; cache:word);
|
---|
275 | BEGIN
|
---|
276 | nr:=cacheopen(fname,coappend,cache);
|
---|
277 | END;
|
---|
278 |
|
---|
279 |
|
---|
280 |
|
---|
281 | PROCEDURE cacheerase(fname:STRING);
|
---|
282 | var f:FILE;
|
---|
283 | BEGIN
|
---|
284 | {$i-}
|
---|
285 | Assign(f,fname);
|
---|
286 | IF ioresult>0 THEN
|
---|
287 | BEGIN
|
---|
288 | cacheioresult:=ioresult;
|
---|
289 | Exit;
|
---|
290 | END;
|
---|
291 | Erase(f);
|
---|
292 | {$i+}
|
---|
293 | cacheioresult:=ioresult;
|
---|
294 | END;
|
---|
295 |
|
---|
296 |
|
---|
297 | PROCEDURE cacheclose(var nr:CacheFile);
|
---|
298 | BEGIN
|
---|
299 | IF nr=maxcachefiles THEN exit;
|
---|
300 | IF filedata[nr].p=NIL THEN
|
---|
301 | BEGIN
|
---|
302 | cacheioresult:=cerrorclosed;
|
---|
303 | Exit;
|
---|
304 | END;
|
---|
305 | with filedata[nr] DO
|
---|
306 | BEGIN
|
---|
307 | IF changed THEN
|
---|
308 | BEGIN
|
---|
309 | changed:=FALSE;
|
---|
310 | cblockio(nr,block,_Write);
|
---|
311 | END;
|
---|
312 | {$i-}
|
---|
313 | Close(f);
|
---|
314 | {$i+}
|
---|
315 | cacheioresult:=ioresult;
|
---|
316 | {if cioresult>0 then exit;}
|
---|
317 | FreeMem(p,maxcachemem);
|
---|
318 | p:=NIL;
|
---|
319 | END;
|
---|
320 | nr:=maxcachefiles;
|
---|
321 | END;
|
---|
322 |
|
---|
323 |
|
---|
324 | PROCEDURE cacheclose1(var nr:CacheFile);
|
---|
325 | BEGIN
|
---|
326 | IF nr=maxcachefiles THEN exit;
|
---|
327 | IF filedata[nr].p=NIL THEN
|
---|
328 | BEGIN
|
---|
329 | cacheioresult:=cerrorclosed;
|
---|
330 | Exit;
|
---|
331 | END;
|
---|
332 | with filedata[nr] DO
|
---|
333 | BEGIN
|
---|
334 | {$i-}
|
---|
335 | Close(f);
|
---|
336 | {$i+}
|
---|
337 | cacheioresult:=ioresult;
|
---|
338 | {if cioresult>0 then exit;}
|
---|
339 | FreeMem(p,maxcachemem);
|
---|
340 | p:=NIL;
|
---|
341 | END;
|
---|
342 | nr:=maxcachefiles;
|
---|
343 | END;
|
---|
344 |
|
---|
345 |
|
---|
346 | PROCEDURE cacheread(nr:CacheFile; var value:BYTE);
|
---|
347 | var v:pointer;
|
---|
348 | BEGIN
|
---|
349 | IF cacheeof(nr) THEN
|
---|
350 | BEGIN
|
---|
351 | cacheioresult:=cerrornotinfile;
|
---|
352 | Exit;
|
---|
353 | END;
|
---|
354 | with filedata[nr] DO
|
---|
355 | BEGIN
|
---|
356 | value:=p^[offset];
|
---|
357 | inc(offset);
|
---|
358 | IF offset=maxcachemem THEN
|
---|
359 | BEGIN
|
---|
360 | cblockio(nr,block+1,_Read);
|
---|
361 | offset:=0;
|
---|
362 | inc(block);
|
---|
363 | END;
|
---|
364 | END;
|
---|
365 | END;
|
---|
366 |
|
---|
367 |
|
---|
368 | PROCEDURE cachereadext(nr:CacheFile; var value; l:word);
|
---|
369 | var t:word;
|
---|
370 | v:Bufferpointer;
|
---|
371 | BEGIN
|
---|
372 | IF l=0 THEN exit;
|
---|
373 | v:=Bufferpointer(@value);
|
---|
374 | FOR t:=0 to l-1 DO cacheread(nr,v^[t]);
|
---|
375 | END;
|
---|
376 |
|
---|
377 |
|
---|
378 | PROCEDURE cachewrite(nr:CacheFile;value:BYTE);
|
---|
379 | BEGIN
|
---|
380 | WITH filedata[nr] DO
|
---|
381 | BEGIN
|
---|
382 | IF value<>p^[offset] THEN
|
---|
383 | BEGIN
|
---|
384 | p^[offset]:=value;
|
---|
385 | changed:=true;
|
---|
386 | END;
|
---|
387 | IF cacheeof(nr) THEN
|
---|
388 | BEGIN
|
---|
389 | changed:=true;
|
---|
390 | expand(nr);
|
---|
391 | END;
|
---|
392 | inc(offset);
|
---|
393 | IF offset=maxcachemem THEN
|
---|
394 | BEGIN
|
---|
395 | changed:=FALSE;
|
---|
396 | {alten Block Schreiben}
|
---|
397 | cblockio(nr,block,_Write);
|
---|
398 | {neuen Block lesen}
|
---|
399 | offset:=0;
|
---|
400 | inc(block);
|
---|
401 | cblockio(nr,block,_Read);
|
---|
402 | END;
|
---|
403 | END;
|
---|
404 | END;
|
---|
405 |
|
---|
406 |
|
---|
407 | PROCEDURE cachewriteext(nr:CacheFile; var value; l:word);
|
---|
408 | var
|
---|
409 | t:word;
|
---|
410 | v:Bufferpointer;
|
---|
411 | BEGIN
|
---|
412 | IF l=0 THEN exit;
|
---|
413 | v:=BufferPointer(@value);
|
---|
414 | FOR t:=0 to l-1 DO cachewrite(nr,v^[t]);
|
---|
415 | END;
|
---|
416 |
|
---|
417 |
|
---|
418 | PROCEDURE cachewritestring(nr:CacheFile; var value; l:word);
|
---|
419 | var
|
---|
420 | t:word;
|
---|
421 | v:Bufferpointer;
|
---|
422 | BEGIN
|
---|
423 | v:=BufferPointer(@value);
|
---|
424 | FOR t:=0 to l-1 DO
|
---|
425 | BEGIN
|
---|
426 | cachewrite(nr,v^[t+1]);
|
---|
427 | IF cacheioresult<>0 THEN Exit;
|
---|
428 | END;
|
---|
429 | END;
|
---|
430 |
|
---|
431 |
|
---|
432 |
|
---|
433 |
|
---|
434 | var exitsave:pointer;
|
---|
435 |
|
---|
436 |
|
---|
437 | PROCEDURE cacheexit;
|
---|
438 | var
|
---|
439 | i:CacheFile;
|
---|
440 | BEGIN
|
---|
441 | exitproc:=exitsave;
|
---|
442 | FOR i:=1 to maxcachefiles DO
|
---|
443 | with filedata[i] DO IF p<>NIL THEN
|
---|
444 | FreeMem(p,maxcachemem);
|
---|
445 | END;
|
---|
446 |
|
---|
447 | BEGIN
|
---|
448 | {filemode:=2;}
|
---|
449 | exitsave:=exitproc;
|
---|
450 | exitproc:=@cacheexit;
|
---|
451 | cacheinit;
|
---|
452 | END.
|
---|