| 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 |  |