eina: add a way to iterate over a pure C array with no NUL terminating element.
authorCedric BAIL <cedric@osg.samsung.com>
Thu, 15 Nov 2018 23:37:15 +0000 (15:37 -0800)
committerHermet Park <hermetpark@gmail.com>
Wed, 5 Dec 2018 05:37:06 +0000 (14:37 +0900)
Reviewed-by: Vitor Sousa da Silva <vitorsousa@expertisesolutions.com.br>
Differential Revision: https://phab.enlightenment.org/D7284

src/lib/eina/eina_iterator.c
src/lib/eina/eina_iterator.h

index 4a4e281..d025b6a 100644 (file)
@@ -229,6 +229,67 @@ eina_carray_iterator_new(void** array)
    return &it->iterator;
 }
 
+typedef struct _Eina_Iterator_CArray_Length Eina_Iterator_CArray_Length;
+
+struct _Eina_Iterator_CArray_Length
+{
+   Eina_Iterator iterator;
+
+   void** array;
+   uintptr_t current;
+
+   uintptr_t end;
+   unsigned int step;
+};
+
+static Eina_Bool
+eina_carray_length_iterator_next(Eina_Iterator_CArray_Length *it, void **data)
+{
+   if (it->current >= it->end)
+     return EINA_FALSE;
+
+   memcpy(data, (void*) it->current, it->step);
+   it->current += it->step;
+
+   return EINA_TRUE;
+}
+
+static void**
+eina_carray_length_iterator_get_container(Eina_Iterator_CArray_Length *it)
+{
+   return it->array;
+}
+
+static void
+eina_carray_length_iterator_free(Eina_Iterator_CArray_Length *it)
+{
+   free(it);
+}
+
+EAPI Eina_Iterator *
+eina_carray_length_iterator_new(void** array, unsigned int step, unsigned int length)
+{
+   Eina_Iterator_CArray_Length *it;
+
+   it = calloc(1, sizeof (Eina_Iterator_CArray_Length));
+   if (!it) return NULL;
+
+   EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
+
+   it->array = array;
+   it->current = (uintptr_t) it->array;
+   it->end = it->current + length * step;
+   it->step = step;
+
+   it->iterator.version = EINA_ITERATOR_VERSION;
+   it->iterator.next = FUNC_ITERATOR_NEXT(eina_carray_length_iterator_next);
+   it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
+      eina_carray_length_iterator_get_container);
+   it->iterator.free = FUNC_ITERATOR_FREE(eina_carray_length_iterator_free);
+
+   return &it->iterator;
+}
+
 typedef struct {
    Eina_Iterator iterator;
 
index 6c33db1..1bed2bd 100644 (file)
@@ -294,11 +294,42 @@ EAPI Eina_Bool eina_iterator_unlock(Eina_Iterator *iterator) EINA_ARG_NONNULL(1)
  * int array[] = {1, 2, 3, 4};
  * int* array2[] = {&array[0], &array[1], &array[2], &array[3], NULL};
  *
- * Eina_Iterator* iterator = eina_carray_iterator_new((void**)array);
+ * Eina_Iterator* iterator = eina_carray_iterator_new((void**)array2);
  *
  * @since 1.18
  */
-EAPI Eina_Iterator* eina_carray_iterator_new(void** array) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+EAPI Eina_Iterator *eina_carray_iterator_new(void** array) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+/**
+ * @brief Creates an Eina_Iterator that iterates through a
+ * C array of specified size.
+ *
+ * @param[in] array The array
+ *
+ * You can create it like this:
+ * int array[] = {1, 2, 3, 4};
+ *
+ * Eina_Iterator* iterator = eina_carray_length_iterator_new((void**)array, sizeof (array[0]), (EINA_C_ARRAY_LENGTH(array));
+ *
+ * @since 1.22
+ */
+EAPI Eina_Iterator *eina_carray_length_iterator_new(void** array, unsigned int step, unsigned int length) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+
+/**
+ * @def EINA_C_ARRAY_ITERATOR_NEW
+ * @brief Creates an Eina_Iterator that iterates through a
+ * NUL-terminated C array.
+ *
+ * @param[in] array The NUL-terminated array
+ *
+ * You can create it like this:
+ * int array[] = {1, 2, 3, 4};
+ *
+ * Eina_Iterator* iterator = EINA_C_ARRAY_ITERATOR_NEW(array);
+ *
+ * @since 1.22
+ */
+#define EINA_C_ARRAY_ITERATOR_NEW(Array) eina_carray_length_iterator_new((void**) Array, sizeof (Array[0]), EINA_C_ARRAY_LENGTH(Array))
 
 /**
  * @brief Creates a new iterator which which iterates through all elements with are accepted by the filter callback