#include "Eet.h"
#include "Eet_private.h"
+#ifdef _WIN32
+# define FMT_CHAR "%c"
+# define FMT_UCHAR "%c"
+# define FMT_LONG_LONG "%I64i"
+# define FMT_ULONG_LONG "%I64u"
+#else
+# define FMT_CHAR "%hhi"
+# define FMT_UCHAR "%hhu"
+# define FMT_LONG_LONG "%lli"
+# define FMT_ULONG_LONG "%llu"
+#endif
+
/*
* routines for doing data -> struct and struct -> data conversion
*
Eet_Dictionary *ed;
};
+#define EET_FREE_COUNT 256
struct _Eet_Free
{
int ref;
- int len[256];
- int num[256];
- void **list[256];
+ Eina_Array list[EET_FREE_COUNT];
};
struct _Eet_Free_Context
struct _Eet_Variant_Unknow
{
- EINA_MAGIC;
+ EINA_MAGIC
int size;
char data[1];
/*---*/
+static void eet_free_context_init(Eet_Free_Context *context);
+static void eet_free_context_shutdown(Eet_Free_Context *context);
+
static int eet_data_get_char(const Eet_Dictionary *ed,
const void *src,
const void *src_end,
const Eet_Dictionary *ed,
Eet_Data_Descriptor *edd,
const void *data_in,
- int size_in);
+ int size_in,
+ void *data_out,
+ int size_out);
/*---*/
if (!___r) { goto Label; }\
} while (0)
-#define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, Label)\
+#define STRUCT_TYPE_DECODE(Data_Ret, Context, Ed, Ede, Data, Size, SubSize, Label) \
do {\
Data_Ret = _eet_data_descriptor_decode(Context,\
Ed,\
Ede,\
Data,\
- Size);\
+ Size,\
+ SubSize > 0 ? Data_Ret : NULL,\
+ SubSize); \
if (!Data_Ret) { goto Label; }\
} while (0)
EAPI Eet_Data_Descriptor *
eet_data_descriptor_new(const char *name,
int size,
- void *(*func_list_next)(void *l),
- void *(*func_list_append)(void *l, void *d),
- void *(*func_list_data)(void *l),
- void *(*func_list_free)(void *l),
- void (*func_hash_foreach)(void *h, int (*func)(void *h, const char *k, void *dt, void *fdt), void *fdt),
- void *(*func_hash_add)(void *h, const char *k, void *d),
- void (*func_hash_free)(void *h))
+ Eet_Descriptor_List_Next_Callback func_list_next,
+ Eet_Descriptor_List_Append_Callback func_list_append,
+ Eet_Descriptor_List_Data_Callback func_list_data,
+ Eet_Descriptor_List_Free_Callback func_list_free,
+ Eet_Descriptor_Hash_Foreach_Callback func_hash_foreach,
+ Eet_Descriptor_Hash_Add_Callback func_hash_add,
+ Eet_Descriptor_Hash_Free_Callback func_hash_free)
{
Eet_Data_Descriptor_Class eddc;
return NULL;
}
- memset(&context, 0, sizeof (context));
- data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size);
+ eet_free_context_init(&context);
+ data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, NULL, 0);
+ eet_free_context_shutdown(&context);
+
if (required_free)
free((void *)data);
return NULL;
}
- memset(&context, 0, sizeof (context));
- result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
+ eet_free_context_init(&context);
+ result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
+ eet_free_context_shutdown(&context);
+
if (required_free)
free((void *)data);
return eet_data_write_cipher(ef, edd, name, NULL, data, compress);
} /* eet_data_write */
+static void
+eet_free_context_init(Eet_Free_Context *context)
+{
+ unsigned int i = 0;
+
+ memset(context, 0, sizeof (Eet_Free_Context));
+ for (i = 0; i < EET_FREE_COUNT; ++i)
+ {
+ eina_array_step_set(&context->freelist.list[i],
+ sizeof (context->freelist.list[i]),
+ 32);
+ eina_array_step_set(&context->freelist_array.list[i],
+ sizeof (context->freelist.list[i]),
+ 32);
+ eina_array_step_set(&context->freelist_list.list[i],
+ sizeof (context->freelist.list[i]),
+ 32);
+ eina_array_step_set(&context->freelist_hash.list[i],
+ sizeof (context->freelist.list[i]),
+ 32);
+ eina_array_step_set(&context->freelist_str.list[i],
+ sizeof (context->freelist.list[i]),
+ 32);
+ eina_array_step_set(&context->freelist_direct_str.list[i],
+ sizeof (context->freelist.list[i]),
+ 32);
+ }
+}
+
+static void
+eet_free_context_shutdown(Eet_Free_Context *context)
+{
+ unsigned int i = 0;
+
+ for (i = 0; i < EET_FREE_COUNT; ++i)
+ {
+ eina_array_flush(&context->freelist.list[i]);
+ eina_array_flush(&context->freelist_array.list[i]);
+ eina_array_flush(&context->freelist_list.list[i]);
+ eina_array_flush(&context->freelist_hash.list[i]);
+ eina_array_flush(&context->freelist_str.list[i]);
+ eina_array_flush(&context->freelist_direct_str.list[i]);
+ }
+}
+
static int
_eet_free_hash(void *data)
{
_eet_free_add(Eet_Free *ef,
void *data)
{
+ void *track;
+ Eina_Array_Iterator it;
+ unsigned int i;
int hash;
- int i;
hash = _eet_free_hash(data);
- for (i = 0; i < ef->num[hash]; ++i)
- if (ef->list[hash][i] == data)
- return;
-
- ef->num[hash]++;
- if (ef->num[hash] > ef->len[hash])
- {
- void **tmp;
-
- tmp = realloc(ef->list[hash], (ef->len[hash] + 16) * sizeof(void *));
- if (!tmp)
- return;
-
- ef->len[hash] += 16;
- ef->list[hash] = tmp;
- }
+ EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it)
+ if (track == data)
+ return;
- ef->list[hash][ef->num[hash] - 1] = data;
+ eina_array_push(&ef->list[hash], data);
} /* _eet_free_add */
+#if 0
static void
_eet_free_del(Eet_Free *ef,
void *data)
{
+ void *track;
+ Eina_Array_Iterator it;
+ unsigned int i;
int hash;
- int i;
hash = _eet_free_hash(data);
- for (i = 0; i < ef->num[hash]; ++i)
- if (ef->list[hash][i] == data)
- {
- ef->list[hash][i] = NULL;
- return;
- }
+ EINA_ARRAY_ITER_NEXT(&ef->list[hash], i, track, it)
+ if (track == data)
+ {
+ eina_array_data_set(&ef->list[hash], i, NULL);
+ return;
+ }
}
+#endif
static void
_eet_free_reset(Eet_Free *ef)
{
- int i;
+ unsigned int i;
if (ef->ref > 0)
return;
- for (i = 0; i < 256; ++i)
- {
- ef->len[i] = 0;
- ef->num[i] = 0;
- if (ef->list[i])
- free(ef->list[i]);
-
- ef->list[i] = NULL;
- }
+ for (i = 0; i < EET_FREE_COUNT; ++i)
+ eina_array_clean(&ef->list[i]);
} /* _eet_free_reset */
static void
_eet_freelist_free(Eet_Free_Context *context,
Eet_Data_Descriptor *edd)
{
- int j;
- int i;
+ void *track;
+ Eina_Array_Iterator it;
+ unsigned int j;
+ unsigned int i;
if (context->freelist.ref > 0)
return;
- for (j = 0; j < 256; ++j)
- for (i = 0; i < context->freelist.num[j]; ++i)
- if (context->freelist.list[j][i])
- {
- if (edd)
- edd->func.mem_free(context->freelist.list[j][i]);
- else
- free(context->freelist.list[j][i]);
- }
+ for (j = 0; j < EET_FREE_COUNT; ++j)
+ EINA_ARRAY_ITER_NEXT(&context->freelist.list[j], i, track, it)
+ if (track)
+ {
+ if (edd)
+ edd->func.mem_free(track);
+ else
+ free(track);
+ }
_eet_free_reset(&context->freelist);
} /* _eet_freelist_free */
_eet_freelist_array_free(Eet_Free_Context *context,
Eet_Data_Descriptor *edd)
{
- int j;
- int i;
+ void *track;
+ Eina_Array_Iterator it;
+ unsigned int j;
+ unsigned int i;
if (context->freelist_array.ref > 0)
return;
- for (j = 0; j < 256; ++j)
- for (i = 0; i < context->freelist_array.num[j]; ++i)
- if (context->freelist_array.list[j][i])
- {
- if (edd)
- {
- if (edd->func.array_free)
- edd->func.array_free(context->freelist_array.list[j][i]);
- else
- edd->func.mem_free(context->freelist_array.list[j][i]);
- }
- else
- free(context->freelist_array.list[j][i]);
- }
+ for (j = 0; j < EET_FREE_COUNT; ++j)
+ EINA_ARRAY_ITER_NEXT(&context->freelist_array.list[j], i, track, it)
+ if (track)
+ {
+ if (edd)
+ {
+ if (edd->func.array_free)
+ edd->func.array_free(track);
+ else
+ edd->func.mem_free(track);
+ }
+ else
+ free(track);
+ }
_eet_free_reset(&context->freelist_array);
} /* _eet_freelist_array_free */
_eet_freelist_list_free(Eet_Free_Context *context,
Eet_Data_Descriptor *edd)
{
- int j;
- int i;
+ void *track;
+ Eina_Array_Iterator it;
+ unsigned int j;
+ unsigned int i;
if (context->freelist_list.ref > 0)
return;
- for (j = 0; j < 256; ++j)
- for (i = 0; i < context->freelist_list.num[j]; ++i)
- if (context->freelist_list.list[j][i])
- {
- if (edd)
- edd->func.list_free(*((void **)(context->freelist_list.list[j][i])));
- }
+ for (j = 0; j < EET_FREE_COUNT; ++j)
+ EINA_ARRAY_ITER_NEXT(&context->freelist_list.list[j], i, track, it)
+ if (track)
+ {
+ if (edd)
+ edd->func.list_free(*((void **)(track)));
+ }
_eet_free_reset(&context->freelist_list);
} /* _eet_freelist_list_free */
static void
_eet_freelist_str_free(Eet_Free_Context *context, Eet_Data_Descriptor *edd)
{
- int j;
- int i;
+ void *track;
+ Eina_Array_Iterator it;
+ unsigned int j;
+ unsigned int i;
if (context->freelist_str.ref > 0)
return;
- for (j = 0; j < 256; ++j)
- for (i = 0; i < context->freelist_str.num[j]; ++i)
- if (context->freelist_str.list[j][i])
- {
- if (edd)
- edd->func.str_free(context->freelist_str.list[j][i]);
- else
- free(context->freelist_str.list[j][i]);
- }
+ for (j = 0; j < EET_FREE_COUNT; ++j)
+ EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
+ if (track)
+ {
+ if (edd)
+ edd->func.str_free(track);
+ else
+ free(track);
+ }
_eet_free_reset(&context->freelist_str);
} /* _eet_freelist_str_free */
_eet_freelist_direct_str_free(Eet_Free_Context *context,
Eet_Data_Descriptor *edd)
{
- int j;
- int i;
+ void *track;
+ Eina_Array_Iterator it;
+ unsigned int j;
+ unsigned int i;
if (context->freelist_direct_str.ref > 0)
return;
- for (j = 0; j < 256; ++j)
- for (i = 0; i < context->freelist_direct_str.num[j]; ++i)
- if (context->freelist_direct_str.list[j][i])
- {
- if (edd)
- edd->func.str_direct_free(context->freelist_direct_str.list[j][i]);
- else
- free(context->freelist_direct_str.list[j][i]);
+ for (j = 0; j < EET_FREE_COUNT; ++j)
+ EINA_ARRAY_ITER_NEXT(&context->freelist_str.list[j], i, track, it)
+ if (track)
+ {
+ if (edd)
+ edd->func.str_direct_free(track);
+ else
+ free(track);
}
_eet_free_reset(&context->freelist_direct_str);
} /* _eet_freelist_direct_str_free */
_eet_freelist_hash_free(Eet_Free_Context *context,
Eet_Data_Descriptor *edd)
{
- int j;
- int i;
+ void *track;
+ Eina_Array_Iterator it;
+ unsigned int j;
+ unsigned int i;
if (context->freelist_hash.ref > 0)
return;
- for (j = 0; j < 256; ++j)
- for (i = 0; i < context->freelist_hash.num[j]; ++i)
- if (context->freelist_hash.list[j][i])
- {
- if (edd)
- edd->func.hash_free(context->freelist_hash.list[j][i]);
- else
- free(context->freelist_hash.list[j][i]);
- }
+ for (j = 0; j < EET_FREE_COUNT; ++j)
+ EINA_ARRAY_ITER_NEXT(&context->freelist_hash.list[j], i, track, it)
+ if (track)
+ {
+ if (edd)
+ edd->func.hash_free(track);
+ else
+ free(track);
+ }
_eet_free_reset(&context->freelist_hash);
} /* _eet_freelist_hash_free */
if (!strcmp(tok3, "char:"))
{
n->type = EET_T_CHAR;
- sscanf(tok4, "%hhi",
+ sscanf(tok4, FMT_CHAR,
&(n->data.value.c));
}
else if (!strcmp(tok3, "short:"))
else if (!strcmp(tok3, "long_long:"))
{
n->type = EET_T_LONG_LONG;
- sscanf(tok4, "%lli",
+ sscanf(tok4, FMT_LONG_LONG,
&(n->data.value.l));
}
else if (!strcmp(tok3, "float:"))
else if (!strcmp(tok3, "uchar:"))
{
n->type = EET_T_UCHAR;
- sscanf(tok4, "%hhu",
+ sscanf(tok4, FMT_UCHAR,
&(n->data.value.uc));
}
else if (!strcmp(tok3, "ushort:"))
else if (!strcmp(tok3, "ulong_long:"))
{
n->type = EET_T_ULONG_LONG;
- sscanf(tok4, "%llu",
+ sscanf(tok4, FMT_ULONG_LONG,
&(n->data.value.ul));
}
else if (!strcmp(tok3, "string:"))
#define NEXT_CHUNK(P, Size, Echnk, Ed)\
{\
- int tmp;\
- tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4;\
- P += (4 + Echnk.size + tmp);\
- Size -= (4 + Echnk.size + tmp);\
+ int __tmp;\
+ __tmp = Ed ? (int)(sizeof(int) * 2) : Echnk.len + 4;\
+ P += (4 + Echnk.size + __tmp);\
+ Size -= (4 + Echnk.size + __tmp);\
}
static void *
const Eet_Dictionary *ed,
Eet_Data_Descriptor *edd,
const void *data_in,
- int size_in)
+ int size_in,
+ void *data_out,
+ int size_out)
{
Eet_Node *result = NULL;
void *data = NULL;
if (edd)
{
- data = edd->func.mem_alloc(edd->size);
+ if (data_out)
+ {
+ if (size_out <= edd->size)
+ data = data_out;
+ }
+ else
+ {
+ data = edd->func.mem_alloc(edd->size);
+ }
+
if (!data)
return NULL;
}
_eet_freelist_all_ref(context);
- if (data)
+ if (data && !data_out)
_eet_freelist_add(context, data);
memset(&chnk, 0, sizeof(Eet_Data_Chunk));
subtype,
echnk->data,
echnk->size,
+ -1,
on_error);
if (edd)
ede ? ede->subtype : NULL,
echnk->data,
echnk->size,
+ -1,
on_error);
if (edd)
for (i = 0; i < count; i++)
{
void *dst = NULL;
- void *data_ret = NULL;
/* Advance to next chunk */
NEXT_CHUNK((*p), (*size), (*echnk), ed);
if (IS_POINTER_TYPE(echnk->type))
{
+ void *data_ret = NULL;
+
POINTER_TYPE_DECODE(context,
ed,
edd,
}
else
{
- STRUCT_TYPE_DECODE(data_ret,
+ STRUCT_TYPE_DECODE(dst,
context,
ed,
ede ? ede->subtype : NULL,
echnk->data,
echnk->size,
+ subsize,
on_error);
- if (dst)
- {
- memcpy(dst, data_ret, subsize);
- if ((ede) && (ede->subtype))
- ede->subtype->func.mem_free(data_ret);
- else if (edd)
- edd->func.mem_free(data_ret);
- else free(data_ret);
- _eet_freelist_del(context, data_ret);
- }
if (!edd)
- childs = eina_list_append(childs, data_ret);
+ childs = eina_list_append(childs, dst);
}
}
on_error:
EINA_LIST_FREE(childs, tmp)
- eet_node_del(tmp);
+ eet_node_del(tmp);
return 0;
} /* eet_data_get_array */
ed,
sede->subtype,
echnk->data,
- echnk->size);
+ echnk->size,
+ data,
+ sede->subtype->size);
if (!data_ret)
goto on_error;
- /* Memcopy the structure content to remove pointer indirection. */
- memcpy(data, data_ret, sede->subtype->size);
-
- /* data_ret is now useless. */
- sede->subtype->func.mem_free(data_ret);
-
/* Set union type. */
if ((!ed) || (!ede->subtype->func.str_direct_alloc))
{
/* FIXME: generate node structure. */
data_ret = _eet_data_descriptor_decode(context,
ed, NULL,
- echnk->data, echnk->size);
+ echnk->data, echnk->size,
+ NULL, 0);
goto on_error;
}
Eet_Data_Chunk chnk;
char *p2;
int size2;
- int ret;
p2 = echnk->data;
size2 = echnk->size;
ed,
sede->subtype,
echnk->data,
- echnk->size);
+ echnk->size,
+ NULL, 0);
if (!data_ret)
break;
/* FIXME: dump node structure. */
data_ret = _eet_data_descriptor_decode(context,
ed, NULL,
- echnk->data, echnk->size);
+ echnk->data, echnk->size,
+ NULL, 0);
goto on_error;
}
ed,
subtype,
echnk->data,
- echnk->size);
+ echnk->size,
+ NULL, 0);
if (!data_ret)
return 0;
eet_data_dump_cipher(Eet_File *ef,
const char *name,
const char *cipher_key,
- void (*dumpfunc)(void *data, const char *str),
+ Eet_Dump_Callback dumpfunc,
void *dumpdata)
{
const Eet_Dictionary *ed = NULL;
return 0;
}
- memset(&context, 0, sizeof (context));
- result = _eet_data_descriptor_decode(&context, ed, NULL, data, size);
+ eet_free_context_init(&context);
+ result = _eet_data_descriptor_decode(&context, ed, NULL, data, size, NULL, 0);
+ eet_free_context_shutdown(&context);
eet_node_dump(result, 0, dumpfunc, dumpdata);
EAPI int
eet_data_dump(Eet_File *ef,
const char *name,
- void (*dumpfunc)(void *data, const char *str),
+ Eet_Dump_Callback dumpfunc,
void *dumpdata)
{
return eet_data_dump_cipher(ef, name, NULL, dumpfunc, dumpdata);
eet_data_text_dump_cipher(const void *data_in,
const char *cipher_key,
int size_in,
- void (*dumpfunc)(void *data, const char *str),
+ Eet_Dump_Callback dumpfunc,
void *dumpdata)
{
void *ret = NULL;
ret_len = size_in;
}
- memset(&context, 0, sizeof (context));
- result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len);
+ eet_free_context_init(&context);
+ result = _eet_data_descriptor_decode(&context, NULL, NULL, ret, ret_len, NULL, 0);
+ eet_free_context_shutdown(&context);
eet_node_dump(result, 0, dumpfunc, dumpdata);
EAPI int
eet_data_text_dump(const void *data_in,
int size_in,
- void (*dumpfunc)(void *data, const char *str),
+ Eet_Dump_Callback dumpfunc,
void *dumpdata)
{
return eet_data_text_dump_cipher(data_in, NULL, size_in, dumpfunc, dumpdata);
return NULL;
}
- memset(&context, 0, sizeof (context));
+ eet_free_context_init(&context);
ret = _eet_data_descriptor_decode(&context,
NULL,
edd,
deciphered,
- deciphered_len);
+ deciphered_len,
+ NULL, 0);
+ eet_free_context_shutdown(&context);
if (data_in != deciphered)
free(deciphered);
return NULL;
}
- memset(&context, 0, sizeof (context));
+ eet_free_context_init(&context);
ret = _eet_data_descriptor_decode(&context,
NULL,
NULL,
deciphered,
- deciphered_len);
+ deciphered_len,
+ NULL, 0);
+ eet_free_context_shutdown(&context);
if (data_in != deciphered)
free(deciphered);