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;
/*---*/
int pos;
};
+struct _Eet_Data_Descriptor_Hash
+{
+ Eet_Data_Element *element;
+ Eet_Data_Descriptor_Hash *next;
+};
+
struct _Eet_Data_Descriptor
{
char *name;
struct {
int num;
Eet_Data_Element *set;
+ struct {
+ int size;
+ Eet_Data_Descriptor_Hash *buckets;
+ } hash;
} elements;
};
/*---*/
+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,
{
int i;
+ _eet_descriptor_hash_free(edd);
if (edd->name) free(edd->name);
for (i = 0; i < edd->elements.num; i++)
{
}
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);
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)
{
- 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;
+ _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
+ }
+ else
+ {
+ switch (ede->group_type)
{
- switch (ede->group_type)
+ case EET_G_ARRAY:
+ case EET_G_VAR_ARRAY:
{
- case EET_G_ARRAY:
- case EET_G_VAR_ARRAY:
- {
- printf("ARRAY TYPE NOT IMPLIMENTED YET!!!\n");
- }
- break;
- case EET_G_LIST:
+ 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))
{
- 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();
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();
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 */
#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
{
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
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] =
{
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];
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))
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++;
}
}
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;
}
}
}
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);
/* 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;
}
}
}
/* 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 */
}
/* 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];
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);
}
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);
/* 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);
}
/* parse directory block */
p = dyn_buf;
+// printf("entries: %i\n", num_entries);
for (i = 0; i < num_entries; i++)
{
int offset;
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 */
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;
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;
}
{
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);
}
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) &&
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;
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)
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);
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;
/* 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;
}
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 */
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;
/* 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;
}
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) ||
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;
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;
}
}
}