Enlightenment CVS committal Author : raster Project : e17 Module : libs/eet
Dir : e17/libs/eet/src/lib Modified Files: Eet.h eet_data.c eet_image.c eet_lib.c Log Message: cedric's eet race patch =================================================================== RCS file: /cvs/e/e17/libs/eet/src/lib/Eet.h,v retrieving revision 1.42 retrieving revision 1.43 diff -u -3 -r1.42 -r1.43 --- Eet.h 20 Dec 2007 07:22:52 -0000 1.42 +++ Eet.h 21 Jan 2008 01:09:51 -0000 1.43 @@ -253,7 +253,7 @@ * If the eet file handle is not valid NULL is returned and size_ret is * filled with 0. */ - EAPI void *eet_read_direct (Eet_File *ef, const char *name, int *size_ret); + EAPI const void *eet_read_direct(Eet_File *ef, const char *name, int *size_ret); /** * Write a specified entry to an eet file handle =================================================================== RCS file: /cvs/e/e17/libs/eet/src/lib/eet_data.c,v retrieving revision 1.59 retrieving revision 1.60 diff -u -3 -r1.59 -r1.60 --- eet_data.c 18 Jan 2008 18:29:29 -0000 1.59 +++ eet_data.c 21 Jan 2008 01:09:51 -0000 1.60 @@ -906,7 +906,7 @@ eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name) { void *data_dec; - void *data; + const void *data; int size; int required_free = 0; =================================================================== RCS file: /cvs/e/e17/libs/eet/src/lib/eet_image.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -3 -r1.10 -r1.11 --- eet_image.c 25 Nov 2006 15:37:45 -0000 1.10 +++ eet_image.c 21 Jan 2008 01:09:51 -0000 1.11 @@ -733,7 +733,7 @@ unsigned int *d = NULL; int free_data = 0; - data = eet_read_direct (ef, name, &size); + data = (void*) eet_read_direct (ef, name, &size); if (!data) { data = eet_read(ef, name, &size); @@ -759,7 +759,7 @@ int d; int free_data = 0; - data = eet_read_direct (ef, name, &size); + data = (void*) eet_read_direct (ef, name, &size); if (!data) { data = eet_read(ef, name, &size); =================================================================== RCS file: /cvs/e/e17/libs/eet/src/lib/eet_lib.c,v retrieving revision 1.83 retrieving revision 1.84 diff -u -3 -r1.83 -r1.84 --- eet_lib.c 14 Dec 2007 05:57:16 -0000 1.83 +++ eet_lib.c 21 Jan 2008 01:09:51 -0000 1.84 @@ -23,20 +23,20 @@ struct _Eet_File { - char *path; - FILE *fp; - Eet_File_Header *header; - unsigned char *data; - - int magic; - int references; - - Eet_File_Mode mode; - int data_size; - time_t mtime; + char *path; + FILE *fp; + Eet_File_Header *header; + const unsigned char *data; + + int magic; + int references; + + Eet_File_Mode mode; + int data_size; + time_t mtime; - unsigned char writes_pending : 1; - unsigned char delete_me_now : 1; + unsigned char writes_pending : 1; + unsigned char delete_me_now : 1; }; struct _Eet_File_Header @@ -448,21 +448,211 @@ num++; } } - + for (i = 0; i < num; i++) eet_close(closelist[i]); } } +static Eet_File* +eet_internal_read (Eet_File *ef) +{ + const unsigned char *dyn_buf = NULL; + const unsigned char *p = NULL; + int index = 0; + int num_entries; + int byte_entries; + int i; + + if (eet_test_close((ef->data == (void *)-1) || (ef->data == NULL), ef)) + return NULL; + + if (eet_test_close(ef->data_size < sizeof(int) * 3, ef)) + return NULL; + + /* build header table if read mode */ + /* geat header */ + index += sizeof(int); + if (eet_test_close((int)ntohl(*((int *)ef->data)) != EET_MAGIC_FILE, ef)) + return NULL; + +#define EXTRACT_INT(Value, Pointer, Index) \ + { \ + int tmp; \ + memcpy(&tmp, Pointer + Index, sizeof(int)); \ + Value = ntohl(tmp); \ + Index += sizeof(int); \ + } + + /* get entries count and byte count */ + EXTRACT_INT(num_entries, ef->data, index); + EXTRACT_INT(byte_entries, ef->data, index); + + /* we cant have <= 0 values here - invalid */ + if (eet_test_close((num_entries <= 0) || (byte_entries <= 0), ef)) + return NULL; + + /* we can't have more entires than minimum bytes for those! invalid! */ + if (eet_test_close((num_entries * 20) > byte_entries, ef)) + return NULL; + + /* allocate header */ + ef->header = calloc(1, sizeof(Eet_File_Header)); + if (eet_test_close(!ef->header, ef)) + return NULL; + + ef->header->magic = EET_MAGIC_FILE_HEADER; + + /* allocate directory block in ram */ + ef->header->directory = calloc(1, sizeof(Eet_File_Directory)); + if (eet_test_close(!ef->header->directory, ef)) + return NULL; + + /* 8 bit hash table (256 buckets) */ + ef->header->directory->size = 8; + /* allocate base hash table */ + ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size)); + if (eet_test_close(!ef->header->directory->nodes, ef)) + return NULL; + + /* actually read the directory block - all of it, into ram */ + dyn_buf = ef->data + index; + + /* parse directory block */ + p = dyn_buf; + + for (i = 0; i < num_entries; i++) + { + Eet_File_Node *efn; + void *data = NULL; + int indexn = 0; + int name_size; + int hash; + int k; + +#define HEADER_SIZE (sizeof(int) * 5) + + /* out directory block is inconsistent - we have oveerun our */ + /* dynamic block buffer before we finished scanning dir entries */ + if (eet_test_close(p + HEADER_SIZE >= (dyn_buf + byte_entries), ef)) + return NULL; + + /* allocate all the ram needed for this stored node accounting */ + efn = malloc (sizeof(Eet_File_Node)); + if (eet_test_close(!efn, ef)) + return NULL; + + /* get entrie header */ + EXTRACT_INT(efn->offset, p, indexn); + EXTRACT_INT(efn->compression, p, indexn); + EXTRACT_INT(efn->size, p, indexn); + EXTRACT_INT(efn->data_size, p, indexn); + EXTRACT_INT(name_size, p, indexn); + + /* invalid size */ + if (eet_test_close(efn->size <= 0, ef)) + { + free (efn); + return NULL; + } + + /* invalid name_size */ + if (eet_test_close(name_size <= 0, ef)) + { + free (efn); + return NULL; + } + + /* reading name would mean falling off end of dyn_buf - invalid */ + if (eet_test_close((p + 16 + name_size) > (dyn_buf + byte_entries), ef)) + { + free (efn); + return NULL; + } + + /* This code is useless if we dont want backward compatibility */ + for (k = name_size; k > 0 && ((unsigned char) * (p + HEADER_SIZE + k)) != 0; --k) + ; + + efn->free_name = ((unsigned char) * (p + HEADER_SIZE + k)) != 0; + + if (efn->free_name) + { + efn->name = malloc(sizeof(char) * name_size + 1); + if (eet_test_close(efn->name == NULL, ef)) + { + free (efn); + return NULL; + } + + strncpy(efn->name, (char *)p + HEADER_SIZE, name_size); + efn->name[name_size] = 0; + + printf("File: %s is not up to date for key \"%s\" - needs rebuilding sometime\n", ef->path, efn->name); + } + else + /* The only really usefull peace of code for efn->name (no backward compatibility) */ + efn->name = (char*)((unsigned char*)(p + HEADER_SIZE)); + + /* get hash bucket it should go in */ + hash = _eet_hash_gen(efn->name, ef->header->directory->size); + efn->next = ef->header->directory->nodes[hash]; + ef->header->directory->nodes[hash] = efn; + + /* read-only mode, so currently we have no data loaded */ + if (ef->mode == EET_FILE_MODE_READ) + efn->data = NULL; + /* read-write mode - read everything into ram */ + else + { + data = malloc(efn->size); + if (data) + memcpy(data, ef->data + efn->offset, efn->size); + efn->data = data; + } + /* advance */ + p += HEADER_SIZE + name_size; + } + return ef; +} + +EAPI Eet_File * +eet_memopen_read(const void *data, size_t size) +{ + Eet_File *ef; + + if (data == NULL || size == 0) + return NULL; + + ef = malloc (sizeof (Eet_File)); + if (!ef) + return NULL; + + ef->path = NULL; + ef->magic = EET_MAGIC_FILE; + ef->references = 1; + ef->mode = EET_FILE_MODE_READ; + ef->header = NULL; + ef->mtime = 0; + ef->delete_me_now = 1; + ef->fp = NULL; + ef->data = data; + ef->data_size = size; + + return eet_internal_read(ef); +} + EAPI Eet_File * eet_open(const char *file, Eet_File_Mode mode) { + FILE *fp; Eet_File *ef; - struct stat file_stat; + struct stat file_stat; + #ifdef _WIN32 - HANDLE h; + HANDLE h; #endif - + if (!file) return NULL; @@ -479,7 +669,8 @@ } ef = eet_cache_find((char *)file, eet_readers, eet_readers_num); } - else if ((mode == EET_FILE_MODE_WRITE) || (mode == EET_FILE_MODE_READ_WRITE)) + else if ((mode == EET_FILE_MODE_WRITE) || + (mode == EET_FILE_MODE_READ_WRITE)) { ef = eet_cache_find((char *)file, eet_readers, eet_readers_num); if (ef) @@ -490,19 +681,32 @@ ef = eet_cache_find((char *)file, eet_writers, eet_writers_num); } - if (stat(file, &file_stat)) + /* try open the file based on mode */ + if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE)) { - if (mode == EET_FILE_MODE_WRITE) - memset(&file_stat, 0, sizeof(file_stat)); - else - return NULL; - } - else if ((mode == EET_FILE_MODE_READ) && + fp = fopen(file, "rb"); + if (!fp) return NULL; + if (fstat(fileno(fp), &file_stat)) + { + fclose(fp); + return NULL; + } + if ((mode == EET_FILE_MODE_READ) && (file_stat.st_size < (sizeof(int) * 3))) + { + fclose(fp); + return NULL; + } + } + else { - return NULL; + if (mode != EET_FILE_MODE_WRITE) return NULL; + memset(&file_stat, 0, sizeof(file_stat)); + /* opening for write - delete old copy of file right away */ + unlink(file); + fp = fopen(file, "wb"); } - + /* We found one */ if (ef && (file_stat.st_mtime != ef->mtime)) { @@ -510,10 +714,11 @@ eet_close(ef); ef = NULL; } - + if (ef) { /* reference it up and return it */ + fclose(fp); ef->references++; return ef; } @@ -524,6 +729,7 @@ return NULL; /* fill some of the members */ + ef->fp = fp; ef->path = ((char *)ef) + sizeof(Eet_File); strcpy(ef->path, file); ef->magic = EET_MAGIC_FILE; @@ -535,21 +741,6 @@ ef->data = NULL; ef->data_size = 0; - /* try open the file based on mode */ - if ((ef->mode == EET_FILE_MODE_READ) || (ef->mode == EET_FILE_MODE_READ_WRITE)) - ef->fp = fopen(ef->path, "rb"); - else - { - if (eet_test_close(ef->mode != EET_FILE_MODE_WRITE, ef)) - return NULL; - else - { - /* opening for write - delete old copy of file right away */ - unlink(ef->path); - ef->fp = fopen(ef->path, "wb"); - } - } - /* if we can't open - bail out */ if (eet_test_close(!ef->fp, ef)) return NULL; @@ -566,12 +757,6 @@ /* if we opened for read or read-write */ if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE)) { - unsigned char *dyn_buf = NULL; - unsigned char *p = NULL; - int index = 0; - int num_entries; - int byte_entries; - int i; #ifdef _WIN32 HANDLE fm; #endif @@ -596,152 +781,9 @@ CloseHandle(fm); #endif - if (eet_test_close((ef->data == (void *)-1) || (ef->data == NULL), ef)) - return NULL; - - /* build header table if read mode */ - /* geat header */ - index += sizeof(int); - if (eet_test_close((int)ntohl(*((int *)ef->data)) != EET_MAGIC_FILE, ef)) - return NULL; - -#define EXTRACT_INT(Value, Pointer, Index) \ - { \ - int tmp; \ - memcpy(&tmp, Pointer + Index, sizeof(int)); \ - Value = ntohl(tmp); \ - Index += sizeof(int); \ - } - - /* get entries count and byte count */ - EXTRACT_INT(num_entries, ef->data, index); - EXTRACT_INT(byte_entries, ef->data, index); - - /* we cant have <= 0 values here - invalid */ -// if (eet_test_close((num_entries <= 0) || (byte_entries <= 0), ef)) -// return NULL; - - /* we can't have more entires than minimum bytes for those! invalid! */ - if (eet_test_close((num_entries * 20) > byte_entries, ef)) - return NULL; - - /* allocate header */ - ef->header = calloc(1, sizeof(Eet_File_Header)); - if (eet_test_close(!ef->header, ef)) - return NULL; - - ef->header->magic = EET_MAGIC_FILE_HEADER; - - /* allocate directory block in ram */ - ef->header->directory = calloc(1, sizeof(Eet_File_Directory)); - if (eet_test_close(!ef->header->directory, ef)) + ef = eet_internal_read(ef); + if (!ef) return NULL; - - /* 8 bit hash table (256 buckets) */ - ef->header->directory->size = 8; - /* allocate base hash table */ - ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size)); - if (eet_test_close(!ef->header->directory->nodes, ef)) - return NULL; - - /* actually read the directory block - all of it, into ram */ - dyn_buf = ef->data + index; - - /* parse directory block */ - p = dyn_buf; - - for (i = 0; i < num_entries; i++) - { - Eet_File_Node *efn; - void *data = NULL; - int indexn = 0; - int name_size; - int hash; - int k; - -#define HEADER_SIZE (sizeof(int) * 5) - - /* out directory block is inconsistent - we have oveerun our */ - /* dynamic block buffer before we finished scanning dir entries */ - if (eet_test_close(p + HEADER_SIZE >= (dyn_buf + byte_entries), ef)) - return NULL; - - /* allocate all the ram needed for this stored node accounting */ - efn = malloc (sizeof(Eet_File_Node)); - if (eet_test_close(!efn, ef)) - return NULL; - - /* get entrie header */ - EXTRACT_INT(efn->offset, p, indexn); - EXTRACT_INT(efn->compression, p, indexn); - EXTRACT_INT(efn->size, p, indexn); - EXTRACT_INT(efn->data_size, p, indexn); - EXTRACT_INT(name_size, p, indexn); - - /* invalid size */ - if (eet_test_close(efn->size <= 0, ef)) - { - free (efn); - return NULL; - } - - /* invalid name_size */ - if (eet_test_close(name_size <= 0, ef)) - { - free (efn); - return NULL; - } - - /* reading name would mean falling off end of dyn_buf - invalid */ - if (eet_test_close((p + 16 + name_size) > (dyn_buf + byte_entries), ef)) - { - free (efn); - return NULL; - } - - /* This code is useless if we dont want backward compatibility */ - for (k = name_size; k > 0 && ((unsigned char) * (p + HEADER_SIZE + k)) != 0; --k) - ; - - efn->free_name = ((unsigned char) * (p + HEADER_SIZE + k)) != 0; - - if (efn->free_name) - { - efn->name = malloc(sizeof(char) * name_size + 1); - if (eet_test_close(efn->name == NULL, ef)) - { - free (efn); - return NULL; - } - - strncpy(efn->name, (char *)p + HEADER_SIZE, name_size); - efn->name[name_size] = 0; - - printf("File: %s is not up to date for key \"%s\" - needs rebuilding sometime\n", ef->path, efn->name); - } - else - /* The only really usefull peace of code for efn->name (no backward compatibility) */ - efn->name = (char*)((unsigned char *)(p + HEADER_SIZE)); - - /* get hash bucket it should go in */ - hash = _eet_hash_gen(efn->name, ef->header->directory->size); - efn->next = ef->header->directory->nodes[hash]; - ef->header->directory->nodes[hash] = efn; - - /* read-only mode, so currently we have no data loaded */ - if (mode == EET_FILE_MODE_READ) - efn->data = NULL; - /* read-write mode - read everything into ram */ - else - { - data = malloc(efn->size); - if (data) - memcpy(data, ef->data + efn->offset, efn->size); - efn->data = data; - } - /* advance */ - p += HEADER_SIZE + name_size; - } } /* we need to delete the original file in read-write mode and re-open for writing */ @@ -848,16 +890,18 @@ } free(ef->header); } + #ifndef _WIN32 - if (ef->data) munmap(ef->data, ef->data_size); + if (ef->data) munmap((void*)ef->data, ef->data_size); #else if (ef->data) UnmapViewOfFile (ef->data); #endif + if (ef->fp) fclose(ef->fp); /* zero out ram for struct - caution tactic against stale memory use */ memset(ef, 0, sizeof(Eet_File)); - + /* free it */ free(ef); return err; @@ -962,11 +1006,11 @@ return data; } -EAPI void * +EAPI const void * eet_read_direct(Eet_File *ef, const char *name, int *size_ret) { - void *data = NULL; - int size = 0; + const void *data = NULL; + int size = 0; Eet_File_Node *efn; if (size_ret) ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs