forked from enlightenment/efl
and lo-and-behold. eet gets faster! a lot faster for data chunk decoding
(used by edje and ecore_config and e_config) and just general eet archive opening times... SVN revision: 14943
This commit is contained in:
parent
526a8099fa
commit
67506e226f
|
@ -34,7 +34,7 @@ void _eet_memfile_write_close(FILE *f);
|
||||||
void _eet_memfile_shutdown();
|
void _eet_memfile_shutdown();
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
#define PATH_MAX 4095
|
#define PATH_MAX 4096
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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_Basic_Type_Decoder Eet_Data_Basic_Type_Decoder;
|
||||||
typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
|
typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
|
||||||
typedef struct _Eet_Data_Stream Eet_Data_Stream;
|
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;
|
int pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _Eet_Data_Descriptor_Hash
|
||||||
|
{
|
||||||
|
Eet_Data_Element *element;
|
||||||
|
Eet_Data_Descriptor_Hash *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct _Eet_Data_Descriptor
|
struct _Eet_Data_Descriptor
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -85,6 +92,10 @@ struct _Eet_Data_Descriptor
|
||||||
struct {
|
struct {
|
||||||
int num;
|
int num;
|
||||||
Eet_Data_Element *set;
|
Eet_Data_Element *set;
|
||||||
|
struct {
|
||||||
|
int size;
|
||||||
|
Eet_Data_Descriptor_Hash *buckets;
|
||||||
|
} hash;
|
||||||
} elements;
|
} 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 *
|
||||||
eet_data_descriptor_new(char *name,
|
eet_data_descriptor_new(char *name,
|
||||||
int size,
|
int size,
|
||||||
|
@ -599,6 +711,7 @@ eet_data_descriptor_free(Eet_Data_Descriptor *edd)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
_eet_descriptor_hash_free(edd);
|
||||||
if (edd->name) free(edd->name);
|
if (edd->name) free(edd->name);
|
||||||
for (i = 0; i < edd->elements.num; i++)
|
for (i = 0; i < edd->elements.num; i++)
|
||||||
{
|
{
|
||||||
|
@ -811,10 +924,11 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
||||||
}
|
}
|
||||||
p = chnk->data;
|
p = chnk->data;
|
||||||
size = size_in - (4 + 4 + strlen(chnk->name) + 1);
|
size = size_in - (4 + 4 + strlen(chnk->name) + 1);
|
||||||
|
if (!edd->elements.hash.buckets) _eet_descriptor_hash_new(edd);
|
||||||
while (size > 0)
|
while (size > 0)
|
||||||
{
|
{
|
||||||
Eet_Data_Chunk *echnk;
|
Eet_Data_Chunk *echnk;
|
||||||
int i;
|
Eet_Data_Element *ede;
|
||||||
|
|
||||||
/* get next data chunk */
|
/* get next data chunk */
|
||||||
echnk = eet_data_chunk_get(p, size);
|
echnk = eet_data_chunk_get(p, size);
|
||||||
|
@ -827,88 +941,77 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
||||||
eet_data_chunk_free(chnk);
|
eet_data_chunk_free(chnk);
|
||||||
return NULL;
|
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;
|
if (ede->group_type == EET_G_UNKNOWN)
|
||||||
|
|
||||||
ede = &(edd->elements.set[i]);
|
|
||||||
if (!strcmp(echnk->name, ede->name))
|
|
||||||
{
|
{
|
||||||
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;
|
ret = eet_data_get_type(ede->type,
|
||||||
void *data_ret;
|
echnk->data,
|
||||||
|
((char *)echnk->data) + echnk->size,
|
||||||
if ((ede->type >= EET_T_CHAR) &&
|
((char *)data) + ede->offset);
|
||||||
(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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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:
|
_eet_freelist_unref();
|
||||||
case EET_G_VAR_ARRAY:
|
_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");
|
data_ret = calloc(1, eet_coder[ede->type].size);
|
||||||
}
|
if (data_ret)
|
||||||
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);
|
_eet_freelist_add(data_ret);
|
||||||
if (data_ret)
|
ret = eet_data_get_type(ede->type,
|
||||||
{
|
echnk->data,
|
||||||
_eet_freelist_add(data_ret);
|
((char *)echnk->data) + echnk->size,
|
||||||
ret = eet_data_get_type(ede->type,
|
data_ret);
|
||||||
echnk->data,
|
if (ret <= 0)
|
||||||
((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_unref();
|
_eet_freelist_unref();
|
||||||
_eet_freelist_list_unref();
|
_eet_freelist_list_unref();
|
||||||
|
@ -918,18 +1021,6 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
||||||
return NULL;
|
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
|
else
|
||||||
{
|
{
|
||||||
_eet_freelist_unref();
|
_eet_freelist_unref();
|
||||||
|
@ -940,15 +1031,35 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
else if (ede->subtype)
|
||||||
case EET_G_HASH:
|
{
|
||||||
printf("HASH TYPE NOT IMPLIMENTED YET!!!\n");
|
data_ret = eet_data_descriptor_decode(ede->subtype,
|
||||||
break;
|
echnk->data,
|
||||||
default:
|
echnk->size);
|
||||||
break;
|
}
|
||||||
|
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 */
|
/* advance to next chunk */
|
||||||
|
|
|
@ -11,14 +11,10 @@
|
||||||
|
|
||||||
#define EET_MAGIC_FILE 0x1ee7ff00
|
#define EET_MAGIC_FILE 0x1ee7ff00
|
||||||
#define EET_MAGIC_FILE_HEADER 0x1ee7ff01
|
#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_Header Eet_File_Header;
|
||||||
typedef struct _Eet_File_Node Eet_File_Node;
|
typedef struct _Eet_File_Node Eet_File_Node;
|
||||||
typedef struct _Eet_File_Directory Eet_File_Directory;
|
typedef struct _Eet_File_Directory Eet_File_Directory;
|
||||||
typedef struct _Eet_File_Directory_Hash Eet_File_Directory_Hash;
|
|
||||||
|
|
||||||
struct _Eet_File
|
struct _Eet_File
|
||||||
{
|
{
|
||||||
|
@ -42,26 +38,21 @@ struct _Eet_File_Header
|
||||||
Eet_File_Directory *directory;
|
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
|
struct _Eet_File_Directory
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
Eet_File_Directory_Hash *hash;
|
Eet_File_Node **nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Eet_File_Directory_Hash
|
struct _Eet_File_Node
|
||||||
{
|
{
|
||||||
|
char *name;
|
||||||
|
int offset;
|
||||||
|
int compression;
|
||||||
int size;
|
int size;
|
||||||
Eet_File_Node *node;
|
int data_size;
|
||||||
|
void *data;
|
||||||
|
Eet_File_Node *next; /* FIXME: make buckets linked lists */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -200,7 +191,7 @@ eet_string_match(char *s1, char *s2)
|
||||||
static int
|
static int
|
||||||
eet_hash_gen(char *key, int hash_size)
|
eet_hash_gen(char *key, int hash_size)
|
||||||
{
|
{
|
||||||
int hash_num = 0;
|
int hash_num = 0, i;
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
const int masks[9] =
|
const int masks[9] =
|
||||||
{
|
{
|
||||||
|
@ -219,8 +210,8 @@ eet_hash_gen(char *key, int hash_size)
|
||||||
if (!key) return 0;
|
if (!key) return 0;
|
||||||
|
|
||||||
/* calc hash num */
|
/* calc hash num */
|
||||||
for (ptr = (unsigned char *)key; *ptr; ptr++)
|
for (i = 0, ptr = (unsigned char *)key; *ptr; ptr++, i++)
|
||||||
hash_num ^= (int)(*ptr);
|
hash_num ^= ((int)(*ptr) | ((int)(*ptr) << 8)) >> (i % 8);
|
||||||
|
|
||||||
/* mask it */
|
/* mask it */
|
||||||
hash_num &= masks[hash_size];
|
hash_num &= masks[hash_size];
|
||||||
|
@ -232,9 +223,10 @@ eet_hash_gen(char *key, int hash_size)
|
||||||
static void
|
static void
|
||||||
eet_flush(Eet_File *ef)
|
eet_flush(Eet_File *ef)
|
||||||
{
|
{
|
||||||
int i, j, count, size, num, offset;
|
int i, count, size, num, offset;
|
||||||
int head[3];
|
int head[3];
|
||||||
unsigned long int i1, i2;
|
unsigned long int i1, i2;
|
||||||
|
Eet_File_Node *efn;
|
||||||
|
|
||||||
/* check to see its' an eet file pointer */
|
/* check to see its' an eet file pointer */
|
||||||
if ((!ef) || (ef->magic != EET_MAGIC_FILE))
|
if ((!ef) || (ef->magic != EET_MAGIC_FILE))
|
||||||
|
@ -250,11 +242,11 @@ eet_flush(Eet_File *ef)
|
||||||
num = (1 << (ef->header->directory->size - 1));
|
num = (1 << (ef->header->directory->size - 1));
|
||||||
for (i = 0; i < num; i++)
|
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++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,12 +255,12 @@ eet_flush(Eet_File *ef)
|
||||||
offset = 0;
|
offset = 0;
|
||||||
for (i = 0; i < num; i++)
|
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;
|
efn->offset = 12 + size + offset;
|
||||||
offset += ef->header->directory->hash[i].node[j].size;
|
offset += efn->size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,34 +279,34 @@ eet_flush(Eet_File *ef)
|
||||||
offset = 12;
|
offset = 12;
|
||||||
for (i = 0; i < num; i++)
|
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;
|
unsigned char *buf;
|
||||||
int buf_size;
|
int buf_size;
|
||||||
int name_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_size = 20 + name_size;
|
||||||
buf = malloc(buf_size);
|
buf = malloc(buf_size);
|
||||||
if (!buf) return;
|
if (!buf) return;
|
||||||
i1 = (unsigned long int)ef->header->directory->hash[i].node[j].offset;
|
i1 = (unsigned long int)efn->offset;
|
||||||
i2 = htonl(i1);
|
i2 = htonl(i1);
|
||||||
*((int *)(buf + 0)) = (int)i2;
|
*((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);
|
i2 = htonl(i1);
|
||||||
*((int *)(buf + 4)) = (int)i2;
|
*((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);
|
i2 = htonl(i1);
|
||||||
*((int *)(buf + 8)) = (int)i2;
|
*((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);
|
i2 = htonl(i1);
|
||||||
*((int *)(buf + 12)) = (int)i2;
|
*((int *)(buf + 12)) = (int)i2;
|
||||||
i1 = (unsigned long int)name_size;
|
i1 = (unsigned long int)name_size;
|
||||||
i2 = htonl(i1);
|
i2 = htonl(i1);
|
||||||
*((int *)(buf + 16)) = (int)i2;
|
*((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)
|
if (fwrite(buf, buf_size, 1, ef->fp) != 1)
|
||||||
{
|
{
|
||||||
free(buf);
|
free(buf);
|
||||||
|
@ -328,13 +320,11 @@ eet_flush(Eet_File *ef)
|
||||||
/* write data */
|
/* write data */
|
||||||
for (i = 0; i < num; i++)
|
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,
|
if (fwrite(efn->data, efn->size, 1, ef->fp) != 1)
|
||||||
ef->header->directory->hash[i].node[j].size,
|
|
||||||
1, ef->fp) != 1)
|
|
||||||
return;
|
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 */
|
/* 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;
|
if (!ef) return NULL;
|
||||||
|
|
||||||
/* fill some of the members */
|
/* 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 */
|
/* if we opened for read or read-write */
|
||||||
|
// printf("OPEN!\n");
|
||||||
if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
|
if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
|
||||||
{
|
{
|
||||||
unsigned char buf[12];
|
unsigned char buf[12];
|
||||||
|
@ -462,7 +453,7 @@ eet_open(const char *file, Eet_File_Mode mode)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* allocate header */
|
/* allocate header */
|
||||||
ef->header = calloc(sizeof(Eet_File_Header), 1);
|
ef->header = calloc(1, sizeof(Eet_File_Header));
|
||||||
if (!ef->header)
|
if (!ef->header)
|
||||||
{
|
{
|
||||||
free(dyn_buf);
|
free(dyn_buf);
|
||||||
|
@ -471,7 +462,7 @@ eet_open(const char *file, Eet_File_Mode mode)
|
||||||
}
|
}
|
||||||
ef->header->magic = EET_MAGIC_FILE_HEADER;
|
ef->header->magic = EET_MAGIC_FILE_HEADER;
|
||||||
/* allocate directory block in ram */
|
/* 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)
|
if (!ef->header->directory)
|
||||||
{
|
{
|
||||||
free(dyn_buf);
|
free(dyn_buf);
|
||||||
|
@ -481,8 +472,8 @@ eet_open(const char *file, Eet_File_Mode mode)
|
||||||
/* 8 bit hash table (256 buckets) */
|
/* 8 bit hash table (256 buckets) */
|
||||||
ef->header->directory->size = 8;
|
ef->header->directory->size = 8;
|
||||||
/* allocate base hash table */
|
/* allocate base hash table */
|
||||||
ef->header->directory->hash = calloc(sizeof(Eet_File_Directory_Hash), (1 << (ef->header->directory->size - 1)));
|
ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
|
||||||
if (!ef->header->directory->hash)
|
if (!ef->header->directory->nodes)
|
||||||
{
|
{
|
||||||
free(dyn_buf);
|
free(dyn_buf);
|
||||||
eet_close(ef);
|
eet_close(ef);
|
||||||
|
@ -498,6 +489,7 @@ eet_open(const char *file, Eet_File_Mode mode)
|
||||||
}
|
}
|
||||||
/* parse directory block */
|
/* parse directory block */
|
||||||
p = dyn_buf;
|
p = dyn_buf;
|
||||||
|
// printf("entries: %i\n", num_entries);
|
||||||
for (i = 0; i < num_entries; i++)
|
for (i = 0; i < num_entries; i++)
|
||||||
{
|
{
|
||||||
int offset;
|
int offset;
|
||||||
|
@ -507,8 +499,7 @@ eet_open(const char *file, Eet_File_Mode mode)
|
||||||
int name_size;
|
int name_size;
|
||||||
char *name;
|
char *name;
|
||||||
int hash;
|
int hash;
|
||||||
Eet_File_Node *node;
|
Eet_File_Node *efn;
|
||||||
int node_size;
|
|
||||||
void *data = NULL;
|
void *data = NULL;
|
||||||
|
|
||||||
/* out directory block is inconsistent - we have oveerun our */
|
/* 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;
|
name[name_size] = 0;
|
||||||
/* get hask bucket it should go in */
|
/* get hask bucket it should go in */
|
||||||
hash = eet_hash_gen(name, ef->header->directory->size);
|
hash = eet_hash_gen(name, ef->header->directory->size);
|
||||||
/* resize hask bucket */
|
efn = calloc(1, sizeof(Eet_File_Node));
|
||||||
node = realloc(ef->header->directory->hash[hash].node,
|
if (!efn)
|
||||||
(ef->header->directory->hash[hash].size + 1) *
|
|
||||||
sizeof(Eet_File_Node));
|
|
||||||
if (!node)
|
|
||||||
{
|
{
|
||||||
free(dyn_buf);
|
free(dyn_buf);
|
||||||
eet_close(ef);
|
eet_close(ef);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* current node size */
|
efn->next = ef->header->directory->nodes[hash];
|
||||||
node_size = ef->header->directory->hash[hash].size;
|
ef->header->directory->nodes[hash] = efn;
|
||||||
/* resized node list set up */
|
efn->name = name;
|
||||||
ef->header->directory->hash[hash].node = node;
|
efn->offset = offset;
|
||||||
/* new node at end */
|
efn->compression = flags;
|
||||||
ef->header->directory->hash[hash].node[node_size].name = name;
|
efn->size = size;
|
||||||
ef->header->directory->hash[hash].node[node_size].offset = offset;
|
efn->data_size = data_size;
|
||||||
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;
|
|
||||||
|
|
||||||
/* read-only mode, so currently we have no data loaded */
|
/* read-only mode, so currently we have no data loaded */
|
||||||
if (mode == EET_FILE_MODE_READ)
|
if (mode == EET_FILE_MODE_READ)
|
||||||
{
|
efn->data = NULL;
|
||||||
ef->header->directory->hash[hash].node[node_size].data = NULL;
|
|
||||||
}
|
|
||||||
/* read-write mode - read everything into ram */
|
/* read-write mode - read everything into ram */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data = malloc(size);
|
data = malloc(size);
|
||||||
if (data)
|
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);
|
free(data);
|
||||||
data = NULL;
|
data = NULL;
|
||||||
|
@ -616,12 +599,9 @@ eet_open(const char *file, Eet_File_Mode mode)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
efn->data = data;
|
||||||
ef->header->directory->hash[hash].node[node_size].data = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* increment number of nodes */
|
|
||||||
ef->header->directory->hash[hash].size++;
|
|
||||||
/* advance */
|
/* advance */
|
||||||
p += 20 + name_size;
|
p += 20 + name_size;
|
||||||
}
|
}
|
||||||
|
@ -683,30 +663,24 @@ eet_close(Eet_File *ef)
|
||||||
{
|
{
|
||||||
if (ef->header->directory)
|
if (ef->header->directory)
|
||||||
{
|
{
|
||||||
if (ef->header->directory->hash)
|
if (ef->header->directory->nodes)
|
||||||
{
|
{
|
||||||
int i, num;
|
int i, num;
|
||||||
|
|
||||||
num = (1 << (ef->header->directory->size - 1));
|
num = (1 << ef->header->directory->size);
|
||||||
for (i = 0; i < num; i++)
|
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;
|
if (efn->name) free(efn->name);
|
||||||
int num2;
|
if (efn->data) free(efn->data);
|
||||||
|
ef->header->directory->nodes[i] = efn->next;
|
||||||
num2 = ef->header->directory->hash[i].size;
|
free(efn);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(ef->header->directory->hash);
|
free(ef->header->directory->nodes);
|
||||||
}
|
}
|
||||||
free(ef->header->directory);
|
free(ef->header->directory);
|
||||||
}
|
}
|
||||||
|
@ -723,9 +697,10 @@ void *
|
||||||
eet_read(Eet_File *ef, char *name, int *size_ret)
|
eet_read(Eet_File *ef, char *name, int *size_ret)
|
||||||
{
|
{
|
||||||
void *data = NULL;
|
void *data = NULL;
|
||||||
int size = 0, tmp_size;
|
int size = 0, tmp_size;
|
||||||
int hash, i, num;
|
int hash;
|
||||||
|
Eet_File_Node *efn;
|
||||||
|
|
||||||
/* check to see its' an eet file pointer */
|
/* check to see its' an eet file pointer */
|
||||||
if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!name) ||
|
if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!name) ||
|
||||||
((ef->mode != EET_FILE_MODE_READ) &&
|
((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);
|
hash = eet_hash_gen(name, ef->header->directory->size);
|
||||||
// printf("read %s\n", name);
|
// printf("read %s\n", name);
|
||||||
/* hunt hash bucket */
|
/* hunt hash bucket */
|
||||||
num = ef->header->directory->hash[hash].size;
|
for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next)
|
||||||
for (i = 0; i < num; i++)
|
|
||||||
{
|
{
|
||||||
/* if it matches */
|
/* 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 */
|
/* uncompressed data */
|
||||||
if (ef->header->directory->hash[hash].node[i].compression == 0)
|
if (efn->compression == 0)
|
||||||
{
|
{
|
||||||
/* get size */
|
/* get size */
|
||||||
size = ef->header->directory->hash[hash].node[i].size;
|
size = efn->size;
|
||||||
/* allocate data */
|
/* allocate data */
|
||||||
data = malloc(size);
|
data = malloc(size);
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
/* if we alreayd have the data in ram... copy that */
|
/* if we alreayd have the data in ram... copy that */
|
||||||
if (ef->header->directory->hash[hash].node[i].data)
|
if (efn->data)
|
||||||
memcpy(data,
|
memcpy(data, efn->data, efn->size);
|
||||||
ef->header->directory->hash[hash].node[i].data,
|
|
||||||
ef->header->directory->hash[hash].node[i].size);
|
|
||||||
/* or get data from disk */
|
/* or get data from disk */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* seek to data location */
|
/* 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);
|
free(data);
|
||||||
data = NULL;
|
data = NULL;
|
||||||
|
@ -789,11 +761,11 @@ eet_read(Eet_File *ef, char *name, int *size_ret)
|
||||||
void *tmp_data;
|
void *tmp_data;
|
||||||
|
|
||||||
/* get size of data in file */
|
/* 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);
|
tmp_data = malloc(tmp_size);
|
||||||
if (!tmp_data) break;
|
if (!tmp_data) break;
|
||||||
/* get size uncompressed */
|
/* get size uncompressed */
|
||||||
size = ef->header->directory->hash[hash].node[i].data_size;
|
size = efn->data_size;
|
||||||
/* allocate data */
|
/* allocate data */
|
||||||
data = malloc(size);
|
data = malloc(size);
|
||||||
if (data)
|
if (data)
|
||||||
|
@ -801,15 +773,13 @@ eet_read(Eet_File *ef, char *name, int *size_ret)
|
||||||
uLongf dlen;
|
uLongf dlen;
|
||||||
|
|
||||||
/* if we already have the data in ram... copy that */
|
/* if we already have the data in ram... copy that */
|
||||||
if (ef->header->directory->hash[hash].node[i].data)
|
if (efn->data)
|
||||||
memcpy(tmp_data,
|
memcpy(tmp_data, efn->data, tmp_size);
|
||||||
ef->header->directory->hash[hash].node[i].data,
|
|
||||||
tmp_size);
|
|
||||||
/* or get data from disk */
|
/* or get data from disk */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* seek to data location */
|
/* 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(tmp_data);
|
||||||
free(data);
|
free(data);
|
||||||
|
@ -851,38 +821,35 @@ int
|
||||||
eet_write(Eet_File *ef, char *name, void *data, int size, int compress)
|
eet_write(Eet_File *ef, char *name, void *data, int size, int compress)
|
||||||
{
|
{
|
||||||
int data_size;
|
int data_size;
|
||||||
int hash, node_size;
|
int hash;
|
||||||
Eet_File_Node *node;
|
Eet_File_Node *efn;
|
||||||
char *name2;
|
char *name2;
|
||||||
void *data2;
|
void *data2;
|
||||||
int exists_already = 0;
|
int exists_already = 0;
|
||||||
|
|
||||||
/* check to see its' an eet file pointer */
|
/* check to see its' an eet file pointer */
|
||||||
if ((!ef) || (ef->magic != EET_MAGIC_FILE)
|
if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!name) || (!data) ||
|
||||||
|| (!name) || (!data) || (size <= 0) ||
|
(size <= 0) || ((ef->mode != EET_FILE_MODE_WRITE) &&
|
||||||
((ef->mode != EET_FILE_MODE_WRITE) &&
|
(ef->mode != EET_FILE_MODE_READ_WRITE)))
|
||||||
(ef->mode != EET_FILE_MODE_READ_WRITE)))
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!ef->header)
|
if (!ef->header)
|
||||||
{
|
{
|
||||||
/* allocate header */
|
/* allocate header */
|
||||||
ef->header = calloc(sizeof(Eet_File_Header), 1);
|
ef->header = calloc(1, sizeof(Eet_File_Header));
|
||||||
if (!ef->header) return 0;
|
if (!ef->header) return 0;
|
||||||
ef->header->magic = EET_MAGIC_FILE_HEADER;
|
ef->header->magic = EET_MAGIC_FILE_HEADER;
|
||||||
/* allocate directory block in ram */
|
/* 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;
|
if (!ef->header->directory) return 0;
|
||||||
/* 8 bit hash table (256 buckets) */
|
/* 8 bit hash table (256 buckets) */
|
||||||
ef->header->directory->size = 8;
|
ef->header->directory->size = 8;
|
||||||
/* allocate base hash table */
|
/* allocate base hash table */
|
||||||
ef->header->directory->hash = calloc(sizeof(Eet_File_Directory_Hash), (1 << (ef->header->directory->size - 1)));
|
ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
|
||||||
if (!ef->header->directory->hash) return 0;
|
if (!ef->header->directory->nodes) return 0;
|
||||||
}
|
}
|
||||||
/* figure hash bucket */
|
/* figure hash bucket */
|
||||||
hash = eet_hash_gen(name, ef->header->directory->size);
|
hash = eet_hash_gen(name, ef->header->directory->size);
|
||||||
node_size = ef->header->directory->hash[hash].size;
|
|
||||||
/* dup name */
|
/* dup name */
|
||||||
name2 = strdup(name);
|
name2 = strdup(name);
|
||||||
if (!name2) return 0;
|
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? */
|
/* Does this node already exist? */
|
||||||
if (ef->mode == EET_FILE_MODE_READ_WRITE)
|
if (ef->mode == EET_FILE_MODE_READ_WRITE)
|
||||||
{
|
{
|
||||||
int i;
|
for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next)
|
||||||
for (i = 0; i < node_size; i++)
|
|
||||||
{
|
{
|
||||||
/* if it matches */
|
/* 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);
|
free(efn->data);
|
||||||
ef->header->directory->hash[hash].node[i].compression = compress;
|
efn->compression = compress;
|
||||||
ef->header->directory->hash[hash].node[i].size = data_size;
|
efn->size = data_size;
|
||||||
ef->header->directory->hash[hash].node[i].data_size = size;
|
efn->data_size = size;
|
||||||
ef->header->directory->hash[hash].node[i].data = data2;
|
efn->data = data2;
|
||||||
exists_already = 1;
|
exists_already = 1;
|
||||||
free(name2);
|
free(name2);
|
||||||
break;
|
break;
|
||||||
|
@ -952,25 +918,23 @@ eet_write(Eet_File *ef, char *name, void *data, int size, int compress)
|
||||||
}
|
}
|
||||||
if (!exists_already)
|
if (!exists_already)
|
||||||
{
|
{
|
||||||
/* increase hash bucket size */
|
efn = calloc(1, sizeof(Eet_File_Node));
|
||||||
node = realloc(ef->header->directory->hash[hash].node,
|
if (!efn)
|
||||||
(node_size + 1) * sizeof(Eet_File_Node));
|
|
||||||
if (!node)
|
|
||||||
{
|
{
|
||||||
free(name2);
|
free(name2);
|
||||||
free(data2);
|
free(data2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* resized node list set up */
|
/* 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 */
|
/* new node at end */
|
||||||
ef->header->directory->hash[hash].node[node_size].name = name2;
|
efn->name = name2;
|
||||||
ef->header->directory->hash[hash].node[node_size].offset = 0;
|
efn->offset = 0;
|
||||||
ef->header->directory->hash[hash].node[node_size].compression = compress;
|
efn->compression = compress;
|
||||||
ef->header->directory->hash[hash].node[node_size].size = data_size;
|
efn->size = data_size;
|
||||||
ef->header->directory->hash[hash].node[node_size].data_size = size;
|
efn->data_size = size;
|
||||||
ef->header->directory->hash[hash].node[node_size].data = data2;
|
efn->data = data2;
|
||||||
ef->header->directory->hash[hash].size++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flags that writes are pending */
|
/* flags that writes are pending */
|
||||||
|
@ -982,9 +946,10 @@ eet_write(Eet_File *ef, char *name, void *data, int size, int compress)
|
||||||
int
|
int
|
||||||
eet_delete(Eet_File *ef, char *name)
|
eet_delete(Eet_File *ef, char *name)
|
||||||
{
|
{
|
||||||
int hash, node_size, i;
|
int hash;
|
||||||
int exists_already = 0;
|
int exists_already = 0;
|
||||||
|
Eet_File_Node *efn, *pefn;
|
||||||
|
|
||||||
/* check to see its' an eet file pointer */
|
/* check to see its' an eet file pointer */
|
||||||
if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!name))
|
if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!name))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -996,19 +961,20 @@ eet_delete(Eet_File *ef, char *name)
|
||||||
|
|
||||||
/* figure hash bucket */
|
/* figure hash bucket */
|
||||||
hash = eet_hash_gen(name, ef->header->directory->size);
|
hash = eet_hash_gen(name, ef->header->directory->size);
|
||||||
node_size = ef->header->directory->hash[hash].size;
|
|
||||||
|
|
||||||
/* Does this node already exist? */
|
/* 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 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);
|
if (efn->name) free(efn->name);
|
||||||
ef->header->directory->hash[hash].node[i].compression = -1;
|
if (efn->data) free(efn->data);
|
||||||
ef->header->directory->hash[hash].node[i].size = 0;
|
if (efn == ef->header->directory->nodes[hash])
|
||||||
ef->header->directory->hash[hash].node[i].data_size = 0;
|
ef->header->directory->nodes[hash] = efn->next;
|
||||||
ef->header->directory->hash[hash].node[i].data = NULL;
|
else
|
||||||
|
pefn->next = efn->next;
|
||||||
|
free(efn);
|
||||||
exists_already = 1;
|
exists_already = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1026,6 +992,7 @@ eet_list(Eet_File *ef, char *glob, int *count_ret)
|
||||||
int list_count = 0;
|
int list_count = 0;
|
||||||
int list_count_alloc = 0;
|
int list_count_alloc = 0;
|
||||||
int i, j, num;
|
int i, j, num;
|
||||||
|
Eet_File_Node *efn;
|
||||||
|
|
||||||
/* check to see its' an eet file pointer */
|
/* check to see its' an eet file pointer */
|
||||||
if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!glob) ||
|
if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!glob) ||
|
||||||
|
@ -1037,13 +1004,13 @@ eet_list(Eet_File *ef, char *glob, int *count_ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* loop through all entries */
|
/* loop through all entries */
|
||||||
num = (1 << (ef->header->directory->size - 1));
|
num = (1 << ef->header->directory->size);
|
||||||
for (i = 0; i < num; i++)
|
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 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;
|
char **new_list;
|
||||||
|
|
||||||
|
@ -1063,7 +1030,7 @@ eet_list(Eet_File *ef, char *glob, int *count_ret)
|
||||||
list_ret = new_list;
|
list_ret = new_list;
|
||||||
}
|
}
|
||||||
/* put pointer of name string in */
|
/* 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue