src/fileman.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- vf_fm_init
- vf_fm_OpenTextFileStream
- vf_fm_OpenBinaryFileStream
- get_file_stream
- vf_fm_OpenFileStreamApp
- vf_fm_CloseTextFileStream
- vf_fm_CloseBinaryFileStream
- close_file_stream
- vf_fm_CloseFileStreamApp
- open_file
- close_file
- simple_open
- simple_close
- vf_fm_Init
- vf_fm_OpenFileStream
- vf_fm_GetFileStream
- open_file
- close_file
1 /*
2 * fileman.c - a module for file descripter management
3 * by Hirotsugu Kakugawa
4 *
5 */
6 /*
7 * Copyright (C) 1996-1998 Hirotsugu Kakugawa.
8 * All rights reserved.
9 *
10 * This file is part of the VFlib Library. This library is free
11 * software; you can redistribute it and/or modify it under the terms of
12 * the GNU Library General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your
14 * option) any later version. This library is distributed in the hope
15 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
16 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
17 * PURPOSE. See the GNU Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23 #include "config.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include "VFlib-3_6.h"
27 #include "VFsys.h"
28 #include "cache.h"
29 #include "consts.h"
30
31
32 #define VF_MAX_FD_HASH 101
33 Private VF_CACHE fp_cache = NULL;
34 Private int fp_case_size = VF_MAX_FILE_DESCRIPTERS;
35
36
37
38 #if 1
39
40 /* NEW CODE */
41
42
43 struct s_ck {
44 char path[MAXPATHLEN+16];
45 long iarg1, iarg2;
46 void *arg1, *arg2;
47 FM_OPEN_METHOD open;
48 FM_CLOSE_METHOD close;
49 /* debug msg */
50 char dbgmsg[160];
51 };
52 typedef struct s_ck CK;
53
54 struct s_val {
55 void *val;
56 long iarg1, iarg2;
57 void *arg1, *arg2;
58 FM_OPEN_METHOD open;
59 FM_CLOSE_METHOD close;
60 };
61 typedef struct s_val VAL;
62
63 Private FILE *get_file_stream(char *file_path, int bin_file);
64 Private void close_file_stream(char *file_path, int bin_file);
65 Private VAL *open_file(VF_CACHE,CK*,int);
66 Private void close_file(VAL*);
67 Private void *simple_open(char*,long,long,void*,void*);
68 Private void simple_close(void*,long,long,void*,void*);
69
70 static int debug_fileman = 0;
71
72
73 Public int
74 vf_fm_init(void)
/* [<][>][^][v][top][bottom][index][help] */
75 {
76 char *s;
77
78 if (fp_cache != NULL){
79 /* XXX TO DO: dispose fp_cache here */
80 }
81
82 debug_fileman = 0;
83 if (getenv(VF_ENV_DEBUG_FILEMAN) != NULL)
84 debug_fileman = 1;
85
86 fp_case_size = VF_MAX_FILE_DESCRIPTERS;
87 if ((s = getenv(VF_ENV_MAX_FILE_DESCRIPTERS)) != NULL)
88 fp_case_size = atoi(s);
89 if (fp_case_size < 1)
90 fp_case_size = VF_MAX_FILE_DESCRIPTERS;
91 if (debug_fileman != 0)
92 printf("VFlib fileman: #fd = %d\n", fp_case_size);
93
94 fp_cache = vf_cache_create(fp_case_size, VF_MAX_FD_HASH,
95 (void*(*)(VF_CACHE,void*,int))open_file,
96 (void(*)(void*))close_file);
97 if (fp_cache == NULL){
98 vf_error = VF_ERR_NO_MEMORY;
99 return -1;
100 }
101
102 return 0;
103 }
104
105 Public FILE*
106 vf_fm_OpenTextFileStream(char *file_path)
/* [<][>][^][v][top][bottom][index][help] */
107 {
108 FILE *fp;
109
110 if ((fp = get_file_stream(file_path, 0)) != NULL)
111 fseek(fp, 0L, SEEK_SET);
112 return fp;
113 }
114
115 Public FILE*
116 vf_fm_OpenBinaryFileStream(char *file_path)
/* [<][>][^][v][top][bottom][index][help] */
117 {
118 FILE *fp;
119
120 if ((fp = get_file_stream(file_path, 1)) != NULL)
121 fseek(fp, 0L, SEEK_SET);
122 return fp;
123 }
124
125 Private FILE*
126 get_file_stream(char *file_path, int bin_file)
/* [<][>][^][v][top][bottom][index][help] */
127 {
128 struct s_ck ck;
129 struct s_val *val;
130
131 if (debug_fileman != 0)
132 printf("VFlib fileman: Get file stream for %s\n", file_path);
133
134 if (file_path == NULL)
135 return NULL;
136
137 memset(&ck, 0, sizeof(ck));
138 strncpy(ck.path, file_path, sizeof(ck.path));
139 ck.iarg1 = 0;
140 ck.iarg2 = 0;
141 ck.arg1 = (void*)bin_file;
142 ck.arg2 = NULL;
143 ck.open = simple_open;
144 ck.close = simple_close;
145 strncpy(ck.dbgmsg, file_path, sizeof(ck.dbgmsg));
146
147 if ((val = (fp_cache->get)(fp_cache, &ck, sizeof(struct s_ck))) == NULL){
148 vf_error = VF_ERR_CANT_OPEN;
149 return NULL;
150 }
151
152 return val->val;
153 }
154
155
156 Public void*
157 vf_fm_OpenFileStreamApp(char *arg,
/* [<][>][^][v][top][bottom][index][help] */
158 long iarg1, long iarg2, void *arg1, void *arg2,
159 FM_OPEN_METHOD open_method,
160 FM_CLOSE_METHOD close_method,
161 char *dbgmsg)
162 {
163 struct s_ck ck;
164 struct s_val *val;
165
166 if ((debug_fileman != 0) && (dbgmsg != NULL))
167 printf("VFlib fileman: Get file stream %s (%s)\n", arg, dbgmsg);
168
169 memset(&ck, 0, sizeof(ck));
170 if (arg != NULL)
171 strncpy(ck.path, arg, sizeof(ck.path));
172 ck.iarg1 = iarg1;
173 ck.iarg2 = iarg2;
174 ck.arg1 = arg1;
175 ck.arg2 = arg2;
176 ck.open = open_method;
177 ck.close = close_method;
178 if (dbgmsg != NULL)
179 strncpy(ck.dbgmsg, dbgmsg, sizeof(ck.dbgmsg));
180
181 if ((val = (fp_cache->get)(fp_cache, &ck, sizeof(ck))) == NULL){
182 vf_error = VF_ERR_CANT_OPEN;
183 return NULL;
184 }
185
186 return val->val;
187 }
188
189
190 Public void
191 vf_fm_CloseTextFileStream(char *file_path)
/* [<][>][^][v][top][bottom][index][help] */
192 {
193 close_file_stream(file_path, 0);
194 }
195
196 Public void
197 vf_fm_CloseBinaryFileStream(char *file_path)
/* [<][>][^][v][top][bottom][index][help] */
198 {
199 close_file_stream(file_path, 1);
200 }
201
202 Public void
203 close_file_stream(char *file_path, int bin_file)
/* [<][>][^][v][top][bottom][index][help] */
204 {
205 struct s_ck ck;
206
207 if (debug_fileman != 0)
208 printf("VFlib fileman: Close file stream for %s\n", file_path);
209
210 if (file_path == NULL)
211 return;
212
213 memset(&ck, 0, sizeof(ck));
214 strncpy(ck.path, file_path, sizeof(ck.path));
215 ck.iarg1 = 0;
216 ck.iarg2 = 0;
217 ck.arg1 = (void*)bin_file;
218 ck.arg2 = NULL;
219 ck.open = simple_open;
220 ck.close = simple_close;
221 strncpy(ck.dbgmsg, file_path, sizeof(ck.dbgmsg));
222
223 (fp_cache->del)(fp_cache, &ck, sizeof(struct s_ck));
224 }
225
226 Public void
227 vf_fm_CloseFileStreamApp(char *arg,
/* [<][>][^][v][top][bottom][index][help] */
228 long iarg1, long iarg2, void *arg1, void *arg2,
229 FM_OPEN_METHOD open_method,
230 FM_CLOSE_METHOD close_method,
231 char *dbgmsg)
232 {
233 struct s_ck ck;
234
235 if ((debug_fileman != 0) && (dbgmsg != NULL))
236 printf("VFlib fileman: Close App file stream %s (%s)\n", arg, dbgmsg);
237
238 memset(&ck, 0, sizeof(ck));
239 if (arg != NULL)
240 strncpy(ck.path, arg, sizeof(ck.path));
241 ck.iarg1 = iarg1;
242 ck.iarg2 = iarg2;
243 ck.arg1 = arg1;
244 ck.arg2 = arg2;
245 ck.open = open_method;
246 ck.close = close_method;
247 if (dbgmsg != NULL)
248 strncpy(ck.dbgmsg, dbgmsg, sizeof(ck.dbgmsg));
249
250 (fp_cache->del)(fp_cache, &ck, sizeof(struct s_ck));
251 }
252
253
254
255
256 /* Cache Loader and Disposer */
257
258 Private VAL*
259 open_file(VF_CACHE c, CK *ck, int key_len)
/* [<][>][^][v][top][bottom][index][help] */
260 {
261 VAL *val;
262
263 ALLOC_IF_ERR(val, VAL){
264 return NULL;
265 }
266 val->iarg1 = ck->iarg1;
267 val->iarg2 = ck->iarg2;
268 val->arg1 = ck->arg1;
269 val->arg2 = ck->arg2;
270 val->open = ck->open;
271 val->close = ck->close;
272
273 if (debug_fileman != 0)
274 printf("VFlib fileman: call open function for %s\n", ck->dbgmsg);
275 val->val = ck->open(ck->path, ck->iarg1, ck->iarg2, ck->arg1, ck->arg2);
276
277 return val;
278 }
279
280 Private void
281 close_file(VAL *val)
/* [<][>][^][v][top][bottom][index][help] */
282 {
283 if (debug_fileman != 0)
284 printf("VFlib fileman: call close function\n");
285 val->close(val->val, val->iarg1, val->iarg2, val->arg1, val->arg2);
286 vf_free(val);
287 }
288
289
290
291 /* Simple File Opener/Closer */
292
293 Private void*
294 simple_open(char *path, long iarg1, long iarg2, void *arg1, void *arg2)
/* [<][>][^][v][top][bottom][index][help] */
295 {
296 FILE *fp;
297 char *mode;
298
299 if ((int)arg1 == 1)
300 mode = "rb";
301 else
302 mode = "rt";
303
304 fp = fopen(path, mode);
305
306 if (debug_fileman != 0){
307 printf("VFlib fileman: fopen(\"%s\", \"%s\")\n", path, mode);
308 printf(" ==> %p\n", fp);
309 }
310
311 return fp;
312 }
313
314 Private void
315 simple_close(void *v, long iarg1, long iarg2, void *arg1, void *arg2)
/* [<][>][^][v][top][bottom][index][help] */
316 {
317 FILE *fp = (FILE*)v;
318
319 if (debug_fileman != 0)
320 printf("VFlib fileman: fclose %p\n", fp);
321
322 if (fp != NULL)
323 fclose(fp);
324 }
325
326
327
328 #else /* old code */
329
330
331 static int last_file_valid = 0;
332 static char *last_file_path = NULL; /* a kind of a cache */
333 static int last_file_path_size = 0;
334 static FILE *last_fp = NULL;
335
336 Private FILE* open_file(VF_CACHE c, char *key, int key_len);
337 Private void close_file(FILE* fp);
338
339
340 Public int
341 vf_fm_Init(void)
/* [<][>][^][v][top][bottom][index][help] */
342 {
343 if (fp_cache != NULL){
344 /* XXX TO DO: dispose fp_cache here */
345 }
346
347 fp_cache = vf_cache_create(VF_MAX_FILE_DESCRIPTERS, VF_MAX_FD_HASH,
348 (void*(*)(VF_CACHE,void*,int))open_file,
349 (void(*)(void*))close_file);
350 if (fp_cache == NULL){
351 vf_error = VF_ERR_NO_MEMORY;
352 return -1;
353 }
354
355 return 0;
356 }
357
358 Public FILE*
359 vf_fm_OpenFileStream(char *file_path)
/* [<][>][^][v][top][bottom][index][help] */
360 {
361 FILE *fp;
362
363 if ((fp = vf_fm_GetFileStream(file_path)) != NULL)
364 fseek(fp, 0L, SEEK_SET);
365
366 return fp;
367 }
368
369 Public FILE*
370 vf_fm_GetFileStream(char *file_path)
/* [<][>][^][v][top][bottom][index][help] */
371 {
372 FILE *fp;
373 int n;
374
375 #if 0
376 printf("FileMan: Path %s\n", file_path);
377 #endif
378
379 if (file_path == NULL)
380 return NULL;
381
382 if ((last_file_path != NULL) && (last_fp != NULL) && (last_file_valid == 1)
383 && (strcmp(last_file_path, file_path) == 0)){
384 return last_fp;
385 }
386
387 if ((fp = (fp_cache->get)(fp_cache, file_path,
388 strlen(file_path)+1)) == NULL){
389 vf_error = VF_ERR_CANT_OPEN;
390 return NULL;
391 }
392
393 if (last_file_path_size < strlen(file_path)+1){
394 n = strlen(file_path) + 64;
395 vf_free(last_file_path);
396 ALLOCN_IF_ERR(last_file_path, char, n){
397 last_file_valid = 0;
398 last_file_path_size = 0;
399 last_file_path = NULL;
400 return fp;
401 }
402 last_file_path_size = n;
403 last_file_valid = 1;
404 strcpy(last_file_path, file_path);
405 }
406
407 return fp;
408 }
409
410
411
412 /* cache loader */
413 Private FILE*
414 open_file(VF_CACHE c, char *key, int key_len)
/* [<][>][^][v][top][bottom][index][help] */
415 {
416 #if 0
417 printf("FileMan: Open %s\n", key);
418 #endif
419
420 return fopen(key, FOPEN_RD_MODE_BIN);
421 }
422
423 /* cache disposer */
424 Private void
425 close_file(FILE* fp)
/* [<][>][^][v][top][bottom][index][help] */
426 {
427 /*printf("FileMan: Close \n");*/
428 if (last_fp == fp)
429 last_fp = NULL;
430 if (fp != NULL)
431 fclose(fp);
432 }
433
434
435 #endif
436
437
438
439
440 /*EOF*/