src/fileman.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. vf_fm_init
  2. vf_fm_OpenTextFileStream
  3. vf_fm_OpenBinaryFileStream
  4. get_file_stream
  5. vf_fm_OpenFileStreamApp
  6. vf_fm_CloseTextFileStream
  7. vf_fm_CloseBinaryFileStream
  8. close_file_stream
  9. vf_fm_CloseFileStreamApp
  10. open_file
  11. close_file
  12. simple_open
  13. simple_close
  14. vf_fm_Init
  15. vf_fm_OpenFileStream
  16. vf_fm_GetFileStream
  17. open_file
  18. 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*/

/* [<][>][^][v][top][bottom][index][help] */