1708fc8a09705c8b07af3290fabd7633d6840653
[profile/ivi/eina.git] / src / lib / eina_accessor.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4 /* EINA - EFL data type library
5  * Copyright (C) 2002-2008 Cedric Bail
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library;
19  * if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #include <stdlib.h>
27
28 #include "eina_config.h"
29 #include "eina_private.h"
30
31 /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
32 #include "eina_safety_checks.h"
33 #include "eina_accessor.h"
34
35 /*============================================================================*
36  *                                  Local                                     *
37  *============================================================================*/
38
39 /**
40  * @cond LOCAL
41  */
42
43 #define EINA_MAGIC_CHECK_ACCESSOR(d)                            \
44   do {                                                          \
45     if (!EINA_MAGIC_CHECK(d, EINA_MAGIC_ACCESSOR))              \
46       EINA_MAGIC_FAIL(d, EINA_MAGIC_ACCESSOR);                  \
47   } while(0);
48
49 /**
50  * @endcond
51  */
52
53 /*============================================================================*
54  *                                 Global                                     *
55  *============================================================================*/
56
57 /*============================================================================*
58  *                                   API                                      *
59  *============================================================================*/
60
61 /**
62  * @addtogroup Eina_Accessor_Group Accessor Functions
63  *
64  * @brief These functions manage accessor on containers.
65  *
66  * These functions allow to access elements of a container in a
67  * generic way, without knowing which container is used (a bit like
68  * iterators in the C++ STL). Accessors allows random access (that is, any
69  * element in the container). For sequential access, see
70  * @ref Eina_Iterator_Group.
71  *
72  * An accessor is created from container data types, so no creation
73  * function is available here. An accessor is deleted with
74  * eina_accessor_free(). To get the data of an element at a given
75  * position, use eina_accessor_data_get(). To call a function on
76  * chosen elements of a container, use eina_accessor_over().
77  *
78  * @{
79  */
80
81 /**
82  * @brief Free an accessor.
83  *
84  * @param accessor The accessor to free.
85  *
86  * This function frees @p accessor if it is not @c NULL;
87  */
88 EAPI void
89 eina_accessor_free(Eina_Accessor *accessor)
90 {
91    EINA_MAGIC_CHECK_ACCESSOR(accessor);
92    EINA_SAFETY_ON_NULL_RETURN(accessor);
93    EINA_SAFETY_ON_NULL_RETURN(accessor->free);
94    accessor->free(accessor);
95 }
96
97 /**
98  * @brief Return the container of an accessor.
99  *
100  * @param accessor The accessor.
101  * @return The container which created the accessor.
102  *
103  * This function returns the container which created @p accessor. If
104  * @p accessor is @c NULL, this function returns @c NULL.
105  */
106 EAPI void *
107 eina_accessor_container_get(Eina_Accessor *accessor)
108 {
109    EINA_MAGIC_CHECK_ACCESSOR(accessor);
110    EINA_SAFETY_ON_NULL_RETURN_VAL(accessor, NULL);
111    EINA_SAFETY_ON_NULL_RETURN_VAL(accessor->get_container, NULL);
112    return accessor->get_container(accessor);
113 }
114
115 /**
116  * @brief Retrieve the data of an accessor at a given position.
117  *
118  * @param accessor The accessor.
119  * @param position The position of the element.
120  * @param data The pointer that stores the data to retrieve.
121  * @return #EINA_TRUE on success, #EINA_FALSE otherwise.
122  *
123  * This function retrieves the data of the element pointed by
124  * @p accessor at the porition @p position, and stores it in
125  * @p data. If @p accessor is @c NULL or if an error occurred,
126  * #EINA_FALSE is returned, otherwise EINA_TRUE is returned.
127  */
128 EAPI Eina_Bool
129 eina_accessor_data_get(Eina_Accessor *accessor, unsigned int position, void **data)
130 {
131    EINA_MAGIC_CHECK_ACCESSOR(accessor);
132    EINA_SAFETY_ON_NULL_RETURN_VAL(accessor, EINA_FALSE);
133    EINA_SAFETY_ON_NULL_RETURN_VAL(accessor->get_at, EINA_FALSE);
134    EINA_SAFETY_ON_NULL_RETURN_VAL(data, EINA_FALSE);
135    return accessor->get_at(accessor, position, data);
136 }
137
138 /**
139  * @brief Iterate over the container and execute a callback on chosen elements.
140  *
141  * @param accessor The accessor.
142  * @param cb The callback called on the chosen elements.
143  * @param start The position of the first element.
144  * @param end The position of the last element.
145  * @param fdata The data passed to the callback.
146  *
147  * This function iterates over the elements pointed by @p accessor,
148  * starting from the element at position @p start and ending to the
149  * element at position @p end. For Each element, the callback
150  * @p cb is called with the data @p fdata. If @p accessor is @c NULL
151  * or if @p start is greter or equal than @p end, the function returns
152  * immediatly.
153  */
154 EAPI void
155 eina_accessor_over(Eina_Accessor *accessor,
156                    Eina_Each cb,
157                    unsigned int start,
158                    unsigned int end,
159                    const void *fdata)
160 {
161    const void *container;
162    void *data;
163    unsigned int i;
164
165    EINA_MAGIC_CHECK_ACCESSOR(accessor);
166    EINA_SAFETY_ON_NULL_RETURN(accessor);
167    EINA_SAFETY_ON_NULL_RETURN(accessor->get_container);
168    EINA_SAFETY_ON_NULL_RETURN(accessor->get_at);
169    EINA_SAFETY_ON_NULL_RETURN(cb);
170    EINA_SAFETY_ON_FALSE_RETURN(start < end);
171
172    container = accessor->get_container(accessor);
173    for (i = start; i < end && accessor->get_at(accessor, i, &data) == EINA_TRUE; ++i)
174       if (cb(container, data, (void*) fdata) != EINA_TRUE) return ;
175 }
176
177 /**
178  * @}
179  */