EFL 1.7 svn doobies
[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    if (!iterator)
99      return;
100
101    EINA_MAGIC_CHECK_ITERATOR(iterator);
102    EINA_SAFETY_ON_NULL_RETURN(iterator->free);
103    iterator->free(iterator);
104 }
105
106 EAPI void *
107 eina_iterator_container_get(Eina_Iterator *iterator)
108 {
109    EINA_MAGIC_CHECK_ITERATOR(iterator);
110    EINA_SAFETY_ON_NULL_RETURN_VAL(iterator,                NULL);
111    EINA_SAFETY_ON_NULL_RETURN_VAL(iterator->get_container, NULL);
112    return iterator->get_container(iterator);
113 }
114
115 EAPI Eina_Bool
116 eina_iterator_next(Eina_Iterator *iterator, void **data)
117 {
118    if (!iterator)
119      return EINA_FALSE;
120
121    EINA_MAGIC_CHECK_ITERATOR(iterator);
122    EINA_SAFETY_ON_NULL_RETURN_VAL(iterator->next, EINA_FALSE);
123    EINA_SAFETY_ON_NULL_RETURN_VAL(data,           EINA_FALSE);
124    return iterator->next(iterator, data);
125 }
126
127 EAPI void
128 eina_iterator_foreach(Eina_Iterator *iterator,
129                       Eina_Each_Cb cb,
130                       const void *fdata)
131 {
132    const void *container;
133    void *data;
134
135    if (!iterator)
136      return;
137
138    EINA_MAGIC_CHECK_ITERATOR(iterator);
139    EINA_SAFETY_ON_NULL_RETURN(iterator->get_container);
140    EINA_SAFETY_ON_NULL_RETURN(iterator->next);
141    EINA_SAFETY_ON_NULL_RETURN(cb);
142
143    if (!eina_iterator_lock(iterator)) return ;
144
145    container = iterator->get_container(iterator);
146    while (iterator->next(iterator, &data) == EINA_TRUE)
147      {
148         if (cb(container, data, (void *)fdata) != EINA_TRUE)
149           goto on_exit;
150      }
151
152 on_exit:
153    (void) eina_iterator_unlock(iterator);
154 }
155
156 EAPI Eina_Bool
157 eina_iterator_lock(Eina_Iterator *iterator)
158 {
159    EINA_MAGIC_CHECK_ITERATOR(iterator);
160    EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, EINA_FALSE);
161
162    if (iterator->lock)
163      return iterator->lock(iterator);
164    return EINA_TRUE;
165 }
166
167 EAPI Eina_Bool
168 eina_iterator_unlock(Eina_Iterator *iterator)
169 {
170    EINA_MAGIC_CHECK_ITERATOR(iterator);
171    EINA_SAFETY_ON_NULL_RETURN_VAL(iterator, EINA_FALSE);
172
173    if (iterator->unlock)
174      return iterator->unlock(iterator);
175    return EINA_TRUE;
176 }