1 /* GStreamer 2 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com> 3 * Copyright (C) 2011 Sebastian Dröge <sebastian.droege@collabora.co.uk> 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 G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstIterator, gst_iterator_free) 287 288 G_END_DECLS 289 290 #endif /* __GST_ITERATOR_H__ */ 291