eina: add accessors for c arrays

This adds a new API which can be used to get access to a carray via the eina_accessor API.
This commit is contained in:
Marcel Hollerbach 2019-07-01 19:18:11 +02:00 committed by Xavi Artigas
parent 132520bc7b
commit 223a433be8
3 changed files with 121 additions and 0 deletions

View File

@ -189,3 +189,64 @@ eina_accessor_unlock(Eina_Accessor *accessor)
return accessor->unlock(accessor);
return EINA_TRUE;
}
typedef struct _Eina_Accessor_CArray_Length Eina_Accessor_CArray_Length;
struct _Eina_Accessor_CArray_Length
{
Eina_Accessor accessor;
void** array;
void** current;
void** end;
unsigned int step;
};
static Eina_Bool
eina_carray_length_accessor_get_at(Eina_Accessor_CArray_Length *accessor, unsigned int idx, void **data)
{
if (accessor->array + idx*accessor->step >= accessor->end)
return EINA_FALSE;
memcpy(data, (void*) accessor->array + idx*accessor->step, accessor->step);
accessor->current += accessor->step;
return EINA_TRUE;
}
static void**
eina_carray_length_accessor_get_container(Eina_Accessor_CArray_Length *accessor)
{
return accessor->array;
}
static void
eina_carray_length_accessor_free(Eina_Accessor_CArray_Length *accessor)
{
free(accessor);
}
EAPI Eina_Accessor *
eina_carray_length_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->current = accessor->array;
accessor->end = accessor->current + length * step;
accessor->step = step;
accessor->accessor.version = EINA_ACCESSOR_VERSION;
accessor->accessor.get_at = FUNC_ACCESSOR_GET_AT(eina_carray_length_accessor_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

@ -348,6 +348,38 @@ EAPI Eina_Bool eina_accessor_unlock(Eina_Accessor *accessor) EINA_ARG_NONNULL(1)
eina_accessor_data_get((accessor), (counter), (void **)(void *)&(data)); \
(counter)++)
/**
* @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));
*
* @since 1.23
*/
EAPI Eina_Accessor* eina_carray_length_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
*
* @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_NEW(Array) eina_carray_length_accessor_new((void**) Array, sizeof (Array[0]), EINA_C_ARRAY_LENGTH(Array))
/**
* @}
*/

View File

@ -230,10 +230,38 @@ EFL_START_TEST(eina_accessor_list_simple)
}
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_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);
}