Rev 7696 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7696 | Rev 7983 | ||
---|---|---|---|
1 | (* |
1 | (* |
2 | BSD 2-Clause License |
2 | BSD 2-Clause License |
3 | 3 | ||
4 | Copyright (c) 2018-2019, Anton Krotov |
4 | Copyright (c) 2018-2020, Anton Krotov |
5 | All rights reserved. |
5 | All rights reserved. |
6 | *) |
6 | *) |
7 | 7 | ||
8 | MODULE FILES; |
8 | MODULE FILES; |
9 | 9 | ||
10 | IMPORT UTILS, C := COLLECTIONS, CONSOLE; |
10 | IMPORT UTILS, C := COLLECTIONS, CONSOLE; |
11 | 11 | ||
12 | 12 | ||
13 | TYPE |
13 | TYPE |
14 | 14 | ||
15 | FILE* = POINTER TO RECORD (C.ITEM) |
15 | FILE* = POINTER TO RECORD (C.ITEM) |
16 | 16 | ||
17 | ptr: INTEGER; |
17 | ptr: INTEGER; |
18 | 18 | ||
19 | buffer: ARRAY 64*1024 OF BYTE; |
19 | buffer: ARRAY 64*1024 OF BYTE; |
20 | count: INTEGER |
20 | count: INTEGER; |
- | 21 | ||
- | 22 | chksum*: INTEGER |
|
21 | 23 | ||
22 | END; |
24 | END; |
23 | 25 | ||
24 | VAR |
26 | VAR |
25 | 27 | ||
26 | files: C.COLLECTION; |
28 | files: C.COLLECTION; |
27 | 29 | ||
28 | 30 | ||
29 | PROCEDURE copy (src: ARRAY OF BYTE; src_idx: INTEGER; VAR dst: ARRAY OF BYTE; dst_idx: INTEGER; bytes: INTEGER); |
31 | PROCEDURE copy (src: ARRAY OF BYTE; src_idx: INTEGER; VAR dst: ARRAY OF BYTE; dst_idx: INTEGER; bytes: INTEGER); |
30 | BEGIN |
32 | BEGIN |
31 | WHILE bytes > 0 DO |
33 | WHILE bytes > 0 DO |
32 | dst[dst_idx] := src[src_idx]; |
34 | dst[dst_idx] := src[src_idx]; |
33 | INC(dst_idx); |
35 | INC(dst_idx); |
34 | INC(src_idx); |
36 | INC(src_idx); |
35 | DEC(bytes) |
37 | DEC(bytes) |
36 | END |
38 | END |
37 | END copy; |
39 | END copy; |
38 | 40 | ||
39 | 41 | ||
40 | PROCEDURE flush (file: FILE): INTEGER; |
42 | PROCEDURE flush (file: FILE): INTEGER; |
41 | VAR |
43 | VAR |
42 | res: INTEGER; |
44 | res: INTEGER; |
43 | 45 | ||
44 | BEGIN |
46 | BEGIN |
45 | IF file # NIL THEN |
47 | IF file # NIL THEN |
46 | res := UTILS.FileWrite(file.ptr, file.buffer, file.count); |
48 | res := UTILS.FileWrite(file.ptr, file.buffer, file.count); |
47 | IF res < 0 THEN |
49 | IF res < 0 THEN |
48 | res := 0 |
50 | res := 0 |
49 | END |
51 | END |
50 | ELSE |
52 | ELSE |
51 | res := 0 |
53 | res := 0 |
52 | END |
54 | END |
53 | 55 | ||
54 | RETURN res |
56 | RETURN res |
55 | END flush; |
57 | END flush; |
56 | 58 | ||
57 | 59 | ||
58 | PROCEDURE NewFile (): FILE; |
60 | PROCEDURE NewFile (): FILE; |
59 | VAR |
61 | VAR |
60 | file: FILE; |
62 | file: FILE; |
61 | citem: C.ITEM; |
63 | citem: C.ITEM; |
62 | 64 | ||
63 | BEGIN |
65 | BEGIN |
64 | citem := C.pop(files); |
66 | citem := C.pop(files); |
65 | IF citem = NIL THEN |
67 | IF citem = NIL THEN |
66 | NEW(file) |
68 | NEW(file) |
67 | ELSE |
69 | ELSE |
68 | file := citem(FILE) |
70 | file := citem(FILE) |
69 | END |
71 | END |
70 | 72 | ||
71 | RETURN file |
73 | RETURN file |
72 | END NewFile; |
74 | END NewFile; |
73 | 75 | ||
74 | 76 | ||
75 | PROCEDURE create* (name: ARRAY OF CHAR): FILE; |
77 | PROCEDURE create* (name: ARRAY OF CHAR): FILE; |
76 | VAR |
78 | VAR |
77 | file: FILE; |
79 | file: FILE; |
78 | ptr: INTEGER; |
80 | ptr: INTEGER; |
79 | 81 | ||
80 | BEGIN |
82 | BEGIN |
81 | ptr := UTILS.FileCreate(name); |
83 | ptr := UTILS.FileCreate(name); |
82 | 84 | ||
83 | IF ptr > 0 THEN |
85 | IF ptr > 0 THEN |
84 | file := NewFile(); |
86 | file := NewFile(); |
85 | file.ptr := ptr; |
87 | file.ptr := ptr; |
86 | file.count := 0 |
88 | file.count := 0; |
- | 89 | file.chksum := 0 |
|
87 | ELSE |
90 | ELSE |
88 | file := NIL |
91 | file := NIL |
89 | END |
92 | END |
90 | 93 | ||
91 | RETURN file |
94 | RETURN file |
92 | END create; |
95 | END create; |
93 | 96 | ||
94 | 97 | ||
95 | PROCEDURE open* (name: ARRAY OF CHAR): FILE; |
98 | PROCEDURE open* (name: ARRAY OF CHAR): FILE; |
96 | VAR |
99 | VAR |
97 | file: FILE; |
100 | file: FILE; |
98 | ptr: INTEGER; |
101 | ptr: INTEGER; |
99 | 102 | ||
100 | BEGIN |
103 | BEGIN |
101 | ptr := UTILS.FileOpen(name); |
104 | ptr := UTILS.FileOpen(name); |
102 | 105 | ||
103 | IF ptr > 0 THEN |
106 | IF ptr > 0 THEN |
104 | file := NewFile(); |
107 | file := NewFile(); |
105 | file.ptr := ptr; |
108 | file.ptr := ptr; |
106 | file.count := -1 |
109 | file.count := -1 |
107 | ELSE |
110 | ELSE |
108 | file := NIL |
111 | file := NIL |
109 | END |
112 | END |
110 | 113 | ||
111 | RETURN file |
114 | RETURN file |
112 | END open; |
115 | END open; |
113 | 116 | ||
114 | 117 | ||
115 | PROCEDURE close* (VAR file: FILE); |
118 | PROCEDURE close* (VAR file: FILE); |
116 | VAR |
119 | VAR |
117 | n: INTEGER; |
120 | n: INTEGER; |
118 | 121 | ||
119 | BEGIN |
122 | BEGIN |
120 | IF file # NIL THEN |
123 | IF file # NIL THEN |
121 | 124 | ||
122 | IF file.count > 0 THEN |
125 | IF file.count > 0 THEN |
123 | n := flush(file) |
126 | n := flush(file) |
124 | END; |
127 | END; |
125 | 128 | ||
126 | file.count := -1; |
129 | file.count := -1; |
127 | 130 | ||
128 | UTILS.FileClose(file.ptr); |
131 | UTILS.FileClose(file.ptr); |
129 | file.ptr := 0; |
132 | file.ptr := 0; |
130 | 133 | ||
131 | C.push(files, file); |
134 | C.push(files, file); |
132 | file := NIL |
135 | file := NIL |
133 | END |
136 | END |
134 | END close; |
137 | END close; |
135 | 138 | ||
136 | 139 | ||
137 | PROCEDURE read* (file: FILE; VAR chunk: ARRAY OF CHAR; bytes: INTEGER): INTEGER; |
140 | PROCEDURE read* (file: FILE; VAR chunk: ARRAY OF CHAR; bytes: INTEGER): INTEGER; |
138 | VAR |
141 | VAR |
139 | res: INTEGER; |
142 | res: INTEGER; |
140 | 143 | ||
141 | BEGIN |
144 | BEGIN |
142 | IF file # NIL THEN |
145 | IF file # NIL THEN |
143 | res := UTILS.FileRead(file.ptr, chunk, MAX(MIN(bytes, LEN(chunk)), 0)); |
146 | res := UTILS.FileRead(file.ptr, chunk, MAX(MIN(bytes, LEN(chunk)), 0)); |
144 | IF res < 0 THEN |
147 | IF res < 0 THEN |
145 | res := 0 |
148 | res := 0 |
146 | END |
149 | END |
147 | ELSE |
150 | ELSE |
148 | res := 0 |
151 | res := 0 |
149 | END |
152 | END |
150 | 153 | ||
151 | RETURN res |
154 | RETURN res |
152 | END read; |
155 | END read; |
153 | 156 | ||
154 | 157 | ||
155 | PROCEDURE write* (file: FILE; chunk: ARRAY OF BYTE; bytes: INTEGER): INTEGER; |
158 | PROCEDURE write* (file: FILE; chunk: ARRAY OF BYTE; bytes: INTEGER): INTEGER; |
156 | VAR |
159 | VAR |
157 | free, n, k, res, idx: INTEGER; |
160 | free, n, k, res, idx: INTEGER; |
158 | 161 | ||
159 | BEGIN |
162 | BEGIN |
160 | idx := 0; |
163 | idx := 0; |
161 | res := 0; |
164 | res := 0; |
162 | IF (file # NIL) & (file.count >= 0) THEN |
165 | IF (file # NIL) & (file.count >= 0) THEN |
163 | 166 | ||
164 | free := LEN(file.buffer) - file.count; |
167 | free := LEN(file.buffer) - file.count; |
165 | WHILE bytes > 0 DO |
168 | WHILE bytes > 0 DO |
166 | n := MIN(free, bytes); |
169 | n := MIN(free, bytes); |
167 | copy(chunk, idx, file.buffer, file.count, n); |
170 | copy(chunk, idx, file.buffer, file.count, n); |
168 | INC(res, n); |
171 | INC(res, n); |
169 | DEC(free, n); |
172 | DEC(free, n); |
170 | DEC(bytes, n); |
173 | DEC(bytes, n); |
171 | INC(idx, n); |
174 | INC(idx, n); |
172 | INC(file.count, n); |
175 | INC(file.count, n); |
173 | IF free = 0 THEN |
176 | IF free = 0 THEN |
174 | k := flush(file); |
177 | k := flush(file); |
175 | IF k # LEN(file.buffer) THEN |
178 | IF k # LEN(file.buffer) THEN |
176 | bytes := 0; |
179 | bytes := 0; |
177 | DEC(res, n) |
180 | DEC(res, n) |
178 | ELSE |
181 | ELSE |
179 | file.count := 0; |
182 | file.count := 0; |
180 | free := LEN(file.buffer) |
183 | free := LEN(file.buffer) |
181 | END |
184 | END |
182 | END |
185 | END |
183 | END |
186 | END |
184 | 187 | ||
185 | END |
188 | END |
186 | 189 | ||
187 | RETURN res |
190 | RETURN res |
188 | END write; |
191 | END write; |
189 | 192 | ||
190 | 193 | ||
191 | PROCEDURE WriteByte* (file: FILE; byte: BYTE): BOOLEAN; |
194 | PROCEDURE WriteByte* (file: FILE; byte: BYTE): BOOLEAN; |
192 | VAR |
195 | VAR |
193 | res: BOOLEAN; |
196 | arr: ARRAY 1 OF BYTE; |
194 | 197 | ||
195 | BEGIN |
198 | BEGIN |
196 | res := TRUE; |
- | |
197 | IF (file # NIL) & (file.count >= 0) THEN |
- | |
198 | IF file.count = LEN(file.buffer) THEN |
- | |
199 | IF flush(file) # LEN(file.buffer) THEN |
- | |
200 | res := FALSE |
- | |
201 | ELSE |
- | |
202 | file.buffer[0] := byte; |
199 | arr[0] := byte |
203 | file.count := 1 |
- | |
204 | END |
- | |
205 | ELSE |
- | |
206 | file.buffer[file.count] := byte; |
- | |
207 | INC(file.count) |
- | |
208 | END |
- | |
209 | ELSE |
- | |
210 | res := FALSE |
- | |
211 | END |
- | |
212 | - | ||
213 | RETURN res |
200 | RETURN write(file, arr, 1) = 1 |
214 | END WriteByte; |
201 | END WriteByte; |
215 | 202 | ||
216 | 203 | ||
217 | BEGIN |
204 | BEGIN |
218 | files := C.create() |
205 | files := C.create() |
219 | END FILES.>> |
206 | END FILES.>> |