1 | /* GStreamer |
2 | * Copyright (C) 2004 Wim Taymans <[email protected]> |
3 | * Copyright (C) 2011 Sebastian Dröge <[email protected]> |
4 | * |
5 | * gstiterator.h: Header for GstIterator |
6 | * |
7 | * This library is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2 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 | * Library General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Library General Public |
18 | * License along with this library; if not, write to the |
19 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
20 | * Boston, MA 02110-1301, USA. |
21 | */ |
22 | |
23 | #ifndef __GST_ITERATOR_H__ |
24 | #define __GST_ITERATOR_H__ |
25 | |
26 | #include <glib-object.h> /* for GValue in the fold */ |
27 | #include <gst/gstconfig.h> |
28 | |
29 | G_BEGIN_DECLS |
30 | |
31 | #define GST_TYPE_ITERATOR (gst_iterator_get_type ()) |
32 | |
33 | /** |
34 | * GstIteratorResult: |
35 | * @GST_ITERATOR_DONE: No more items in the iterator |
36 | * @GST_ITERATOR_OK: An item was retrieved |
37 | * @GST_ITERATOR_RESYNC: Datastructure changed while iterating |
38 | * @GST_ITERATOR_ERROR: An error happened |
39 | * |
40 | * The result of gst_iterator_next(). |
41 | */ |
42 | typedef enum { |
43 | GST_ITERATOR_DONE = 0, |
44 | GST_ITERATOR_OK = 1, |
45 | GST_ITERATOR_RESYNC = 2, |
46 | GST_ITERATOR_ERROR = 3 |
47 | } GstIteratorResult; |
48 | |
49 | typedef struct _GstIterator GstIterator; |
50 | |
51 | /** |
52 | * GstIteratorItem: |
53 | * @GST_ITERATOR_ITEM_SKIP: Skip this item |
54 | * @GST_ITERATOR_ITEM_PASS: Return item |
55 | * @GST_ITERATOR_ITEM_END: Stop after this item. |
56 | * |
57 | * The result of a #GstIteratorItemFunction. |
58 | */ |
59 | typedef enum { |
60 | GST_ITERATOR_ITEM_SKIP = 0, |
61 | GST_ITERATOR_ITEM_PASS = 1, |
62 | GST_ITERATOR_ITEM_END = 2 |
63 | } GstIteratorItem; |
64 | |
65 | /** |
66 | * GstIteratorCopyFunction: |
67 | * @it: The original iterator |
68 | * @copy: The copied iterator |
69 | * |
70 | * This function will be called when creating a copy of @it and should |
71 | * create a copy of all custom iterator fields or increase their |
72 | * reference counts. |
73 | */ |
74 | typedef void (*GstIteratorCopyFunction) (const GstIterator *it, GstIterator *copy); |
75 | |
76 | /** |
77 | * GstIteratorItemFunction: |
78 | * @it: the iterator |
79 | * @item: the item being retrieved. |
80 | * |
81 | * The function that will be called after the next item of the iterator |
82 | * has been retrieved. This function can be used to skip items or stop |
83 | * the iterator. |
84 | * |
85 | * The function will be called with the iterator lock held. |
86 | * |
87 | * Returns: the result of the operation. |
88 | */ |
89 | typedef GstIteratorItem (*GstIteratorItemFunction) (GstIterator *it, const GValue * item); |
90 | |
91 | /** |
92 | * GstIteratorNextFunction: |
93 | * @it: the iterator |
94 | * @result: a pointer to hold the next item |
95 | * |
96 | * The function that will be called when the next element of the iterator |
97 | * should be retrieved. |
98 | * |
99 | * Implementors of a #GstIterator should implement this |
100 | * function and pass it to the constructor of the custom iterator. |
101 | * The function will be called with the iterator lock held. |
102 | * |
103 | * Returns: the result of the operation. |
104 | */ |
105 | typedef GstIteratorResult (*GstIteratorNextFunction) (GstIterator *it, GValue *result); |
106 | /** |
107 | * GstIteratorResyncFunction: |
108 | * @it: the iterator |
109 | * |
110 | * This function will be called whenever a concurrent update happened |
111 | * to the iterated datastructure. The implementor of the iterator should |
112 | * restart the iterator from the beginning and clean up any state it might |
113 | * have. |
114 | * |
115 | * Implementors of a #GstIterator should implement this |
116 | * function and pass it to the constructor of the custom iterator. |
117 | * The function will be called with the iterator lock held. |
118 | */ |
119 | typedef void (*GstIteratorResyncFunction) (GstIterator *it); |
120 | /** |
121 | * GstIteratorFreeFunction: |
122 | * @it: the iterator |
123 | * |
124 | * This function will be called when the iterator is freed. |
125 | * |
126 | * Implementors of a #GstIterator should implement this |
127 | * function and pass it to the constructor of the custom iterator. |
128 | * The function will be called with the iterator lock held. |
129 | */ |
130 | typedef void (*GstIteratorFreeFunction) (GstIterator *it); |
131 | |
132 | /** |
133 | * GstIteratorForeachFunction: |
134 | * @item: The item |
135 | * @user_data: User data |
136 | * |
137 | * A function that is called by gst_iterator_foreach() for every element. |
138 | */ |
139 | typedef void (*GstIteratorForeachFunction) (const GValue * item, gpointer user_data); |
140 | |
141 | /** |
142 | * GstIteratorFoldFunction: |
143 | * @item: the item to fold |
144 | * @ret: a #GValue collecting the result |
145 | * @user_data: data passed to gst_iterator_fold() |
146 | * |
147 | * A function to be passed to gst_iterator_fold(). |
148 | * |
149 | * Returns: %TRUE if the fold should continue, %FALSE if it should stop. |
150 | */ |
151 | typedef gboolean (*GstIteratorFoldFunction) (const GValue * item, GValue * ret, gpointer user_data); |
152 | |
153 | /** |
154 | * GST_ITERATOR: |
155 | * @it: the #GstIterator value |
156 | * |
157 | * Macro to cast to a #GstIterator |
158 | */ |
159 | #define GST_ITERATOR(it) ((GstIterator*)(it)) |
160 | /** |
161 | * GST_ITERATOR_LOCK: |
162 | * @it: the #GstIterator to get the lock of |
163 | * |
164 | * Macro to get the lock protecting the datastructure being iterated. |
165 | */ |
166 | #define GST_ITERATOR_LOCK(it) (GST_ITERATOR(it)->lock) |
167 | /** |
168 | * GST_ITERATOR_COOKIE: |
169 | * @it: the #GstIterator to get the cookie of |
170 | * |
171 | * Macro to get the cookie of a #GstIterator. The cookie of the |
172 | * iterator is the value of the master cookie when the iterator |
173 | * was created. |
174 | * Whenever the iterator is iterated, the value is compared to the |
175 | * value of the master cookie. If they are different, a concurrent |
176 | * modification happened to the iterator and a resync is needed. |
177 | */ |
178 | #define GST_ITERATOR_COOKIE(it) (GST_ITERATOR(it)->cookie) |
179 | /** |
180 | * GST_ITERATOR_ORIG_COOKIE: |
181 | * @it: the #GstIterator to get the master cookie of |
182 | * |
183 | * Macro to get a pointer to where the master cookie is stored. The |
184 | * master cookie protects the structure being iterated and gets updated |
185 | * whenever the datastructure changes. |
186 | */ |
187 | #define GST_ITERATOR_ORIG_COOKIE(it) (GST_ITERATOR(it)->master_cookie) |
188 | |
189 | /** |
190 | * GstIterator: |
191 | * @copy: The function to copy the iterator |
192 | * @next: The function to get the next item in the iterator |
193 | * @item: The function to be called for each item retrieved |
194 | * @resync: The function to call when a resync is needed. |
195 | * @free: The function to call when the iterator is freed |
196 | * @pushed: The iterator that is currently pushed with gst_iterator_push() |
197 | * @type: The type of the object that this iterator will return |
198 | * @lock: The lock protecting the data structure and the cookie. |
199 | * @cookie: The cookie; the value of the master_cookie when this iterator was |
200 | * created. |
201 | * @master_cookie: A pointer to the master cookie. |
202 | * @size: the size of the iterator |
203 | * |
204 | * #GstIterator base structure. The values of this structure are |
205 | * protected for subclasses, use the methods to use the #GstIterator. |
206 | */ |
207 | struct _GstIterator { |
208 | /*< protected >*/ |
209 | GstIteratorCopyFunction copy; |
210 | GstIteratorNextFunction next; |
211 | GstIteratorItemFunction item; |
212 | GstIteratorResyncFunction resync; |
213 | GstIteratorFreeFunction free; |
214 | |
215 | GstIterator *pushed; /* pushed iterator */ |
216 | |
217 | GType type; |
218 | GMutex *lock; |
219 | guint32 cookie; /* cookie of the iterator */ |
220 | guint32 *master_cookie; /* pointer to guint32 holding the cookie when this |
221 | iterator was created */ |
222 | guint size; |
223 | |
224 | /*< private >*/ |
225 | gpointer _gst_reserved[GST_PADDING]; |
226 | }; |
227 | |
228 | GST_API |
229 | GType gst_iterator_get_type (void); |
230 | |
231 | /* creating iterators */ |
232 | |
233 | GST_API |
234 | GstIterator* gst_iterator_new (guint size, |
235 | GType type, |
236 | GMutex *lock, |
237 | guint32 *master_cookie, |
238 | GstIteratorCopyFunction copy, |
239 | GstIteratorNextFunction next, |
240 | GstIteratorItemFunction item, |
241 | GstIteratorResyncFunction resync, |
242 | GstIteratorFreeFunction free) G_GNUC_MALLOC; |
243 | GST_API |
244 | GstIterator* gst_iterator_new_list (GType type, |
245 | GMutex *lock, |
246 | guint32 *master_cookie, |
247 | GList **list, |
248 | GObject * owner, |
249 | GstIteratorItemFunction item) G_GNUC_MALLOC; |
250 | GST_API |
251 | GstIterator* gst_iterator_new_single (GType type, |
252 | const GValue * object) G_GNUC_MALLOC; |
253 | GST_API |
254 | GstIterator* gst_iterator_copy (const GstIterator *it) G_GNUC_MALLOC; |
255 | |
256 | /* using iterators */ |
257 | |
258 | GST_API |
259 | GstIteratorResult gst_iterator_next (GstIterator *it, GValue * elem); |
260 | |
261 | GST_API |
262 | void gst_iterator_resync (GstIterator *it); |
263 | |
264 | GST_API |
265 | void gst_iterator_free (GstIterator *it); |
266 | |
267 | GST_API |
268 | void gst_iterator_push (GstIterator *it, GstIterator *other); |
269 | |
270 | /* higher-order functions that operate on iterators */ |
271 | |
272 | GST_API |
273 | GstIterator* gst_iterator_filter (GstIterator *it, GCompareFunc func, |
274 | const GValue * user_data) G_GNUC_MALLOC; |
275 | GST_API |
276 | GstIteratorResult gst_iterator_fold (GstIterator *it, |
277 | GstIteratorFoldFunction func, |
278 | GValue *ret, gpointer user_data); |
279 | GST_API |
280 | GstIteratorResult gst_iterator_foreach (GstIterator *it, |
281 | GstIteratorForeachFunction func, gpointer user_data); |
282 | GST_API |
283 | gboolean gst_iterator_find_custom (GstIterator *it, GCompareFunc func, |
284 | GValue *elem, gpointer user_data); |
285 | |
286 | #ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC |
287 | G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstIterator, gst_iterator_free) |
288 | #endif |
289 | |
290 | G_END_DECLS |
291 | |
292 | #endif /* __GST_ITERATOR_H__ */ |
293 | |