diff --git a/legacy/eet/src/lib/Eet_private.h b/legacy/eet/src/lib/Eet_private.h index 81c64d14c5..adde2ed181 100644 --- a/legacy/eet/src/lib/Eet_private.h +++ b/legacy/eet/src/lib/Eet_private.h @@ -34,7 +34,7 @@ void _eet_memfile_write_close(FILE *f); void _eet_memfile_shutdown(); #ifndef PATH_MAX -#define PATH_MAX 4095 +#define PATH_MAX 4096 #endif #endif diff --git a/legacy/eet/src/lib/eet_data.c b/legacy/eet/src/lib/eet_data.c index 7c6ec7a24d..1d3a0b7a40 100644 --- a/legacy/eet/src/lib/eet_data.c +++ b/legacy/eet/src/lib/eet_data.c @@ -45,6 +45,7 @@ typedef struct _Eet_Data_Element Eet_Data_Element; typedef struct _Eet_Data_Basic_Type_Decoder Eet_Data_Basic_Type_Decoder; typedef struct _Eet_Data_Chunk Eet_Data_Chunk; typedef struct _Eet_Data_Stream Eet_Data_Stream; +typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash; /*---*/ @@ -69,6 +70,12 @@ struct _Eet_Data_Stream int pos; }; +struct _Eet_Data_Descriptor_Hash +{ + Eet_Data_Element *element; + Eet_Data_Descriptor_Hash *next; +}; + struct _Eet_Data_Descriptor { char *name; @@ -85,6 +92,10 @@ struct _Eet_Data_Descriptor struct { int num; Eet_Data_Element *set; + struct { + int size; + Eet_Data_Descriptor_Hash *buckets; + } hash; } elements; }; @@ -567,6 +578,107 @@ eet_data_chunk_put(Eet_Data_Chunk *chnk, Eet_Data_Stream *ds) /*---*/ +static int +_eet_descriptor_hash_gen(char *key, int hash_size) +{ + int hash_num = 0, i; + unsigned char *ptr; + const int masks[9] = + { + 0x00, + 0x01, + 0x03, + 0x07, + 0x0f, + 0x1f, + 0x3f, + 0x7f, + 0xff + }; + + /* no string - index 0 */ + if (!key) return 0; + + /* calc hash num */ + for (i = 0, ptr = (unsigned char *)key; *ptr; ptr++, i++) + hash_num ^= ((int)(*ptr) | ((int)(*ptr) << 8)) >> (i % 8); + + /* mask it */ + hash_num &= masks[hash_size]; + /* return it */ + return hash_num; +} + +static void +_eet_descriptor_hash_new(Eet_Data_Descriptor *edd) +{ + int i; + + edd->elements.hash.size = 1 << 6; + edd->elements.hash.buckets = calloc(1, sizeof(Eet_Data_Descriptor_Hash) * edd->elements.hash.size); + for (i = 0; i < edd->elements.num; i++) + { + Eet_Data_Element *ede; + int hash; + + ede = &(edd->elements.set[i]); + hash = _eet_descriptor_hash_gen(ede->name, 6); + if (!edd->elements.hash.buckets[hash].element) + edd->elements.hash.buckets[hash].element = ede; + else + { + Eet_Data_Descriptor_Hash *bucket; + + bucket = calloc(1, sizeof(Eet_Data_Descriptor_Hash)); + bucket->element = ede; + bucket->next = edd->elements.hash.buckets[hash].next; + edd->elements.hash.buckets[hash].next = bucket; + } + } +} + +static void +_eet_descriptor_hash_free(Eet_Data_Descriptor *edd) +{ + int i; + + for (i = 0; i < edd->elements.hash.size; i++) + { + Eet_Data_Descriptor_Hash *bucket, *pbucket; + + bucket = edd->elements.hash.buckets[i].next; + while (bucket) + { + pbucket = bucket; + bucket = bucket->next; + free(pbucket); + } + } + if (edd->elements.hash.buckets) free(edd->elements.hash.buckets); +} + +static Eet_Data_Element * +_eet_descriptor_hash_find(Eet_Data_Descriptor *edd, char *name) +{ + int hash; + Eet_Data_Element *ede; + Eet_Data_Descriptor_Hash *bucket; + + hash = _eet_descriptor_hash_gen(name, 6); + if (!edd->elements.hash.buckets[hash].element) return NULL; + if (!strcmp(edd->elements.hash.buckets[hash].element->name, name)) + return edd->elements.hash.buckets[hash].element; + bucket = edd->elements.hash.buckets[hash].next; + while (bucket) + { + if (!strcmp(bucket->element->name, name)) return bucket->element; + bucket = bucket->next; + } + return NULL; +} + +/*---*/ + Eet_Data_Descriptor * eet_data_descriptor_new(char *name, int size, @@ -599,6 +711,7 @@ eet_data_descriptor_free(Eet_Data_Descriptor *edd) { int i; + _eet_descriptor_hash_free(edd); if (edd->name) free(edd->name); for (i = 0; i < edd->elements.num; i++) { @@ -811,10 +924,11 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd, } p = chnk->data; size = size_in - (4 + 4 + strlen(chnk->name) + 1); + if (!edd->elements.hash.buckets) _eet_descriptor_hash_new(edd); while (size > 0) { Eet_Data_Chunk *echnk; - int i; + Eet_Data_Element *ede; /* get next data chunk */ echnk = eet_data_chunk_get(p, size); @@ -827,88 +941,77 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd, eet_data_chunk_free(chnk); return NULL; } - for (i = 0; i < edd->elements.num; i++) + /* FIXME: this is a linear search/match - speed up by putting in a + * hash lookup + */ + ede = _eet_descriptor_hash_find(edd, echnk->name); + if (ede) { - Eet_Data_Element *ede; - - ede = &(edd->elements.set[i]); - if (!strcmp(echnk->name, ede->name)) + if (ede->group_type == EET_G_UNKNOWN) { - if (ede->group_type == EET_G_UNKNOWN) + int ret; + void *data_ret; + + if ((ede->type >= EET_T_CHAR) && + (ede->type <= EET_T_STRING)) { - int ret; - void *data_ret; - - if ((ede->type >= EET_T_CHAR) && - (ede->type <= EET_T_STRING)) - { - ret = eet_data_get_type(ede->type, - echnk->data, - ((char *)echnk->data) + echnk->size, - ((char *)data) + ede->offset); - } - else if (ede->subtype) - { - void **ptr; - - data_ret = eet_data_descriptor_decode(ede->subtype, - echnk->data, - echnk->size); - if (!data_ret) - { - _eet_freelist_unref(); - _eet_freelist_list_unref(); - _eet_freelist_free(); - _eet_freelist_list_free(edd); - eet_data_chunk_free(chnk); - return NULL; - } - ptr = (void **)(((char *)data) + ede->offset); - *ptr = (void *)data_ret; - } + ret = eet_data_get_type(ede->type, + echnk->data, + ((char *)echnk->data) + echnk->size, + ((char *)data) + ede->offset); } - else + else if (ede->subtype) { - switch (ede->group_type) + void **ptr; + + data_ret = eet_data_descriptor_decode(ede->subtype, + echnk->data, + echnk->size); + if (!data_ret) { - case EET_G_ARRAY: - case EET_G_VAR_ARRAY: + _eet_freelist_unref(); + _eet_freelist_list_unref(); + _eet_freelist_free(); + _eet_freelist_list_free(edd); + eet_data_chunk_free(chnk); + return NULL; + } + ptr = (void **)(((char *)data) + ede->offset); + *ptr = (void *)data_ret; + } + } + else + { + switch (ede->group_type) + { + case EET_G_ARRAY: + case EET_G_VAR_ARRAY: + { + printf("ARRAY TYPE NOT IMPLIMENTED YET!!!\n"); + } + break; + case EET_G_LIST: + { + int ret; + void *list = NULL; + void **ptr; + void *data_ret; + + ptr = (void **)(((char *)data) + ede->offset); + list = *ptr; + data_ret = NULL; + if ((ede->type >= EET_T_CHAR) && + (ede->type <= EET_T_STRING)) { - printf("ARRAY TYPE NOT IMPLIMENTED YET!!!\n"); - } - break; - case EET_G_LIST: - { - int ret; - void *list = NULL; - void **ptr; - void *data_ret; - - ptr = (void **)(((char *)data) + ede->offset); - list = *ptr; - data_ret = NULL; - if ((ede->type >= EET_T_CHAR) && - (ede->type <= EET_T_STRING)) + data_ret = calloc(1, eet_coder[ede->type].size); + if (data_ret) { - data_ret = calloc(1, eet_coder[ede->type].size); - if (data_ret) - { - _eet_freelist_add(data_ret); - ret = eet_data_get_type(ede->type, - echnk->data, - ((char *)echnk->data) + echnk->size, - data_ret); - if (ret <= 0) - { - _eet_freelist_unref(); - _eet_freelist_list_unref(); - _eet_freelist_free(); - _eet_freelist_list_free(edd); - eet_data_chunk_free(chnk); - return NULL; - } - } - else + _eet_freelist_add(data_ret); + ret = eet_data_get_type(ede->type, + echnk->data, + ((char *)echnk->data) + echnk->size, + data_ret); + if (ret <= 0) { _eet_freelist_unref(); _eet_freelist_list_unref(); @@ -918,18 +1021,6 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd, return NULL; } } - else if (ede->subtype) - { - data_ret = eet_data_descriptor_decode(ede->subtype, - echnk->data, - echnk->size); - } - if (data_ret) - { - list = edd->func.list_append(list, data_ret); - *ptr = list; - _eet_freelist_list_add(ptr); - } else { _eet_freelist_unref(); @@ -940,15 +1031,35 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd, return NULL; } } - break; - case EET_G_HASH: - printf("HASH TYPE NOT IMPLIMENTED YET!!!\n"); - break; - default: - break; + else if (ede->subtype) + { + data_ret = eet_data_descriptor_decode(ede->subtype, + echnk->data, + echnk->size); + } + if (data_ret) + { + list = edd->func.list_append(list, data_ret); + *ptr = list; + _eet_freelist_list_add(ptr); + } + else + { + _eet_freelist_unref(); + _eet_freelist_list_unref(); + _eet_freelist_free(); + _eet_freelist_list_free(edd); + eet_data_chunk_free(chnk); + return NULL; + } } + break; + case EET_G_HASH: + printf("HASH TYPE NOT IMPLIMENTED YET!!!\n"); + break; + default: + break; } - break; } } /* advance to next chunk */ diff --git a/legacy/eet/src/lib/eet_lib.c b/legacy/eet/src/lib/eet_lib.c index 6fab64f431..19cd5765fd 100644 --- a/legacy/eet/src/lib/eet_lib.c +++ b/legacy/eet/src/lib/eet_lib.c @@ -11,14 +11,10 @@ #define EET_MAGIC_FILE 0x1ee7ff00 #define EET_MAGIC_FILE_HEADER 0x1ee7ff01 -#define EET_MAGIC_FILE_NODE 0x1ee7ff02 -#define EET_MAGIC_FILE_DIRECTORY 0x1ee7ff03 -#define EET_MAGIC_FILE_DIRECTORY_HASH 0x1ee7ff04 typedef struct _Eet_File_Header Eet_File_Header; typedef struct _Eet_File_Node Eet_File_Node; typedef struct _Eet_File_Directory Eet_File_Directory; -typedef struct _Eet_File_Directory_Hash Eet_File_Directory_Hash; struct _Eet_File { @@ -42,26 +38,21 @@ struct _Eet_File_Header Eet_File_Directory *directory; }; -struct _Eet_File_Node -{ - char *name; - int offset; - int compression; - int size; - int data_size; - void *data; -}; - struct _Eet_File_Directory { - int size; - Eet_File_Directory_Hash *hash; + int size; + Eet_File_Node **nodes; }; -struct _Eet_File_Directory_Hash +struct _Eet_File_Node { + char *name; + int offset; + int compression; int size; - Eet_File_Node *node; + int data_size; + void *data; + Eet_File_Node *next; /* FIXME: make buckets linked lists */ }; #if 0 @@ -200,7 +191,7 @@ eet_string_match(char *s1, char *s2) static int eet_hash_gen(char *key, int hash_size) { - int hash_num = 0; + int hash_num = 0, i; unsigned char *ptr; const int masks[9] = { @@ -219,8 +210,8 @@ eet_hash_gen(char *key, int hash_size) if (!key) return 0; /* calc hash num */ - for (ptr = (unsigned char *)key; *ptr; ptr++) - hash_num ^= (int)(*ptr); + for (i = 0, ptr = (unsigned char *)key; *ptr; ptr++, i++) + hash_num ^= ((int)(*ptr) | ((int)(*ptr) << 8)) >> (i % 8); /* mask it */ hash_num &= masks[hash_size]; @@ -232,9 +223,10 @@ eet_hash_gen(char *key, int hash_size) static void eet_flush(Eet_File *ef) { - int i, j, count, size, num, offset; + int i, count, size, num, offset; int head[3]; unsigned long int i1, i2; + Eet_File_Node *efn; /* check to see its' an eet file pointer */ if ((!ef) || (ef->magic != EET_MAGIC_FILE)) @@ -250,11 +242,11 @@ eet_flush(Eet_File *ef) num = (1 << (ef->header->directory->size - 1)); for (i = 0; i < num; i++) { - for (j = 0; j < ef->header->directory->hash[i].size; j++) + for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next) { - if (ef->header->directory->hash[i].node[j].compression >= 0) + if (efn->compression >= 0) { - size += 20 + strlen(ef->header->directory->hash[i].node[j].name); + size += 20 + strlen(efn->name); count++; } } @@ -263,12 +255,12 @@ eet_flush(Eet_File *ef) offset = 0; for (i = 0; i < num; i++) { - for (j = 0; j < ef->header->directory->hash[i].size; j++) + for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next) { - if (ef->header->directory->hash[i].node[j].compression >= 0) + if (efn->compression >= 0) { - ef->header->directory->hash[i].node[j].offset = 12 + size + offset; - offset += ef->header->directory->hash[i].node[j].size; + efn->offset = 12 + size + offset; + offset += efn->size; } } } @@ -287,34 +279,34 @@ eet_flush(Eet_File *ef) offset = 12; for (i = 0; i < num; i++) { - for (j = 0; j < ef->header->directory->hash[i].size; j++) + for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next) { unsigned char *buf; int buf_size; int name_size; - if (ef->header->directory->hash[i].node[j].compression >= 0) + if (efn->compression >= 0) { - name_size = strlen(ef->header->directory->hash[i].node[j].name); + name_size = strlen(efn->name); buf_size = 20 + name_size; buf = malloc(buf_size); if (!buf) return; - i1 = (unsigned long int)ef->header->directory->hash[i].node[j].offset; + i1 = (unsigned long int)efn->offset; i2 = htonl(i1); *((int *)(buf + 0)) = (int)i2; - i1 = (unsigned long int)ef->header->directory->hash[i].node[j].compression; + i1 = (unsigned long int)efn->compression; i2 = htonl(i1); *((int *)(buf + 4)) = (int)i2; - i1 = (unsigned long int)ef->header->directory->hash[i].node[j].size; + i1 = (unsigned long int)efn->size; i2 = htonl(i1); *((int *)(buf + 8)) = (int)i2; - i1 = (unsigned long int)ef->header->directory->hash[i].node[j].data_size; + i1 = (unsigned long int)efn->data_size; i2 = htonl(i1); *((int *)(buf + 12)) = (int)i2; i1 = (unsigned long int)name_size; i2 = htonl(i1); *((int *)(buf + 16)) = (int)i2; - memcpy(buf + 20, ef->header->directory->hash[i].node[j].name, name_size); + memcpy(buf + 20, efn->name, name_size); if (fwrite(buf, buf_size, 1, ef->fp) != 1) { free(buf); @@ -328,13 +320,11 @@ eet_flush(Eet_File *ef) /* write data */ for (i = 0; i < num; i++) { - for (j = 0; j < ef->header->directory->hash[i].size; j++) + for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next) { - if (ef->header->directory->hash[i].node[j].compression >= 0) + if (efn->compression >= 0) { - if (fwrite(ef->header->directory->hash[i].node[j].data, - ef->header->directory->hash[i].node[j].size, - 1, ef->fp) != 1) + if (fwrite(efn->data, efn->size, 1, ef->fp) != 1) return; } } @@ -378,7 +368,7 @@ eet_open(const char *file, Eet_File_Mode mode) } /* allocate struct for eet file and have it zero'd out */ - ef = calloc(sizeof(Eet_File), 1); + ef = calloc(1, sizeof(Eet_File)); if (!ef) return NULL; /* fill some of the members */ @@ -411,6 +401,7 @@ eet_open(const char *file, Eet_File_Mode mode) } /* if we opened for read or read-write */ +// printf("OPEN!\n"); if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE)) { unsigned char buf[12]; @@ -462,7 +453,7 @@ eet_open(const char *file, Eet_File_Mode mode) return NULL; } /* allocate header */ - ef->header = calloc(sizeof(Eet_File_Header), 1); + ef->header = calloc(1, sizeof(Eet_File_Header)); if (!ef->header) { free(dyn_buf); @@ -471,7 +462,7 @@ eet_open(const char *file, Eet_File_Mode mode) } ef->header->magic = EET_MAGIC_FILE_HEADER; /* allocate directory block in ram */ - ef->header->directory = calloc(sizeof(Eet_File_Directory), 1); + ef->header->directory = calloc(1, sizeof(Eet_File_Directory)); if (!ef->header->directory) { free(dyn_buf); @@ -481,8 +472,8 @@ eet_open(const char *file, Eet_File_Mode mode) /* 8 bit hash table (256 buckets) */ ef->header->directory->size = 8; /* allocate base hash table */ - ef->header->directory->hash = calloc(sizeof(Eet_File_Directory_Hash), (1 << (ef->header->directory->size - 1))); - if (!ef->header->directory->hash) + ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size)); + if (!ef->header->directory->nodes) { free(dyn_buf); eet_close(ef); @@ -498,6 +489,7 @@ eet_open(const char *file, Eet_File_Mode mode) } /* parse directory block */ p = dyn_buf; +// printf("entries: %i\n", num_entries); for (i = 0; i < num_entries; i++) { int offset; @@ -507,8 +499,7 @@ eet_open(const char *file, Eet_File_Mode mode) int name_size; char *name; int hash; - Eet_File_Node *node; - int node_size; + Eet_File_Node *efn; void *data = NULL; /* out directory block is inconsistent - we have oveerun our */ @@ -569,39 +560,31 @@ eet_open(const char *file, Eet_File_Mode mode) name[name_size] = 0; /* get hask bucket it should go in */ hash = eet_hash_gen(name, ef->header->directory->size); - /* resize hask bucket */ - node = realloc(ef->header->directory->hash[hash].node, - (ef->header->directory->hash[hash].size + 1) * - sizeof(Eet_File_Node)); - if (!node) + efn = calloc(1, sizeof(Eet_File_Node)); + if (!efn) { free(dyn_buf); eet_close(ef); return NULL; } - /* current node size */ - node_size = ef->header->directory->hash[hash].size; - /* resized node list set up */ - ef->header->directory->hash[hash].node = node; - /* new node at end */ - ef->header->directory->hash[hash].node[node_size].name = name; - ef->header->directory->hash[hash].node[node_size].offset = offset; - ef->header->directory->hash[hash].node[node_size].compression = flags; - ef->header->directory->hash[hash].node[node_size].size = size; - ef->header->directory->hash[hash].node[node_size].data_size = data_size; + efn->next = ef->header->directory->nodes[hash]; + ef->header->directory->nodes[hash] = efn; + efn->name = name; + efn->offset = offset; + efn->compression = flags; + efn->size = size; + efn->data_size = data_size; /* read-only mode, so currently we have no data loaded */ if (mode == EET_FILE_MODE_READ) - { - ef->header->directory->hash[hash].node[node_size].data = NULL; - } + efn->data = NULL; /* read-write mode - read everything into ram */ else { data = malloc(size); if (data) { - if (fseek(ef->fp, ef->header->directory->hash[hash].node[node_size].offset, SEEK_SET) < 0) + if (fseek(ef->fp, efn->offset, SEEK_SET) < 0) { free(data); data = NULL; @@ -616,12 +599,9 @@ eet_open(const char *file, Eet_File_Mode mode) break; } } - - ef->header->directory->hash[hash].node[node_size].data = data; + efn->data = data; } - /* increment number of nodes */ - ef->header->directory->hash[hash].size++; /* advance */ p += 20 + name_size; } @@ -683,30 +663,24 @@ eet_close(Eet_File *ef) { if (ef->header->directory) { - if (ef->header->directory->hash) + if (ef->header->directory->nodes) { int i, num; - num = (1 << (ef->header->directory->size - 1)); + num = (1 << ef->header->directory->size); for (i = 0; i < num; i++) { - if (ef->header->directory->hash[i].node) + Eet_File_Node *efn; + + while ((efn = ef->header->directory->nodes[i])) { - int j; - int num2; - - num2 = ef->header->directory->hash[i].size; - for (j = 0; j < num2; j++) - { - if (ef->header->directory->hash[i].node[j].name) - free(ef->header->directory->hash[i].node[j].name); - if (ef->header->directory->hash[i].node[j].data) - free(ef->header->directory->hash[i].node[j].data); - } - free(ef->header->directory->hash[i].node); + if (efn->name) free(efn->name); + if (efn->data) free(efn->data); + ef->header->directory->nodes[i] = efn->next; + free(efn); } } - free(ef->header->directory->hash); + free(ef->header->directory->nodes); } free(ef->header->directory); } @@ -723,9 +697,10 @@ void * eet_read(Eet_File *ef, char *name, int *size_ret) { void *data = NULL; - int size = 0, tmp_size; - int hash, i, num; - + int size = 0, tmp_size; + int hash; + Eet_File_Node *efn; + /* check to see its' an eet file pointer */ if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!name) || ((ef->mode != EET_FILE_MODE_READ) && @@ -742,31 +717,28 @@ eet_read(Eet_File *ef, char *name, int *size_ret) hash = eet_hash_gen(name, ef->header->directory->size); // printf("read %s\n", name); /* hunt hash bucket */ - num = ef->header->directory->hash[hash].size; - for (i = 0; i < num; i++) + for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next) { /* if it matches */ - if (eet_string_match(ef->header->directory->hash[hash].node[i].name, name)) + if (eet_string_match(efn->name, name)) { /* uncompressed data */ - if (ef->header->directory->hash[hash].node[i].compression == 0) + if (efn->compression == 0) { /* get size */ - size = ef->header->directory->hash[hash].node[i].size; + size = efn->size; /* allocate data */ data = malloc(size); if (data) { /* if we alreayd have the data in ram... copy that */ - if (ef->header->directory->hash[hash].node[i].data) - memcpy(data, - ef->header->directory->hash[hash].node[i].data, - ef->header->directory->hash[hash].node[i].size); + if (efn->data) + memcpy(data, efn->data, efn->size); /* or get data from disk */ else { /* seek to data location */ - if (fseek(ef->fp, ef->header->directory->hash[hash].node[i].offset, SEEK_SET) < 0) + if (fseek(ef->fp, efn->offset, SEEK_SET) < 0) { free(data); data = NULL; @@ -789,11 +761,11 @@ eet_read(Eet_File *ef, char *name, int *size_ret) void *tmp_data; /* get size of data in file */ - tmp_size = ef->header->directory->hash[hash].node[i].size; + tmp_size = efn->size; tmp_data = malloc(tmp_size); if (!tmp_data) break; /* get size uncompressed */ - size = ef->header->directory->hash[hash].node[i].data_size; + size = efn->data_size; /* allocate data */ data = malloc(size); if (data) @@ -801,15 +773,13 @@ eet_read(Eet_File *ef, char *name, int *size_ret) uLongf dlen; /* if we already have the data in ram... copy that */ - if (ef->header->directory->hash[hash].node[i].data) - memcpy(tmp_data, - ef->header->directory->hash[hash].node[i].data, - tmp_size); + if (efn->data) + memcpy(tmp_data, efn->data, tmp_size); /* or get data from disk */ else { /* seek to data location */ - if (fseek(ef->fp, ef->header->directory->hash[hash].node[i].offset, SEEK_SET) < 0) + if (fseek(ef->fp, efn->offset, SEEK_SET) < 0) { free(tmp_data); free(data); @@ -851,38 +821,35 @@ int eet_write(Eet_File *ef, char *name, void *data, int size, int compress) { int data_size; - int hash, node_size; - Eet_File_Node *node; + int hash; + Eet_File_Node *efn; char *name2; void *data2; int exists_already = 0; /* check to see its' an eet file pointer */ - if ((!ef) || (ef->magic != EET_MAGIC_FILE) - || (!name) || (!data) || (size <= 0) || - ((ef->mode != EET_FILE_MODE_WRITE) && - (ef->mode != EET_FILE_MODE_READ_WRITE))) - + if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!name) || (!data) || + (size <= 0) || ((ef->mode != EET_FILE_MODE_WRITE) && + (ef->mode != EET_FILE_MODE_READ_WRITE))) return 0; if (!ef->header) { /* allocate header */ - ef->header = calloc(sizeof(Eet_File_Header), 1); + ef->header = calloc(1, sizeof(Eet_File_Header)); if (!ef->header) return 0; ef->header->magic = EET_MAGIC_FILE_HEADER; /* allocate directory block in ram */ - ef->header->directory = calloc(sizeof(Eet_File_Directory), 1); + ef->header->directory = calloc(1, sizeof(Eet_File_Directory)); if (!ef->header->directory) return 0; /* 8 bit hash table (256 buckets) */ ef->header->directory->size = 8; /* allocate base hash table */ - ef->header->directory->hash = calloc(sizeof(Eet_File_Directory_Hash), (1 << (ef->header->directory->size - 1))); - if (!ef->header->directory->hash) return 0; + ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size)); + if (!ef->header->directory->nodes) return 0; } /* figure hash bucket */ hash = eet_hash_gen(name, ef->header->directory->size); - node_size = ef->header->directory->hash[hash].size; /* dup name */ name2 = strdup(name); if (!name2) return 0; @@ -933,17 +900,16 @@ eet_write(Eet_File *ef, char *name, void *data, int size, int compress) /* Does this node already exist? */ if (ef->mode == EET_FILE_MODE_READ_WRITE) { - int i; - for (i = 0; i < node_size; i++) + for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next) { /* if it matches */ - if (eet_string_match(ef->header->directory->hash[hash].node[i].name, name)) + if (eet_string_match(efn->name, name)) { - free(ef->header->directory->hash[hash].node[i].data); - ef->header->directory->hash[hash].node[i].compression = compress; - ef->header->directory->hash[hash].node[i].size = data_size; - ef->header->directory->hash[hash].node[i].data_size = size; - ef->header->directory->hash[hash].node[i].data = data2; + free(efn->data); + efn->compression = compress; + efn->size = data_size; + efn->data_size = size; + efn->data = data2; exists_already = 1; free(name2); break; @@ -952,25 +918,23 @@ eet_write(Eet_File *ef, char *name, void *data, int size, int compress) } if (!exists_already) { - /* increase hash bucket size */ - node = realloc(ef->header->directory->hash[hash].node, - (node_size + 1) * sizeof(Eet_File_Node)); - if (!node) + efn = calloc(1, sizeof(Eet_File_Node)); + if (!efn) { free(name2); free(data2); return 0; } /* resized node list set up */ - ef->header->directory->hash[hash].node = node; + efn->next = ef->header->directory->nodes[hash]; + ef->header->directory->nodes[hash] = efn; /* new node at end */ - ef->header->directory->hash[hash].node[node_size].name = name2; - ef->header->directory->hash[hash].node[node_size].offset = 0; - ef->header->directory->hash[hash].node[node_size].compression = compress; - ef->header->directory->hash[hash].node[node_size].size = data_size; - ef->header->directory->hash[hash].node[node_size].data_size = size; - ef->header->directory->hash[hash].node[node_size].data = data2; - ef->header->directory->hash[hash].size++; + efn->name = name2; + efn->offset = 0; + efn->compression = compress; + efn->size = data_size; + efn->data_size = size; + efn->data = data2; } /* flags that writes are pending */ @@ -982,9 +946,10 @@ eet_write(Eet_File *ef, char *name, void *data, int size, int compress) int eet_delete(Eet_File *ef, char *name) { - int hash, node_size, i; + int hash; int exists_already = 0; - + Eet_File_Node *efn, *pefn; + /* check to see its' an eet file pointer */ if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!name)) return 0; @@ -996,19 +961,20 @@ eet_delete(Eet_File *ef, char *name) /* figure hash bucket */ hash = eet_hash_gen(name, ef->header->directory->size); - node_size = ef->header->directory->hash[hash].size; /* Does this node already exist? */ - for (i = 0; i < node_size; i++) + for (pefn = NULL, efn = ef->header->directory->nodes[hash]; efn; pefn = efn, efn = efn->next) { /* if it matches */ - if (eet_string_match(ef->header->directory->hash[hash].node[i].name, name)) + if (eet_string_match(efn->name, name)) { - free(ef->header->directory->hash[hash].node[i].data); - ef->header->directory->hash[hash].node[i].compression = -1; - ef->header->directory->hash[hash].node[i].size = 0; - ef->header->directory->hash[hash].node[i].data_size = 0; - ef->header->directory->hash[hash].node[i].data = NULL; + if (efn->name) free(efn->name); + if (efn->data) free(efn->data); + if (efn == ef->header->directory->nodes[hash]) + ef->header->directory->nodes[hash] = efn->next; + else + pefn->next = efn->next; + free(efn); exists_already = 1; break; } @@ -1026,6 +992,7 @@ eet_list(Eet_File *ef, char *glob, int *count_ret) int list_count = 0; int list_count_alloc = 0; int i, j, num; + Eet_File_Node *efn; /* check to see its' an eet file pointer */ if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!glob) || @@ -1037,13 +1004,13 @@ eet_list(Eet_File *ef, char *glob, int *count_ret) return NULL; } /* loop through all entries */ - num = (1 << (ef->header->directory->size - 1)); + num = (1 << ef->header->directory->size); for (i = 0; i < num; i++) { - for (j = 0; j < ef->header->directory->hash[i].size; j++) + for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next) { /* if the entry matches the input glob */ - if (!fnmatch(glob, ef->header->directory->hash[i].node[j].name, 0)) + if (!fnmatch(glob, efn->name, 0)) { char **new_list; @@ -1063,7 +1030,7 @@ eet_list(Eet_File *ef, char *glob, int *count_ret) list_ret = new_list; } /* put pointer of name string in */ - list_ret[list_count - 1] = ef->header->directory->hash[i].node[j].name; + list_ret[list_count - 1] = efn->name; } } }