file.c

Go to the documentation of this file.
00001 
00002 /****************************************************************************
00003 *
00004 * MODULE:       Vector library 
00005 *               
00006 * AUTHOR(S):    Dave Gerdes, Radim Blazek
00007 *
00008 * PURPOSE:      Lower level functions for reading/writing/manipulating vectors.
00009 *
00010 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00011 *
00012 *               This program is free software under the GNU General Public
00013 *               License (>=v2). Read the file COPYING that comes with GRASS
00014 *               for details.
00015 *
00016 *****************************************************************************/
00017 #include <string.h>
00018 #include <stdio.h>
00019 #include <unistd.h>
00020 #include <sys/types.h>
00021 #include <sys/stat.h>
00022 #include <grass/gis.h>
00023 #include <grass/Vect.h>
00024 
00025 /* 
00026  *  Note: seems that the time is almost the same for both cases: 
00027  *        - reading from file 
00028  *        - load whole file to memory and read from memory
00029  */
00030 
00031 /* Get GVFILE position.
00032  *
00033  *  Returns: current file position
00034  */
00035 long dig_ftell(GVFILE * file)
00036 {
00037     if (file->loaded)           /* using memory */
00038         return (file->current - file->start);
00039 
00040     return (ftell(file->file));
00041 }
00042 
00043 /* Set GVFILE position.
00044  *
00045  *  Returns: 0 OK, -1 error
00046  */
00047 int dig_fseek(GVFILE * file, long offset, int whence)
00048 {
00049     if (file->loaded) {         /* using memory */
00050         switch (whence) {
00051         case SEEK_SET:
00052             file->current = file->start + offset;
00053             break;
00054         case SEEK_CUR:
00055             file->current += offset;
00056             break;
00057         case SEEK_END:
00058             file->current = file->start + file->size + offset;
00059             break;
00060         }
00061         return 0;
00062     }
00063 
00064     return (fseek(file->file, offset, whence));
00065 }
00066 
00067 /* Rewind  GVFILE position.
00068  *
00069  *  Returns: nothing
00070  */
00071 void dig_rewind(GVFILE * file)
00072 {
00073     if (file->loaded) {         /* using memory */
00074         file->current = file->start;
00075     }
00076     else {
00077         rewind(file->file);
00078     }
00079 }
00080 
00081 /* Flush GVFILE.
00082  *
00083  *  Returns: nothing
00084  */
00085 int dig_fflush(GVFILE * file)
00086 {
00087     if (file->loaded) {         /* using memory */
00088         return 0;
00089     }
00090     else {
00091         return (fflush(file->file));
00092     }
00093 }
00094 
00095 /* Read GVFILE.
00096  *
00097  *  Returns: number of read members
00098  */
00099 size_t dig_fread(void *ptr, size_t size, size_t nmemb, GVFILE * file)
00100 {
00101     long tot;
00102     size_t cnt;
00103 
00104     if (file->loaded) {         /* using memory */
00105         if (file->current >= file->end) {       /* EOF */
00106             return 0;
00107         }
00108         tot = size * nmemb;
00109         cnt = nmemb;
00110         if (file->current + tot > file->end) {
00111             tot = file->end - file->current;
00112             cnt = (int)tot / size;
00113         }
00114         memcpy(ptr, file->current, tot);
00115         file->current += tot;
00116         return (cnt);
00117     }
00118     return (fread(ptr, size, nmemb, file->file));
00119 }
00120 
00121 /* Write GVFILE.
00122  *
00123  *  Returns: number of items written
00124  */
00125 size_t dig_fwrite(void *ptr, size_t size, size_t nmemb, GVFILE * file)
00126 {
00127     if (file->loaded) {         /* using memory */
00128         G_fatal_error("Writing to file loaded to memory not supported");
00129     }
00130 
00131     return fwrite(ptr, size, nmemb, file->file);
00132 }
00133 
00134 /* Init GVFILE.
00135  *
00136  *  Returns: nothing
00137  */
00138 void dig_file_init(GVFILE * file)
00139 {
00140     file->file = NULL;
00141     file->start = NULL;
00142     file->current = NULL;
00143     file->end = NULL;
00144     file->size = 0;
00145     file->alloc = 0;
00146     file->loaded = 0;
00147 }
00148 
00149 /* Load opened GVFILE to memory.
00150  *  Warning: position in file is set to the beginning.
00151  *
00152  *  Returns: 1 loaded, 0, not loaded, -1 Error
00153  */
00154 int dig_file_load(GVFILE * file)
00155 {
00156     int ret, mode, load;
00157     char *cmode;
00158     size_t size;
00159     struct stat sbuf;
00160 
00161     G_debug(2, "dig_file_load ()");
00162 
00163     if (file->file == NULL) {
00164         G_warning("Cannot load file to memory, file not open.");
00165         return -1;
00166     }
00167 
00168     /* Get mode */
00169     mode = GV_MEMORY_NEVER;
00170     cmode = G__getenv("GV_MEMORY");
00171     if (cmode != NULL) {
00172         if (G_strcasecmp(cmode, "ALWAYS") == 0)
00173             mode = GV_MEMORY_ALWAYS;
00174         else if (G_strcasecmp(cmode, "NEVER") == 0)
00175             mode = GV_MEMORY_NEVER;
00176         else if (G_strcasecmp(cmode, "AUTO") == 0)
00177             mode = GV_MEMORY_AUTO;
00178         else
00179             G_warning("Vector memory mode not supported, using 'AUTO'");
00180     }
00181     G_debug(2, "  requested mode = %d", mode);
00182 
00183 
00184     fstat(fileno(file->file), &sbuf);
00185     size = sbuf.st_size;
00186 
00187     G_debug(2, "  size = %u", size);
00188 
00189     /* Decide if the file should be loaded */
00190     /* TODO: I don't know how to get size of free memory (portability) to decide if load or not for auto */
00191     if (mode == GV_MEMORY_AUTO)
00192         mode = GV_MEMORY_NEVER;
00193     if (mode == GV_MEMORY_ALWAYS)
00194         load = 1;
00195     else
00196         load = 0;
00197 
00198     if (load) {
00199         file->start = G_malloc(size);
00200         if (file->start == NULL)
00201             return -1;
00202 
00203         fseek(file->file, 0L, 0);
00204         ret = fread(file->start, size, 1, file->file);  /* Better to read in smaller portions? */
00205         fseek(file->file, 0L, 0);       /* reset to the beginning */
00206 
00207         if (ret <= 0) {
00208             G_free(file->start);
00209             return -1;
00210         }
00211 
00212         file->alloc = size;
00213         file->size = size;
00214         file->current = file->start;
00215         file->end = file->start + size;
00216 
00217         file->loaded = 1;
00218         G_debug(2, "  file was loaded to the memory");
00219         return 1;
00220     }
00221     else {
00222         G_debug(2, "  file was not loaded to the memory");
00223     }
00224 
00225     return 0;
00226 }
00227 
00228 /* Free GVFILE.
00229  *
00230  *  Returns: nothing
00231  */
00232 void dig_file_free(GVFILE * file)
00233 {
00234     if (file->loaded) {
00235         G_free(file->start);
00236         file->loaded = 0;
00237         file->alloc = 0;
00238     }
00239 }

Generated on Thu Jul 16 13:21:17 2009 for GRASS Programmer's Manual by  doxygen 1.5.6