0721066e54e318d3b83ce73fa749ca8fe7518bc0
[profile/ivi/eina.git] / src / lib / eina_iterator.c
1 /* EINA - EFL data type library
2  * Copyright (C) 2002-2008 Cedric Bail
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library;
16  * if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 #include <stdlib.h>
24
25 #include "eina_config.h"
26 #include "eina_private.h"
27
28 /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
29 #include "eina_safety_checks.h"
30 #include "eina_iterator.h"
31
32 /*============================================================================*
33 *                                  Local                                     *
34 *============================================================================*/
35
36 /**
37  * @cond LOCAL
38  */
39
40 static const char EINA_MAGIC_ITERATOR_STR[] = "Eina Iterator";
41
42 #define EINA_MAGIC_CHECK_ITERATOR(d)                            \
43    do {                                                          \
44         if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ITERATOR)) {              \
45              EINA_MAGIC_FAIL(d, EINA_MAGIC_ITERATOR); }                  \
46      } while(0)
47
48 /**
49  * @endcond
50  */
51
52
53 /*============================================================================*
54 *                                 Global                                     *
55 *============================================================================*/
56
57 /**
58  * @internal
59  * @brief Initialize the iterator module.
60  *
61  * @return #EINA_TRUE on success, #EINA_FALSE on failure.
62  *
63  * This function sets up the iterator module of Eina. It is called by
64  * eina_init().
65  *
66  * @see eina_init()
67  */
68 Eina_Bool
69 eina_iterator_init(void)
70 {
71    return eina_magic_string_set(EINA_MAGIC_ITERATOR, EINA_MAGIC_ITERATOR_STR);
72 }
73
74 /**
75  * @internal
76  * @brief Shut down the iterator module.
77  *
78  * @return #EINA_TRUE on success, #EINA_FALSE on failure.
79  *
80  * This function shuts down the iterator module set up by
81  * eina_iterator_init(). It is called by eina_shutdown().
82  *
83  * @see eina_shutdown()
84  */
85 Eina_Bool
86 eina_iterator_shutdown(void)
87 {
88    return EINA_TRUE;
89 }
90
91 /*============================================================================*
92 *                                   API                                      *
93 *============================================================================*/
94
95 EAPI void
96 eina_iterator_free(Eina_Iterator *iterator)
97 {
98    EINA_MAGIC_CHECK_ITERATOR(iterator);
99    EINA_SAFETY_ON_NULL_RETURN(iterator);
100    EINA_SAFETY_ON_NULL_RETURN(iterator->free);
101    iterator->free(iterator);
102 }
103
104 EAPI void *
105 eina_iterator_container_get(Eina_Iterator *iterator)
106 {
107    EINA_MAGIC_CHECK_ITERATOR(iterator);
108    EINA_SAFETY_ON_NULL_RETURN_VAL(iterator,                NULL);
109    EINA_SAFETY_ON_NULL_RETURN_VAL(iterator->get_container, NULL);
110    return iterator->get_container(iterator);
111 }
112
113 EAPI Eina_Bool
114 eina_iterator_next(Eina_Iterator *iterator, void **data)
115 {
116    if (!iterator)
117       return EINA_FALSE;
118
119    EINA_MAGIC_CHECK_ITERATOR(iterator);
120    EINA_SAFETY_ON_NULL_RETURN_VAL(iterator,       EINA_FALSE);
121    EINA_SAFETY_ON_NULL_RETURN_VAL(iterator->next, EINA_FALSE);
122    EINA_SAFETY_ON_NULL_RETURN_VAL(data,           EINA_FALSE);
123    return iterator->next(iterator, data);
124 }
125
126 EAPI void
127 eina_iterator_foreach(Eina_Iterator *iterator,
128                       Eina_Each_Cb cb,
129                       const void *fdata)
130 {
131    const void *container;
132    void *data;
133
134    EINA_MAGIC_CHECK_ITERATOR(iterator);
135    EINA_SAFETY_ON_NULL_RETURN(iterator);
136    EINA_SAFETY_ON_NULL_RETURN(iterator->get_container);
137    EINA_SAFETY_ON_NULL_RETURN(iterator->next);
138    EINA_SAFETY_ON_NULL_RETURN(cb);
139
140    if (!eina_iterator_lock(iterator)) return ;
141
142    container = iterator->get_container(iterator);
143    while (iterator->next(iterator, &data) == EINA_TRUE) {
144         if (cb(container, data, (void *)fdata) != EINA_TRUE)
145            goto on_exit;
146      }
147
148  on_exit:
149    (void) eina_iterator_unlock(iterator);
150 }
151
152 EAPI Eina_Bool
153 eina_iterator_lock(Eina_Iterator *iterator)
154 {
155    EINA_MAGIC_CHECK_ITERATOR(iterator);
156    EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, EINA_FALSE);
157
158    if (iterator->lock)
159       return iterator->lock(iterator);
160    return EINA_TRUE;
161 }
162
163 EAPI Eina_Bool
164 eina_iterator_unlock(Eina_Iterator *iterator)
165 {
166    EINA_MAGIC_CHECK_ITERATOR(iterator);
167    EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, EINA_FALSE);
168
169    if (iterator->unlock)
170       return iterator->unlock(iterator);
171    return EINA_TRUE;
172 }