file.c

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

Generated on Sun Apr 6 17:32:44 2008 for GRASS by  doxygen 1.5.5