eina_accessor: make carray accessor work properly

a accessor is not really helpfull if it operates like the carray
accessor before this commit. What it was doing is to fill the content of
the "current line" into the data pointer. In a carray the
"current line" is the content of its carray-member.

However, accessors like for inarray array list or inlist do work
completly differently. They are returning the pointer to the "current
line" not the value of the current line.

The only case where this worked is efl_ui_format.c which was only tested
with this accessor, and this accessor also only worked with this
accessor.

Reviewed-by: Cedric BAIL <cedric.bail@free.fr>
Differential Revision: https://phab.enlightenment.org/D10908
This commit is contained in:
Marcel Hollerbach 2019-12-18 17:15:09 +01:00
parent 52aa2f629f
commit 9ccc66b900
3 changed files with 101 additions and 5 deletions

View File

@ -197,7 +197,6 @@ struct _Eina_Accessor_CArray_Length
Eina_Accessor accessor;
void** array;
void** current;
void** end;
unsigned int step;
@ -210,7 +209,16 @@ eina_carray_length_accessor_get_at(Eina_Accessor_CArray_Length *accessor, unsign
return EINA_FALSE;
memcpy(data, (void*) accessor->array + idx*accessor->step, accessor->step);
accessor->current += accessor->step;
return EINA_TRUE;
}
static Eina_Bool
eina_carray_length_accessor_ptr_get_at(Eina_Accessor_CArray_Length *accessor, unsigned int idx, void **data)
{
if (accessor->array + idx*accessor->step >= accessor->end)
return EINA_FALSE;
*data = (((void*)accessor->array) + idx*accessor->step);
return EINA_TRUE;
}
@ -238,8 +246,7 @@ eina_carray_length_accessor_new(void** array, unsigned int step, unsigned int le
EINA_MAGIC_SET(&accessor->accessor, EINA_MAGIC_ACCESSOR);
accessor->array = array;
accessor->current = accessor->array;
accessor->end = accessor->current + length * step;
accessor->end = accessor->array + length * step;
accessor->step = step;
accessor->accessor.version = EINA_ACCESSOR_VERSION;
@ -250,3 +257,26 @@ eina_carray_length_accessor_new(void** array, unsigned int step, unsigned int le
return &accessor->accessor;
}
EAPI Eina_Accessor *
eina_carray_length_ptr_accessor_new(void** array, unsigned int step, unsigned int length)
{
Eina_Accessor_CArray_Length *accessor;
accessor = calloc(1, sizeof (Eina_Accessor_CArray_Length));
if (!accessor) return NULL;
EINA_MAGIC_SET(&accessor->accessor, EINA_MAGIC_ACCESSOR);
accessor->array = array;
accessor->end = accessor->array + length * step;
accessor->step = step;
accessor->accessor.version = EINA_ACCESSOR_VERSION;
accessor->accessor.get_at = FUNC_ACCESSOR_GET_AT(eina_carray_length_accessor_ptr_get_at);
accessor->accessor.get_container = FUNC_ACCESSOR_GET_CONTAINER(
eina_carray_length_accessor_get_container);
accessor->accessor.free = FUNC_ACCESSOR_FREE(eina_carray_length_accessor_free);
return &accessor->accessor;
}

View File

@ -364,6 +364,26 @@ EAPI Eina_Bool eina_accessor_unlock(Eina_Accessor *accessor) EINA_ARG_NONNULL(1)
* @since 1.23
*/
EAPI Eina_Accessor* eina_carray_length_accessor_new(void** array, unsigned int step, unsigned int length);
/**
* @brief Creates an Eina_Accessor that wraps a plain fixed size C array
*
* @param[in] array The array
* @param[in] step The size of one element in the array
* @param[in] length The number of elements in the array
* @return The accessor that will give access to the passed array
*
* You can create it like this:
* int array[] = {1, 2, 3, 4, 1337, 42};
*
* Eina_Accessor* accessor = eina_carray_length_accessor_new(array, sizeof(int), sizeof(array)/sizeof(int));
*
* Note: The difference to eina_carray_length_accessor_new is that this will fill the pointer to the value into the data pointer. *
* @since 1.24
*/
EAPI Eina_Accessor* eina_carray_length_ptr_accessor_new(void** array, unsigned int step, unsigned int length);
/**
* @def EINA_C_ARRAY_ACCESSOR_NEW
* @brief Creates an Eina_Accessor that wraps a plain fixed size C array
@ -379,6 +399,22 @@ EAPI Eina_Accessor* eina_carray_length_accessor_new(void** array, unsigned int s
* @since 1.23
*/
#define EINA_C_ARRAY_ACCESSOR_NEW(Array) eina_carray_length_accessor_new((void**) Array, sizeof (Array[0]), EINA_C_ARRAY_LENGTH(Array))
/**
* @def EINA_C_ARRAY_ACCESSOR_NEW
* @brief Creates an Eina_Accessor that wraps a plain fixed size C array
*
* @param[in] array The array
* @return The accessor that will give access to the passed array
*
* You can create it like this:
* int array[] = {1, 2, 3, 4, 1337, 42};
*
* Eina_Accessor* accessor = EINA_C_ARRAY_ACCESSOR_NEW(array)
*
* @since 1.23
*/
#define EINA_C_ARRAY_ACCESSOR_PTR_NEW(Array) eina_carray_length_ptr_accessor_new((void**) Array, sizeof (Array[0]), EINA_C_ARRAY_LENGTH(Array))
/**
* @}

View File

@ -230,7 +230,7 @@ EFL_START_TEST(eina_accessor_list_simple)
}
EFL_END_TEST
EFL_START_TEST(eina_accessor_carray_simple)
EFL_START_TEST(eina_accessor_carray_simple_ptr)
{
Eina_Accessor *it;
int data[] = { 6, 9, 42, 1, 7, 1337, 81, 1664 };
@ -257,11 +257,41 @@ EFL_START_TEST(eina_accessor_carray_simple)
eina_accessor_free(it);
}
EFL_END_TEST
EFL_START_TEST(eina_accessor_carray_simple)
{
Eina_Accessor *it;
int data[] = { 6, 9, 42, 1, 7, 1337, 81, 1664 };
int *j, c;
it = EINA_C_ARRAY_ACCESSOR_PTR_NEW(data);
EINA_ACCESSOR_FOREACH(it, c, j)
{
ck_assert_int_eq(data[c], *j);
}
fail_if(eina_accessor_data_get(it, 5, (void **)&j) != EINA_TRUE);
fail_if(*j != 1337);
fail_if(eina_accessor_data_get(it, 3, (void **)&j) != EINA_TRUE);
fail_if(*j != 1);
fail_if(eina_accessor_data_get(it, 3, (void **)&j) != EINA_TRUE);
fail_if(*j != 1);
fail_if(eina_accessor_data_get(it, 1, (void **)&j) != EINA_TRUE);
fail_if(*j != 9);
fail_if(eina_accessor_data_get(it, 5, (void **)&j) != EINA_TRUE);
fail_if(*j != 1337);
eina_accessor_free(it);
}
EFL_END_TEST
void
eina_test_accessor(TCase *tc)
{
tcase_add_test(tc, eina_accessor_array_simple);
tcase_add_test(tc, eina_accessor_inlist_simple);
tcase_add_test(tc, eina_accessor_list_simple);
tcase_add_test(tc, eina_accessor_carray_simple_ptr);
tcase_add_test(tc, eina_accessor_carray_simple);
}