support special strign and alloc methods

SVN revision: 18731
This commit is contained in:
Carsten Haitzler 2005-11-30 15:36:19 +00:00
parent 430b2a1901
commit f8dd4d1af7
2 changed files with 186 additions and 23 deletions

View File

@ -1,6 +1,8 @@
#ifndef _EET_H
#define _EET_H
#include <stdlib.h>
#ifdef EAPI
#undef EAPI
#endif
@ -63,11 +65,34 @@ extern "C" {
EET_FILE_MODE_READ_WRITE
};
typedef enum _Eet_File_Mode Eet_File_Mode;
typedef enum _Eet_File_Mode Eet_File_Mode;
typedef struct _Eet_File Eet_File;
typedef struct _Eet_Data_Descriptor Eet_Data_Descriptor;
typedef struct _Eet_File Eet_File;
typedef struct _Eet_Data_Descriptor Eet_Data_Descriptor;
typedef struct _Eet_Data_Descriptor_Class Eet_Data_Descriptor_Class;
#define EET_DATA_DESCRIPTOR_CLASS_VERSION 1
struct _Eet_Data_Descriptor_Class
{
int version;
const char *name;
int size;
struct {
void *(*mem_alloc) (size_t size);
void (*mem_free) (void *mem);
char *(*str_alloc) (const char *str);
void (*str_free) (const char *str);
void *(*list_next) (void *l);
void *(*list_append) (void *l, void *d);
void *(*list_data) (void *l);
void *(*list_free) (void *l);
void (*hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt);
void *(*hash_add) (void *h, const char *k, void *d);
void (*hash_free) (void *h);
} func;
};
/***************************************************************************/
/**

View File

@ -81,6 +81,10 @@ struct _Eet_Data_Descriptor
const char *name;
int size;
struct {
void *(*mem_alloc) (size_t size);
void (*mem_free) (void *mem);
char *(*str_alloc) (const char *str);
void (*str_free) (const char *str);
void *(*list_next) (void *l);
void *(*list_append) (void *l, void *d);
void *(*list_data) (void *l);
@ -353,8 +357,7 @@ eet_data_get_float(void *src, void *src_end, void *dst)
p = s;
len = 0;
while ((p < (char *)src_end) && (*p != 0)) {len++; p++;}
str = malloc(len + 1);
if (!str) return -1;
str = alloca(len + 1);
memcpy(str, s, len);
str[len] = 0;
@ -364,8 +367,7 @@ eet_data_get_float(void *src, void *src_end, void *dst)
sscanf(str, "%a", &tf);
*d = (float)tf;
if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
free(str);
return len + 1;
}
@ -402,8 +404,7 @@ eet_data_get_double(void *src, void *src_end, void *dst)
p = s;
len = 0;
while ((p < (char *)src_end) && (*p != 0)) {len++; p++;}
str = malloc(len + 1);
if (!str) return -1;
str = alloca(len + 1);
memcpy(str, s, len);
str[len] = 0;
@ -414,7 +415,6 @@ eet_data_get_double(void *src, void *src_end, void *dst)
*d = (double)tf;
if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
free(str);
return len + 1;
}
@ -686,6 +686,30 @@ _eet_descriptor_hash_find(Eet_Data_Descriptor *edd, char *name)
return NULL;
}
static void *
_eet_mem_alloc(size_t size)
{
return calloc(1, size);
}
static void
_eet_mem_free(void *mem)
{
free(mem);
}
static char *
_eet_str_alloc(const char *str)
{
return strdup(str);
}
static void
_eet_str_free(const char *str)
{
free((char *)str);
}
/*---*/
Eet_Data_Descriptor *
@ -710,6 +734,10 @@ eet_data_descriptor_new(const char *name,
edd = calloc(1, sizeof(Eet_Data_Descriptor));
edd->name = name;
edd->size = size;
edd->func.mem_alloc = _eet_mem_alloc;
edd->func.mem_free = _eet_mem_free;
edd->func.str_alloc = _eet_str_alloc;
edd->func.str_free = _eet_str_free;
edd->func.list_next = func_list_next;
edd->func.list_append = func_list_append;
edd->func.list_data = func_list_data;
@ -720,6 +748,39 @@ eet_data_descriptor_new(const char *name,
return edd;
}
/* new replcement */
Eet_Data_Descriptor *
eet_data_descriptor2_new(Eet_Data_Descriptor_Class *eddc)
{
Eet_Data_Descriptor *edd;
if (!eddc) return NULL;
edd = calloc(1, sizeof(Eet_Data_Descriptor));
if (eddc->version < 1) return edd;
edd->name = eddc->name;
edd->size = eddc->size;
edd->func.mem_alloc = _eet_mem_alloc;
edd->func.mem_free = _eet_mem_free;
edd->func.str_alloc = _eet_str_alloc;
edd->func.str_free = _eet_str_free;
if (eddc->func.mem_alloc)
edd->func.mem_alloc = eddc->func.mem_alloc;
if (eddc->func.mem_free)
edd->func.mem_free = eddc->func.mem_free;
if (eddc->func.str_alloc)
edd->func.str_alloc = eddc->func.str_alloc;
if (eddc->func.str_free)
edd->func.str_free = eddc->func.str_free;
edd->func.list_next = eddc->func.list_next;
edd->func.list_append = eddc->func.list_append;
edd->func.list_data = eddc->func.list_data;
edd->func.list_free = eddc->func.list_free;
edd->func.hash_foreach = eddc->func.hash_foreach;
edd->func.hash_add = eddc->func.hash_add;
edd->func.hash_free = eddc->func.hash_free;
return edd;
}
void
eet_data_descriptor_free(Eet_Data_Descriptor *edd)
{
@ -848,13 +909,13 @@ _eet_freelist_reset(void)
}
static void
_eet_freelist_free(void)
_eet_freelist_free(Eet_Data_Descriptor *edd)
{
int i;
if (freelist_ref > 0) return;
for (i = 0; i < freelist_num; i++)
free(freelist[i]);
edd->func.mem_free(freelist[i]);
_eet_freelist_reset();
}
@ -926,6 +987,56 @@ _eet_freelist_list_unref(void)
freelist_list_ref--;
}
static int freelist_str_ref = 0;
static int freelist_str_len = 0;
static int freelist_str_num = 0;
static void **freelist_str = NULL;
static void
_eet_freelist_str_add(void *data)
{
freelist_str_num++;
if (freelist_str_num > freelist_str_len)
{
freelist_str_len += 16;
freelist_str = realloc(freelist_str, freelist_str_len * sizeof(void *));
}
freelist_str[freelist_str_num - 1] = data;
}
static void
_eet_freelist_str_reset(void)
{
if (freelist_str_ref > 0) return;
freelist_str_len = 0;
freelist_str_num = 0;
if (freelist_str) free(freelist_str);
freelist_str = NULL;
}
static void
_eet_freelist_str_free(Eet_Data_Descriptor *edd)
{
int i;
if (freelist_str_ref > 0) return;
for (i = 0; i < freelist_str_num; i++)
edd->func.str_free(freelist_str[i]);
_eet_freelist_str_reset();
}
static void
_eet_freelist_str_ref(void)
{
freelist_str_ref++;
}
static void
_eet_freelist_str_unref(void)
{
freelist_str_ref--;
}
void *
eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
void *data_in,
@ -945,9 +1056,10 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
else words_bigendian = 0;
}
data = calloc(1, edd->size);
data = edd->func.mem_alloc(edd->size);
if (!data) return NULL;
_eet_freelist_ref();
_eet_freelist_str_ref();
_eet_freelist_list_ref();
_eet_freelist_add(data);
memset(&chnk, 0, sizeof(Eet_Data_Chunk));
@ -955,8 +1067,10 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
if (!chnk.name)
{
_eet_freelist_unref();
_eet_freelist_str_unref();
_eet_freelist_list_unref();
_eet_freelist_free();
_eet_freelist_free(edd);
_eet_freelist_str_free(edd);
_eet_freelist_list_free(edd);
return NULL;
}
@ -964,8 +1078,10 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
{
free(chnk.name);
_eet_freelist_unref();
_eet_freelist_str_unref();
_eet_freelist_list_unref();
_eet_freelist_free();
_eet_freelist_free(edd);
_eet_freelist_str_free(edd);
_eet_freelist_list_free(edd);
return NULL;
}
@ -983,15 +1099,14 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
if (!echnk.name)
{
_eet_freelist_unref();
_eet_freelist_str_unref();
_eet_freelist_list_unref();
_eet_freelist_free();
_eet_freelist_free(edd);
_eet_freelist_str_free(edd);
_eet_freelist_list_free(edd);
free(chnk.name);
return NULL;
}
/* 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)
{
@ -1007,6 +1122,19 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
echnk.data,
((char *)echnk.data) + echnk.size,
((char *)data) + ede->offset);
if (ede->type == EET_T_STRING)
{
char **str, *str2;
str = (((char *)data) + ede->offset);
if (*str)
{
str2 = edd->func.str_alloc(*str);
free(*str);
*str = str2;
_eet_freelist_str_add(str2);
}
}
}
else if (ede->subtype)
{
@ -1018,8 +1146,10 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
if (!data_ret)
{
_eet_freelist_unref();
_eet_freelist_str_unref();
_eet_freelist_list_unref();
_eet_freelist_free();
_eet_freelist_free(edd);
_eet_freelist_str_free(edd);
_eet_freelist_list_free(edd);
free(chnk.name);
return NULL;
@ -1062,8 +1192,10 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
if (ret <= 0)
{
_eet_freelist_unref();
_eet_freelist_str_unref();
_eet_freelist_list_unref();
_eet_freelist_free();
_eet_freelist_free(edd);
_eet_freelist_str_free(edd);
_eet_freelist_list_free(edd);
free(chnk.name);
return NULL;
@ -1072,8 +1204,10 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
else
{
_eet_freelist_unref();
_eet_freelist_str_unref();
_eet_freelist_list_unref();
_eet_freelist_free();
_eet_freelist_free(edd);
_eet_freelist_str_free(edd);
_eet_freelist_list_free(edd);
free(chnk.name);
return NULL;
@ -1094,8 +1228,10 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
else
{
_eet_freelist_unref();
_eet_freelist_str_unref();
_eet_freelist_list_unref();
_eet_freelist_free();
_eet_freelist_free(edd);
_eet_freelist_str_free(edd);
_eet_freelist_list_free(edd);
free(chnk.name);
return NULL;
@ -1117,8 +1253,10 @@ eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
}
free(chnk.name);
_eet_freelist_unref();
_eet_freelist_str_unref();
_eet_freelist_list_unref();
_eet_freelist_reset();
_eet_freelist_str_reset();
_eet_freelist_list_reset();
return data;
}