#include "debug.h"
#include "cache.h"
#include "file.h"
+#include "atom.h"
#include "config.h"
#ifndef O_LARGEFILE
static struct cache *file_cache;
struct file_cache_id {
+ long long offset;
int size;
int file_name_id;
int method;
- long long offset;
-};
+} __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);
- if (! file)
- return file;
file->fd=open(name, O_RDONLY|O_LARGEFILE | O_BINARY);
if (file->fd == -1) {
g_free(file);
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;
}
+long long
+file_size(struct file *file)
+{
+ return file->size;
+}
+
int file_mkdir(char *name, int pflag)
{
char buffer[strlen(name)+1];
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");
}
#endif
dbg_assert(file->begin != (void *)0xffffffff);
+ file->mmap_end=file->begin+mmap_size;
file->end=file->begin+file->size;
return 1;
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) {
}
+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, 0);
+ if (!file)
+ return 0;
+ *size=file_size(file);
+ *buffer=file_data_read_all(file);
+ file_destroy(file);
+ return 1;
+}
+
+
static int
uncompress_int(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
{
file_data_read_compressed(struct file *file, long long offset, int size, int size_uncomp)
{
void *ret;
- char buffer[size];
+ char *buffer = 0;
uLongf destLen=size_uncomp;
if (file_cache) {
} else
ret=g_malloc(size_uncomp);
lseek(file->fd, offset, SEEK_SET);
+
+ buffer = (char *)g_malloc(size);
if (read(file->fd, buffer, size) != size) {
g_free(ret);
ret=NULL;
ret=NULL;
}
}
+ g_free(buffer);
+
return ret;
}
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);
}
struct file *
-file_create_caseinsensitive(char *name)
+file_create_caseinsensitive(char *name, enum file_flags flags)
{
char dirname[strlen(name)+1];
char *filename;
void *d;
struct file *ret;
- ret=file_create(name);
+ ret=file_create(name, flags);
if (ret)
return ret;
while ((filename=file_readdir(d))) {
if (!strcasecmp(filename, p)) {
strcpy(p, filename);
- ret=file_create(dirname);
+ ret=file_create(dirname, flags);
if (ret)
break;
}
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 )
{
}
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
void *
file_get_os_handle(struct file *file)
{
- return (void *)(file->fd);
+ return GINT_TO_POINTER(file->fd);
}
void