file.c

Go to the documentation of this file.
00001 
00020 #include <string.h>
00021 #include <stdio.h>
00022 #include <unistd.h>
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 #include <grass/gis.h>
00026 #include <grass/Vect.h>
00027 #include <grass/glocale.h>
00028 
00036 long dig_ftell(GVFILE *file)
00037 {
00038     if (file->loaded) /* using memory */
00039         return (file->current - file->start);
00040 
00041     return (ftell(file->file));
00042 }
00043 
00060 int dig_fseek(GVFILE * file, long offset, int whence)
00061 {
00062     if (file->loaded) {  /* using memory */
00063         switch (whence) {
00064         case SEEK_SET:
00065             file->current = file->start + offset;
00066             break;
00067         case SEEK_CUR:
00068             file->current += offset;
00069             break;
00070         case SEEK_END:
00071             file->current = file->start + file->size + offset;
00072             break;
00073         }
00074         return 0;
00075     }
00076 
00077     return (fseek(file->file, offset, whence));
00078 }
00079 
00085 void dig_rewind(GVFILE * file)
00086 {
00087     if (file->loaded) { /* using memory */
00088         file->current = file->start;
00089     }
00090     else {
00091         rewind(file->file);
00092     }
00093 }
00094 
00102 int dig_fflush(GVFILE * file)
00103 {
00104     if (file->loaded) { /* using memory */
00105         return 0;
00106     }
00107     else {
00108         return (fflush(file->file));
00109     }
00110 }
00111 
00122 size_t dig_fread(void *ptr, size_t size, size_t nmemb, GVFILE *file)
00123 {
00124     long tot;
00125     size_t cnt;
00126 
00127     if (file->loaded) { /* using memory */
00128         if (file->current >= file->end) { /* EOF */
00129             return 0;
00130         }
00131         tot = size * nmemb;
00132         cnt = nmemb;
00133         if (file->current + tot > file->end) {
00134             tot = file->end - file->current;
00135             cnt = (int)tot / size;
00136         }
00137         memcpy(ptr, file->current, tot);
00138         file->current += tot;
00139         return (cnt);
00140     }
00141     return (fread(ptr, size, nmemb, file->file));
00142 }
00143 
00154 size_t dig_fwrite(void *ptr, size_t size, size_t nmemb, GVFILE *file)
00155 {
00156     if (file->loaded) { /* using memory */
00157         G_fatal_error(_("Writing to file loaded to memory not supported"));
00158     }
00159 
00160     return fwrite(ptr, size, nmemb, file->file);
00161 }
00162 
00168 void dig_file_init(GVFILE *file)
00169 {
00170     file->file = NULL;
00171     file->start = NULL;
00172     file->current = NULL;
00173     file->end = NULL;
00174     file->size = 0;
00175     file->alloc = 0;
00176     file->loaded = 0;
00177 }
00178 
00190 int dig_file_load(GVFILE * file)
00191 {
00192     int ret, mode, load;
00193     char *cmode;
00194     size_t size;
00195     struct stat sbuf;
00196 
00197     G_debug(2, "dig_file_load ()");
00198 
00199     if (file->file == NULL) {
00200         G_warning(_("Unable to load file to memory, file not open"));
00201         return -1;
00202     }
00203 
00204     /* Get mode */
00205     mode = GV_MEMORY_NEVER;
00206     cmode = G__getenv("GV_MEMORY");
00207     if (cmode != NULL) {
00208         if (G_strcasecmp(cmode, "ALWAYS") == 0)
00209             mode = GV_MEMORY_ALWAYS;
00210         else if (G_strcasecmp(cmode, "NEVER") == 0)
00211             mode = GV_MEMORY_NEVER;
00212         else if (G_strcasecmp(cmode, "AUTO") == 0)
00213             mode = GV_MEMORY_AUTO;
00214         else
00215             G_warning(_("Vector memory mode not supported, using 'AUTO'"));
00216     }
00217     G_debug(2, "  requested mode = %d", mode);
00218 
00219 
00220     fstat(fileno(file->file), &sbuf);
00221     size = sbuf.st_size;
00222     
00223     G_debug(2, "  size = %u", size);
00224     
00225     /* Decide if the file should be loaded */
00226     /* TODO: I don't know how to get size of free memory (portability) to decide if load or not for auto */
00227     if (mode == GV_MEMORY_AUTO)
00228         mode = GV_MEMORY_NEVER;
00229     if (mode == GV_MEMORY_ALWAYS)
00230         load = 1;
00231     else
00232         load = 0;
00233 
00234     if (load) {
00235         file->start = G_malloc(size);
00236         if (file->start == NULL)
00237             return -1;
00238 
00239         fseek(file->file, 0L, 0);
00240         ret = fread(file->start, size, 1, file->file);  /* Better to read in smaller portions? */
00241         fseek(file->file, 0L, 0);       /* reset to the beginning */
00242 
00243         if (ret <= 0) {
00244             G_free(file->start);
00245             return -1;
00246         }
00247 
00248         file->alloc = size;
00249         file->size = size;
00250         file->current = file->start;
00251         file->end = file->start + size;
00252 
00253         file->loaded = 1;
00254         G_debug(2, "  file was loaded to the memory");
00255         return 1;
00256     }
00257     else {
00258         G_debug(2, "  file was not loaded to the memory");
00259     }
00260 
00261     return 0;
00262 }
00263 
00269 void dig_file_free(GVFILE * file)
00270 {
00271     if (file->loaded) {
00272         G_free(file->start);
00273         file->loaded = 0;
00274         file->alloc = 0;
00275     }
00276 }