summaryrefslogtreecommitdiff
path: root/apps/codecs/dumb/src/core/dumbfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/dumb/src/core/dumbfile.c')
-rw-r--r--apps/codecs/dumb/src/core/dumbfile.c401
1 files changed, 401 insertions, 0 deletions
diff --git a/apps/codecs/dumb/src/core/dumbfile.c b/apps/codecs/dumb/src/core/dumbfile.c
new file mode 100644
index 0000000000..71108c0c3b
--- /dev/null
+++ b/apps/codecs/dumb/src/core/dumbfile.c
@@ -0,0 +1,401 @@
1/* _______ ____ __ ___ ___
2 * \ _ \ \ / \ / \ \ / / ' ' '
3 * | | \ \ | | || | \/ | . .
4 * | | | | | | || ||\ /| |
5 * | | | | | | || || \/ | | ' ' '
6 * | | | | | | || || | | . .
7 * | |_/ / \ \__// || | |
8 * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
9 * / \
10 * / . \
11 * dumbfile.c - Hookable, strictly sequential / / \ \
12 * file input functions. | < / \_
13 * | \/ /\ /
14 * By entheh. \_ / > /
15 * | \ / /
16 * | ' /
17 * \__/
18 */
19
20#include <stdlib.h>
21
22#include "dumb.h"
23
24
25
26static DUMBFILE_SYSTEM *the_dfs = NULL;
27
28
29
30void register_dumbfile_system(DUMBFILE_SYSTEM *dfs)
31{
32 ASSERT(dfs);
33 ASSERT(dfs->open);
34 ASSERT(dfs->getc);
35 ASSERT(dfs->close);
36 the_dfs = dfs;
37}
38
39
40
41struct DUMBFILE
42{
43 DUMBFILE_SYSTEM *dfs;
44 void *file;
45 long pos;
46};
47
48
49
50DUMBFILE *dumbfile_open(const char *filename)
51{
52 DUMBFILE *f;
53
54 ASSERT(the_dfs);
55
56 f = malloc(sizeof(*f));
57
58 if (!f)
59 return NULL;
60
61 f->dfs = the_dfs;
62
63 f->file = (*the_dfs->open)(filename);
64
65 if (!f->file) {
66 free(f);
67 return NULL;
68 }
69
70 f->pos = 0;
71
72 return f;
73}
74
75
76
77DUMBFILE *dumbfile_open_ex(void *file, DUMBFILE_SYSTEM *dfs)
78{
79 DUMBFILE *f;
80
81 ASSERT(dfs);
82 ASSERT(dfs->getc);
83 ASSERT(file);
84
85 f = malloc(sizeof(*f));
86
87 if (!f) {
88 if (dfs->close)
89 (*dfs->close)(file);
90 return NULL;
91 }
92
93 f->dfs = dfs;
94 f->file = file;
95
96 f->pos = 0;
97
98 return f;
99}
100
101
102
103long dumbfile_pos(DUMBFILE *f)
104{
105 ASSERT(f);
106
107 return f->pos;
108}
109
110
111
112int dumbfile_skip(DUMBFILE *f, long n)
113{
114 int rv;
115
116 ASSERT(f);
117 ASSERT(n >= 0);
118
119 if (f->pos < 0)
120 return -1;
121
122 f->pos += n;
123
124 if (f->dfs->skip) {
125 rv = (*f->dfs->skip)(f->file, n);
126 if (rv) {
127 f->pos = -1;
128 return rv;
129 }
130 } else {
131 while (n) {
132 rv = (*f->dfs->getc)(f->file);
133 if (rv < 0) {
134 f->pos = -1;
135 return rv;
136 }
137 n--;
138 }
139 }
140
141 return 0;
142}
143
144
145
146int dumbfile_getc(DUMBFILE *f)
147{
148 int rv;
149
150 ASSERT(f);
151
152 if (f->pos < 0)
153 return -1;
154
155 rv = (*f->dfs->getc)(f->file);
156
157 if (rv < 0) {
158 f->pos = -1;
159 return rv;
160 }
161
162 f->pos++;
163
164 return rv;
165}
166
167
168
169int dumbfile_igetw(DUMBFILE *f)
170{
171 int l, h;
172
173 ASSERT(f);
174
175 if (f->pos < 0)
176 return -1;
177
178 l = (*f->dfs->getc)(f->file);
179 if (l < 0) {
180 f->pos = -1;
181 return l;
182 }
183
184 h = (*f->dfs->getc)(f->file);
185 if (h < 0) {
186 f->pos = -1;
187 return h;
188 }
189
190 f->pos += 2;
191
192 return l | (h << 8);
193}
194
195
196
197int dumbfile_mgetw(DUMBFILE *f)
198{
199 int l, h;
200
201 ASSERT(f);
202
203 if (f->pos < 0)
204 return -1;
205
206 h = (*f->dfs->getc)(f->file);
207 if (h < 0) {
208 f->pos = -1;
209 return h;
210 }
211
212 l = (*f->dfs->getc)(f->file);
213 if (l < 0) {
214 f->pos = -1;
215 return l;
216 }
217
218 f->pos += 2;
219
220 return l | (h << 8);
221}
222
223
224
225long dumbfile_igetl(DUMBFILE *f)
226{
227 unsigned long rv, b;
228
229 ASSERT(f);
230
231 if (f->pos < 0)
232 return -1;
233
234 rv = (*f->dfs->getc)(f->file);
235 if ((signed long)rv < 0) {
236 f->pos = -1;
237 return rv;
238 }
239
240 b = (*f->dfs->getc)(f->file);
241 if ((signed long)b < 0) {
242 f->pos = -1;
243 return b;
244 }
245 rv |= b << 8;
246
247 b = (*f->dfs->getc)(f->file);
248 if ((signed long)b < 0) {
249 f->pos = -1;
250 return b;
251 }
252 rv |= b << 16;
253
254 b = (*f->dfs->getc)(f->file);
255 if ((signed long)b < 0) {
256 f->pos = -1;
257 return b;
258 }
259 rv |= b << 24;
260
261 f->pos += 4;
262
263 return rv;
264}
265
266
267
268long dumbfile_mgetl(DUMBFILE *f)
269{
270 unsigned long rv, b;
271
272 ASSERT(f);
273
274 if (f->pos < 0)
275 return -1;
276
277 rv = (*f->dfs->getc)(f->file);
278 if ((signed long)rv < 0) {
279 f->pos = -1;
280 return rv;
281 }
282 rv <<= 24;
283
284 b = (*f->dfs->getc)(f->file);
285 if ((signed long)b < 0) {
286 f->pos = -1;
287 return b;
288 }
289 rv |= b << 16;
290
291 b = (*f->dfs->getc)(f->file);
292 if ((signed long)b < 0) {
293 f->pos = -1;
294 return b;
295 }
296 rv |= b << 8;
297
298 b = (*f->dfs->getc)(f->file);
299 if ((signed long)b < 0) {
300 f->pos = -1;
301 return b;
302 }
303 rv |= b;
304
305 f->pos += 4;
306
307 return rv;
308}
309
310
311
312unsigned long dumbfile_cgetul(DUMBFILE *f)
313{
314 unsigned long rv = 0;
315 int v;
316
317 do {
318 v = dumbfile_getc(f);
319
320 if (v < 0)
321 return v;
322
323 rv <<= 7;
324 rv |= v & 0x7F;
325 } while (v & 0x80);
326
327 return rv;
328}
329
330
331
332signed long dumbfile_cgetsl(DUMBFILE *f)
333{
334 unsigned long rv = dumbfile_cgetul(f);
335
336 if (f->pos < 0)
337 return rv;
338
339 return (rv >> 1) | (rv << 31);
340}
341
342
343
344long dumbfile_getnc(char *ptr, long n, DUMBFILE *f)
345{
346 long rv;
347
348 ASSERT(f);
349 ASSERT(n >= 0);
350
351 if (f->pos < 0)
352 return -1;
353
354 if (f->dfs->getnc) {
355 rv = (*f->dfs->getnc)(ptr, n, f->file);
356 if (rv < n) {
357 f->pos = -1;
358 return MAX(rv, 0);
359 }
360 } else {
361 for (rv = 0; rv < n; rv++) {
362 int c = (*f->dfs->getc)(f->file);
363 if (c < 0) {
364 f->pos = -1;
365 return rv;
366 }
367 *ptr++ = c;
368 }
369 }
370
371 f->pos += rv;
372
373 return rv;
374}
375
376
377
378int dumbfile_error(DUMBFILE *f)
379{
380 ASSERT(f);
381
382 return f->pos < 0;
383}
384
385
386
387int dumbfile_close(DUMBFILE *f)
388{
389 int rv;
390
391 ASSERT(f);
392
393 rv = f->pos < 0;
394
395 if (f->dfs->close)
396 (*f->dfs->close)(f->file);
397
398 free(f);
399
400 return rv;
401}