Fix:maptool:Another name for faroe islands
[navit-package] / navit / file.c
index 890dcbf..b41d269 100644 (file)
@@ -33,6 +33,7 @@
 #include "debug.h"
 #include "cache.h"
 #include "file.h"
+#include "atom.h"
 #include "config.h"
 
 #ifndef O_LARGEFILE
@@ -57,7 +58,7 @@ struct file_cache_id {
 } __attribute__ ((packed));
 
 struct file *
-file_create(char *name)
+file_create(char *name, enum file_flags flags)
 {
        struct stat stat;
        struct file *file= g_new0(struct file,1);
@@ -72,10 +73,28 @@ file_create(char *name)
        file->size=stat.st_size;
        dbg(1,"size=%Ld\n", file->size);
        file->name = g_strdup(name);
+       file->name_id = (int)atom(name);
+       if (file_cache && !(flags & file_flag_nocache)) 
+               file->cache=1;
        dbg_assert(file != NULL);
        return file;
 }
 
+#if 0
+struct file *
+file_create_url(char *url)
+{
+       struct file *file= g_new0(struct file,1);
+       char *cmd=g_strdup_printf("curl %s",url);
+       file->name = g_strdup(url);
+       file->stdfile=popen(cmd,"r");
+       file->fd=fileno(file->stdfile);
+       file->special=1;
+       g_free(cmd);
+       return file;
+}
+#endif
+
 int file_is_dir(char *name)
 {
        struct stat buf;
@@ -86,7 +105,7 @@ int file_is_dir(char *name)
 
 }
 
