diff --git a/src/lib/eina/eina_accessor.c b/src/lib/eina/eina_accessor.c index 1c5889f918..67494987a9 100644 --- a/src/lib/eina/eina_accessor.c +++ b/src/lib/eina/eina_accessor.c @@ -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; +} diff --git a/src/lib/eina/eina_accessor.h b/src/lib/eina/eina_accessor.h index 7b47d31a01..ccfccceba3 100644 --- a/src/lib/eina/eina_accessor.h +++ b/src/lib/eina/eina_accessor.h @@ -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)) + /** * @} diff --git a/src/tests/eina/eina_test_accessor.c b/src/tests/eina/eina_test_accessor.c index 734d833205..62e77e06ee 100644 --- a/src/tests/eina/eina_test_accessor.c +++ b/src/tests/eina/eina_test_accessor.c @@ -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); }