* Add EET_DATA_DESCRIPTOR_ADD_HASH_STRING.
+2010-08-06 Cedric BAIL
+
+ * Break eet_eina_* function helper to provide a clean API/ABI to
+ prevent futur break. This should prevent the ABI break that was
+ introduced with release 1.3.0.
+
+ * Add a specific allocator for array. This should fix wrong allocation
+ case discovered with recent edje file format change.
* version member so it is compatible with abi changes, or at least
* will not crash with them.
*/
-#define EET_DATA_DESCRIPTOR_CLASS_VERSION 3
+#define EET_DATA_DESCRIPTOR_CLASS_VERSION 4
/**
* @typedef Eet_Data_Descriptor_Class
void (*str_direct_free)(const char *str); /**< how to free a string returned by str_direct_alloc */
const char *(*type_get)(const void *data, Eina_Bool *unknow); /**< convert any kind of data type to a name that define an Eet_Data_Element. */
Eina_Bool (*type_set)(const char *type, void *data, Eina_Bool unknow); /**< set the type at a particular adress */
+ void * (*array_alloc)(size_t size); /**< how to allocate memory for array (usually malloc()) */
+ void (*array_free)(void *mem); /**< how to free memory for array (usually malloc()) */
} func;
};
* @ingroup Eet_Data_Group
*/
EAPI Eina_Bool eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
+ unsigned int eddc_size,
const char *name,
int size);
* @ingroup Eet_Data_Group
*/
#define EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(clas, type)\
- (eet_eina_stream_data_descriptor_class_set(clas, # type, sizeof(type)))
+ (eet_eina_stream_data_descriptor_class_set(clas, sizeof (*(clas)), # type, sizeof(type)))
/**
* This function is an helper that set all the parameter of an
* @ingroup Eet_Data_Group
*/
EAPI Eina_Bool eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
+ unsigned int eddc_size,
const char *name,
int size);
* @since 1.2.3
* @ingroup Eet_Data_Group
*/
-#define EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(clas, type) (\
- eet_eina_file_data_descriptor_class_set(clas, # type, sizeof(type)))
+#define EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(clas, type)\
+ (eet_eina_file_data_descriptor_class_set(clas, sizeof (*(clas)), # type, sizeof(type)))
/**
* This function frees a data descriptor when it is not needed anymore.
void (*hash_free)(void *h);
const char *(*type_get)(const void *data, Eina_Bool *unknow);
Eina_Bool (*type_set)(const char *type, void *data, Eina_Bool unknow);
+ void * (*array_alloc)(size_t size);
+ void (*array_free)(void *mem);
} func;
struct
{
struct _Eet_Free_Context
{
Eet_Free freelist;
+ Eet_Free freelist_array;
Eet_Free freelist_list;
Eet_Free freelist_hash;
Eet_Free freelist_str;
/*---*/
EAPI Eina_Bool
eet_eina_stream_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
+ /* When we change the structure content in the future, we need to handle old structure type too */
+ unsigned int eddc_size,
const char *name,
int size)
{
- if (!eddc || !name)
+ if (!eddc || !name || eddc_size != sizeof (Eet_Data_Descriptor_Class))
return EINA_FALSE;
eddc->name = name;
eddc->func.hash_add = (void * (*)(void *, const char *, void *))_eet_eina_hash_add_alloc;
eddc->func.hash_free = (void (*)(void *))_eet_eina_hash_free;
+ /* This will cause an ABI incompatibility */
+ eddc->func.array_alloc = _eet_mem_alloc;
+ eddc->func.array_free = _eet_mem_free;
+
return EINA_TRUE;
} /* eet_eina_stream_data_descriptor_class_set */
EAPI Eina_Bool
eet_eina_file_data_descriptor_class_set(Eet_Data_Descriptor_Class *eddc,
+ /* When we change the structure content in the future, we need to handle old structure type too */
+ unsigned int eddc_size,
const char *name,
int size)
{
- if (!eet_eina_stream_data_descriptor_class_set(eddc, name, size))
+ if (!eet_eina_stream_data_descriptor_class_set(eddc, eddc_size, name, size))
return EINA_FALSE;
eddc->version = 2;
edd->func.type_set = eddc->func.type_set;
}
+ if (eddc->version > 3)
+ {
+ edd->func.array_alloc = eddc->func.array_alloc;
+ edd->func.array_free = eddc->func.array_free;
+ }
+
return edd;
} /* _eet_data_descriptor_new */
_eet_free_reset(&context->freelist);
} /* _eet_freelist_free */
+#define _eet_freelist_array_add(Ctx, Data) _eet_free_add(&Ctx->freelist_array, Data);
+#define _eet_freelist_array_reset(Ctx) _eet_free_reset(&Ctx->freelist_array);
+#define _eet_freelist_array_ref(Ctx) _eet_free_ref(&Ctx->freelist_array);
+#define _eet_freelist_array_unref(Ctx) _eet_free_unref(&Ctx->freelist_array);
+
+static void
+_eet_freelist_array_free(Eet_Free_Context *context,
+ Eet_Data_Descriptor *edd)
+{
+ int j;
+ 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 (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]);
+ }
+ _eet_free_reset(&context->freelist_array);
+} /* _eet_freelist_array_free */
+
#define _eet_freelist_list_add(Ctx, Data) _eet_free_add(&Ctx->freelist_list, Data);
#define _eet_freelist_list_reset(Ctx) _eet_free_reset(&Ctx->freelist_list);
#define _eet_freelist_list_ref(Ctx) _eet_free_ref(&Ctx->freelist_list);
_eet_freelist_direct_str_free(context, edd);
_eet_freelist_list_free(context, edd);
_eet_freelist_hash_free(context, edd);
+ _eet_freelist_array_free(context, edd);
_eet_freelist_free(context, edd);
}
else
_eet_freelist_list_reset(context);
_eet_freelist_hash_reset(context);
_eet_freelist_direct_str_reset(context);
+ _eet_freelist_array_reset(context);
}
if (!edd)
_eet_freelist_direct_str_free(context, edd);
_eet_freelist_list_free(context, edd);
_eet_freelist_hash_free(context, edd);
+ _eet_freelist_array_free(context, edd);
_eet_freelist_free(context, edd);
/* FIXME: Warn that something goes wrong here. */
* on the counter offset */
*(int *)(((char *)data) + ede->count - ede->offset) = count;
/* allocate space for the array of elements */
- *(void **)ptr = edd->func.mem_alloc(count * subsize);
+ if (edd->func.array_alloc)
+ *(void **) ptr = edd->func.array_alloc(count * subsize);
+ else
+ *(void **) ptr = edd->func.mem_alloc(count * subsize);
if (!*(void **)ptr)
return 0;
memset(*(void **)ptr, 0, count * subsize);
- _eet_freelist_add(context, *(void **)ptr);
+ _eet_freelist_array_add(context, *(void **)ptr);
}
}
eddc->func.hash_free = (void *)_eet_eina_hash_free;
eddc->func.str_direct_alloc = (void *)_eet_str_direct_alloc;
eddc->func.str_direct_free = (void *)_eet_str_direct_free;
+ eddc->func.array_alloc = NULL;
+ eddc->func.array_free = NULL;
} /* eet_test_setup_eddc */
memset(&etbt.charray, 0, sizeof(etbt.charray));
etbt.charray[0] = "test";
- eet_eina_file_data_descriptor_class_set(&eddc, "Eet_Test_Ex_Type",
+ eet_eina_file_data_descriptor_class_set(&eddc, sizeof (eddc),
+ "Eet_Test_Ex_Type",
sizeof(Eet_Test_Ex_Type));
edd = eet_data_descriptor_file_new(&eddc);
memset(&etbt.charray, 0, sizeof(etbt.charray));
etbt.charray[0] = "test";
- eet_eina_file_data_descriptor_class_set(&eddc, "Eet_Test_Ex_Type",
+ eet_eina_file_data_descriptor_class_set(&eddc, sizeof (eddc),
+ "Eet_Test_Ex_Type",
sizeof(Eet_Test_Ex_Type));
edd = eet_data_descriptor_file_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(edd_5FP, Eet_5FP, "f1", f1, EET_T_F32P32);
EET_DATA_DESCRIPTOR_ADD_BASIC(edd_5FP, Eet_5FP, "f0", f0, EET_T_F32P32);
- eet_eina_stream_data_descriptor_class_set(&eddc, "Eet_5FP", sizeof (Eet_5DBL));
+ eet_eina_stream_data_descriptor_class_set(&eddc, sizeof (eddc), "Eet_5FP", sizeof (Eet_5DBL));
edd_5DBL = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(edd_5DBL, Eet_5DBL, "fp32", fp32, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(edd_5FP, Eet_5FP, "f1", f1, EET_T_F32P32);
EET_DATA_DESCRIPTOR_ADD_BASIC(edd_5FP, Eet_5FP, "f0", f0, EET_T_F32P32);
- eet_eina_file_data_descriptor_class_set(&eddc, "Eet_5FP", sizeof (Eet_5DBL));
+ eet_eina_file_data_descriptor_class_set(&eddc, sizeof (eddc), "Eet_5FP", sizeof (Eet_5DBL));
edd_5DBL = eet_data_descriptor_file_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(edd_5DBL, Eet_5DBL, "fp32", fp32, EET_T_DOUBLE);