-int
+long long
 file_size(struct file *file)
 {
        return file->size;
@@ -126,10 +145,15 @@ int file_mkdir(char *name, int pflag)
 int
 file_mmap(struct file *file)
 {
-#if defined(_WIN32) || defined(__CEGCC__)
-    file->begin = (char*)mmap_readonly_win32( file->name, &file->map_handle, &file->map_file );
+#if 0
+       int mmap_size=file->size+1024*1024;
 #else
-       file->begin=mmap(NULL, file->size, PROT_READ|PROT_WRITE, MAP_PRIVATE, file->fd, 0);
+       int mmap_size=file->size;
+#endif
+#ifdef HAVE_API_WIN32_BASE
+       file->begin = (char*)mmap_readonly_win32( file->name, &file->map_handle, &file->map_file );
+#else
+       file->begin=mmap(NULL, mmap_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, file->fd, 0);
        dbg_assert(file->begin != NULL);
        if (file->begin == (void *)0xffffffff) {
                perror("mmap");
@@ -137,6 +161,7 @@ file_mmap(struct file *file)
        }
 #endif
        dbg_assert(file->begin != (void *)0xffffffff);
+       file->mmap_end=file->begin+mmap_size;
        file->end=file->begin+file->size;
 
        return 1;
@@ -146,6 +171,8 @@ unsigned char *
 file_data_read(struct file *file, long long offset, int size)
 {
        void *ret;
+       if (file->special)
+               return NULL;
        if (file->begin)
                return file->begin+offset;
        if (file_cache) {
@@ -166,16 +193,42 @@ file_data_read(struct file *file, long long offset, int size)
 }
 
 unsigned char *
+file_data_read_special(struct file *file, int size, int *size_ret)
+{
+       void *ret;
+       if (!file->special)
+               return NULL;
+       ret=g_malloc(size);
+       *size_ret=read(file->fd, ret, size);
+       return ret;
+}
+
+unsigned char *
 file_data_read_all(struct file *file)
 {
        return file_data_read(file, 0, file->size);
 }
 
 int
+file_data_write(struct file *file, long long offset, int size, unsigned char *data)
+{
+       if (file_cache) {
+               struct file_cache_id id={offset,size,file->name_id,0};
+               cache_flush(file_cache,&id);
+       }
+       lseek(file->fd, offset, SEEK_SET);
+       if (write(file->fd, data, size) != size)
+               return 0;
+       if (file->size < offset+size)
+               file->size=offset+size;
+       return 1;
+}
+
+int
 file_get_contents(char *name, unsigned char **buffer, int *size)
 {
        struct file *file;
-       file=file_create(name);
+       file=file_create(name, 0);
        if (!file)
                return 0;
        *size=file_size(file);
@@ -251,9 +304,13 @@ file_data_read_compressed(struct file *file, long long offset, int size, int siz
 void
 file_data_free(struct file *file, unsigned char *data)
 {
-       if (file->begin && data >= file->begin && data < file->end)
-               return;
-       if (file_cache) {
+       if (file->begin) {
+               if (data == file->begin)
+                       return;
+               if (data >= file->begin && data < file->end)
+                       return;
+       }       
+       if (file->cache && data) {
                cache_entry_destroy(file_cache, data);
        } else
                g_free(data);
@@ -315,7 +372,7 @@ file_closedir(void *hnd)
 }
 
 struct file *
-file_create_caseinsensitive(char *name)
+file_create_caseinsensitive(char *name, enum file_flags flags)
 {
        char dirname[strlen(name)+1];
        char *filename;
@@ -323,7 +380,7 @@ file_create_caseinsensitive(char *name)
        void *d;
        struct file *ret;
 
-       ret=file_create(name);
+       ret=file_create(name, flags);
        if (ret)
                return ret;
 
@@ -341,7 +398,7 @@ file_create_caseinsensitive(char *name)
                while ((filename=file_readdir(d))) {
                        if (!strcasecmp(filename, p)) {
                                strcpy(p, filename);
-                               ret=file_create(dirname);
+                               ret=file_create(dirname, flags);
                                if (ret)
                                        break;
                        }
@@ -354,7 +411,16 @@ file_create_caseinsensitive(char *name)
 void
 file_destroy(struct file *f)
 {
-       close(f->fd);
+       switch (f->special) {
+       case 0:
+               close(f->fd);
+               break;
+#if 0
+       case 1:
+               pclose(f->stdfile);
+               break;
+#endif
+       }
 
     if ( f->begin != NULL )
     {
@@ -412,20 +478,31 @@ file_get_param(struct file *file, struct param_list *param, int count)
 }
 
 int
-file_version(struct file *file, int byname)
+file_version(struct file *file, int mode)
 {
-#ifndef __CEGCC__
+#ifndef HAVE_API_WIN32_BASE
        struct stat st;
        int error;
-       if (byname)
-               error=stat(file->name, &st);
-       else
-               error=fstat(file->fd, &st);
-       if (error || !file->version || file->mtime != st.st_mtime || file->ctime != st.st_ctime) {
-               file->mtime=st.st_mtime;
-               file->ctime=st.st_ctime;
-               file->version++;
-               dbg(0,"%s now version %d\n", file->name, file->version);
+       if (mode == 3) {
+               long long size=lseek(file->fd, 0, SEEK_END);
+               if (file->begin && file->begin+size > file->mmap_end) {
+                       file->version++;
+               } else {
+                       file->size=size;
+                       if (file->begin)
+                               file->end=file->begin+file->size;
+               }
+       } else {
+               if (mode == 2)
+                       error=stat(file->name, &st);
+               else
+                       error=fstat(file->fd, &st);
+               if (error || !file->version || file->mtime != st.st_mtime || file->ctime != st.st_ctime) {
+                       file->mtime=st.st_mtime;
+                       file->ctime=st.st_ctime;
+                       file->version++;
+                       dbg(1,"%s now version %d\n", file->name, file->version);
+               }
        }
        return file->version;
 #else
@@ -436,7 +513,7 @@ file_version(struct file *file, int byname)
 void *
 file_get_os_handle(struct file *file)
 {
-       return (void *)(file->fd);
+       return GINT_TO_POINTER(file->fd);
 }
 
 void