Skip to content

Commit 0885cc7

Browse files
author
dosworld
committed
Source update
1 parent c3522af commit 0885cc7

2 files changed

Lines changed: 223 additions & 0 deletions

File tree

DBU.PAS

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
{ MIT License
2+
3+
Copyright (c) 2022 Viacheslav Komenda
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+
}
23+
{$A+,I-,S-,R-,D-,L-,Q-,F-,G-,O-,B-}
24+
UNIT DBU;
25+
26+
INTERFACE
27+
28+
USES System2;
29+
30+
TYPE
31+
PDBUFile = ^DBUFile;
32+
DBUFile=RECORD
33+
f : PBFILE;
34+
idx : PBFIle;
35+
first_free : WORD;
36+
END;
37+
38+
PROCEDURE DBU_Reset(VAR d : DBUFile; VAR f, idx : BFile);
39+
PROCEDURE DBU_ReWrite(VAR d : DBUFile; VAR f, idx : BFile);
40+
FUNCTION DBU_IsOpen(VAR d : DBUFile) : BOOLEAN;
41+
FUNCTION DBU_Create(VAR d : DBUFile) : WORD;
42+
PROCEDURE DBU_Read(VAR d : DBUFile; h : WORD; ofs : DWORD; VAR mem; size : WORD);
43+
PROCEDURE DBU_Write(VAR d : DBUFile; h : WORD; ofs : DWORD; VAR mem; size : WORD);
44+
PROCEDURE DBU_Free(VAR d : DBUFile; h : WORD);
45+
PROCEDURE DBU_Close(VAR d : DBUFile);
46+
47+
IMPLEMENTATION
48+
49+
CONST
50+
BLOCK_SIZE_KB = 16;
51+
BLOCK_SIZE = BLOCK_SIZE_KB * 1024;
52+
53+
PROCEDURE L_Append(VAR d : DBUFile);
54+
VAR i : INTEGER;
55+
n : ARRAY[1..1024] OF CHAR;
56+
BEGIN
57+
FillChar(n, SizeOf(n), #0);
58+
FOR i := 1 TO BLOCK_SIZE_KB DO BlockWrite(d.f^, n, SizeOf(n));
59+
END;
60+
61+
FUNCTION L_Size(VAR d : DBUFile) : WORD;
62+
VAR r1 : WORD;
63+
r2 : WORD;
64+
BEGIN
65+
r1 := FileSize(d.f^) SHR 14;
66+
r2 := FileSize(d.idx^) SHR 2;
67+
IF r1 > r2 THEN L_Size := r2 ELSE L_Size := r1;
68+
END;
69+
70+
PROCEDURE L_Seek(VAR d : DBUFile; page : WORD);
71+
VAR npage : WORD;
72+
sz : WORD;
73+
BEGIN
74+
sz := L_Size(d);
75+
IF (sz < page) THEN BEGIN
76+
Seek(d.f^, sz SHL 14);
77+
Seek(d.idx^, sz SHL 1);
78+
WHILE sz <= page DO BEGIN
79+
L_Append(d);
80+
WriteWord(d.idx^, d.first_free);
81+
d.first_free := sz;
82+
sz := L_Size(d);
83+
END;
84+
END;
85+
Seek(d.f^, page SHL 14);
86+
Seek(d.idx^, page SHL 1);
87+
END;
88+
89+
PROCEDURE DBU_Reset(VAR d : DBUFile; VAR f, idx : BFile);
90+
BEGIN
91+
FillChar(d, SizeOf(DBUFile), #0);
92+
d.f := @f;
93+
d.idx := @idx;
94+
IF (NOT EOF(d.f^)) AND (NOT EOF(d.idx^)) THEN BEGIN
95+
Seek(d.idx^, 0);
96+
d.first_free := ReadWord(d.idx^);
97+
END ELSE DBU_ReWrite(d, f, idx);
98+
END;
99+
100+
FUNCTION DBU_IsOpen(VAR d : DBUFile) : BOOLEAN;
101+
BEGIN
102+
DBU_IsOpen := IsOpen(d.f^) AND IsOpen(d.idx^);
103+
END;
104+
105+
PROCEDURE DBU_ReWrite(VAR d : DBUFile; VAR f, idx : BFile);
106+
BEGIN
107+
FillChar(d, SizeOf(DBUFile), #0);
108+
d.f := @f;
109+
d.idx := @idx;
110+
111+
Seek(d.f^, 0);
112+
L_Append(d);
113+
Truncate(d.f^);
114+
115+
Seek(d.idx^, 0);
116+
WriteWord(d.idx^, 0);
117+
Truncate(d.idx^);
118+
END;
119+
120+
PROCEDURE DBU_Close(VAR d : DBUFile);
121+
BEGIN
122+
Seek(d.idx^, 0);
123+
WriteWord(d.idx^, d.first_free);
124+
Close(d.f^);
125+
Close(d.idx^);
126+
END;
127+
128+
FUNCTION DBU_Create(VAR d : DBUFile) : WORD;
129+
VAR r : WORD;
130+
BEGIN
131+
IF d.first_free = 0 THEN L_Seek(d, L_Size(d) + 1);
132+
r := d.first_free;
133+
L_Seek(d, r);
134+
WriteWord(d.idx^, 0);
135+
Seek(d.idx^, FilePos(d.idx^) - SizeOf(WORD));
136+
DBU_Create := r;
137+
END;
138+
139+
140+
PROCEDURE DBU_Free(VAR d : DBUFile; h : WORD);
141+
VAR next : WORD;
142+
BEGIN
143+
WHILE h <> 0 DO BEGIN
144+
next := GetWord(d.idx^, h SHL 1);
145+
SetWord(d.idx^, h SHL 1, d.first_free);
146+
d.first_free := h;
147+
h := next;
148+
END;
149+
END;
150+
151+
FUNCTION next_page(VAR d : DBUFile; cpage : WORD) : WORD;
152+
VAR npage : WORD;
153+
BEGIN
154+
Seek(d.idx^, cpage SHL 2);
155+
npage := ReadWord(d.idx^);
156+
IF npage = 0 THEN BEGIN
157+
IF d.first_free = 0 THEN L_Seek(d, (L_Size(d) + 1));
158+
npage := d.first_free;
159+
Seek(d.idx^, d.first_free SHL 1);
160+
d.first_free := ReadWord(d.idx^);
161+
Seek(d.idx^, d.first_free SHL 1);
162+
WriteWord(d.idx^, 0);
163+
Seek(d.idx^, cpage SHL 1);
164+
WriteWord(d.idx^, npage);
165+
END;
166+
next_page := npage;
167+
END;
168+
169+
PROCEDURE DBU_Write(VAR d : DBUFile; h : WORD; ofs : DWORD; VAR mem; size : WORD);
170+
VAR page : WORD;
171+
pofs : WORD;
172+
p : PCHAR;
173+
s : WORD;
174+
BEGIN
175+
page := ofs SHR 14;
176+
pofs := ofs AND $3FFF;
177+
p := @mem;
178+
WHILE page <> 0 DO BEGIN
179+
h := next_page(d, h);
180+
Dec(page);
181+
END;
182+
WHILE size <> 0 DO BEGIN
183+
L_Seek(d, h);
184+
s := size;
185+
IF s > (BLOCK_SIZE - pofs) THEN s := BLOCK_SIZE - pofs;
186+
IF pofs <> 0 THEN Seek(d.f^, FilePos(d.f^) + pofs);
187+
BlockWrite(d.f^, p[0], s);
188+
pofs := 0;
189+
Dec(size, s);
190+
Inc(p, s);
191+
h := next_page(d, h);
192+
END;
193+
END;
194+
195+
PROCEDURE DBU_Read(VAR d : DBUFile; h : WORD; ofs : DWORD; VAR mem; size : WORD);
196+
VAR page : WORD;
197+
pofs : WORD;
198+
p : PCHAR;
199+
s : WORD;
200+
r : WORD;
201+
BEGIN
202+
page := ofs SHR 14;
203+
pofs := ofs AND $3FFF;
204+
p := @mem;
205+
WHILE page <> 0 DO BEGIN
206+
h := next_page(d, h);
207+
Dec(page);
208+
END;
209+
WHILE size <> 0 DO BEGIN
210+
L_Seek(d, h);
211+
s := size;
212+
IF s > (BLOCK_SIZE - pofs) THEN s := BLOCK_SIZE - pofs;
213+
IF pofs <> 0 THEN Seek(d.f^, FilePos(d.f^) + pofs);
214+
BlockRead(d.f^, p[0], s);
215+
pofs := 0;
216+
Dec(size, s);
217+
Inc(p, s);
218+
h := next_page(d, h);
219+
END;
220+
END;
221+
222+
END.

SYSTEM2.PAS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ TCACHE_PAGE = RECORD
6767
END;
6868
{$ENDIF}
6969

70+
PBFILE = ^BFILE;
7071
BFILE = RECORD
7172
f : WORD;
7273
filename : STRING;

0 commit comments

Comments
 (0)