GRASS Programmer's Manual 6.4.1(2011)
|
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 }